2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
26 struct policy_handle *handle);
29 this makes the debug code display the right thing
31 static void init_samr_Name(struct samr_Name *name, const char *s)
33 name->name_len = strlen_m(s)*2;
34 name->name_size = name->name_len;
35 if (name->name_len == 0) {
42 static BOOL test_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
43 struct policy_handle *handle)
49 r.out.handle = handle;
51 status = dcerpc_samr_Close(p, mem_ctx, &r);
52 if (!NT_STATUS_IS_OK(status)) {
53 printf("Close handle failed - %s\n", nt_errstr(status));
61 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
62 struct policy_handle *handle)
65 struct samr_QuerySecurity r;
70 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
71 if (!NT_STATUS_IS_OK(status)) {
72 printf("QuerySecurity failed - %s\n", nt_errstr(status));
80 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
81 struct policy_handle *handle)
84 struct samr_SetUserInfo s;
85 struct samr_QueryUserInfo q;
86 union samr_UserInfo u;
94 #define TESTCALL(call, r) \
95 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
96 if (!NT_STATUS_IS_OK(status)) { \
97 printf(#call " level %u failed - %s (line %d)\n", \
98 r.in.level, nt_errstr(status), __LINE__); \
103 #define STRING_EQUAL(s1, s2, field) \
104 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
105 printf("Failed to set %s to '%s' (line %d)\n", \
106 #field, s2, __LINE__); \
111 #define INT_EQUAL(i1, i2, field) \
113 printf("Failed to set %s to %u (line %d)\n", \
114 #field, i2, __LINE__); \
119 #define TEST_USERINFO_NAME(lvl1, field1, lvl2, field2, value) do { \
120 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
122 TESTCALL(QueryUserInfo, q) \
125 init_samr_Name(&u.info ## lvl1.field1, value); \
126 TESTCALL(SetUserInfo, s) \
127 init_samr_Name(&u.info ## lvl1.field1, ""); \
128 TESTCALL(QueryUserInfo, q); \
130 STRING_EQUAL(u.info ## lvl1.field1.name, value, field1); \
132 TESTCALL(QueryUserInfo, q) \
134 STRING_EQUAL(u.info ## lvl2.field2.name, value, field2); \
137 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2) do { \
138 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
140 TESTCALL(QueryUserInfo, q) \
143 u.info ## lvl1.field1 = __LINE__; \
144 TESTCALL(SetUserInfo, s) \
145 u.info ## lvl1.field1 = 0; \
146 TESTCALL(QueryUserInfo, q); \
148 INT_EQUAL(u.info ## lvl1.field1, __LINE__, field1); \
150 TESTCALL(QueryUserInfo, q) \
152 INT_EQUAL(u.info ## lvl2.field2, __LINE__, field1); \
156 TEST_USERINFO_NAME(2, comment, 1, comment, "xx2-1 comment");
157 TEST_USERINFO_NAME(2, comment, 21, comment, "xx2-21 comment");
159 TEST_USERINFO_NAME(6, full_name, 1, full_name, "xx6-1 full_name");
160 TEST_USERINFO_NAME(6, full_name, 3, full_name, "xx6-3 full_name");
161 TEST_USERINFO_NAME(6, full_name, 5, full_name, "xx6-5 full_name");
162 TEST_USERINFO_NAME(6, full_name, 6, full_name, "xx6-6 full_name");
163 TEST_USERINFO_NAME(6, full_name, 8, full_name, "xx6-8 full_name");
164 TEST_USERINFO_NAME(6, full_name, 21, full_name, "xx6-21 full_name");
165 TEST_USERINFO_NAME(8, full_name, 21, full_name, "xx7-21 full_name");
167 TEST_USERINFO_NAME(11, logon_script, 21, logon_script, "xx11-21 logon_script");
168 TEST_USERINFO_NAME(12, profile, 21, profile, "xx12-21 profile");
169 TEST_USERINFO_NAME(13, description, 21, description, "xx13-21 description");
170 TEST_USERINFO_NAME(14, workstations, 21, workstations, "testworkstation");
171 TEST_USERINFO_NAME(20, callback, 21, callback, "xx20-21 callback");
173 TEST_USERINFO_INT(2, country_code, 21, country_code);
174 TEST_USERINFO_INT(2, code_page, 21, code_page);
175 TEST_USERINFO_INT(4, logon_hours[3], 5, logon_hours[3]);
181 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
182 struct policy_handle *handle)
186 if (!test_QuerySecurity(p, mem_ctx, handle)) {
190 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
194 if (!test_SetUserInfo(p, mem_ctx, handle)) {
202 static BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
203 struct policy_handle *handle, const char *name)
206 struct samr_LookupNames n;
207 struct samr_OpenUser r;
208 struct samr_DeleteUser d;
209 struct policy_handle acct_handle;
210 struct samr_Name sname;
212 init_samr_Name(&sname, name);
214 n.in.handle = handle;
217 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
218 if (!NT_STATUS_IS_OK(status)) {
222 r.in.handle = handle;
223 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
224 r.in.rid = n.out.rids.ids[0];
225 r.out.acct_handle = &acct_handle;
226 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
227 if (!NT_STATUS_IS_OK(status)) {
231 d.in.handle = &acct_handle;
232 d.out.handle = &acct_handle;
233 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
234 if (!NT_STATUS_IS_OK(status)) {
241 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
246 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
247 struct policy_handle *handle)
250 struct samr_CreateUser r;
251 struct samr_DeleteUser d;
252 struct policy_handle acct_handle;
254 struct samr_Name name;
257 init_samr_Name(&name, "samrtorturetest");
259 r.in.handle = handle;
260 r.in.username = &name;
261 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
262 r.out.acct_handle = &acct_handle;
265 printf("Testing CreateUser(%s)\n", r.in.username->name);
267 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
269 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
270 printf("Server refused create of '%s'\n", r.in.username->name);
274 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
275 if (!test_DeleteUser_byname(p, mem_ctx, handle, r.in.username->name)) {
278 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
280 if (!NT_STATUS_IS_OK(status)) {
281 printf("CreateUser failed - %s\n", nt_errstr(status));
286 if (!test_user_ops(p, mem_ctx, &acct_handle)) {
290 printf("Testing DeleteUser\n");
292 d.in.handle = &acct_handle;
293 d.out.handle = &acct_handle;
295 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
296 if (!NT_STATUS_IS_OK(status)) {
297 printf("DeleteUser failed - %s\n", nt_errstr(status));
304 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
305 struct policy_handle *handle)
308 struct samr_QueryAliasInfo r;
309 uint16 levels[] = {1, 2, 3};
313 for (i=0;i<ARRAY_SIZE(levels);i++) {
314 printf("Testing QueryAliasInfo level %u\n", levels[i]);
316 r.in.handle = handle;
317 r.in.level = levels[i];
319 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
320 if (!NT_STATUS_IS_OK(status)) {
321 printf("QueryAliasInfo level %u failed - %s\n",
322 levels[i], nt_errstr(status));
330 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
331 struct policy_handle *handle)
334 struct samr_QueryGroupInfo r;
335 uint16 levels[] = {1, 2, 3, 4};
339 for (i=0;i<ARRAY_SIZE(levels);i++) {
340 printf("Testing QueryGroupInfo level %u\n", levels[i]);
342 r.in.handle = handle;
343 r.in.level = levels[i];
345 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
346 if (!NT_STATUS_IS_OK(status)) {
347 printf("QueryGroupInfo level %u failed - %s\n",
348 levels[i], nt_errstr(status));
356 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
357 struct policy_handle *handle)
360 struct samr_QueryUserInfo r;
361 uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
362 11, 12, 13, 14, 16, 17, 20, 21};
366 for (i=0;i<ARRAY_SIZE(levels);i++) {
367 printf("Testing QueryUserInfo level %u\n", levels[i]);
369 r.in.handle = handle;
370 r.in.level = levels[i];
372 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
373 if (!NT_STATUS_IS_OK(status)) {
374 printf("QueryUserInfo level %u failed - %s\n",
375 levels[i], nt_errstr(status));
383 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
384 struct policy_handle *handle, uint32 rid)
387 struct samr_OpenUser r;
388 struct policy_handle acct_handle;
391 printf("Testing OpenUser(%u)\n", rid);
393 r.in.handle = handle;
394 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
396 r.out.acct_handle = &acct_handle;
398 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
399 if (!NT_STATUS_IS_OK(status)) {
400 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
404 if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
408 if (!test_QueryUserInfo(p, mem_ctx, &acct_handle)) {
412 if (!test_Close(p, mem_ctx, &acct_handle)) {
419 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
420 struct policy_handle *handle, uint32 rid)
423 struct samr_OpenGroup r;
424 struct policy_handle acct_handle;
427 printf("Testing OpenGroup(%u)\n", rid);
429 r.in.handle = handle;
430 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
432 r.out.acct_handle = &acct_handle;
434 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
435 if (!NT_STATUS_IS_OK(status)) {
436 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
440 if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
444 if (!test_QueryGroupInfo(p, mem_ctx, &acct_handle)) {
448 if (!test_Close(p, mem_ctx, &acct_handle)) {
455 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
456 struct policy_handle *handle, uint32 rid)
459 struct samr_OpenAlias r;
460 struct policy_handle acct_handle;
463 printf("Testing OpenAlias(%u)\n", rid);
465 r.in.handle = handle;
466 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
468 r.out.acct_handle = &acct_handle;
470 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
471 if (!NT_STATUS_IS_OK(status)) {
472 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
476 if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
480 if (!test_QueryAliasInfo(p, mem_ctx, &acct_handle)) {
484 if (!test_Close(p, mem_ctx, &acct_handle)) {
491 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
492 struct policy_handle *handle)
495 struct samr_EnumDomainUsers r;
496 uint32 resume_handle=0;
499 struct samr_LookupNames n;
500 struct samr_LookupRids lr ;
502 printf("Testing EnumDomainUsers\n");
504 r.in.handle = handle;
505 r.in.resume_handle = &resume_handle;
507 r.in.max_size = (uint32)-1;
508 r.out.resume_handle = &resume_handle;
510 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
511 if (!NT_STATUS_IS_OK(status)) {
512 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
520 if (r.out.sam->count == 0) {
524 for (i=0;i<r.out.sam->count;i++) {
525 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
530 printf("Testing LookupNames\n");
531 n.in.handle = handle;
532 n.in.num_names = r.out.sam->count;
533 n.in.names = talloc(mem_ctx, r.out.sam->count * sizeof(struct samr_Name));
534 for (i=0;i<r.out.sam->count;i++) {
535 n.in.names[i] = r.out.sam->entries[i].name;
537 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
538 if (!NT_STATUS_IS_OK(status)) {
539 printf("LookupNames failed - %s\n", nt_errstr(status));
544 printf("Testing LookupRids\n");
545 lr.in.handle = handle;
546 lr.in.num_rids = r.out.sam->count;
547 lr.in.rids = talloc(mem_ctx, r.out.sam->count * sizeof(uint32));
548 for (i=0;i<r.out.sam->count;i++) {
549 lr.in.rids[i] = r.out.sam->entries[i].idx;
551 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
552 if (!NT_STATUS_IS_OK(status)) {
553 printf("LookupRids failed - %s\n", nt_errstr(status));
560 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
561 struct policy_handle *handle)
564 struct samr_EnumDomainGroups r;
565 uint32 resume_handle=0;
569 printf("Testing EnumDomainGroups\n");
571 r.in.handle = handle;
572 r.in.resume_handle = &resume_handle;
573 r.in.max_size = (uint32)-1;
574 r.out.resume_handle = &resume_handle;
576 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
577 if (!NT_STATUS_IS_OK(status)) {
578 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
586 for (i=0;i<r.out.sam->count;i++) {
587 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
595 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
596 struct policy_handle *handle)
599 struct samr_EnumDomainAliases r;
600 uint32 resume_handle=0;
604 printf("Testing EnumDomainAliases\n");
606 r.in.handle = handle;
607 r.in.resume_handle = &resume_handle;
608 r.in.max_size = (uint32)-1;
609 r.out.resume_handle = &resume_handle;
611 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
612 if (!NT_STATUS_IS_OK(status)) {
613 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
621 for (i=0;i<r.out.sam->count;i++) {
622 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
630 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
631 struct policy_handle *handle)
634 struct samr_QueryDomainInfo r;
635 uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
639 for (i=0;i<ARRAY_SIZE(levels);i++) {
640 printf("Testing QueryDomainInfo level %u\n", levels[i]);
642 r.in.handle = handle;
643 r.in.level = levels[i];
645 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
646 if (!NT_STATUS_IS_OK(status)) {
647 printf("QueryDomainInfo level %u failed - %s\n",
648 r.in.level, nt_errstr(status));
657 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
658 struct policy_handle *handle, struct dom_sid2 *sid)
661 struct samr_OpenDomain r;
662 struct policy_handle domain_handle;
665 printf("Testing OpenDomain\n");
667 r.in.handle = handle;
668 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
670 r.out.domain_handle = &domain_handle;
672 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
673 if (!NT_STATUS_IS_OK(status)) {
674 printf("OpenDomain failed - %s\n", nt_errstr(status));
678 if (!test_CreateUser(p, mem_ctx, &domain_handle)) {
682 if (!test_QuerySecurity(p, mem_ctx, &domain_handle)) {
686 if (!test_QueryDomainInfo(p, mem_ctx, &domain_handle)) {
690 if (!test_EnumDomainUsers(p, mem_ctx, &domain_handle)) {
694 if (!test_EnumDomainGroups(p, mem_ctx, &domain_handle)) {
698 if (!test_EnumDomainAliases(p, mem_ctx, &domain_handle)) {
702 if (!test_Close(p, mem_ctx, &domain_handle)) {
709 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
710 struct policy_handle *handle, struct samr_Name *domain)
713 struct samr_LookupDomain r;
715 printf("Testing LookupDomain(%s)\n", domain->name);
717 r.in.handle = handle;
718 r.in.domain = domain;
720 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
721 if (!NT_STATUS_IS_OK(status)) {
722 printf("LookupDomain failed - %s\n", nt_errstr(status));
726 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
734 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
735 struct policy_handle *handle)
738 struct samr_EnumDomains r;
739 uint32 resume_handle = 0;
740 uint32 num_entries=0;
744 r.in.handle = handle;
745 r.in.resume_handle = &resume_handle;
746 r.in.buf_size = (uint32)-1;
747 r.out.resume_handle = &resume_handle;
748 r.out.num_entries = &num_entries;
750 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
751 if (!NT_STATUS_IS_OK(status)) {
752 printf("EnumDomains failed - %s\n", nt_errstr(status));
760 for (i=0;i<r.out.sam->count;i++) {
761 if (!test_LookupDomain(p, mem_ctx, handle,
762 &r.out.sam->entries[i].name)) {
771 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
772 struct policy_handle *handle)
775 struct samr_Connect r;
776 struct samr_Connect4 r4;
778 r.in.system_name = 0;
779 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
780 r.out.handle = handle;
782 status = dcerpc_samr_Connect(p, mem_ctx, &r);
783 if (!NT_STATUS_IS_OK(status)) {
784 printf("Connect failed - %s\n", nt_errstr(status));
788 r4.in.system_name = "";
790 r4.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
791 r4.out.handle = handle;
793 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
794 if (!NT_STATUS_IS_OK(status)) {
795 printf("Connect4 failed - %s\n", nt_errstr(status));
803 BOOL torture_rpc_samr(int dummy)
806 struct dcerpc_pipe *p;
809 struct policy_handle handle;
811 mem_ctx = talloc_init("torture_rpc_samr");
813 status = torture_rpc_connection(&p,
816 DCERPC_SAMR_VERSION);
817 if (!NT_STATUS_IS_OK(status)) {
821 p->flags |= DCERPC_DEBUG_PRINT_BOTH;
823 if (!test_Connect(p, mem_ctx, &handle)) {
827 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
831 if (!test_EnumDomains(p, mem_ctx, &handle)) {
835 if (!test_Close(p, mem_ctx, &handle)) {
839 torture_rpc_close(p);