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/ndr_lsa.h"
26 #include "librpc/gen_ndr/ndr_samr.h"
28 #include "lib/crypto/crypto.h"
29 #include "libcli/auth/proto.h"
30 #include "libcli/security/proto.h"
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
39 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
40 struct policy_handle *handle);
42 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
43 struct policy_handle *handle);
45 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
46 struct policy_handle *handle);
48 static void init_lsa_String(struct lsa_String *string, const char *s)
53 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 struct policy_handle *handle)
60 r.out.handle = handle;
62 status = dcerpc_samr_Close(p, mem_ctx, &r);
63 if (!NT_STATUS_IS_OK(status)) {
64 printf("Close handle failed - %s\n", nt_errstr(status));
71 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
72 struct policy_handle *handle)
75 struct samr_Shutdown r;
77 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
78 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
82 r.in.connect_handle = handle;
84 printf("testing samr_Shutdown\n");
86 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
87 if (!NT_STATUS_IS_OK(status)) {
88 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
95 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
96 struct policy_handle *handle)
99 struct samr_SetDsrmPassword r;
100 struct lsa_String string;
101 struct samr_Password hash;
103 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
104 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
108 E_md4hash("TeSTDSRM123", hash.hash);
110 init_lsa_String(&string, "Administrator");
116 printf("testing samr_SetDsrmPassword\n");
118 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
119 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
120 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
128 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
129 struct policy_handle *handle)
132 struct samr_QuerySecurity r;
133 struct samr_SetSecurity s;
135 r.in.handle = handle;
138 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
139 if (!NT_STATUS_IS_OK(status)) {
140 printf("QuerySecurity failed - %s\n", nt_errstr(status));
144 if (r.out.sdbuf == NULL) {
148 s.in.handle = handle;
150 s.in.sdbuf = r.out.sdbuf;
152 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
153 if (!NT_STATUS_IS_OK(status)) {
154 printf("SetSecurity failed - %s\n", nt_errstr(status));
158 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
159 if (!NT_STATUS_IS_OK(status)) {
160 printf("QuerySecurity failed - %s\n", nt_errstr(status));
168 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
169 struct policy_handle *handle, uint32_t base_acct_flags,
170 const char *base_account_name)
173 struct samr_SetUserInfo s;
174 struct samr_SetUserInfo2 s2;
175 struct samr_QueryUserInfo q;
176 struct samr_QueryUserInfo q0;
177 union samr_UserInfo u;
179 const char *test_account_name;
181 uint32_t user_extra_flags = 0;
182 if (base_acct_flags == ACB_NORMAL) {
183 /* When created, accounts are expired by default */
184 user_extra_flags = ACB_PW_EXPIRED;
187 s.in.user_handle = handle;
190 s2.in.user_handle = handle;
193 q.in.user_handle = handle;
197 #define TESTCALL(call, r) \
198 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
199 if (!NT_STATUS_IS_OK(status)) { \
200 printf(#call " level %u failed - %s (%s)\n", \
201 r.in.level, nt_errstr(status), __location__); \
206 #define STRING_EQUAL(s1, s2, field) \
207 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
208 printf("Failed to set %s to '%s' (%s)\n", \
209 #field, s2, __location__); \
214 #define INT_EQUAL(i1, i2, field) \
216 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
217 #field, i2, i1, __location__); \
222 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
223 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
225 TESTCALL(QueryUserInfo, q) \
227 s2.in.level = lvl1; \
230 ZERO_STRUCT(u.info21); \
231 u.info21.fields_present = fpval; \
233 init_lsa_String(&u.info ## lvl1.field1, value); \
234 TESTCALL(SetUserInfo, s) \
235 TESTCALL(SetUserInfo2, s2) \
236 init_lsa_String(&u.info ## lvl1.field1, ""); \
237 TESTCALL(QueryUserInfo, q); \
239 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
241 TESTCALL(QueryUserInfo, q) \
243 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
246 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
247 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
249 TESTCALL(QueryUserInfo, q) \
251 s2.in.level = lvl1; \
254 uint8_t *bits = u.info21.logon_hours.bits; \
255 ZERO_STRUCT(u.info21); \
256 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
257 u.info21.logon_hours.units_per_week = 168; \
258 u.info21.logon_hours.bits = bits; \
260 u.info21.fields_present = fpval; \
262 u.info ## lvl1.field1 = value; \
263 TESTCALL(SetUserInfo, s) \
264 TESTCALL(SetUserInfo2, s2) \
265 u.info ## lvl1.field1 = 0; \
266 TESTCALL(QueryUserInfo, q); \
268 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
270 TESTCALL(QueryUserInfo, q) \
272 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
275 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
276 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
280 do { TESTCALL(QueryUserInfo, q0) } while (0);
282 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
283 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
284 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
287 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
288 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
289 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
290 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
291 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
292 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
293 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
294 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
295 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
296 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
297 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
298 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
299 test_account_name = base_account_name;
300 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
301 SAMR_FIELD_ACCOUNT_NAME);
303 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
304 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
305 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
306 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
307 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
308 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
309 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
310 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
311 SAMR_FIELD_FULL_NAME);
313 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
314 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
315 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
316 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
317 SAMR_FIELD_LOGON_SCRIPT);
319 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
320 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
321 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
322 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
323 SAMR_FIELD_PROFILE_PATH);
325 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
326 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
327 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
328 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
329 SAMR_FIELD_DESCRIPTION);
331 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
332 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
333 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
334 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
335 SAMR_FIELD_WORKSTATIONS);
337 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
338 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
339 SAMR_FIELD_PARAMETERS);
341 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
342 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
343 SAMR_FIELD_COUNTRY_CODE);
345 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
346 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
347 SAMR_FIELD_CODE_PAGE);
349 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
350 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
351 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
352 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
353 SAMR_FIELD_LOGON_HOURS);
355 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
356 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
357 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
359 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
360 (base_acct_flags | ACB_DISABLED),
361 (base_acct_flags | ACB_DISABLED | user_extra_flags),
364 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
365 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
366 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
367 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
369 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
370 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
371 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
374 /* The 'autolock' flag doesn't stick - check this */
375 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
376 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
377 (base_acct_flags | ACB_DISABLED | user_extra_flags),
379 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
380 (base_acct_flags | ACB_DISABLED),
381 (base_acct_flags | ACB_DISABLED | user_extra_flags),
382 SAMR_FIELD_ACCT_FLAGS);
385 /* these fail with win2003 - it appears you can't set the primary gid?
386 the set succeeds, but the gid isn't changed. Very weird! */
387 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
388 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
389 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
390 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
397 generate a random password for password change tests
399 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
401 size_t len = MAX(8, min_len) + (random() % 6);
402 char *s = generate_random_str(mem_ctx, len);
403 printf("Generated password '%s'\n", s);
407 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
408 struct policy_handle *handle, char **password)
411 struct samr_SetUserInfo s;
412 union samr_UserInfo u;
414 DATA_BLOB session_key;
416 struct samr_GetUserPwInfo pwp;
417 int policy_min_pw_len = 0;
418 pwp.in.user_handle = handle;
420 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
421 if (NT_STATUS_IS_OK(status)) {
422 policy_min_pw_len = pwp.out.info.min_password_length;
424 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
426 s.in.user_handle = handle;
430 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
431 /* w2k3 ignores this length */
432 u.info24.pw_len = strlen_m(newpass) * 2;
434 status = dcerpc_fetch_session_key(p, &session_key);
435 if (!NT_STATUS_IS_OK(status)) {
436 printf("SetUserInfo level %u - no session key - %s\n",
437 s.in.level, nt_errstr(status));
441 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
443 printf("Testing SetUserInfo level 24 (set password)\n");
445 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
446 if (!NT_STATUS_IS_OK(status)) {
447 printf("SetUserInfo level %u failed - %s\n",
448 s.in.level, nt_errstr(status));
458 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
459 struct policy_handle *handle, uint32_t fields_present,
463 struct samr_SetUserInfo s;
464 union samr_UserInfo u;
466 DATA_BLOB session_key;
468 struct samr_GetUserPwInfo pwp;
469 int policy_min_pw_len = 0;
470 pwp.in.user_handle = handle;
472 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
473 if (NT_STATUS_IS_OK(status)) {
474 policy_min_pw_len = pwp.out.info.min_password_length;
476 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
478 s.in.user_handle = handle;
484 u.info23.info.fields_present = fields_present;
486 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
488 status = dcerpc_fetch_session_key(p, &session_key);
489 if (!NT_STATUS_IS_OK(status)) {
490 printf("SetUserInfo level %u - no session key - %s\n",
491 s.in.level, nt_errstr(status));
495 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
497 printf("Testing SetUserInfo level 23 (set password)\n");
499 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
500 if (!NT_STATUS_IS_OK(status)) {
501 printf("SetUserInfo level %u failed - %s\n",
502 s.in.level, nt_errstr(status));
512 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
513 struct policy_handle *handle, char **password)
516 struct samr_SetUserInfo s;
517 union samr_UserInfo u;
519 DATA_BLOB session_key;
520 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
521 uint8_t confounder[16];
523 struct MD5Context ctx;
524 struct samr_GetUserPwInfo pwp;
525 int policy_min_pw_len = 0;
526 pwp.in.user_handle = handle;
528 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
529 if (NT_STATUS_IS_OK(status)) {
530 policy_min_pw_len = pwp.out.info.min_password_length;
532 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
534 s.in.user_handle = handle;
538 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
539 u.info26.pw_len = strlen(newpass);
541 status = dcerpc_fetch_session_key(p, &session_key);
542 if (!NT_STATUS_IS_OK(status)) {
543 printf("SetUserInfo level %u - no session key - %s\n",
544 s.in.level, nt_errstr(status));
548 generate_random_buffer((uint8_t *)confounder, 16);
551 MD5Update(&ctx, confounder, 16);
552 MD5Update(&ctx, session_key.data, session_key.length);
553 MD5Final(confounded_session_key.data, &ctx);
555 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
556 memcpy(&u.info26.password.data[516], confounder, 16);
558 printf("Testing SetUserInfo level 26 (set password ex)\n");
560 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
561 if (!NT_STATUS_IS_OK(status)) {
562 printf("SetUserInfo level %u failed - %s\n",
563 s.in.level, nt_errstr(status));
572 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
573 struct policy_handle *handle, uint32_t fields_present,
577 struct samr_SetUserInfo s;
578 union samr_UserInfo u;
580 DATA_BLOB session_key;
581 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
582 struct MD5Context ctx;
583 uint8_t confounder[16];
585 struct samr_GetUserPwInfo pwp;
586 int policy_min_pw_len = 0;
587 pwp.in.user_handle = handle;
589 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
590 if (NT_STATUS_IS_OK(status)) {
591 policy_min_pw_len = pwp.out.info.min_password_length;
593 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
595 s.in.user_handle = handle;
601 u.info25.info.fields_present = fields_present;
603 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
605 status = dcerpc_fetch_session_key(p, &session_key);
606 if (!NT_STATUS_IS_OK(status)) {
607 printf("SetUserInfo level %u - no session key - %s\n",
608 s.in.level, nt_errstr(status));
612 generate_random_buffer((uint8_t *)confounder, 16);
615 MD5Update(&ctx, confounder, 16);
616 MD5Update(&ctx, session_key.data, session_key.length);
617 MD5Final(confounded_session_key.data, &ctx);
619 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
620 memcpy(&u.info25.password.data[516], confounder, 16);
622 printf("Testing SetUserInfo level 25 (set password ex)\n");
624 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
625 if (!NT_STATUS_IS_OK(status)) {
626 printf("SetUserInfo level %u failed - %s\n",
627 s.in.level, nt_errstr(status));
636 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
637 struct policy_handle *handle)
640 struct samr_SetAliasInfo r;
641 struct samr_QueryAliasInfo q;
642 uint16_t levels[] = {2, 3};
646 /* Ignoring switch level 1, as that includes the number of members for the alias
647 * and setting this to a wrong value might have negative consequences
650 for (i=0;i<ARRAY_SIZE(levels);i++) {
651 printf("Testing SetAliasInfo level %u\n", levels[i]);
653 r.in.alias_handle = handle;
654 r.in.level = levels[i];
655 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
656 switch (r.in.level) {
657 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
658 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
659 "Test Description, should test I18N as well"); break;
662 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
663 if (!NT_STATUS_IS_OK(status)) {
664 printf("SetAliasInfo level %u failed - %s\n",
665 levels[i], nt_errstr(status));
669 q.in.alias_handle = handle;
670 q.in.level = levels[i];
672 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
673 if (!NT_STATUS_IS_OK(status)) {
674 printf("QueryAliasInfo level %u failed - %s\n",
675 levels[i], nt_errstr(status));
683 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
684 struct policy_handle *user_handle)
686 struct samr_GetGroupsForUser r;
690 printf("testing GetGroupsForUser\n");
692 r.in.user_handle = user_handle;
694 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
695 if (!NT_STATUS_IS_OK(status)) {
696 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
704 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
705 struct lsa_String *domain_name)
708 struct samr_GetDomPwInfo r;
711 r.in.domain_name = domain_name;
712 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
714 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
715 if (!NT_STATUS_IS_OK(status)) {
716 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
720 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
721 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
723 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
724 if (!NT_STATUS_IS_OK(status)) {
725 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
729 r.in.domain_name->string = "\\\\__NONAME__";
730 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
732 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
733 if (!NT_STATUS_IS_OK(status)) {
734 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
738 r.in.domain_name->string = "\\\\Builtin";
739 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
741 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
742 if (!NT_STATUS_IS_OK(status)) {
743 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
751 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
752 struct policy_handle *handle)
755 struct samr_GetUserPwInfo r;
758 printf("Testing GetUserPwInfo\n");
760 r.in.user_handle = handle;
762 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
763 if (!NT_STATUS_IS_OK(status)) {
764 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
771 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
772 struct policy_handle *domain_handle, const char *name,
776 struct samr_LookupNames n;
777 struct lsa_String sname[2];
779 init_lsa_String(&sname[0], name);
781 n.in.domain_handle = domain_handle;
784 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
785 if (NT_STATUS_IS_OK(status)) {
786 *rid = n.out.rids.ids[0];
791 init_lsa_String(&sname[1], "xxNONAMExx");
793 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
794 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
795 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
799 init_lsa_String(&sname[1], "xxNONAMExx");
801 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
802 if (!NT_STATUS_IS_OK(status)) {
803 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
809 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
810 struct policy_handle *domain_handle,
811 const char *name, struct policy_handle *user_handle)
814 struct samr_OpenUser r;
817 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
818 if (!NT_STATUS_IS_OK(status)) {
822 r.in.domain_handle = domain_handle;
823 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
825 r.out.user_handle = user_handle;
826 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
827 if (!NT_STATUS_IS_OK(status)) {
828 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
835 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
836 struct policy_handle *handle)
839 struct samr_ChangePasswordUser r;
841 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
842 struct policy_handle user_handle;
843 char *oldpass = "test";
844 char *newpass = "test2";
845 uint8_t old_nt_hash[16], new_nt_hash[16];
846 uint8_t old_lm_hash[16], new_lm_hash[16];
848 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
849 if (!NT_STATUS_IS_OK(status)) {
853 printf("Testing ChangePasswordUser for user 'testuser'\n");
855 printf("old password: %s\n", oldpass);
856 printf("new password: %s\n", newpass);
858 E_md4hash(oldpass, old_nt_hash);
859 E_md4hash(newpass, new_nt_hash);
860 E_deshash(oldpass, old_lm_hash);
861 E_deshash(newpass, new_lm_hash);
863 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
864 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
865 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
866 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
867 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
868 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
870 r.in.handle = &user_handle;
872 r.in.old_lm_crypted = &hash1;
873 r.in.new_lm_crypted = &hash2;
875 r.in.old_nt_crypted = &hash3;
876 r.in.new_nt_crypted = &hash4;
877 r.in.cross1_present = 1;
878 r.in.nt_cross = &hash5;
879 r.in.cross2_present = 1;
880 r.in.lm_cross = &hash6;
882 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
883 if (!NT_STATUS_IS_OK(status)) {
884 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
888 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
896 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
897 struct policy_handle *handle, char **password)
900 struct samr_ChangePasswordUser r;
902 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
903 struct policy_handle user_handle;
904 char *oldpass = *password;
905 uint8_t old_nt_hash[16], new_nt_hash[16];
906 uint8_t old_lm_hash[16], new_lm_hash[16];
909 struct samr_GetUserPwInfo pwp;
910 int policy_min_pw_len = 0;
912 status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
913 if (!NT_STATUS_IS_OK(status)) {
916 pwp.in.user_handle = &user_handle;
918 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
919 if (NT_STATUS_IS_OK(status)) {
920 policy_min_pw_len = pwp.out.info.min_password_length;
922 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
924 printf("Testing ChangePasswordUser\n");
926 E_md4hash(oldpass, old_nt_hash);
927 E_md4hash(newpass, new_nt_hash);
928 E_deshash(oldpass, old_lm_hash);
929 E_deshash(newpass, new_lm_hash);
931 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
932 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
933 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
934 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
935 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
936 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
938 r.in.user_handle = &user_handle;
940 r.in.old_lm_crypted = &hash1;
941 r.in.new_lm_crypted = &hash2;
943 r.in.old_nt_crypted = &hash3;
944 r.in.new_nt_crypted = &hash4;
945 r.in.cross1_present = 1;
946 r.in.nt_cross = &hash5;
947 r.in.cross2_present = 1;
948 r.in.lm_cross = &hash6;
950 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
951 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
952 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
953 } else if (!NT_STATUS_IS_OK(status)) {
954 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
960 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
968 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
969 struct policy_handle *handle, char **password)
972 struct samr_OemChangePasswordUser2 r;
974 struct samr_Password lm_verifier;
975 struct samr_CryptPassword lm_pass;
976 struct lsa_AsciiString server, account, account_bad;
977 char *oldpass = *password;
979 uint8_t old_lm_hash[16], new_lm_hash[16];
981 struct samr_GetDomPwInfo dom_pw_info;
982 int policy_min_pw_len = 0;
984 struct lsa_String domain_name;
985 domain_name.string = "";
986 dom_pw_info.in.domain_name = &domain_name;
988 printf("Testing OemChangePasswordUser2\n");
990 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
991 if (NT_STATUS_IS_OK(status)) {
992 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
995 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
997 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
998 account.string = TEST_ACCOUNT_NAME;
1000 E_deshash(oldpass, old_lm_hash);
1001 E_deshash(newpass, new_lm_hash);
1003 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1004 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1005 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1007 r.in.server = &server;
1008 r.in.account = &account;
1009 r.in.password = &lm_pass;
1010 r.in.hash = &lm_verifier;
1012 /* Break the verification */
1013 lm_verifier.hash[0]++;
1015 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1017 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1018 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1019 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1024 /* This shouldn't be a valid name */
1025 account_bad.string = TEST_ACCOUNT_NAME "XX";
1026 r.in.account = &account_bad;
1028 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1030 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1031 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1036 E_deshash(oldpass, old_lm_hash);
1037 E_deshash(newpass, new_lm_hash);
1039 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1040 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1041 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1043 r.in.server = &server;
1044 r.in.account = &account;
1045 r.in.password = &lm_pass;
1046 r.in.hash = &lm_verifier;
1048 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1049 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1050 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1051 } else if (!NT_STATUS_IS_OK(status)) {
1052 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1055 *password = newpass;
1062 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1063 struct policy_handle *handle, char **password)
1066 struct samr_ChangePasswordUser2 r;
1068 struct lsa_String server, account;
1069 struct samr_CryptPassword nt_pass, lm_pass;
1070 struct samr_Password nt_verifier, lm_verifier;
1071 char *oldpass = *password;
1073 uint8_t old_nt_hash[16], new_nt_hash[16];
1074 uint8_t old_lm_hash[16], new_lm_hash[16];
1076 struct samr_GetDomPwInfo dom_pw_info;
1077 int policy_min_pw_len = 0;
1079 struct lsa_String domain_name;
1080 domain_name.string = "";
1081 dom_pw_info.in.domain_name = &domain_name;
1083 printf("Testing ChangePasswordUser2\n");
1085 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1086 if (NT_STATUS_IS_OK(status)) {
1087 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1090 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1092 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1093 init_lsa_String(&account, TEST_ACCOUNT_NAME);
1095 E_md4hash(oldpass, old_nt_hash);
1096 E_md4hash(newpass, new_nt_hash);
1098 E_deshash(oldpass, old_lm_hash);
1099 E_deshash(newpass, new_lm_hash);
1101 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1102 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1103 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1105 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1106 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1107 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1109 r.in.server = &server;
1110 r.in.account = &account;
1111 r.in.nt_password = &nt_pass;
1112 r.in.nt_verifier = &nt_verifier;
1114 r.in.lm_password = &lm_pass;
1115 r.in.lm_verifier = &lm_verifier;
1117 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1118 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1119 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1120 } else if (!NT_STATUS_IS_OK(status)) {
1121 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1124 *password = newpass;
1131 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1132 const char *account_string,
1133 int policy_min_pw_len,
1137 struct samr_ChangePasswordUser3 r;
1139 struct lsa_String server, account, account_bad;
1140 struct samr_CryptPassword nt_pass, lm_pass;
1141 struct samr_Password nt_verifier, lm_verifier;
1142 char *oldpass = *password;
1143 char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1144 uint8_t old_nt_hash[16], new_nt_hash[16];
1145 uint8_t old_lm_hash[16], new_lm_hash[16];
1147 printf("Testing ChangePasswordUser3\n");
1149 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1150 init_lsa_String(&account, account_string);
1152 E_md4hash(oldpass, old_nt_hash);
1153 E_md4hash(newpass, new_nt_hash);
1155 E_deshash(oldpass, old_lm_hash);
1156 E_deshash(newpass, new_lm_hash);
1158 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1159 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1160 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1162 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1163 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1164 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1166 /* Break the verification */
1167 nt_verifier.hash[0]++;
1169 r.in.server = &server;
1170 r.in.account = &account;
1171 r.in.nt_password = &nt_pass;
1172 r.in.nt_verifier = &nt_verifier;
1174 r.in.lm_password = &lm_pass;
1175 r.in.lm_verifier = &lm_verifier;
1176 r.in.password3 = NULL;
1178 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1179 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1180 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1181 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1186 /* This shouldn't be a valid name */
1187 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1189 r.in.account = &account_bad;
1190 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1191 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1192 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1197 E_md4hash(oldpass, old_nt_hash);
1198 E_md4hash(newpass, new_nt_hash);
1200 E_deshash(oldpass, old_lm_hash);
1201 E_deshash(newpass, new_lm_hash);
1203 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1204 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1205 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1207 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1208 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1209 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1211 r.in.server = &server;
1212 r.in.account = &account;
1213 r.in.nt_password = &nt_pass;
1214 r.in.nt_verifier = &nt_verifier;
1216 r.in.lm_password = &lm_pass;
1217 r.in.lm_verifier = &lm_verifier;
1218 r.in.password3 = NULL;
1220 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1221 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1222 && !policy_min_pw_len) {
1223 if (r.out.dominfo) {
1224 policy_min_pw_len = r.out.dominfo->min_password_length;
1226 if (policy_min_pw_len) /* try again with the right min password length */ {
1227 ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password);
1229 printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1232 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1233 printf("ChangePasswordUser3 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1234 } else if (!NT_STATUS_IS_OK(status)) {
1235 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1238 *password = newpass;
1245 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1246 struct policy_handle *alias_handle)
1248 struct samr_GetMembersInAlias r;
1249 struct lsa_SidArray sids;
1253 printf("Testing GetMembersInAlias\n");
1255 r.in.alias_handle = alias_handle;
1258 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1259 if (!NT_STATUS_IS_OK(status)) {
1260 printf("GetMembersInAlias failed - %s\n",
1268 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1269 struct policy_handle *alias_handle,
1270 const struct dom_sid *domain_sid)
1272 struct samr_AddAliasMember r;
1273 struct samr_DeleteAliasMember d;
1276 struct dom_sid *sid;
1278 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1280 printf("testing AddAliasMember\n");
1281 r.in.alias_handle = alias_handle;
1284 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1285 if (!NT_STATUS_IS_OK(status)) {
1286 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1290 d.in.alias_handle = alias_handle;
1293 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1294 if (!NT_STATUS_IS_OK(status)) {
1295 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1302 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1303 struct policy_handle *alias_handle)
1305 struct samr_AddMultipleMembersToAlias a;
1306 struct samr_RemoveMultipleMembersFromAlias r;
1309 struct lsa_SidArray sids;
1311 printf("testing AddMultipleMembersToAlias\n");
1312 a.in.alias_handle = alias_handle;
1316 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1318 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1319 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1320 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1322 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1323 if (!NT_STATUS_IS_OK(status)) {
1324 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1329 printf("testing RemoveMultipleMembersFromAlias\n");
1330 r.in.alias_handle = alias_handle;
1333 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1334 if (!NT_STATUS_IS_OK(status)) {
1335 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1339 /* strange! removing twice doesn't give any error */
1340 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1341 if (!NT_STATUS_IS_OK(status)) {
1342 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1346 /* but removing an alias that isn't there does */
1347 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1349 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1350 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1351 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1358 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1359 struct policy_handle *user_handle)
1361 struct samr_TestPrivateFunctionsUser r;
1365 printf("Testing TestPrivateFunctionsUser\n");
1367 r.in.user_handle = user_handle;
1369 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1370 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1371 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1379 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1380 struct policy_handle *handle, uint32_t base_acct_flags,
1381 const char *base_acct_name)
1385 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1389 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1393 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1397 if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1402 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1406 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1413 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1414 struct policy_handle *alias_handle,
1415 const struct dom_sid *domain_sid)
1419 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1423 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1427 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1431 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1435 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1443 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1444 struct policy_handle *handle, const char *name)
1447 struct samr_DeleteUser d;
1448 struct policy_handle user_handle;
1451 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1452 if (!NT_STATUS_IS_OK(status)) {
1456 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1457 if (!NT_STATUS_IS_OK(status)) {
1461 d.in.user_handle = &user_handle;
1462 d.out.user_handle = &user_handle;
1463 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1464 if (!NT_STATUS_IS_OK(status)) {
1471 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1476 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1477 struct policy_handle *handle, const char *name)
1480 struct samr_OpenGroup r;
1481 struct samr_DeleteDomainGroup d;
1482 struct policy_handle group_handle;
1485 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1486 if (!NT_STATUS_IS_OK(status)) {
1490 r.in.domain_handle = handle;
1491 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1493 r.out.group_handle = &group_handle;
1494 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1495 if (!NT_STATUS_IS_OK(status)) {
1499 d.in.group_handle = &group_handle;
1500 d.out.group_handle = &group_handle;
1501 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1502 if (!NT_STATUS_IS_OK(status)) {
1509 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1514 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1515 struct policy_handle *domain_handle, const char *name)
1518 struct samr_OpenAlias r;
1519 struct samr_DeleteDomAlias d;
1520 struct policy_handle alias_handle;
1523 printf("testing DeleteAlias_byname\n");
1525 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1526 if (!NT_STATUS_IS_OK(status)) {
1530 r.in.domain_handle = domain_handle;
1531 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1533 r.out.alias_handle = &alias_handle;
1534 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1535 if (!NT_STATUS_IS_OK(status)) {
1539 d.in.alias_handle = &alias_handle;
1540 d.out.alias_handle = &alias_handle;
1541 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1542 if (!NT_STATUS_IS_OK(status)) {
1549 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1553 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1554 struct policy_handle *alias_handle)
1556 struct samr_DeleteDomAlias d;
1559 printf("Testing DeleteAlias\n");
1561 d.in.alias_handle = alias_handle;
1562 d.out.alias_handle = alias_handle;
1564 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1565 if (!NT_STATUS_IS_OK(status)) {
1566 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1573 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1574 struct policy_handle *domain_handle,
1575 struct policy_handle *alias_handle,
1576 const struct dom_sid *domain_sid)
1579 struct samr_CreateDomAlias r;
1580 struct lsa_String name;
1584 init_lsa_String(&name, TEST_ALIASNAME);
1585 r.in.domain_handle = domain_handle;
1586 r.in.alias_name = &name;
1587 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1588 r.out.alias_handle = alias_handle;
1591 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1593 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1595 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1596 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1600 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1601 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1604 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1607 if (!NT_STATUS_IS_OK(status)) {
1608 printf("CreateAlias failed - %s\n", nt_errstr(status));
1612 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1619 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1620 struct policy_handle *domain_handle, char **password)
1628 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1632 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1636 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1640 /* we change passwords twice - this has the effect of verifying
1641 they were changed correctly for the final call */
1642 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1646 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1653 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1654 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1657 struct samr_CreateUser r;
1658 struct samr_QueryUserInfo q;
1660 char *password = NULL;
1663 const uint32_t password_fields[] = {
1664 SAMR_FIELD_PASSWORD,
1665 SAMR_FIELD_PASSWORD2,
1666 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1670 TALLOC_CTX *user_ctx;
1672 /* This call creates a 'normal' account - check that it really does */
1673 const uint32_t acct_flags = ACB_NORMAL;
1674 struct lsa_String name;
1677 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1678 init_lsa_String(&name, TEST_ACCOUNT_NAME);
1680 r.in.domain_handle = domain_handle;
1681 r.in.account_name = &name;
1682 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1683 r.out.user_handle = user_handle;
1686 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1688 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1690 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1691 printf("Server refused create of '%s'\n", r.in.account_name->string);
1692 ZERO_STRUCTP(user_handle);
1693 talloc_free(user_ctx);
1697 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1698 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1699 talloc_free(user_ctx);
1702 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1704 if (!NT_STATUS_IS_OK(status)) {
1705 talloc_free(user_ctx);
1706 printf("CreateUser failed - %s\n", nt_errstr(status));
1710 q.in.user_handle = user_handle;
1713 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1714 if (!NT_STATUS_IS_OK(status)) {
1715 printf("QueryUserInfo level %u failed - %s\n",
1716 q.in.level, nt_errstr(status));
1719 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1720 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1721 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1722 acct_flags, acct_flags);
1727 if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1731 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1735 for (i = 0; password_fields[i]; i++) {
1736 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1740 /* check it was set right */
1741 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1746 for (i = 0; password_fields[i]; i++) {
1747 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1751 /* check it was set right */
1752 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1757 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1761 if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1765 talloc_free(user_ctx);
1771 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1772 struct policy_handle *user_handle)
1774 struct samr_DeleteUser d;
1778 printf("Testing DeleteUser\n");
1780 d.in.user_handle = user_handle;
1781 d.out.user_handle = user_handle;
1783 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1784 if (!NT_STATUS_IS_OK(status)) {
1785 printf("DeleteUser failed - %s\n", nt_errstr(status));
1792 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1793 struct policy_handle *handle)
1796 struct samr_CreateUser2 r;
1797 struct samr_QueryUserInfo q;
1798 struct samr_DeleteUser d;
1799 struct policy_handle user_handle;
1801 struct lsa_String name;
1806 uint32_t acct_flags;
1807 const char *account_name;
1809 } account_types[] = {
1810 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1811 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1812 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1813 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1814 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1815 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1816 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1817 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1818 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1819 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1820 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1821 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1822 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1823 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1824 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1827 for (i = 0; account_types[i].account_name; i++) {
1828 TALLOC_CTX *user_ctx;
1829 uint32_t acct_flags = account_types[i].acct_flags;
1830 uint32_t access_granted;
1831 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1832 init_lsa_String(&name, account_types[i].account_name);
1834 r.in.domain_handle = handle;
1835 r.in.account_name = &name;
1836 r.in.acct_flags = acct_flags;
1837 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1838 r.out.user_handle = &user_handle;
1839 r.out.access_granted = &access_granted;
1842 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1844 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1846 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1847 talloc_free(user_ctx);
1848 printf("Server refused create of '%s'\n", r.in.account_name->string);
1851 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1852 if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1853 talloc_free(user_ctx);
1857 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1860 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1861 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1862 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1866 if (NT_STATUS_IS_OK(status)) {
1867 q.in.user_handle = &user_handle;
1870 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1871 if (!NT_STATUS_IS_OK(status)) {
1872 printf("QueryUserInfo level %u failed - %s\n",
1873 q.in.level, nt_errstr(status));
1876 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1877 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1878 q.out.info->info16.acct_flags,
1884 if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1888 printf("Testing DeleteUser (createuser2 test)\n");
1890 d.in.user_handle = &user_handle;
1891 d.out.user_handle = &user_handle;
1893 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1894 if (!NT_STATUS_IS_OK(status)) {
1895 printf("DeleteUser failed - %s\n", nt_errstr(status));
1899 talloc_free(user_ctx);
1905 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1906 struct policy_handle *handle)
1909 struct samr_QueryAliasInfo r;
1910 uint16_t levels[] = {1, 2, 3};
1914 for (i=0;i<ARRAY_SIZE(levels);i++) {
1915 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1917 r.in.alias_handle = handle;
1918 r.in.level = levels[i];
1920 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1921 if (!NT_STATUS_IS_OK(status)) {
1922 printf("QueryAliasInfo level %u failed - %s\n",
1923 levels[i], nt_errstr(status));
1931 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1932 struct policy_handle *handle)
1935 struct samr_QueryGroupInfo r;
1936 uint16_t levels[] = {1, 2, 3, 4, 5};
1940 for (i=0;i<ARRAY_SIZE(levels);i++) {
1941 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1943 r.in.group_handle = handle;
1944 r.in.level = levels[i];
1946 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1947 if (!NT_STATUS_IS_OK(status)) {
1948 printf("QueryGroupInfo level %u failed - %s\n",
1949 levels[i], nt_errstr(status));
1957 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1958 struct policy_handle *handle)
1961 struct samr_QueryGroupMember r;
1964 printf("Testing QueryGroupMember\n");
1966 r.in.group_handle = handle;
1968 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1969 if (!NT_STATUS_IS_OK(status)) {
1970 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1978 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1979 struct policy_handle *handle)
1982 struct samr_QueryGroupInfo r;
1983 struct samr_SetGroupInfo s;
1984 uint16_t levels[] = {1, 2, 3, 4};
1985 uint16_t set_ok[] = {0, 1, 1, 1};
1989 for (i=0;i<ARRAY_SIZE(levels);i++) {
1990 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1992 r.in.group_handle = handle;
1993 r.in.level = levels[i];
1995 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1996 if (!NT_STATUS_IS_OK(status)) {
1997 printf("QueryGroupInfo level %u failed - %s\n",
1998 levels[i], nt_errstr(status));
2002 printf("Testing SetGroupInfo level %u\n", levels[i]);
2004 s.in.group_handle = handle;
2005 s.in.level = levels[i];
2006 s.in.info = r.out.info;
2009 /* disabled this, as it changes the name only from the point of view of samr,
2010 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2011 the name is still reserved, so creating the old name fails, but deleting by the old name
2013 if (s.in.level == 2) {
2014 init_lsa_String(&s.in.info->string, "NewName");
2018 if (s.in.level == 4) {
2019 init_lsa_String(&s.in.info->description, "test description");
2022 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2024 if (!NT_STATUS_IS_OK(status)) {
2025 printf("SetGroupInfo level %u failed - %s\n",
2026 r.in.level, nt_errstr(status));
2031 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2032 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2033 r.in.level, nt_errstr(status));
2043 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2044 struct policy_handle *handle)
2047 struct samr_QueryUserInfo r;
2048 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2049 11, 12, 13, 14, 16, 17, 20, 21};
2053 for (i=0;i<ARRAY_SIZE(levels);i++) {
2054 printf("Testing QueryUserInfo level %u\n", levels[i]);
2056 r.in.user_handle = handle;
2057 r.in.level = levels[i];
2059 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2060 if (!NT_STATUS_IS_OK(status)) {
2061 printf("QueryUserInfo level %u failed - %s\n",
2062 levels[i], nt_errstr(status));
2070 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2071 struct policy_handle *handle)
2074 struct samr_QueryUserInfo2 r;
2075 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2076 11, 12, 13, 14, 16, 17, 20, 21};
2080 for (i=0;i<ARRAY_SIZE(levels);i++) {
2081 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2083 r.in.user_handle = handle;
2084 r.in.level = levels[i];
2086 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2087 if (!NT_STATUS_IS_OK(status)) {
2088 printf("QueryUserInfo2 level %u failed - %s\n",
2089 levels[i], nt_errstr(status));
2097 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2098 struct policy_handle *handle, uint32_t rid)
2101 struct samr_OpenUser r;
2102 struct policy_handle user_handle;
2105 printf("Testing OpenUser(%u)\n", rid);
2107 r.in.domain_handle = handle;
2108 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2110 r.out.user_handle = &user_handle;
2112 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2113 if (!NT_STATUS_IS_OK(status)) {
2114 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2118 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2122 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2126 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2130 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2134 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2138 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2145 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2146 struct policy_handle *handle, uint32_t rid)
2149 struct samr_OpenGroup r;
2150 struct policy_handle group_handle;
2153 printf("Testing OpenGroup(%u)\n", rid);
2155 r.in.domain_handle = handle;
2156 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2158 r.out.group_handle = &group_handle;
2160 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2161 if (!NT_STATUS_IS_OK(status)) {
2162 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2166 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2170 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2174 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2178 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2185 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2186 struct policy_handle *handle, uint32_t rid)
2189 struct samr_OpenAlias r;
2190 struct policy_handle alias_handle;
2193 printf("Testing OpenAlias(%u)\n", rid);
2195 r.in.domain_handle = handle;
2196 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2198 r.out.alias_handle = &alias_handle;
2200 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2201 if (!NT_STATUS_IS_OK(status)) {
2202 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2206 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2210 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2214 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2218 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2225 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2226 struct policy_handle *handle)
2229 struct samr_EnumDomainUsers r;
2230 uint32_t resume_handle=0;
2233 struct samr_LookupNames n;
2234 struct samr_LookupRids lr ;
2236 printf("Testing EnumDomainUsers\n");
2238 r.in.domain_handle = handle;
2239 r.in.resume_handle = &resume_handle;
2240 r.in.acct_flags = 0;
2241 r.in.max_size = (uint32_t)-1;
2242 r.out.resume_handle = &resume_handle;
2244 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2245 if (!NT_STATUS_IS_OK(status)) {
2246 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2254 if (r.out.sam->count == 0) {
2258 for (i=0;i<r.out.sam->count;i++) {
2259 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2264 printf("Testing LookupNames\n");
2265 n.in.domain_handle = handle;
2266 n.in.num_names = r.out.sam->count;
2267 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2268 for (i=0;i<r.out.sam->count;i++) {
2269 n.in.names[i].string = r.out.sam->entries[i].name.string;
2271 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2272 if (!NT_STATUS_IS_OK(status)) {
2273 printf("LookupNames failed - %s\n", nt_errstr(status));
2278 printf("Testing LookupRids\n");
2279 lr.in.domain_handle = handle;
2280 lr.in.num_rids = r.out.sam->count;
2281 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2282 for (i=0;i<r.out.sam->count;i++) {
2283 lr.in.rids[i] = r.out.sam->entries[i].idx;
2285 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2286 if (!NT_STATUS_IS_OK(status)) {
2287 printf("LookupRids failed - %s\n", nt_errstr(status));
2295 try blasting the server with a bunch of sync requests
2297 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2298 struct policy_handle *handle)
2301 struct samr_EnumDomainUsers r;
2302 uint32_t resume_handle=0;
2304 #define ASYNC_COUNT 100
2305 struct rpc_request *req[ASYNC_COUNT];
2307 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2308 printf("samr async test disabled - enable dangerous tests to use\n");
2312 printf("Testing EnumDomainUsers_async\n");
2314 r.in.domain_handle = handle;
2315 r.in.resume_handle = &resume_handle;
2316 r.in.acct_flags = 0;
2317 r.in.max_size = (uint32_t)-1;
2318 r.out.resume_handle = &resume_handle;
2320 for (i=0;i<ASYNC_COUNT;i++) {
2321 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2324 for (i=0;i<ASYNC_COUNT;i++) {
2325 status = dcerpc_ndr_request_recv(req[i]);
2326 if (!NT_STATUS_IS_OK(status)) {
2327 printf("EnumDomainUsers[%d] failed - %s\n",
2328 i, nt_errstr(status));
2333 printf("%d async requests OK\n", i);
2338 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2339 struct policy_handle *handle)
2342 struct samr_EnumDomainGroups r;
2343 uint32_t resume_handle=0;
2347 printf("Testing EnumDomainGroups\n");
2349 r.in.domain_handle = handle;
2350 r.in.resume_handle = &resume_handle;
2351 r.in.max_size = (uint32_t)-1;
2352 r.out.resume_handle = &resume_handle;
2354 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2355 if (!NT_STATUS_IS_OK(status)) {
2356 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2364 for (i=0;i<r.out.sam->count;i++) {
2365 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2373 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2374 struct policy_handle *handle)
2377 struct samr_EnumDomainAliases r;
2378 uint32_t resume_handle=0;
2382 printf("Testing EnumDomainAliases\n");
2384 r.in.domain_handle = handle;
2385 r.in.resume_handle = &resume_handle;
2386 r.in.acct_flags = (uint32_t)-1;
2387 r.out.resume_handle = &resume_handle;
2389 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2390 if (!NT_STATUS_IS_OK(status)) {
2391 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2399 for (i=0;i<r.out.sam->count;i++) {
2400 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2408 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2409 struct policy_handle *handle)
2412 struct samr_GetDisplayEnumerationIndex r;
2414 uint16_t levels[] = {1, 2, 3, 4, 5};
2415 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2418 for (i=0;i<ARRAY_SIZE(levels);i++) {
2419 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2421 r.in.domain_handle = handle;
2422 r.in.level = levels[i];
2423 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2425 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2428 !NT_STATUS_IS_OK(status) &&
2429 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2430 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2431 levels[i], nt_errstr(status));
2435 init_lsa_String(&r.in.name, "zzzzzzzz");
2437 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2439 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2440 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2441 levels[i], nt_errstr(status));
2449 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2450 struct policy_handle *handle)
2453 struct samr_GetDisplayEnumerationIndex2 r;
2455 uint16_t levels[] = {1, 2, 3, 4, 5};
2456 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2459 for (i=0;i<ARRAY_SIZE(levels);i++) {
2460 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2462 r.in.domain_handle = handle;
2463 r.in.level = levels[i];
2464 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2466 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2468 !NT_STATUS_IS_OK(status) &&
2469 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2470 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2471 levels[i], nt_errstr(status));
2475 init_lsa_String(&r.in.name, "zzzzzzzz");
2477 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2478 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2479 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2480 levels[i], nt_errstr(status));
2488 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2489 struct policy_handle *handle)
2492 struct samr_QueryDisplayInfo r;
2494 uint16_t levels[] = {1, 2, 3, 4, 5};
2497 for (i=0;i<ARRAY_SIZE(levels);i++) {
2498 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2500 r.in.domain_handle = handle;
2501 r.in.level = levels[i];
2503 r.in.max_entries = 1000;
2504 r.in.buf_size = (uint32_t)-1;
2506 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2507 if (!NT_STATUS_IS_OK(status)) {
2508 printf("QueryDisplayInfo level %u failed - %s\n",
2509 levels[i], nt_errstr(status));
2517 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2518 struct policy_handle *handle)
2521 struct samr_QueryDisplayInfo2 r;
2523 uint16_t levels[] = {1, 2, 3, 4, 5};
2526 for (i=0;i<ARRAY_SIZE(levels);i++) {
2527 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2529 r.in.domain_handle = handle;
2530 r.in.level = levels[i];
2532 r.in.max_entries = 1000;
2533 r.in.buf_size = (uint32_t)-1;
2535 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2536 if (!NT_STATUS_IS_OK(status)) {
2537 printf("QueryDisplayInfo2 level %u failed - %s\n",
2538 levels[i], nt_errstr(status));
2546 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2547 struct policy_handle *handle)
2550 struct samr_QueryDisplayInfo3 r;
2552 uint16_t levels[] = {1, 2, 3, 4, 5};
2555 for (i=0;i<ARRAY_SIZE(levels);i++) {
2556 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2558 r.in.domain_handle = handle;
2559 r.in.level = levels[i];
2561 r.in.max_entries = 1000;
2562 r.in.buf_size = (uint32_t)-1;
2564 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2565 if (!NT_STATUS_IS_OK(status)) {
2566 printf("QueryDisplayInfo3 level %u failed - %s\n",
2567 levels[i], nt_errstr(status));
2576 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2577 struct policy_handle *handle)
2580 struct samr_QueryDisplayInfo r;
2583 printf("Testing QueryDisplayInfo continuation\n");
2585 r.in.domain_handle = handle;
2588 r.in.max_entries = 1;
2589 r.in.buf_size = (uint32_t)-1;
2592 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2593 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2594 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2595 printf("failed: expected idx %d but got %d\n",
2597 r.out.info.info1.entries[0].idx);
2602 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2603 !NT_STATUS_IS_OK(status)) {
2604 printf("QueryDisplayInfo level %u failed - %s\n",
2605 r.in.level, nt_errstr(status));
2610 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2611 NT_STATUS_IS_OK(status)) &&
2612 r.out.returned_size != 0);
2617 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2618 struct policy_handle *handle)
2621 struct samr_QueryDomainInfo r;
2622 struct samr_SetDomainInfo s;
2623 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2624 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2628 for (i=0;i<ARRAY_SIZE(levels);i++) {
2629 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2631 r.in.domain_handle = handle;
2632 r.in.level = levels[i];
2634 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2635 if (!NT_STATUS_IS_OK(status)) {
2636 printf("QueryDomainInfo level %u failed - %s\n",
2637 r.in.level, nt_errstr(status));
2642 printf("Testing SetDomainInfo level %u\n", levels[i]);
2644 s.in.domain_handle = handle;
2645 s.in.level = levels[i];
2646 s.in.info = r.out.info;
2648 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2650 if (!NT_STATUS_IS_OK(status)) {
2651 printf("SetDomainInfo level %u failed - %s\n",
2652 r.in.level, nt_errstr(status));
2657 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2658 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2659 r.in.level, nt_errstr(status));
2665 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2666 if (!NT_STATUS_IS_OK(status)) {
2667 printf("QueryDomainInfo level %u failed - %s\n",
2668 r.in.level, nt_errstr(status));
2678 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2679 struct policy_handle *handle)
2682 struct samr_QueryDomainInfo2 r;
2683 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2687 for (i=0;i<ARRAY_SIZE(levels);i++) {
2688 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2690 r.in.domain_handle = handle;
2691 r.in.level = levels[i];
2693 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2694 if (!NT_STATUS_IS_OK(status)) {
2695 printf("QueryDomainInfo2 level %u failed - %s\n",
2696 r.in.level, nt_errstr(status));
2705 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2706 set of group names. */
2707 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2708 struct policy_handle *handle)
2710 struct samr_EnumDomainGroups q1;
2711 struct samr_QueryDisplayInfo q2;
2713 uint32_t resume_handle=0;
2718 const char **names = NULL;
2720 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2722 q1.in.domain_handle = handle;
2723 q1.in.resume_handle = &resume_handle;
2725 q1.out.resume_handle = &resume_handle;
2727 status = STATUS_MORE_ENTRIES;
2728 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2729 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2731 if (!NT_STATUS_IS_OK(status) &&
2732 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2735 for (i=0; i<q1.out.num_entries; i++) {
2736 add_string_to_array(mem_ctx,
2737 q1.out.sam->entries[i].name.string,
2738 &names, &num_names);
2742 if (!NT_STATUS_IS_OK(status)) {
2743 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2751 q2.in.domain_handle = handle;
2753 q2.in.start_idx = 0;
2754 q2.in.max_entries = 5;
2755 q2.in.buf_size = (uint32_t)-1;
2757 status = STATUS_MORE_ENTRIES;
2758 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2759 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2761 if (!NT_STATUS_IS_OK(status) &&
2762 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2765 for (i=0; i<q2.out.info.info5.count; i++) {
2767 const char *name = q2.out.info.info5.entries[i].account_name.string;
2769 for (j=0; j<num_names; j++) {
2770 if (names[j] == NULL)
2772 /* Hmm. No strequal in samba4 */
2773 if (strequal(names[j], name)) {
2781 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2786 q2.in.start_idx += q2.out.info.info5.count;
2789 if (!NT_STATUS_IS_OK(status)) {
2790 printf("QueryDisplayInfo level 5 failed - %s\n",
2795 for (i=0; i<num_names; i++) {
2796 if (names[i] != NULL) {
2797 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2806 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2807 struct policy_handle *group_handle)
2809 struct samr_DeleteDomainGroup d;
2813 printf("Testing DeleteDomainGroup\n");
2815 d.in.group_handle = group_handle;
2816 d.out.group_handle = group_handle;
2818 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2819 if (!NT_STATUS_IS_OK(status)) {
2820 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2827 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2828 struct policy_handle *domain_handle)
2830 struct samr_TestPrivateFunctionsDomain r;
2834 printf("Testing TestPrivateFunctionsDomain\n");
2836 r.in.domain_handle = domain_handle;
2838 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2839 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2840 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2847 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2848 struct dom_sid *domain_sid,
2849 struct policy_handle *domain_handle)
2851 struct samr_RidToSid r;
2854 struct dom_sid *calc_sid;
2855 int rids[] = { 0, 42, 512, 10200 };
2858 for (i=0;i<ARRAY_SIZE(rids);i++) {
2860 printf("Testing RidToSid\n");
2862 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2863 r.in.domain_handle = domain_handle;
2866 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2867 if (!NT_STATUS_IS_OK(status)) {
2868 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
2871 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
2873 if (!dom_sid_equal(calc_sid, r.out.sid)) {
2874 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
2875 dom_sid_string(mem_ctx, r.out.sid),
2876 dom_sid_string(mem_ctx, calc_sid));
2885 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2886 struct policy_handle *domain_handle)
2888 struct samr_GetBootKeyInformation r;
2892 printf("Testing GetBootKeyInformation\n");
2894 r.in.domain_handle = domain_handle;
2896 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2897 if (!NT_STATUS_IS_OK(status)) {
2898 /* w2k3 seems to fail this sometimes and pass it sometimes */
2899 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2905 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2906 struct policy_handle *domain_handle,
2907 struct policy_handle *group_handle)
2910 struct samr_AddGroupMember r;
2911 struct samr_DeleteGroupMember d;
2912 struct samr_QueryGroupMember q;
2913 struct samr_SetMemberAttributesOfGroup s;
2917 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2918 if (!NT_STATUS_IS_OK(status)) {
2922 r.in.group_handle = group_handle;
2924 r.in.flags = 0; /* ??? */
2926 printf("Testing AddGroupMember and DeleteGroupMember\n");
2928 d.in.group_handle = group_handle;
2931 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2932 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2933 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2938 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2939 if (!NT_STATUS_IS_OK(status)) {
2940 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2944 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2945 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2946 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2951 /* this one is quite strange. I am using random inputs in the
2952 hope of triggering an error that might give us a clue */
2953 s.in.group_handle = group_handle;
2954 s.in.unknown1 = random();
2955 s.in.unknown2 = random();
2957 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2958 if (!NT_STATUS_IS_OK(status)) {
2959 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2963 q.in.group_handle = group_handle;
2965 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2966 if (!NT_STATUS_IS_OK(status)) {
2967 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2971 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2972 if (!NT_STATUS_IS_OK(status)) {
2973 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2977 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2978 if (!NT_STATUS_IS_OK(status)) {
2979 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2987 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2988 struct policy_handle *domain_handle, struct policy_handle *group_handle)
2991 struct samr_CreateDomainGroup r;
2993 struct lsa_String name;
2996 init_lsa_String(&name, TEST_GROUPNAME);
2998 r.in.domain_handle = domain_handle;
3000 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3001 r.out.group_handle = group_handle;
3004 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3006 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3008 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3009 printf("Server refused create of '%s'\n", r.in.name->string);
3010 ZERO_STRUCTP(group_handle);
3014 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3015 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3016 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3019 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3021 if (!NT_STATUS_IS_OK(status)) {
3022 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3026 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3030 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3039 its not totally clear what this does. It seems to accept any sid you like.
3041 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
3042 TALLOC_CTX *mem_ctx,
3043 struct policy_handle *domain_handle)
3046 struct samr_RemoveMemberFromForeignDomain r;
3048 r.in.domain_handle = domain_handle;
3049 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3051 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3052 if (!NT_STATUS_IS_OK(status)) {
3053 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3062 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3063 struct policy_handle *handle);
3065 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3066 struct policy_handle *handle, struct dom_sid *sid)
3069 struct samr_OpenDomain r;
3070 struct policy_handle domain_handle;
3071 struct policy_handle user_handle;
3072 struct policy_handle alias_handle;
3073 struct policy_handle group_handle;
3076 ZERO_STRUCT(user_handle);
3077 ZERO_STRUCT(alias_handle);
3078 ZERO_STRUCT(group_handle);
3079 ZERO_STRUCT(domain_handle);
3081 printf("Testing OpenDomain\n");
3083 r.in.connect_handle = handle;
3084 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3086 r.out.domain_handle = &domain_handle;
3088 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3089 if (!NT_STATUS_IS_OK(status)) {
3090 printf("OpenDomain failed - %s\n", nt_errstr(status));
3094 /* run the domain tests with the main handle closed - this tests
3095 the servers reference counting */
3096 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3098 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3099 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3100 ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
3101 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
3102 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3103 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3104 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3105 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3106 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3107 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3108 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3109 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3110 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3111 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3112 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3113 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3114 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3115 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3116 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3117 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3118 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3119 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3121 if (!policy_handle_empty(&user_handle) &&
3122 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3126 if (!policy_handle_empty(&alias_handle) &&
3127 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3131 if (!policy_handle_empty(&group_handle) &&
3132 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3136 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3138 /* reconnect the main handle */
3139 ret &= test_Connect(p, mem_ctx, handle);
3144 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3145 struct policy_handle *handle, struct lsa_String *domain)
3148 struct samr_LookupDomain r;
3149 struct lsa_String n2;
3152 printf("Testing LookupDomain(%s)\n", domain->string);
3154 /* check for correct error codes */
3155 r.in.connect_handle = handle;
3156 r.in.domain_name = &n2;
3159 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3160 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3161 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3165 n2.string = "xxNODOMAINxx";
3167 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3168 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3169 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3173 r.in.connect_handle = handle;
3174 r.in.domain_name = domain;
3176 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3177 if (!NT_STATUS_IS_OK(status)) {
3178 printf("LookupDomain failed - %s\n", nt_errstr(status));
3182 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3186 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3194 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3195 struct policy_handle *handle)
3198 struct samr_EnumDomains r;
3199 uint32_t resume_handle = 0;
3203 r.in.connect_handle = handle;
3204 r.in.resume_handle = &resume_handle;
3205 r.in.buf_size = (uint32_t)-1;
3206 r.out.resume_handle = &resume_handle;
3208 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3209 if (!NT_STATUS_IS_OK(status)) {
3210 printf("EnumDomains failed - %s\n", nt_errstr(status));
3218 for (i=0;i<r.out.sam->count;i++) {
3219 if (!test_LookupDomain(p, mem_ctx, handle,
3220 &r.out.sam->entries[i].name)) {
3225 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3226 if (!NT_STATUS_IS_OK(status)) {
3227 printf("EnumDomains failed - %s\n", nt_errstr(status));
3235 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3236 struct policy_handle *handle)
3239 struct samr_Connect r;
3240 struct samr_Connect2 r2;
3241 struct samr_Connect3 r3;
3242 struct samr_Connect4 r4;
3243 struct samr_Connect5 r5;
3244 union samr_ConnectInfo info;
3245 struct policy_handle h;
3246 BOOL ret = True, got_handle = False;
3248 printf("testing samr_Connect\n");
3250 r.in.system_name = 0;
3251 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3252 r.out.connect_handle = &h;
3254 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3255 if (!NT_STATUS_IS_OK(status)) {
3256 printf("Connect failed - %s\n", nt_errstr(status));
3263 printf("testing samr_Connect2\n");
3265 r2.in.system_name = NULL;
3266 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3267 r2.out.connect_handle = &h;
3269 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3270 if (!NT_STATUS_IS_OK(status)) {
3271 printf("Connect2 failed - %s\n", nt_errstr(status));
3275 test_samr_handle_Close(p, mem_ctx, handle);
3281 printf("testing samr_Connect3\n");
3283 r3.in.system_name = NULL;
3285 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3286 r3.out.connect_handle = &h;
3288 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3289 if (!NT_STATUS_IS_OK(status)) {
3290 printf("Connect3 failed - %s\n", nt_errstr(status));
3294 test_samr_handle_Close(p, mem_ctx, handle);
3300 printf("testing samr_Connect4\n");
3302 r4.in.system_name = "";
3304 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3305 r4.out.connect_handle = &h;
3307 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3308 if (!NT_STATUS_IS_OK(status)) {
3309 printf("Connect4 failed - %s\n", nt_errstr(status));
3313 test_samr_handle_Close(p, mem_ctx, handle);
3319 printf("testing samr_Connect5\n");
3321 info.info1.unknown1 = 0;
3322 info.info1.unknown2 = 0;
3324 r5.in.system_name = "";
3325 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3328 r5.out.info = &info;
3329 r5.out.connect_handle = &h;
3331 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3332 if (!NT_STATUS_IS_OK(status)) {
3333 printf("Connect5 failed - %s\n", nt_errstr(status));
3337 test_samr_handle_Close(p, mem_ctx, handle);
3347 BOOL torture_rpc_samr(void)
3350 struct dcerpc_pipe *p;
3351 TALLOC_CTX *mem_ctx;
3353 struct policy_handle handle;
3355 mem_ctx = talloc_init("torture_rpc_samr");
3357 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_samr);
3358 if (!NT_STATUS_IS_OK(status)) {
3359 talloc_free(mem_ctx);
3363 if (!test_Connect(p, mem_ctx, &handle)) {
3367 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3371 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3375 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3379 if (!test_Shutdown(p, mem_ctx, &handle)) {
3383 if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3387 talloc_free(mem_ctx);