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.
25 #define TEST_ACCOUNT_NAME "samrtorturetest"
26 #define TEST_ALIASNAME "samrtorturetestalias"
27 #define TEST_GROUPNAME "samrtorturetestgroup"
28 #define TEST_MACHINENAME "samrtorturetestmach$"
29 #define TEST_DOMAINNAME "samrtorturetestdom$"
32 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
33 struct policy_handle *handle);
35 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
36 struct policy_handle *handle);
38 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
39 struct policy_handle *handle);
41 static void init_samr_Name(struct samr_Name *name, const char *s)
46 static BOOL test_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
47 struct policy_handle *handle)
53 r.out.handle = handle;
55 status = dcerpc_samr_Close(p, mem_ctx, &r);
56 if (!NT_STATUS_IS_OK(status)) {
57 printf("Close handle failed - %s\n", nt_errstr(status));
64 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
65 struct policy_handle *handle)
68 struct samr_Shutdown r;
70 if (lp_parm_int(-1, "torture", "dangerous") != 1) {
71 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
77 printf("testing samr_Shutdown\n");
79 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
80 if (!NT_STATUS_IS_OK(status)) {
81 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
88 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
89 struct policy_handle *handle)
92 struct samr_SetDsrmPassword r;
93 struct samr_Name name;
94 struct samr_Password hash;
96 if (lp_parm_int(-1, "torture", "dangerous") != 1) {
97 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
101 E_md4hash("TeSTDSRM123", hash.hash);
103 init_samr_Name(&name, "Administrator");
109 printf("testing samr_SetDsrmPassword\n");
111 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
112 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
113 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
121 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
122 struct policy_handle *handle)
125 struct samr_QuerySecurity r;
126 struct samr_SetSecurity s;
128 r.in.handle = handle;
131 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
132 if (!NT_STATUS_IS_OK(status)) {
133 printf("QuerySecurity failed - %s\n", nt_errstr(status));
137 if (r.out.sdbuf == NULL) {
141 s.in.handle = handle;
143 s.in.sdbuf = r.out.sdbuf;
145 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
146 if (!NT_STATUS_IS_OK(status)) {
147 printf("SetSecurity failed - %s\n", nt_errstr(status));
151 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
152 if (!NT_STATUS_IS_OK(status)) {
153 printf("QuerySecurity failed - %s\n", nt_errstr(status));
161 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
162 struct policy_handle *handle)
165 struct samr_SetUserInfo s;
166 struct samr_SetUserInfo2 s2;
167 struct samr_QueryUserInfo q;
168 struct samr_QueryUserInfo q0;
169 union samr_UserInfo u;
172 s.in.handle = handle;
175 s2.in.handle = handle;
178 q.in.handle = handle;
182 #define TESTCALL(call, r) \
183 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
184 if (!NT_STATUS_IS_OK(status)) { \
185 printf(#call " level %u failed - %s (line %d)\n", \
186 r.in.level, nt_errstr(status), __LINE__); \
191 #define STRING_EQUAL(s1, s2, field) \
192 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
193 printf("Failed to set %s to '%s' (line %d)\n", \
194 #field, s2, __LINE__); \
199 #define INT_EQUAL(i1, i2, field) \
201 printf("Failed to set %s to %u (line %d)\n", \
202 #field, i2, __LINE__); \
207 #define TEST_USERINFO_NAME(lvl1, field1, lvl2, field2, value, fpval) do { \
208 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
210 TESTCALL(QueryUserInfo, q) \
212 s2.in.level = lvl1; \
215 ZERO_STRUCT(u.info21); \
216 u.info21.fields_present = fpval; \
218 init_samr_Name(&u.info ## lvl1.field1, value); \
219 TESTCALL(SetUserInfo, s) \
220 TESTCALL(SetUserInfo2, s2) \
221 init_samr_Name(&u.info ## lvl1.field1, ""); \
222 TESTCALL(QueryUserInfo, q); \
224 STRING_EQUAL(u.info ## lvl1.field1.name, value, field1); \
226 TESTCALL(QueryUserInfo, q) \
228 STRING_EQUAL(u.info ## lvl2.field2.name, value, field2); \
231 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
232 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
234 TESTCALL(QueryUserInfo, q) \
236 s2.in.level = lvl1; \
239 uint8_t *bitmap = u.info21.logon_hours.bitmap; \
240 ZERO_STRUCT(u.info21); \
241 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
242 u.info21.logon_hours.units_per_week = 168; \
243 u.info21.logon_hours.bitmap = bitmap; \
245 u.info21.fields_present = fpval; \
247 u.info ## lvl1.field1 = value; \
248 TESTCALL(SetUserInfo, s) \
249 TESTCALL(SetUserInfo2, s2) \
250 u.info ## lvl1.field1 = 0; \
251 TESTCALL(QueryUserInfo, q); \
253 INT_EQUAL(u.info ## lvl1.field1, value, field1); \
255 TESTCALL(QueryUserInfo, q) \
257 INT_EQUAL(u.info ## lvl2.field2, value, field1); \
261 do { TESTCALL(QueryUserInfo, q0) } while (0);
263 TEST_USERINFO_NAME(2, comment, 1, comment, "xx2-1 comment", 0);
264 TEST_USERINFO_NAME(2, comment, 21, comment, "xx2-21 comment", 0);
265 TEST_USERINFO_NAME(21, comment, 21, comment, "xx21-21 comment",
268 TEST_USERINFO_NAME(6, full_name, 1, full_name, "xx6-1 full_name", 0);
269 TEST_USERINFO_NAME(6, full_name, 3, full_name, "xx6-3 full_name", 0);
270 TEST_USERINFO_NAME(6, full_name, 5, full_name, "xx6-5 full_name", 0);
271 TEST_USERINFO_NAME(6, full_name, 6, full_name, "xx6-6 full_name", 0);
272 TEST_USERINFO_NAME(6, full_name, 8, full_name, "xx6-8 full_name", 0);
273 TEST_USERINFO_NAME(6, full_name, 21, full_name, "xx6-21 full_name", 0);
274 TEST_USERINFO_NAME(8, full_name, 21, full_name, "xx8-21 full_name", 0);
275 TEST_USERINFO_NAME(21, full_name, 21, full_name, "xx21-21 full_name",
278 TEST_USERINFO_NAME(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
279 TEST_USERINFO_NAME(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
280 TEST_USERINFO_NAME(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
281 TEST_USERINFO_NAME(21, logon_script, 21, logon_script, "xx21-21 logon_script",
282 SAMR_FIELD_LOGON_SCRIPT);
284 TEST_USERINFO_NAME(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
285 TEST_USERINFO_NAME(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
286 TEST_USERINFO_NAME(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
287 TEST_USERINFO_NAME(21, profile_path, 21, profile_path, "xx21-21 profile_path",
288 SAMR_FIELD_PROFILE_PATH);
290 TEST_USERINFO_NAME(13, description, 1, description, "xx13-1 description", 0);
291 TEST_USERINFO_NAME(13, description, 5, description, "xx13-5 description", 0);
292 TEST_USERINFO_NAME(13, description, 21, description, "xx13-21 description", 0);
293 TEST_USERINFO_NAME(21, description, 21, description, "xx21-21 description",
294 SAMR_FIELD_DESCRIPTION);
296 TEST_USERINFO_NAME(14, workstations, 3, workstations, "14workstation3", 0);
297 TEST_USERINFO_NAME(14, workstations, 5, workstations, "14workstation4", 0);
298 TEST_USERINFO_NAME(14, workstations, 21, workstations, "14workstation21", 0);
299 TEST_USERINFO_NAME(21, workstations, 21, workstations, "21workstation21",
300 SAMR_FIELD_WORKSTATION);
302 TEST_USERINFO_NAME(20, callback, 21, callback, "xx20-21 callback", 0);
303 TEST_USERINFO_NAME(21, callback, 21, callback, "xx21-21 callback",
304 SAMR_FIELD_CALLBACK);
306 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
307 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
308 SAMR_FIELD_COUNTRY_CODE);
310 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
311 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
312 SAMR_FIELD_CODE_PAGE);
314 TEST_USERINFO_INT(4, logon_hours.bitmap[3], 3, logon_hours.bitmap[3], 1, 0);
315 TEST_USERINFO_INT(4, logon_hours.bitmap[3], 5, logon_hours.bitmap[3], 2, 0);
316 TEST_USERINFO_INT(4, logon_hours.bitmap[3], 21, logon_hours.bitmap[3], 3, 0);
317 TEST_USERINFO_INT(21, logon_hours.bitmap[3], 21, logon_hours.bitmap[3], 4,
318 SAMR_FIELD_LOGON_HOURS);
321 /* these fail with win2003 - it appears you can't set the primary gid?
322 the set succeeds, but the gid isn't changed. Very weird! */
323 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
324 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
325 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
326 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
332 generate a random password for password change tests
334 static char *samr_rand_pass(TALLOC_CTX *mem_ctx)
336 size_t len = 8 + (random() % 6);
337 char *s = generate_random_str(mem_ctx, len);
338 printf("Generated password '%s'\n", s);
342 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
343 struct policy_handle *handle, char **password)
346 struct samr_SetUserInfo s;
347 union samr_UserInfo u;
349 DATA_BLOB session_key;
350 char *newpass = samr_rand_pass(mem_ctx);
352 s.in.handle = handle;
356 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
357 /* w2k3 ignores this length */
358 u.info24.pw_len = str_charnum(newpass)*2;
360 status = dcerpc_fetch_session_key(p, &session_key);
361 if (!NT_STATUS_IS_OK(status)) {
362 printf("SetUserInfo level %u - no session key - %s\n",
363 s.in.level, nt_errstr(status));
367 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
369 printf("Testing SetUserInfo level 24 (set password)\n");
371 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
372 if (!NT_STATUS_IS_OK(status)) {
373 printf("SetUserInfo level %u failed - %s\n",
374 s.in.level, nt_errstr(status));
384 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
385 struct policy_handle *handle, char **password)
388 struct samr_SetUserInfo s;
389 union samr_UserInfo u;
391 DATA_BLOB session_key;
392 char *newpass = samr_rand_pass(mem_ctx);
394 s.in.handle = handle;
400 u.info23.info.fields_present = SAMR_FIELD_PASSWORD;
402 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
404 status = dcerpc_fetch_session_key(p, &session_key);
405 if (!NT_STATUS_IS_OK(status)) {
406 printf("SetUserInfo level %u - no session key - %s\n",
407 s.in.level, nt_errstr(status));
411 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
413 printf("Testing SetUserInfo level 23 (set password)\n");
415 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
416 if (!NT_STATUS_IS_OK(status)) {
417 printf("SetUserInfo level %u failed - %s\n",
418 s.in.level, nt_errstr(status));
428 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
429 struct policy_handle *handle, char **password)
432 struct samr_SetUserInfo s;
433 union samr_UserInfo u;
435 DATA_BLOB session_key;
436 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
437 uint8_t confounder[16];
438 char *newpass = samr_rand_pass(mem_ctx);
439 struct MD5Context ctx;
441 s.in.handle = handle;
445 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
446 u.info26.pw_len = strlen(newpass);
448 status = dcerpc_fetch_session_key(p, &session_key);
449 if (!NT_STATUS_IS_OK(status)) {
450 printf("SetUserInfo level %u - no session key - %s\n",
451 s.in.level, nt_errstr(status));
455 generate_random_buffer((uint8_t *)confounder, 16);
458 MD5Update(&ctx, confounder, 16);
459 MD5Update(&ctx, session_key.data, session_key.length);
460 MD5Final(confounded_session_key.data, &ctx);
462 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
463 memcpy(&u.info26.password.data[516], confounder, 16);
465 printf("Testing SetUserInfo level 26 (set password ex)\n");
467 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
468 if (!NT_STATUS_IS_OK(status)) {
469 printf("SetUserInfo level %u failed - %s\n",
470 s.in.level, nt_errstr(status));
479 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
480 struct policy_handle *handle, char **password)
483 struct samr_SetUserInfo s;
484 union samr_UserInfo u;
486 DATA_BLOB session_key;
487 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
488 uint8_t confounder[16];
489 char *newpass = samr_rand_pass(mem_ctx);
490 struct MD5Context ctx;
492 s.in.handle = handle;
498 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
500 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
502 status = dcerpc_fetch_session_key(p, &session_key);
503 if (!NT_STATUS_IS_OK(status)) {
504 printf("SetUserInfo level %u - no session key - %s\n",
505 s.in.level, nt_errstr(status));
509 generate_random_buffer((uint8_t *)confounder, 16);
512 MD5Update(&ctx, confounder, 16);
513 MD5Update(&ctx, session_key.data, session_key.length);
514 MD5Final(confounded_session_key.data, &ctx);
516 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
517 memcpy(&u.info25.password.data[516], confounder, 16);
519 printf("Testing SetUserInfo level 25 (set password ex)\n");
521 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
522 if (!NT_STATUS_IS_OK(status)) {
523 printf("SetUserInfo level %u failed - %s\n",
524 s.in.level, nt_errstr(status));
533 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
534 struct policy_handle *handle)
537 struct samr_SetAliasInfo r;
538 struct samr_QueryAliasInfo q;
539 uint16_t levels[] = {2, 3};
543 /* Ignoring switch level 1, as that includes the number of members for the alias
544 * and setting this to a wrong value might have negative consequences
547 for (i=0;i<ARRAY_SIZE(levels);i++) {
548 printf("Testing SetAliasInfo level %u\n", levels[i]);
550 r.in.handle = handle;
551 r.in.level = levels[i];
552 switch (r.in.level) {
553 case 2 : init_samr_Name(&r.in.info.name,TEST_ALIASNAME); break;
554 case 3 : init_samr_Name(&r.in.info.description,
555 "Test Description, should test I18N as well"); break;
558 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
559 if (!NT_STATUS_IS_OK(status)) {
560 printf("SetAliasInfo level %u failed - %s\n",
561 levels[i], nt_errstr(status));
565 q.in.handle = handle;
566 q.in.level = levels[i];
568 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
569 if (!NT_STATUS_IS_OK(status)) {
570 printf("QueryAliasInfo level %u failed - %s\n",
571 levels[i], nt_errstr(status));
579 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
580 struct policy_handle *user_handle)
582 struct samr_GetGroupsForUser r;
586 printf("testing GetGroupsForUser\n");
588 r.in.handle = user_handle;
590 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
591 if (!NT_STATUS_IS_OK(status)) {
592 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
600 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
601 struct samr_Name *domain_name)
604 struct samr_GetDomPwInfo r;
607 r.in.name = domain_name;
608 printf("Testing GetDomPwInfo with name %s\n", r.in.name->name);
610 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
611 if (!NT_STATUS_IS_OK(status)) {
612 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
616 r.in.name->name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
617 printf("Testing GetDomPwInfo with name %s\n", r.in.name->name);
619 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
620 if (!NT_STATUS_IS_OK(status)) {
621 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
625 r.in.name->name = "\\\\__NONAME__";
626 printf("Testing GetDomPwInfo with name %s\n", r.in.name->name);
628 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
629 if (!NT_STATUS_IS_OK(status)) {
630 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
634 r.in.name->name = "\\\\Builtin";
635 printf("Testing GetDomPwInfo with name %s\n", r.in.name->name);
637 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
638 if (!NT_STATUS_IS_OK(status)) {
639 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
647 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
648 struct policy_handle *handle)
651 struct samr_GetUserPwInfo r;
654 printf("Testing GetUserPwInfo\n");
656 r.in.handle = handle;
658 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
659 if (!NT_STATUS_IS_OK(status)) {
660 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
667 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
668 struct policy_handle *domain_handle, const char *name,
672 struct samr_LookupNames n;
673 struct samr_Name sname[2];
675 init_samr_Name(&sname[0], name);
677 n.in.handle = domain_handle;
680 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
681 if (NT_STATUS_IS_OK(status)) {
682 *rid = n.out.rids.ids[0];
687 init_samr_Name(&sname[1], "xxNONAMExx");
689 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
690 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
691 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
695 init_samr_Name(&sname[1], "xxNONAMExx");
697 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
698 if (!NT_STATUS_IS_OK(status)) {
699 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
705 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
706 struct policy_handle *domain_handle,
707 const char *name, struct policy_handle *user_handle)
710 struct samr_OpenUser r;
713 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
714 if (!NT_STATUS_IS_OK(status)) {
718 r.in.handle = domain_handle;
719 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
721 r.out.acct_handle = user_handle;
722 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
723 if (!NT_STATUS_IS_OK(status)) {
724 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
731 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
732 struct policy_handle *handle)
735 struct samr_ChangePasswordUser r;
737 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
738 struct policy_handle user_handle;
739 char *oldpass = "test";
740 char *newpass = "test2";
741 uint8_t old_nt_hash[16], new_nt_hash[16];
742 uint8_t old_lm_hash[16], new_lm_hash[16];
744 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
745 if (!NT_STATUS_IS_OK(status)) {
749 printf("Testing ChangePasswordUser for user 'testuser'\n");
751 printf("old password: %s\n", oldpass);
752 printf("new password: %s\n", newpass);
754 E_md4hash(oldpass, old_nt_hash);
755 E_md4hash(newpass, new_nt_hash);
756 E_deshash(oldpass, old_lm_hash);
757 E_deshash(newpass, new_lm_hash);
759 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
760 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
761 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
762 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
763 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
764 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
766 r.in.handle = &user_handle;
768 r.in.old_lm_crypted = &hash1;
769 r.in.new_lm_crypted = &hash2;
771 r.in.old_nt_crypted = &hash3;
772 r.in.new_nt_crypted = &hash4;
773 r.in.cross1_present = 1;
774 r.in.nt_cross = &hash5;
775 r.in.cross2_present = 1;
776 r.in.lm_cross = &hash6;
778 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
779 if (!NT_STATUS_IS_OK(status)) {
780 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
784 if (!test_Close(p, mem_ctx, &user_handle)) {
792 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
793 struct policy_handle *handle, char **password)
796 struct samr_ChangePasswordUser r;
798 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
799 struct policy_handle user_handle;
800 char *oldpass = *password;
801 char *newpass = samr_rand_pass(mem_ctx);
802 uint8_t old_nt_hash[16], new_nt_hash[16];
803 uint8_t old_lm_hash[16], new_lm_hash[16];
805 status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
806 if (!NT_STATUS_IS_OK(status)) {
810 printf("Testing ChangePasswordUser\n");
812 E_md4hash(oldpass, old_nt_hash);
813 E_md4hash(newpass, new_nt_hash);
814 E_deshash(oldpass, old_lm_hash);
815 E_deshash(newpass, new_lm_hash);
817 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
818 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
819 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
820 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
821 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
822 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
824 r.in.handle = &user_handle;
826 r.in.old_lm_crypted = &hash1;
827 r.in.new_lm_crypted = &hash2;
829 r.in.old_nt_crypted = &hash3;
830 r.in.new_nt_crypted = &hash4;
831 r.in.cross1_present = 1;
832 r.in.nt_cross = &hash5;
833 r.in.cross2_present = 1;
834 r.in.lm_cross = &hash6;
836 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
837 if (!NT_STATUS_IS_OK(status)) {
838 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
844 if (!test_Close(p, mem_ctx, &user_handle)) {
852 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
853 struct policy_handle *handle, char **password)
856 struct samr_OemChangePasswordUser2 r;
858 struct samr_Password lm_verifier;
859 struct samr_CryptPassword lm_pass;
860 struct samr_AsciiName server, account;
861 char *oldpass = *password;
862 char *newpass = samr_rand_pass(mem_ctx);
863 uint8_t old_lm_hash[16], new_lm_hash[16];
865 printf("Testing OemChangePasswordUser2\n");
867 server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
868 account.name = TEST_ACCOUNT_NAME;
870 E_deshash(oldpass, old_lm_hash);
871 E_deshash(newpass, new_lm_hash);
873 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
874 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
875 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
877 r.in.server = &server;
878 r.in.account = &account;
879 r.in.password = &lm_pass;
880 r.in.hash = &lm_verifier;
882 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
883 if (!NT_STATUS_IS_OK(status)) {
884 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
894 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
895 struct policy_handle *handle, char **password)
898 struct samr_ChangePasswordUser2 r;
900 struct samr_Name server, account;
901 struct samr_CryptPassword nt_pass, lm_pass;
902 struct samr_Password nt_verifier, lm_verifier;
903 char *oldpass = *password;
904 char *newpass = samr_rand_pass(mem_ctx);
905 uint8_t old_nt_hash[16], new_nt_hash[16];
906 uint8_t old_lm_hash[16], new_lm_hash[16];
908 printf("Testing ChangePasswordUser2\n");
910 server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
911 init_samr_Name(&account, TEST_ACCOUNT_NAME);
913 E_md4hash(oldpass, old_nt_hash);
914 E_md4hash(newpass, new_nt_hash);
916 E_deshash(oldpass, old_lm_hash);
917 E_deshash(newpass, new_lm_hash);
919 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
920 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
921 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
923 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
924 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
925 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
927 r.in.server = &server;
928 r.in.account = &account;
929 r.in.nt_password = &nt_pass;
930 r.in.nt_verifier = &nt_verifier;
932 r.in.lm_password = &lm_pass;
933 r.in.lm_verifier = &lm_verifier;
935 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
936 if (!NT_STATUS_IS_OK(status)) {
937 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
947 static BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
948 struct policy_handle *handle, char **password)
951 struct samr_ChangePasswordUser3 r;
953 struct samr_Name server, account;
954 struct samr_CryptPassword nt_pass, lm_pass;
955 struct samr_Password nt_verifier, lm_verifier;
956 char *oldpass = *password;
957 char *newpass = samr_rand_pass(mem_ctx);
958 uint8_t old_nt_hash[16], new_nt_hash[16];
959 uint8_t old_lm_hash[16], new_lm_hash[16];
961 printf("Testing ChangePasswordUser3\n");
963 server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
964 init_samr_Name(&account, TEST_ACCOUNT_NAME);
966 E_md4hash(oldpass, old_nt_hash);
967 E_md4hash(newpass, new_nt_hash);
969 E_deshash(oldpass, old_lm_hash);
970 E_deshash(newpass, new_lm_hash);
972 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
973 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
974 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
976 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
977 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
978 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
980 r.in.server = &server;
981 r.in.account = &account;
982 r.in.nt_password = &nt_pass;
983 r.in.nt_verifier = &nt_verifier;
985 r.in.lm_password = &lm_pass;
986 r.in.lm_verifier = &lm_verifier;
987 r.in.password3 = NULL;
989 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
990 if (!NT_STATUS_IS_OK(status)) {
991 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1001 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1002 struct policy_handle *alias_handle)
1004 struct samr_GetMembersInAlias r;
1005 struct lsa_SidArray sids;
1009 printf("Testing GetMembersInAlias\n");
1011 r.in.handle = alias_handle;
1014 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1015 if (!NT_STATUS_IS_OK(status)) {
1016 printf("GetMembersInAlias failed - %s\n",
1024 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1025 struct policy_handle *alias_handle,
1026 struct policy_handle *domain_handle,
1027 const struct dom_sid *domain_sid)
1029 struct samr_AddAliasMember r;
1030 struct samr_DeleteAliasMember d;
1033 struct dom_sid *sid;
1035 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1037 printf("testing AddAliasMember\n");
1038 r.in.handle = alias_handle;
1041 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1042 if (!NT_STATUS_IS_OK(status)) {
1043 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1047 d.in.handle = alias_handle;
1050 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1051 if (!NT_STATUS_IS_OK(status)) {
1052 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1059 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1060 struct policy_handle *alias_handle)
1062 struct samr_AddMultipleMembersToAlias a;
1063 struct samr_RemoveMultipleMembersFromAlias r;
1066 struct lsa_SidArray sids;
1068 printf("testing AddMultipleMembersToAlias\n");
1069 a.in.handle = alias_handle;
1073 sids.sids = talloc_array_p(mem_ctx, struct lsa_SidPtr, 3);
1075 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1076 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1077 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1079 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1080 if (!NT_STATUS_IS_OK(status)) {
1081 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1086 printf("testing RemoveMultipleMembersFromAlias\n");
1087 r.in.handle = alias_handle;
1090 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1091 if (!NT_STATUS_IS_OK(status)) {
1092 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1096 /* strange! removing twice doesn't give any error */
1097 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1098 if (!NT_STATUS_IS_OK(status)) {
1099 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1103 /* but removing an alias that isn't there does */
1104 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1106 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1107 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1108 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1115 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1116 struct policy_handle *user_handle)
1118 struct samr_TestPrivateFunctionsUser r;
1122 printf("Testing TestPrivateFunctionsUser\n");
1124 r.in.handle = user_handle;
1126 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1127 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1128 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1136 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1137 struct policy_handle *handle)
1141 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1145 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1149 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1153 if (!test_SetUserInfo(p, mem_ctx, handle)) {
1157 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1161 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1168 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1169 struct policy_handle *alias_handle,
1170 struct policy_handle *domain_handle,
1171 const struct dom_sid *domain_sid)
1175 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1179 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1183 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1187 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle,
1188 domain_handle, domain_sid)) {
1192 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1200 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1201 struct policy_handle *handle, const char *name)
1204 struct samr_DeleteUser d;
1205 struct policy_handle acct_handle;
1208 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1209 if (!NT_STATUS_IS_OK(status)) {
1213 status = test_OpenUser_byname(p, mem_ctx, handle, name, &acct_handle);
1214 if (!NT_STATUS_IS_OK(status)) {
1218 d.in.handle = &acct_handle;
1219 d.out.handle = &acct_handle;
1220 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1221 if (!NT_STATUS_IS_OK(status)) {
1228 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1233 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1234 struct policy_handle *handle, const char *name)
1237 struct samr_OpenGroup r;
1238 struct samr_DeleteDomainGroup d;
1239 struct policy_handle group_handle;
1242 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1243 if (!NT_STATUS_IS_OK(status)) {
1247 r.in.handle = handle;
1248 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1250 r.out.acct_handle = &group_handle;
1251 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1252 if (!NT_STATUS_IS_OK(status)) {
1256 d.in.handle = &group_handle;
1257 d.out.handle = &group_handle;
1258 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1259 if (!NT_STATUS_IS_OK(status)) {
1266 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1271 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1272 struct policy_handle *domain_handle, const char *name)
1275 struct samr_OpenAlias r;
1276 struct samr_DeleteDomAlias d;
1277 struct policy_handle alias_handle;
1280 printf("testing DeleteAlias_byname\n");
1282 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1283 if (!NT_STATUS_IS_OK(status)) {
1287 r.in.handle = domain_handle;
1288 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1290 r.out.acct_handle = &alias_handle;
1291 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1292 if (!NT_STATUS_IS_OK(status)) {
1296 d.in.handle = &alias_handle;
1297 d.out.handle = &alias_handle;
1298 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1299 if (!NT_STATUS_IS_OK(status)) {
1306 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1310 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1311 struct policy_handle *alias_handle)
1313 struct samr_DeleteDomAlias d;
1316 printf("Testing DeleteAlias\n");
1318 d.in.handle = alias_handle;
1319 d.out.handle = alias_handle;
1321 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1322 if (!NT_STATUS_IS_OK(status)) {
1323 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1330 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1331 struct policy_handle *domain_handle,
1332 struct policy_handle *alias_handle,
1333 const struct dom_sid *domain_sid)
1336 struct samr_CreateDomAlias r;
1337 struct samr_Name name;
1341 init_samr_Name(&name, TEST_ALIASNAME);
1342 r.in.handle = domain_handle;
1343 r.in.aliasname = &name;
1344 r.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
1345 r.out.acct_handle = alias_handle;
1348 printf("Testing CreateAlias (%s)\n", r.in.aliasname->name);
1350 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1352 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1353 printf("Server refused create of '%s'\n", r.in.aliasname->name);
1357 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1358 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.aliasname->name)) {
1361 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1364 if (!NT_STATUS_IS_OK(status)) {
1365 printf("CreateAlias failed - %s\n", nt_errstr(status));
1369 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_handle, domain_sid)) {
1376 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1377 struct policy_handle *domain_handle, char **password)
1385 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1389 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1393 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1397 if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, password)) {
1404 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1405 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1408 struct samr_CreateUser r;
1409 struct samr_QueryUserInfo q;
1411 char *password = NULL;
1413 /* This call creates a 'normal' account - check that it really does */
1414 const uint32_t acct_flags = ACB_NORMAL;
1415 struct samr_Name name;
1418 init_samr_Name(&name, TEST_ACCOUNT_NAME);
1420 r.in.handle = domain_handle;
1421 r.in.account_name = &name;
1422 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1423 r.out.acct_handle = user_handle;
1426 printf("Testing CreateUser(%s)\n", r.in.account_name->name);
1428 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1430 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1431 printf("Server refused create of '%s'\n", r.in.account_name->name);
1432 ZERO_STRUCTP(user_handle);
1436 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1437 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.account_name->name)) {
1440 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1442 if (!NT_STATUS_IS_OK(status)) {
1443 printf("CreateUser failed - %s\n", nt_errstr(status));
1447 q.in.handle = user_handle;
1450 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1451 if (!NT_STATUS_IS_OK(status)) {
1452 printf("QueryUserInfo level %u failed - %s\n",
1453 q.in.level, nt_errstr(status));
1456 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1457 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1458 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1459 acct_flags, acct_flags);
1464 if (!test_user_ops(p, mem_ctx, user_handle)) {
1468 if (!test_SetUserPass(p, mem_ctx, user_handle, &password)) {
1472 if (!test_SetUserPass_23(p, mem_ctx, user_handle, &password)) {
1476 if (!test_SetUserPassEx(p, mem_ctx, user_handle, &password)) {
1480 if (!test_SetUserPass_25(p, mem_ctx, user_handle, &password)) {
1484 /* we change passwords twice - this has the effect of verifying
1485 they were changed correctly */
1486 if (!test_ChangePassword(p, mem_ctx, domain_handle, &password)) {
1490 if (!test_ChangePassword(p, mem_ctx, domain_handle, &password)) {
1499 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1500 struct policy_handle *user_handle)
1502 struct samr_DeleteUser d;
1506 printf("Testing DeleteUser\n");
1508 d.in.handle = user_handle;
1509 d.out.handle = user_handle;
1511 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1512 if (!NT_STATUS_IS_OK(status)) {
1513 printf("DeleteUser failed - %s\n", nt_errstr(status));
1520 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1521 struct policy_handle *handle)
1524 struct samr_CreateUser2 r;
1525 struct samr_QueryUserInfo q;
1526 struct samr_DeleteUser d;
1527 struct policy_handle acct_handle;
1529 struct samr_Name name;
1534 uint32_t acct_flags;
1535 const char *account_name;
1537 } account_types[] = {
1538 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1539 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1540 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1541 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1542 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1543 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1544 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1545 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1546 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1547 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1548 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1549 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1550 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1551 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1552 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1555 for (i = 0; account_types[i].account_name; i++) {
1556 uint32_t acct_flags = account_types[i].acct_flags;
1557 uint32_t access_granted;
1559 init_samr_Name(&name, account_types[i].account_name);
1561 r.in.handle = handle;
1562 r.in.account_name = &name;
1563 r.in.acct_flags = acct_flags;
1564 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1565 r.out.acct_handle = &acct_handle;
1566 r.out.access_granted = &access_granted;
1569 printf("Testing CreateUser2(%s)\n", r.in.account_name->name);
1571 status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1573 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1574 printf("Server refused create of '%s'\n", r.in.account_name->name);
1577 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1578 if (!test_DeleteUser_byname(p, mem_ctx, handle, r.in.account_name->name)) {
1581 status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1584 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1585 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1586 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1590 if (NT_STATUS_IS_OK(status)) {
1591 q.in.handle = &acct_handle;
1594 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1595 if (!NT_STATUS_IS_OK(status)) {
1596 printf("QueryUserInfo level %u failed - %s\n",
1597 q.in.level, nt_errstr(status));
1600 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1601 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1602 q.out.info->info16.acct_flags,
1608 if (!test_user_ops(p, mem_ctx, &acct_handle)) {
1612 printf("Testing DeleteUser (createuser2 test)\n");
1614 d.in.handle = &acct_handle;
1615 d.out.handle = &acct_handle;
1617 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1618 if (!NT_STATUS_IS_OK(status)) {
1619 printf("DeleteUser failed - %s\n", nt_errstr(status));
1628 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1629 struct policy_handle *handle)
1632 struct samr_QueryAliasInfo r;
1633 uint16_t levels[] = {1, 2, 3};
1637 for (i=0;i<ARRAY_SIZE(levels);i++) {
1638 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1640 r.in.handle = handle;
1641 r.in.level = levels[i];
1643 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1644 if (!NT_STATUS_IS_OK(status)) {
1645 printf("QueryAliasInfo level %u failed - %s\n",
1646 levels[i], nt_errstr(status));
1654 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1655 struct policy_handle *handle)
1658 struct samr_QueryGroupInfo r;
1659 uint16_t levels[] = {1, 2, 3, 4};
1663 for (i=0;i<ARRAY_SIZE(levels);i++) {
1664 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1666 r.in.handle = handle;
1667 r.in.level = levels[i];
1669 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1670 if (!NT_STATUS_IS_OK(status)) {
1671 printf("QueryGroupInfo level %u failed - %s\n",
1672 levels[i], nt_errstr(status));
1681 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1682 struct policy_handle *handle)
1685 struct samr_QueryGroupInfo r;
1686 struct samr_SetGroupInfo s;
1687 uint16_t levels[] = {1, 2, 3, 4};
1688 uint16_t set_ok[] = {0, 1, 1, 1};
1692 for (i=0;i<ARRAY_SIZE(levels);i++) {
1693 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1695 r.in.handle = handle;
1696 r.in.level = levels[i];
1698 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1699 if (!NT_STATUS_IS_OK(status)) {
1700 printf("QueryGroupInfo level %u failed - %s\n",
1701 levels[i], nt_errstr(status));
1705 printf("Testing SetGroupInfo level %u\n", levels[i]);
1707 s.in.handle = handle;
1708 s.in.level = levels[i];
1709 s.in.info = r.out.info;
1712 /* disabled this, as it changes the name only from the point of view of samr,
1713 but leaves the name from the point of view of w2k3 internals (and ldap). This means
1714 the name is still reserved, so creating the old name fails, but deleting by the old name
1716 if (s.in.level == 2) {
1717 init_samr_Name(&s.in.info->name, "NewName");
1721 if (s.in.level == 4) {
1722 init_samr_Name(&s.in.info->description, "test description");
1725 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
1727 if (!NT_STATUS_IS_OK(status)) {
1728 printf("SetGroupInfo level %u failed - %s\n",
1729 r.in.level, nt_errstr(status));
1734 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
1735 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
1736 r.in.level, nt_errstr(status));
1746 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1747 struct policy_handle *handle)
1750 struct samr_QueryUserInfo r;
1751 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1752 11, 12, 13, 14, 16, 17, 20, 21};
1756 for (i=0;i<ARRAY_SIZE(levels);i++) {
1757 printf("Testing QueryUserInfo level %u\n", levels[i]);
1759 r.in.handle = handle;
1760 r.in.level = levels[i];
1762 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
1763 if (!NT_STATUS_IS_OK(status)) {
1764 printf("QueryUserInfo level %u failed - %s\n",
1765 levels[i], nt_errstr(status));
1773 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1774 struct policy_handle *handle)
1777 struct samr_QueryUserInfo2 r;
1778 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1779 11, 12, 13, 14, 16, 17, 20, 21};
1783 for (i=0;i<ARRAY_SIZE(levels);i++) {
1784 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
1786 r.in.handle = handle;
1787 r.in.level = levels[i];
1789 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
1790 if (!NT_STATUS_IS_OK(status)) {
1791 printf("QueryUserInfo2 level %u failed - %s\n",
1792 levels[i], nt_errstr(status));
1800 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1801 struct policy_handle *handle, uint32_t rid)
1804 struct samr_OpenUser r;
1805 struct policy_handle acct_handle;
1808 printf("Testing OpenUser(%u)\n", rid);
1810 r.in.handle = handle;
1811 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1813 r.out.acct_handle = &acct_handle;
1815 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1816 if (!NT_STATUS_IS_OK(status)) {
1817 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
1821 if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1825 if (!test_QueryUserInfo(p, mem_ctx, &acct_handle)) {
1829 if (!test_QueryUserInfo2(p, mem_ctx, &acct_handle)) {
1833 if (!test_GetUserPwInfo(p, mem_ctx, &acct_handle)) {
1837 if (!test_GetGroupsForUser(p,mem_ctx, &acct_handle)) {
1841 if (!test_Close(p, mem_ctx, &acct_handle)) {
1848 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1849 struct policy_handle *handle, uint32_t rid)
1852 struct samr_OpenGroup r;
1853 struct policy_handle acct_handle;
1856 printf("Testing OpenGroup(%u)\n", rid);
1858 r.in.handle = handle;
1859 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1861 r.out.acct_handle = &acct_handle;
1863 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1864 if (!NT_STATUS_IS_OK(status)) {
1865 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
1869 if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1873 if (!test_QueryGroupInfo(p, mem_ctx, &acct_handle)) {
1877 if (!test_Close(p, mem_ctx, &acct_handle)) {
1884 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1885 struct policy_handle *handle, uint32_t rid)
1888 struct samr_OpenAlias r;
1889 struct policy_handle acct_handle;
1892 printf("Testing OpenAlias(%u)\n", rid);
1894 r.in.handle = handle;
1895 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1897 r.out.acct_handle = &acct_handle;
1899 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1900 if (!NT_STATUS_IS_OK(status)) {
1901 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
1905 if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1909 if (!test_QueryAliasInfo(p, mem_ctx, &acct_handle)) {
1913 if (!test_GetMembersInAlias(p, mem_ctx, &acct_handle)) {
1917 if (!test_Close(p, mem_ctx, &acct_handle)) {
1924 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1925 struct policy_handle *handle)
1928 struct samr_EnumDomainUsers r;
1929 uint32_t resume_handle=0;
1932 struct samr_LookupNames n;
1933 struct samr_LookupRids lr ;
1935 printf("Testing EnumDomainUsers\n");
1937 r.in.handle = handle;
1938 r.in.resume_handle = &resume_handle;
1939 r.in.acct_flags = 0;
1940 r.in.max_size = (uint32_t)-1;
1941 r.out.resume_handle = &resume_handle;
1943 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
1944 if (!NT_STATUS_IS_OK(status)) {
1945 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
1953 if (r.out.sam->count == 0) {
1957 for (i=0;i<r.out.sam->count;i++) {
1958 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1963 printf("Testing LookupNames\n");
1964 n.in.handle = handle;
1965 n.in.num_names = r.out.sam->count;
1966 n.in.names = talloc(mem_ctx, r.out.sam->count * sizeof(struct samr_Name));
1967 for (i=0;i<r.out.sam->count;i++) {
1968 n.in.names[i] = r.out.sam->entries[i].name;
1970 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
1971 if (!NT_STATUS_IS_OK(status)) {
1972 printf("LookupNames failed - %s\n", nt_errstr(status));
1977 printf("Testing LookupRids\n");
1978 lr.in.handle = handle;
1979 lr.in.num_rids = r.out.sam->count;
1980 lr.in.rids = talloc(mem_ctx, r.out.sam->count * sizeof(uint32_t));
1981 for (i=0;i<r.out.sam->count;i++) {
1982 lr.in.rids[i] = r.out.sam->entries[i].idx;
1984 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
1985 if (!NT_STATUS_IS_OK(status)) {
1986 printf("LookupRids failed - %s\n", nt_errstr(status));
1994 try blasting the server with a bunch of sync requests
1996 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1997 struct policy_handle *handle)
2000 struct samr_EnumDomainUsers r;
2001 uint32_t resume_handle=0;
2003 #define ASYNC_COUNT 100
2004 struct rpc_request *req[ASYNC_COUNT];
2006 printf("Testing EnumDomainUsers_async\n");
2008 r.in.handle = handle;
2009 r.in.resume_handle = &resume_handle;
2010 r.in.acct_flags = 0;
2011 r.in.max_size = (uint32_t)-1;
2012 r.out.resume_handle = &resume_handle;
2014 for (i=0;i<ASYNC_COUNT;i++) {
2015 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2018 for (i=0;i<ASYNC_COUNT;i++) {
2019 status = dcerpc_ndr_request_recv(req[i]);
2020 if (!NT_STATUS_IS_OK(status)) {
2021 printf("EnumDomainUsers[%d] failed - %s\n",
2022 i, nt_errstr(status));
2027 printf("%d async requests OK\n", i);
2032 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2033 struct policy_handle *handle)
2036 struct samr_EnumDomainGroups r;
2037 uint32_t resume_handle=0;
2041 printf("Testing EnumDomainGroups\n");
2043 r.in.handle = handle;
2044 r.in.resume_handle = &resume_handle;
2045 r.in.max_size = (uint32_t)-1;
2046 r.out.resume_handle = &resume_handle;
2048 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2049 if (!NT_STATUS_IS_OK(status)) {
2050 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2058 for (i=0;i<r.out.sam->count;i++) {
2059 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2067 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2068 struct policy_handle *handle)
2071 struct samr_EnumDomainAliases r;
2072 uint32_t resume_handle=0;
2076 printf("Testing EnumDomainAliases\n");
2078 r.in.handle = handle;
2079 r.in.resume_handle = &resume_handle;
2080 r.in.account_flags = (uint32_t)-1;
2081 r.out.resume_handle = &resume_handle;
2083 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2084 if (!NT_STATUS_IS_OK(status)) {
2085 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2093 for (i=0;i<r.out.sam->count;i++) {
2094 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2102 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2103 struct policy_handle *handle)
2106 struct samr_GetDisplayEnumerationIndex r;
2108 uint16_t levels[] = {1, 2, 3, 4, 5};
2109 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2112 for (i=0;i<ARRAY_SIZE(levels);i++) {
2113 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2115 r.in.handle = handle;
2116 r.in.level = levels[i];
2117 init_samr_Name(&r.in.name, TEST_ACCOUNT_NAME);
2119 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2122 !NT_STATUS_IS_OK(status) &&
2123 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2124 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2125 levels[i], nt_errstr(status));
2129 init_samr_Name(&r.in.name, "zzzzzzzz");
2131 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2133 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2134 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2135 levels[i], nt_errstr(status));
2143 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2144 struct policy_handle *handle)
2147 struct samr_GetDisplayEnumerationIndex2 r;
2149 uint16_t levels[] = {1, 2, 3, 4, 5};
2150 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2153 for (i=0;i<ARRAY_SIZE(levels);i++) {
2154 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2156 r.in.handle = handle;
2157 r.in.level = levels[i];
2158 init_samr_Name(&r.in.name, TEST_ACCOUNT_NAME);
2160 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2162 !NT_STATUS_IS_OK(status) &&
2163 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2164 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2165 levels[i], nt_errstr(status));
2169 init_samr_Name(&r.in.name, "zzzzzzzz");
2171 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2172 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2173 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2174 levels[i], nt_errstr(status));
2182 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2183 struct policy_handle *handle)
2186 struct samr_QueryDisplayInfo r;
2188 uint16_t levels[] = {1, 2, 3, 4, 5};
2191 for (i=0;i<ARRAY_SIZE(levels);i++) {
2192 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2194 r.in.handle = handle;
2195 r.in.level = levels[i];
2197 r.in.max_entries = 1000;
2198 r.in.buf_size = (uint32_t)-1;
2200 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2201 if (!NT_STATUS_IS_OK(status)) {
2202 printf("QueryDisplayInfo level %u failed - %s\n",
2203 levels[i], nt_errstr(status));
2211 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2212 struct policy_handle *handle)
2215 struct samr_QueryDisplayInfo2 r;
2217 uint16_t levels[] = {1, 2, 3, 4, 5};
2220 for (i=0;i<ARRAY_SIZE(levels);i++) {
2221 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2223 r.in.handle = handle;
2224 r.in.level = levels[i];
2226 r.in.max_entries = 1000;
2227 r.in.buf_size = (uint32_t)-1;
2229 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2230 if (!NT_STATUS_IS_OK(status)) {
2231 printf("QueryDisplayInfo2 level %u failed - %s\n",
2232 levels[i], nt_errstr(status));
2240 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2241 struct policy_handle *handle)
2244 struct samr_QueryDisplayInfo3 r;
2246 uint16_t levels[] = {1, 2, 3, 4, 5};
2249 for (i=0;i<ARRAY_SIZE(levels);i++) {
2250 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2252 r.in.handle = handle;
2253 r.in.level = levels[i];
2255 r.in.max_entries = 1000;
2256 r.in.buf_size = (uint32_t)-1;
2258 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2259 if (!NT_STATUS_IS_OK(status)) {
2260 printf("QueryDisplayInfo3 level %u failed - %s\n",
2261 levels[i], nt_errstr(status));
2269 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2270 struct policy_handle *handle)
2273 struct samr_QueryDomainInfo r;
2274 struct samr_SetDomainInfo s;
2275 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2276 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2280 for (i=0;i<ARRAY_SIZE(levels);i++) {
2281 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2283 r.in.handle = handle;
2284 r.in.level = levels[i];
2286 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2287 if (!NT_STATUS_IS_OK(status)) {
2288 printf("QueryDomainInfo level %u failed - %s\n",
2289 r.in.level, nt_errstr(status));
2294 printf("Testing SetDomainInfo level %u\n", levels[i]);
2296 s.in.handle = handle;
2297 s.in.level = levels[i];
2298 s.in.info = r.out.info;
2300 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2302 if (!NT_STATUS_IS_OK(status)) {
2303 printf("SetDomainInfo level %u failed - %s\n",
2304 r.in.level, nt_errstr(status));
2309 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2310 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2311 r.in.level, nt_errstr(status));
2317 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2318 if (!NT_STATUS_IS_OK(status)) {
2319 printf("QueryDomainInfo level %u failed - %s\n",
2320 r.in.level, nt_errstr(status));
2330 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2331 struct policy_handle *handle)
2334 struct samr_QueryDomainInfo2 r;
2335 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2339 for (i=0;i<ARRAY_SIZE(levels);i++) {
2340 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2342 r.in.handle = handle;
2343 r.in.level = levels[i];
2345 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2346 if (!NT_STATUS_IS_OK(status)) {
2347 printf("QueryDomainInfo2 level %u failed - %s\n",
2348 r.in.level, nt_errstr(status));
2357 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2358 set of group names. */
2359 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2360 struct policy_handle *handle)
2362 struct samr_EnumDomainGroups q1;
2363 struct samr_QueryDisplayInfo q2;
2365 uint32_t resume_handle=0;
2370 const char **names = NULL;
2372 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2374 q1.in.handle = handle;
2375 q1.in.resume_handle = &resume_handle;
2377 q1.out.resume_handle = &resume_handle;
2379 status = STATUS_MORE_ENTRIES;
2380 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2381 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2383 if (!NT_STATUS_IS_OK(status) &&
2384 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2387 for (i=0; i<q1.out.sam->count; i++) {
2388 add_string_to_array(mem_ctx,
2389 q1.out.sam->entries[i].name.name,
2390 &names, &num_names);
2394 if (!NT_STATUS_IS_OK(status)) {
2395 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2403 q2.in.handle = handle;
2405 q2.in.start_idx = 0;
2406 q2.in.max_entries = 5;
2407 q2.in.buf_size = (uint32_t)-1;
2409 status = STATUS_MORE_ENTRIES;
2410 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2411 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2413 if (!NT_STATUS_IS_OK(status) &&
2414 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2417 for (i=0; i<q2.out.info.info5.count; i++) {
2423 /* Querydisplayinfo returns ascii -- convert */
2425 namelen = convert_string_allocate(CH_DISPLAY, CH_UNIX,
2426 q2.out.info.info5.entries[i].account_name.name,
2427 q2.out.info.info5.entries[i].account_name.name_len,
2429 name = realloc(name, namelen+1);
2432 for (j=0; j<num_names; j++) {
2433 if (names[j] == NULL)
2435 /* Hmm. No strequal in samba4 */
2436 if (strequal(names[j], name)) {
2444 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2449 q2.in.start_idx += q2.out.info.info5.count;
2452 if (!NT_STATUS_IS_OK(status)) {
2453 printf("QueryDisplayInfo level 5 failed - %s\n",
2458 for (i=0; i<num_names; i++) {
2459 if (names[i] != NULL) {
2460 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2469 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2470 struct policy_handle *group_handle)
2472 struct samr_DeleteDomainGroup d;
2476 printf("Testing DeleteDomainGroup\n");
2478 d.in.handle = group_handle;
2479 d.out.handle = group_handle;
2481 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2482 if (!NT_STATUS_IS_OK(status)) {
2483 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2490 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2491 struct policy_handle *domain_handle)
2493 struct samr_TestPrivateFunctionsDomain r;
2497 printf("Testing TestPrivateFunctionsDomain\n");
2499 r.in.handle = domain_handle;
2501 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2502 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2503 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2510 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2511 struct policy_handle *domain_handle)
2513 struct samr_RidToSid r;
2517 printf("Testing RidToSid\n");
2519 r.in.handle = domain_handle;
2522 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2523 if (!NT_STATUS_IS_OK(status)) {
2524 printf("RidToSid failed - %s\n", nt_errstr(status));
2531 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2532 struct policy_handle *domain_handle)
2534 struct samr_GetBootKeyInformation r;
2538 printf("Testing GetBootKeyInformation\n");
2540 r.in.handle = domain_handle;
2542 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2543 if (!NT_STATUS_IS_OK(status)) {
2544 /* w2k3 seems to fail this sometimes and pass it sometimes */
2545 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2551 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2552 struct policy_handle *domain_handle,
2553 struct policy_handle *group_handle)
2556 struct samr_AddGroupMember r;
2557 struct samr_DeleteGroupMember d;
2558 struct samr_QueryGroupMember q;
2559 struct samr_SetMemberAttributesOfGroup s;
2563 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2564 if (!NT_STATUS_IS_OK(status)) {
2568 r.in.handle = group_handle;
2570 r.in.flags = 0; /* ??? */
2572 printf("Testing AddGroupMember and DeleteGroupMember\n");
2574 d.in.handle = group_handle;
2577 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2578 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2579 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2584 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2585 if (!NT_STATUS_IS_OK(status)) {
2586 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2590 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2591 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2592 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2597 /* this one is quite strange. I am using random inputs in the
2598 hope of triggering an error that might give us a clue */
2599 s.in.handle = group_handle;
2600 s.in.unknown1 = random();
2601 s.in.unknown2 = random();
2603 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2604 if (!NT_STATUS_IS_OK(status)) {
2605 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2609 q.in.handle = group_handle;
2611 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2612 if (!NT_STATUS_IS_OK(status)) {
2613 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2617 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2618 if (!NT_STATUS_IS_OK(status)) {
2619 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2623 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2624 if (!NT_STATUS_IS_OK(status)) {
2625 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2633 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2634 struct policy_handle *domain_handle, struct policy_handle *group_handle)
2637 struct samr_CreateDomainGroup r;
2639 struct samr_Name name;
2642 init_samr_Name(&name, TEST_GROUPNAME);
2644 r.in.handle = domain_handle;
2646 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2647 r.out.group_handle = group_handle;
2650 printf("Testing CreateDomainGroup(%s)\n", r.in.name->name);
2652 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2654 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2655 printf("Server refused create of '%s'\n", r.in.name->name);
2656 ZERO_STRUCTP(group_handle);
2660 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
2661 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2662 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->name)) {
2665 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2667 if (!NT_STATUS_IS_OK(status)) {
2668 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
2672 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
2676 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
2685 its not totally clear what this does. It seems to accept any sid you like.
2687 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
2688 TALLOC_CTX *mem_ctx,
2689 struct policy_handle *domain_handle)
2692 struct samr_RemoveMemberFromForeignDomain r;
2694 r.in.handle = domain_handle;
2695 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78-9");
2697 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
2698 if (!NT_STATUS_IS_OK(status)) {
2699 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
2709 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2710 struct policy_handle *handle, struct dom_sid *sid)
2713 struct samr_OpenDomain r;
2714 struct policy_handle domain_handle;
2715 struct policy_handle user_handle;
2716 struct policy_handle alias_handle;
2717 struct policy_handle group_handle;
2720 ZERO_STRUCT(user_handle);
2721 ZERO_STRUCT(alias_handle);
2722 ZERO_STRUCT(group_handle);
2723 ZERO_STRUCT(domain_handle);
2725 printf("Testing OpenDomain\n");
2727 r.in.handle = handle;
2728 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2730 r.out.domain_handle = &domain_handle;
2732 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
2733 if (!NT_STATUS_IS_OK(status)) {
2734 printf("OpenDomain failed - %s\n", nt_errstr(status));
2738 if (!test_QuerySecurity(p, mem_ctx, &domain_handle)) {
2742 if (!test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle)) {
2746 if (!test_CreateUser2(p, mem_ctx, &domain_handle)) {
2750 if (!test_CreateUser(p, mem_ctx, &domain_handle, &user_handle)) {
2754 if (!test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid)) {
2758 if (!test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle)) {
2762 if (!test_QueryDomainInfo(p, mem_ctx, &domain_handle)) {
2766 if (!test_QueryDomainInfo2(p, mem_ctx, &domain_handle)) {
2770 if (!test_EnumDomainUsers(p, mem_ctx, &domain_handle)) {
2774 if (!test_EnumDomainUsers_async(p, mem_ctx, &domain_handle)) {
2778 if (!test_EnumDomainGroups(p, mem_ctx, &domain_handle)) {
2782 if (!test_EnumDomainAliases(p, mem_ctx, &domain_handle)) {
2786 if (!test_QueryDisplayInfo(p, mem_ctx, &domain_handle)) {
2790 if (!test_QueryDisplayInfo2(p, mem_ctx, &domain_handle)) {
2794 if (!test_QueryDisplayInfo3(p, mem_ctx, &domain_handle)) {
2798 if (!test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle)) {
2802 if (!test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle)) {
2806 if (!test_GroupList(p, mem_ctx, &domain_handle)) {
2810 if (!test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle)) {
2814 if (!test_RidToSid(p, mem_ctx, &domain_handle)) {
2818 if (!test_GetBootKeyInformation(p, mem_ctx, &domain_handle)) {
2822 if (!policy_handle_empty(&user_handle) &&
2823 !test_DeleteUser(p, mem_ctx, &user_handle)) {
2827 if (!policy_handle_empty(&alias_handle) &&
2828 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
2832 if (!policy_handle_empty(&group_handle) &&
2833 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
2837 if (!test_Close(p, mem_ctx, &domain_handle)) {
2844 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2845 struct policy_handle *handle, struct samr_Name *domain)
2848 struct samr_LookupDomain r;
2849 struct samr_Name n2;
2852 printf("Testing LookupDomain(%s)\n", domain->name);
2854 /* check for correct error codes */
2855 r.in.handle = handle;
2859 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2860 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
2861 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
2865 n2.name = "xxNODOMAINxx";
2867 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2868 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
2869 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
2873 r.in.handle = handle;
2874 r.in.domain = domain;
2876 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2877 if (!NT_STATUS_IS_OK(status)) {
2878 printf("LookupDomain failed - %s\n", nt_errstr(status));
2882 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
2886 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
2894 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2895 struct policy_handle *handle)
2898 struct samr_EnumDomains r;
2899 uint32_t resume_handle = 0;
2903 r.in.handle = handle;
2904 r.in.resume_handle = &resume_handle;
2905 r.in.buf_size = (uint32_t)-1;
2906 r.out.resume_handle = &resume_handle;
2908 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
2909 if (!NT_STATUS_IS_OK(status)) {
2910 printf("EnumDomains failed - %s\n", nt_errstr(status));
2918 for (i=0;i<r.out.sam->count;i++) {
2919 if (!test_LookupDomain(p, mem_ctx, handle,
2920 &r.out.sam->entries[i].name)) {
2925 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
2926 if (!NT_STATUS_IS_OK(status)) {
2927 printf("EnumDomains failed - %s\n", nt_errstr(status));
2935 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2936 struct policy_handle *handle)
2939 struct samr_Connect r;
2940 struct samr_Connect2 r2;
2941 struct samr_Connect3 r3;
2942 struct samr_Connect4 r4;
2943 struct samr_Connect5 r5;
2944 union samr_ConnectInfo info;
2947 printf("testing samr_Connect\n");
2949 r.in.system_name = 0;
2950 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2951 r.out.handle = handle;
2953 status = dcerpc_samr_Connect(p, mem_ctx, &r);
2954 if (!NT_STATUS_IS_OK(status)) {
2955 printf("Connect failed - %s\n", nt_errstr(status));
2959 printf("testing samr_Connect2\n");
2961 r2.in.system_name = NULL;
2962 r2.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2963 r2.out.handle = handle;
2965 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
2966 if (!NT_STATUS_IS_OK(status)) {
2967 printf("Connect2 failed - %s\n", nt_errstr(status));
2971 printf("testing samr_Connect3\n");
2973 r3.in.system_name = NULL;
2975 r3.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2976 r3.out.handle = handle;
2978 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
2979 if (!NT_STATUS_IS_OK(status)) {
2980 printf("Connect3 failed - %s\n", nt_errstr(status));
2984 printf("testing samr_Connect4\n");
2986 r4.in.system_name = "";
2988 r4.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2989 r4.out.handle = handle;
2991 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
2992 if (!NT_STATUS_IS_OK(status)) {
2993 printf("Connect4 failed - %s\n", nt_errstr(status));
2997 printf("testing samr_Connect5\n");
2999 info.info1.unknown1 = 0;
3000 info.info1.unknown2 = 0;
3002 r5.in.system_name = "";
3003 r5.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
3006 r5.out.info = &info;
3007 r5.out.handle = handle;
3009 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3010 if (!NT_STATUS_IS_OK(status)) {
3011 printf("Connect5 failed - %s\n", nt_errstr(status));
3019 BOOL torture_rpc_samr(int dummy)
3022 struct dcerpc_pipe *p;
3023 TALLOC_CTX *mem_ctx;
3025 struct policy_handle handle;
3027 mem_ctx = talloc_init("torture_rpc_samr");
3029 status = torture_rpc_connection(&p,
3032 DCERPC_SAMR_VERSION);
3033 if (!NT_STATUS_IS_OK(status)) {
3037 if (!test_Connect(p, mem_ctx, &handle)) {
3041 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3045 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3049 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3053 if (!test_Shutdown(p, mem_ctx, &handle)) {
3057 if (!test_Close(p, mem_ctx, &handle)) {
3061 talloc_destroy(mem_ctx);
3063 torture_rpc_close(p);