2 Unix SMB/CIFS implementation.
3 test suite for srvsvc rpc operations
5 Copyright (C) Stefan (metze) Metzmacher 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 3 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, see <http://www.gnu.org/licenses/>.
22 #include "torture/torture.h"
23 #include "librpc/gen_ndr/ndr_srvsvc.h"
24 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
25 #include "torture/rpc/rpc.h"
27 /**************************/
28 /* srvsvc_NetCharDev */
29 /**************************/
30 static BOOL test_NetCharDevGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
34 struct srvsvc_NetCharDevGetInfo r;
35 uint32_t levels[] = {0, 1};
39 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
40 r.in.device_name = devname;
42 for (i=0;i<ARRAY_SIZE(levels);i++) {
44 r.in.level = levels[i];
45 d_printf("testing NetCharDevGetInfo level %u on device '%s'\n",
46 r.in.level, r.in.device_name);
47 status = dcerpc_srvsvc_NetCharDevGetInfo(p, mem_ctx, &r);
48 if (!NT_STATUS_IS_OK(status)) {
49 d_printf("NetCharDevGetInfo level %u on device '%s' failed - %s\n",
50 r.in.level, r.in.device_name, nt_errstr(status));
54 if (!W_ERROR_IS_OK(r.out.result)) {
55 d_printf("NetCharDevGetInfo level %u on device '%s' failed - %s\n",
56 r.in.level, r.in.device_name, win_errstr(r.out.result));
64 static BOOL test_NetCharDevControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
68 struct srvsvc_NetCharDevControl r;
69 uint32_t opcodes[] = {0, 1};
73 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
74 r.in.device_name = devname;
76 for (i=0;i<ARRAY_SIZE(opcodes);i++) {
78 r.in.opcode = opcodes[i];
79 d_printf("testing NetCharDevControl opcode %u on device '%s'\n",
80 r.in.opcode, r.in.device_name);
81 status = dcerpc_srvsvc_NetCharDevControl(p, mem_ctx, &r);
82 if (!NT_STATUS_IS_OK(status)) {
83 d_printf("NetCharDevControl opcode %u failed - %s\n", r.in.opcode, nt_errstr(status));
87 if (!W_ERROR_IS_OK(r.out.result)) {
88 d_printf("NetCharDevControl opcode %u failed - %s\n", r.in.opcode, win_errstr(r.out.result));
96 static bool test_NetCharDevEnum(struct torture_context *tctx,
97 struct dcerpc_pipe *p)
100 struct srvsvc_NetCharDevEnum r;
101 struct srvsvc_NetCharDevCtr0 c0;
102 uint32_t levels[] = {0, 1};
106 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
108 r.in.ctr.ctr0->count = 0;
109 r.in.ctr.ctr0->array = NULL;
110 r.in.max_buffer = (uint32_t)-1;
111 r.in.resume_handle = NULL;
113 for (i=0;i<ARRAY_SIZE(levels);i++) {
118 r.in.level = levels[i];
119 printf("testing NetCharDevEnum level %u\n", r.in.level);
120 status = dcerpc_srvsvc_NetCharDevEnum(p, tctx, &r);
121 if (!NT_STATUS_IS_OK(status)) {
122 d_printf("NetCharDevEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
126 if (!W_ERROR_IS_OK(r.out.result)) {
127 d_printf("NetCharDevEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
131 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */
132 if (r.in.level == 1) {
133 for (j=0;j<r.out.ctr.ctr1->count;j++) {
135 device = r.out.ctr.ctr1->array[j].device;
136 if (!test_NetCharDevGetInfo(p, tctx, device)) {
139 if (!test_NetCharDevControl(p, tctx, device)) {
149 /**************************/
150 /* srvsvc_NetCharDevQ */
151 /**************************/
152 static BOOL test_NetCharDevQGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
153 const char *devicequeue)
156 struct srvsvc_NetCharDevQGetInfo r;
157 uint32_t levels[] = {0, 1};
161 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
162 r.in.queue_name = devicequeue;
163 r.in.user = talloc_asprintf(mem_ctx,"Administrator");
165 for (i=0;i<ARRAY_SIZE(levels);i++) {
167 r.in.level = levels[i];
168 d_printf("testing NetCharDevQGetInfo level %u on devicequeue '%s'\n",
169 r.in.level, r.in.queue_name);
170 status = dcerpc_srvsvc_NetCharDevQGetInfo(p, mem_ctx, &r);
171 if (!NT_STATUS_IS_OK(status)) {
172 d_printf("NetCharDevQGetInfo level %u on devicequeue '%s' failed - %s\n",
173 r.in.level, r.in.queue_name, nt_errstr(status));
177 if (!W_ERROR_IS_OK(r.out.result)) {
178 printf("NetCharDevQGetInfo level %u on devicequeue '%s' failed - %s\n",
179 r.in.level, r.in.queue_name, win_errstr(r.out.result));
188 static BOOL test_NetCharDevQSetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
189 const char *devicequeue)
192 struct srvsvc_NetCharDevQSetInfo r;
194 uint32_t levels[] = {0, 1};
198 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
199 r.in.queue_name = devicequeue;
201 for (i=0;i<ARRAY_SIZE(levels);i++) {
204 r.in.level = levels[i];
205 d_printf("testing NetCharDevQSetInfo level %u on devicequeue '%s'\n",
206 r.in.level, devicequeue);
207 switch (r.in.level) {
209 r.in.info.info0 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo0);
210 r.in.info.info0->device = r.in.queue_name;
213 r.in.info.info1 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo1);
214 r.in.info.info1->device = r.in.queue_name;
215 r.in.info.info1->priority = 0x000;
216 r.in.info.info1->devices = r.in.queue_name;
217 r.in.info.info1->users = 0x000;
218 r.in.info.info1->num_ahead = 0x000;
223 r.in.parm_error = &parm_error;
224 status = dcerpc_srvsvc_NetCharDevQSetInfo(p, mem_ctx, &r);
225 if (!NT_STATUS_IS_OK(status)) {
226 d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n",
227 r.in.level, r.in.queue_name, nt_errstr(status));
231 if (!W_ERROR_IS_OK(r.out.result)) {
232 d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n",
233 r.in.level, r.in.queue_name, win_errstr(r.out.result));
242 static BOOL test_NetCharDevQEnum(struct torture_context *tctx,
243 struct dcerpc_pipe *p)
246 struct srvsvc_NetCharDevQEnum r;
247 struct srvsvc_NetCharDevQCtr0 c0;
248 uint32_t levels[] = {0, 1};
252 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
253 r.in.user = talloc_asprintf(tctx,"%s","Administrator");
255 r.in.ctr.ctr0->count = 0;
256 r.in.ctr.ctr0->array = NULL;
257 r.in.max_buffer = (uint32_t)-1;
258 r.in.resume_handle = NULL;
260 for (i=0;i<ARRAY_SIZE(levels);i++) {
264 r.in.level = levels[i];
265 printf("testing NetCharDevQEnum level %u\n", r.in.level);
266 status = dcerpc_srvsvc_NetCharDevQEnum(p, tctx, &r);
267 if (!NT_STATUS_IS_OK(status)) {
268 d_printf("NetCharDevQEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
272 if (!W_ERROR_IS_OK(r.out.result)) {
273 d_printf("NetCharDevQEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
277 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */
278 if (r.in.level == 1) {
279 for (j=0;j<r.out.ctr.ctr1->count;j++) {
281 device = r.out.ctr.ctr1->array[j].device;
282 if (!test_NetCharDevQGetInfo(p, tctx, device)) {
292 /**************************/
294 /**************************/
295 static BOOL test_NetConnEnum(struct torture_context *tctx,
296 struct dcerpc_pipe *p)
299 struct srvsvc_NetConnEnum r;
300 struct srvsvc_NetConnCtr0 c0;
301 uint32_t levels[] = {0, 1};
305 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
306 r.in.path = talloc_asprintf(tctx,"%s","ADMIN$");
308 r.in.ctr.ctr0->count = 0;
309 r.in.ctr.ctr0->array = NULL;
310 r.in.max_buffer = (uint32_t)-1;
311 r.in.resume_handle = NULL;
313 for (i=0;i<ARRAY_SIZE(levels);i++) {
315 r.in.level = levels[i];
316 d_printf("testing NetConnEnum level %u\n", r.in.level);
317 status = dcerpc_srvsvc_NetConnEnum(p, tctx, &r);
318 if (!NT_STATUS_IS_OK(status)) {
319 d_printf("NetConnEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
323 if (!W_ERROR_IS_OK(r.out.result)) {
324 d_printf("NetConnEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
332 /**************************/
334 /**************************/
335 static BOOL test_NetFileEnum(struct torture_context *tctx,
336 struct dcerpc_pipe *p)
339 struct srvsvc_NetFileEnum r;
340 struct srvsvc_NetFileCtr3 c3;
341 uint32_t levels[] = {2, 3};
345 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
349 r.in.ctr.ctr3->count = 0;
350 r.in.ctr.ctr3->array = NULL;
351 r.in.max_buffer = (uint32_t)4096;
352 r.in.resume_handle = NULL;
354 for (i=0;i<ARRAY_SIZE(levels);i++) {
356 r.in.level = levels[i];
357 d_printf("testing NetFileEnum level %u\n", r.in.level);
358 status = dcerpc_srvsvc_NetFileEnum(p, tctx, &r);
359 if (!NT_STATUS_IS_OK(status)) {
360 d_printf("NetFileEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
364 if (!W_ERROR_IS_OK(r.out.result)) {
365 d_printf("NetFileEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
373 /**************************/
375 /**************************/
376 static BOOL test_NetSessEnum(struct torture_context *tctx,
377 struct dcerpc_pipe *p)
380 struct srvsvc_NetSessEnum r;
381 struct srvsvc_NetSessCtr0 c0;
382 uint32_t levels[] = {0, 1, 2, 10, 502};
386 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
390 r.in.ctr.ctr0->count = 0;
391 r.in.ctr.ctr0->array = NULL;
392 r.in.max_buffer = (uint32_t)-1;
393 r.in.resume_handle = NULL;
395 for (i=0;i<ARRAY_SIZE(levels);i++) {
397 r.in.level = levels[i];
398 d_printf("testing NetSessEnum level %u\n", r.in.level);
399 status = dcerpc_srvsvc_NetSessEnum(p, tctx, &r);
400 if (!NT_STATUS_IS_OK(status)) {
401 d_printf("NetSessEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
405 if (!W_ERROR_IS_OK(r.out.result)) {
406 d_printf("NetSessEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
414 /**************************/
415 /* srvsvc_NetShare */
416 /**************************/
417 static BOOL test_NetShareCheck(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
418 const char *device_name)
421 struct srvsvc_NetShareCheck r;
424 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
425 r.in.device_name = device_name;
427 d_printf("testing NetShareCheck on device '%s'\n", r.in.device_name);
429 status = dcerpc_srvsvc_NetShareCheck(p, mem_ctx, &r);
430 if (!NT_STATUS_IS_OK(status)) {
431 d_printf("dcerpc_srvsvc_NetShareCheck on device '%s' failed - %s\n",
432 r.in.device_name, nt_errstr(status));
434 } else if (!W_ERROR_IS_OK(r.out.result)) {
435 d_printf("NetShareCheck on device '%s' failed - %s\n",
436 r.in.device_name, win_errstr(r.out.result));
443 static bool test_NetShareGetInfo(struct torture_context *tctx,
444 struct dcerpc_pipe *p,
445 const char *sharename, bool admin)
448 struct srvsvc_NetShareGetInfo r;
454 { 0, WERR_OK, WERR_OK },
455 { 1, WERR_OK, WERR_OK },
456 { 2, WERR_ACCESS_DENIED, WERR_OK },
457 { 501, WERR_OK, WERR_OK },
458 { 502, WERR_ACCESS_DENIED, WERR_OK },
459 { 1005, WERR_OK, WERR_OK },
464 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
465 r.in.share_name = sharename;
467 for (i=0;i<ARRAY_SIZE(levels);i++) {
470 r.in.level = levels[i].level;
471 expected = levels[i].anon_status;
472 if (admin) expected = levels[i].admin_status;
475 d_printf("testing NetShareGetInfo level %u on share '%s'\n",
476 r.in.level, r.in.share_name);
478 status = dcerpc_srvsvc_NetShareGetInfo(p, tctx, &r);
479 if (!NT_STATUS_IS_OK(status)) {
480 d_printf("NetShareGetInfo level %u on share '%s' failed - %s\n",
481 r.in.level, r.in.share_name, nt_errstr(status));
485 if (!W_ERROR_EQUAL(r.out.result, expected)) {
486 d_printf("NetShareGetInfo level %u on share '%s' failed - %s (expected %s)\n",
487 r.in.level, r.in.share_name, win_errstr(r.out.result),
488 win_errstr(expected));
493 if (r.in.level != 2) continue;
494 if (!r.out.info.info2 || !r.out.info.info2->path) continue;
495 if (!test_NetShareCheck(p, tctx, r.out.info.info2->path)) {
503 static bool test_NetShareGetInfoAdminFull(struct torture_context *tctx,
504 struct dcerpc_pipe *p)
506 return test_NetShareGetInfo(tctx, p, "ADMIN$", true);
509 static bool test_NetShareGetInfoAdminAnon(struct torture_context *tctx,
510 struct dcerpc_pipe *p)
512 return test_NetShareGetInfo(tctx, p, "ADMIN$", false);
515 static bool test_NetShareAddSetDel(struct torture_context *tctx,
516 struct dcerpc_pipe *p)
519 struct srvsvc_NetShareAdd a;
520 struct srvsvc_NetShareSetInfo r;
521 struct srvsvc_NetShareGetInfo q;
522 struct srvsvc_NetShareDel d;
527 { 0, WERR_UNKNOWN_LEVEL },
530 { 501, WERR_UNKNOWN_LEVEL },
535 /* { 1007, WERR_OK }, */
541 if (!torture_setting_bool(tctx, "dangerous", false))
543 "NetShareAddSetDel disabled - enable dangerous tests to use\n");
545 a.in.server_unc = r.in.server_unc = q.in.server_unc = d.in.server_unc =
546 talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
547 r.in.share_name = talloc_strdup(tctx, "testshare");
550 a.in.info.info2 = talloc(tctx, struct srvsvc_NetShareInfo2);
551 a.in.info.info2->name = r.in.share_name;
552 a.in.info.info2->type = STYPE_DISKTREE;
553 a.in.info.info2->comment = talloc_strdup(tctx, "test comment");
554 a.in.info.info2->permissions = 123434566;
555 a.in.info.info2->max_users = -1;
556 a.in.info.info2->current_users = 0;
557 a.in.info.info2->path = talloc_strdup(tctx, "C:\\");
558 a.in.info.info2->password = NULL;
560 a.in.parm_error = NULL;
562 status = dcerpc_srvsvc_NetShareAdd(p, tctx, &a);
563 if (!NT_STATUS_IS_OK(status)) {
564 d_printf("NetShareAdd level 2 on share 'testshare' failed - %s\n",
567 } else if (!W_ERROR_EQUAL(a.out.result, WERR_OK)) {
568 d_printf("NetShareAdd level 2 on share 'testshare' failed - %s\n",
569 win_errstr(a.out.result));
573 r.in.parm_error = NULL;
577 for (i = 0; i < ARRAY_SIZE(levels); i++) {
579 r.in.level = levels[i].level;
582 d_printf("testing NetShareSetInfo level %u on share '%s'\n",
583 r.in.level, r.in.share_name);
585 switch (levels[i].level) {
587 r.in.info.info0 = talloc(tctx, struct srvsvc_NetShareInfo0);
588 r.in.info.info0->name = r.in.share_name;
591 r.in.info.info1 = talloc(tctx, struct srvsvc_NetShareInfo1);
592 r.in.info.info1->name = r.in.share_name;
593 r.in.info.info1->type = STYPE_DISKTREE;
594 r.in.info.info1->comment = talloc_strdup(tctx, "test comment 1");
597 r.in.info.info2 = talloc(tctx, struct srvsvc_NetShareInfo2);
598 r.in.info.info2->name = r.in.share_name;
599 r.in.info.info2->type = STYPE_DISKTREE;
600 r.in.info.info2->comment = talloc_strdup(tctx, "test comment 2");
601 r.in.info.info2->permissions = 0;
602 r.in.info.info2->max_users = 2;
603 r.in.info.info2->current_users = 1;
604 r.in.info.info2->path = talloc_strdup(tctx, "::BLaH::"); /* "C:\\"); */
605 r.in.info.info2->password = NULL;
608 r.in.info.info501 = talloc(tctx, struct srvsvc_NetShareInfo501);
609 r.in.info.info501->name = r.in.share_name;
610 r.in.info.info501->type = STYPE_DISKTREE;
611 r.in.info.info501->comment = talloc_strdup(tctx, "test comment 501");
612 r.in.info.info501->csc_policy = 0;
615 r.in.info.info502 = talloc(tctx, struct srvsvc_NetShareInfo502);
616 r.in.info.info502->name = r.in.share_name;
617 r.in.info.info502->type = STYPE_DISKTREE;
618 r.in.info.info502->comment = talloc_strdup(tctx, "test comment 502");
619 r.in.info.info502->permissions = 0;
620 r.in.info.info502->max_users = 502;
621 r.in.info.info502->current_users = 1;
622 r.in.info.info502->path = talloc_strdup(tctx, "C:\\");
623 r.in.info.info502->password = NULL;
624 r.in.info.info502->unknown = 0;
625 r.in.info.info502->sd = NULL;
628 r.in.info.info1004 = talloc(tctx, struct srvsvc_NetShareInfo1004);
629 r.in.info.info1004->comment = talloc_strdup(tctx, "test comment 1004");
632 r.in.info.info1005 = talloc(tctx, struct srvsvc_NetShareInfo1005);
633 r.in.info.info1005->dfs_flags = 0;
636 r.in.info.info1006 = talloc(tctx, struct srvsvc_NetShareInfo1006);
637 r.in.info.info1006->max_users = 1006;
640 r.in.info.info1007 = talloc(tctx, struct srvsvc_NetShareInfo1007);
641 r.in.info.info1007->flags = 0;
642 r.in.info.info1007->alternate_directory_name = talloc_strdup(tctx, "test");
646 r.in.info.info1501 = talloc_zero(tctx, struct sec_desc_buf);
650 status = dcerpc_srvsvc_NetShareSetInfo(p, tctx, &r);
651 if (!NT_STATUS_IS_OK(status)) {
652 d_printf("NetShareGetInfo level %u on share '%s' failed - %s\n",
653 r.in.level, r.in.share_name, nt_errstr(status));
656 } else if (!W_ERROR_EQUAL(r.out.result, levels[i].expected)) {
657 d_printf("NetShareSetInfo level %u on share '%s' failed - %s (expected %s)\n",
658 r.in.level, r.in.share_name, win_errstr(r.out.result),
659 win_errstr(levels[i].expected));
664 q.in.share_name = r.in.share_name;
666 status = dcerpc_srvsvc_NetShareGetInfo(p, tctx, &q);
667 if (!NT_STATUS_IS_OK(status)) {
668 d_printf("NetShareGetInfo level %u on share '%s' failed - %s\n",
669 q.in.level, q.in.share_name, nt_errstr(status));
672 } else if (!W_ERROR_EQUAL(q.out.result, WERR_OK)) {
673 d_printf("NetShareGetInfo level %u on share '%s' failed - %s\n",
674 q.in.level, q.in.share_name, win_errstr(q.out.result));
679 if (strcmp(q.out.info.info502->name, r.in.share_name) != 0) {
682 switch (levels[i].level) {
686 if (strcmp(q.out.info.info502->comment, "test comment 1") != 0)
690 if (strcmp(q.out.info.info502->comment, "test comment 2") != 0)
692 if (q.out.info.info2->max_users != 2)
694 if (strcmp(q.out.info.info2->path, "C:\\") != 0)
698 if (strcmp(q.out.info.info501->comment, "test comment 501") != 0)
702 if (strcmp(q.out.info.info502->comment, "test comment 502") != 0)
704 if (q.out.info.info2->max_users != 502)
706 if (strcmp(q.out.info.info2->path, "C:\\") != 0)
710 if (strcmp(q.out.info.info502->comment, "test comment 1004") != 0)
716 if (q.out.info.info2->max_users != 1006)
727 d.in.share_name = r.in.share_name;
730 status = dcerpc_srvsvc_NetShareDel(p, tctx, &d);
731 if (!NT_STATUS_IS_OK(status)) {
732 d_printf("NetShareDel on share 'testshare502' failed - %s\n",
735 } else if (!W_ERROR_EQUAL(a.out.result, WERR_OK)) {
736 d_printf("NetShareDel on share 'testshare502' failed - %s\n",
737 win_errstr(d.out.result));
744 /**************************/
745 /* srvsvc_NetShare */
746 /**************************/
747 static bool test_NetShareEnumAll(struct torture_context *tctx,
748 struct dcerpc_pipe *p,
752 struct srvsvc_NetShareEnumAll r;
753 struct srvsvc_NetShareCtr0 c0;
759 { 0, WERR_OK, WERR_OK },
760 { 1, WERR_OK, WERR_OK },
761 { 2, WERR_ACCESS_DENIED, WERR_OK },
762 { 501, WERR_ACCESS_DENIED, WERR_OK },
763 { 502, WERR_ACCESS_DENIED, WERR_OK },
767 uint32_t resume_handle;
771 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
773 r.in.max_buffer = (uint32_t)-1;
774 r.in.resume_handle = &resume_handle;
775 r.out.resume_handle = &resume_handle;
777 for (i=0;i<ARRAY_SIZE(levels);i++) {
781 r.in.level = levels[i].level;
782 expected = levels[i].anon_status;
783 if (admin) expected = levels[i].admin_status;
788 d_printf("testing NetShareEnumAll level %u\n", r.in.level);
789 status = dcerpc_srvsvc_NetShareEnumAll(p, tctx, &r);
790 if (!NT_STATUS_IS_OK(status)) {
791 d_printf("NetShareEnumAll level %u failed - %s\n", r.in.level, nt_errstr(status));
795 if (!W_ERROR_EQUAL(r.out.result, expected)) {
796 d_printf("NetShareEnumAll level %u failed - %s (expected %s)\n",
797 r.in.level, win_errstr(r.out.result),
798 win_errstr(expected));
802 /* call srvsvc_NetShareGetInfo for each returned share */
803 if (r.in.level == 2 && r.out.ctr.ctr2) {
804 for (j=0;j<r.out.ctr.ctr2->count;j++) {
806 name = r.out.ctr.ctr2->array[j].name;
807 if (!test_NetShareGetInfo(tctx, p, name, admin)) {
817 static bool test_NetShareEnumAllFull(struct torture_context *tctx,
818 struct dcerpc_pipe *p)
820 return test_NetShareEnumAll(tctx, p, true);
823 static bool test_NetShareEnumAllAnon(struct torture_context *tctx,
824 struct dcerpc_pipe *p)
826 return test_NetShareEnumAll(tctx, p, false);
829 static bool test_NetShareEnum(struct torture_context *tctx,
830 struct dcerpc_pipe *p, bool admin)
833 struct srvsvc_NetShareEnum r;
834 struct srvsvc_NetShareCtr0 c0;
840 { 0, WERR_OK, WERR_OK },
841 { 1, WERR_OK, WERR_OK },
842 { 2, WERR_ACCESS_DENIED, WERR_OK },
843 { 501, WERR_UNKNOWN_LEVEL, WERR_UNKNOWN_LEVEL },
844 { 502, WERR_ACCESS_DENIED, WERR_OK },
849 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
851 r.in.ctr.ctr0->count = 0;
852 r.in.ctr.ctr0->array = NULL;
853 r.in.max_buffer = (uint32_t)-1;
854 r.in.resume_handle = NULL;
856 for (i=0;i<ARRAY_SIZE(levels);i++) {
859 r.in.level = levels[i].level;
860 expected = levels[i].anon_status;
861 if (admin) expected = levels[i].admin_status;
865 d_printf("testing NetShareEnum level %u\n", r.in.level);
866 status = dcerpc_srvsvc_NetShareEnum(p, tctx, &r);
867 if (!NT_STATUS_IS_OK(status)) {
868 d_printf("NetShareEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
872 if (!W_ERROR_EQUAL(r.out.result, expected)) {
873 d_printf("NetShareEnum level %u failed - %s (expected %s)\n",
874 r.in.level, win_errstr(r.out.result),
875 win_errstr(expected));
883 static bool test_NetShareEnumFull(struct torture_context *tctx,
884 struct dcerpc_pipe *p)
886 return test_NetShareEnum(tctx, p, true);
889 static bool test_NetShareEnumAnon(struct torture_context *tctx,
890 struct dcerpc_pipe *p)
892 return test_NetShareEnum(tctx, p, false);
895 /**************************/
897 /**************************/
898 static bool test_NetSrvGetInfo(struct torture_context *tctx,
899 struct dcerpc_pipe *p)
902 struct srvsvc_NetSrvGetInfo r;
903 struct srvsvc_NetSrvInfo503 i503;
904 uint32_t levels[] = {100, 101, 102, 502, 503};
907 uint32_t resume_handle;
911 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
913 for (i=0;i<ARRAY_SIZE(levels);i++) {
916 r.in.level = levels[i];
917 d_printf("testing NetSrvGetInfo level %u\n", r.in.level);
918 status = dcerpc_srvsvc_NetSrvGetInfo(p, tctx, &r);
919 if (!NT_STATUS_IS_OK(status)) {
920 d_printf("NetSrvGetInfo level %u failed - %s\n", r.in.level, nt_errstr(status));
924 if (!W_ERROR_IS_OK(r.out.result)) {
925 d_printf("NetSrvGetInfo level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
933 /**************************/
935 /**************************/
936 static BOOL test_NetDiskEnum(struct torture_context *tctx,
937 struct dcerpc_pipe *p)
940 struct srvsvc_NetDiskEnum r;
941 uint32_t levels[] = {0};
944 uint32_t resume_handle=0;
947 r.in.server_unc = NULL;
948 r.in.resume_handle = &resume_handle;
950 for (i=0;i<ARRAY_SIZE(levels);i++) {
952 r.in.level = levels[i];
953 d_printf("testing NetDiskEnum level %u\n", r.in.level);
954 status = dcerpc_srvsvc_NetDiskEnum(p, tctx, &r);
955 if (!NT_STATUS_IS_OK(status)) {
956 NDR_PRINT_OUT_DEBUG(srvsvc_NetDiskEnum, &r);
957 d_printf("NetDiskEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
961 if (!W_ERROR_IS_OK(r.out.result)) {
962 d_printf("NetDiskEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
970 /**************************/
971 /* srvsvc_NetTransport */
972 /**************************/
973 static bool test_NetTransportEnum(struct torture_context *tctx,
974 struct dcerpc_pipe *p)
977 struct srvsvc_NetTransportEnum r;
978 struct srvsvc_NetTransportCtr0 c0;
979 uint32_t levels[] = {0, 1};
983 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
984 r.in.transports.ctr0 = &c0;
985 r.in.transports.ctr0->count = 0;
986 r.in.transports.ctr0->array = NULL;
987 r.in.max_buffer = (uint32_t)-1;
988 r.in.resume_handle = NULL;
990 for (i=0;i<ARRAY_SIZE(levels);i++) {
992 r.in.level = levels[i];
993 d_printf("testing NetTransportEnum level %u\n", r.in.level);
994 status = dcerpc_srvsvc_NetTransportEnum(p, tctx, &r);
995 if (!NT_STATUS_IS_OK(status)) {
996 d_printf("NetTransportEnum level %u failed - %s\n", r.in.level, nt_errstr(status));
1000 if (!W_ERROR_IS_OK(r.out.result)) {
1001 d_printf("NetTransportEnum level %u failed - %s\n", r.in.level, win_errstr(r.out.result));
1009 /**************************/
1010 /* srvsvc_NetRemoteTOD */
1011 /**************************/
1012 static BOOL test_NetRemoteTOD(struct torture_context *tctx,
1013 struct dcerpc_pipe *p)
1016 struct srvsvc_NetRemoteTOD r;
1019 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
1022 d_printf("testing NetRemoteTOD\n");
1023 status = dcerpc_srvsvc_NetRemoteTOD(p, tctx, &r);
1024 if (!NT_STATUS_IS_OK(status)) {
1025 d_printf("NetRemoteTOD failed - %s\n", nt_errstr(status));
1028 if (!W_ERROR_IS_OK(r.out.result)) {
1029 d_printf("NetRemoteTOD failed - %s\n", win_errstr(r.out.result));
1035 /**************************/
1036 /* srvsvc_NetName */
1037 /**************************/
1039 static bool test_NetNameValidate(struct torture_context *tctx,
1040 struct dcerpc_pipe *p)
1043 struct srvsvc_NetNameValidate r;
1048 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1051 d_printf("testing NetNameValidate\n");
1053 /* valid path types only between 1 and 13 */
1054 for (i = 1; i < 14; i++) {
1057 /* let's limit ourselves to a maximum of 4096 bytes */
1058 r.in.name = name = talloc_array(tctx, char, 4097);
1065 /* Find maximum length accepted by this type */
1068 memset(name, 'A', n);
1071 status = dcerpc_srvsvc_NetNameValidate(p, tctx, &r);
1072 if (!NT_STATUS_IS_OK(status)) {
1073 d_printf("NetNameValidate failed while checking maximum size (%s)\n",
1078 if (W_ERROR_IS_OK(r.out.result)) {
1080 n += (max - min + 1)/2;
1084 if ((min + 1) >= max) break; /* found it */
1094 d_printf("Maximum length for type %2d, flags %08x: %d\n", i, r.in.flags, max);
1096 /* find invalid chars for this type check only ASCII between 0x20 and 0x7e */
1098 invalidc = talloc_strdup(tctx, "");
1100 for (n = 0x20; n < 0x7e; n++) {
1101 r.in.name = name = talloc_asprintf(tctx, "%c", (char)n);
1103 status = dcerpc_srvsvc_NetNameValidate(p, tctx, &r);
1104 if (!NT_STATUS_IS_OK(status)) {
1105 d_printf("NetNameValidate failed while checking valid chars (%s)\n",
1110 if (!W_ERROR_IS_OK(r.out.result)) {
1111 invalidc = talloc_asprintf_append(invalidc, "%c", (char)n);
1117 d_printf(" Invalid chars for type %2d, flags %08x: \"%s\"\n", i, r.in.flags, invalidc);
1119 /* only two values are accepted for flags: 0x0 and 0x80000000 */
1120 if (r.in.flags == 0x0) {
1121 r.in.flags = 0x80000000;
1131 struct torture_suite *torture_rpc_srvsvc(TALLOC_CTX *mem_ctx)
1133 struct torture_suite *suite = torture_suite_create(mem_ctx, "SRVSVC");
1134 struct torture_tcase *tcase;
1136 tcase = torture_suite_add_rpc_iface_tcase(suite, "srvsvc (admin access)", &ndr_table_srvsvc);
1138 torture_rpc_tcase_add_test(tcase, "NetCharDevEnum", test_NetCharDevEnum);
1139 torture_rpc_tcase_add_test(tcase, "NetCharDevQEnum", test_NetCharDevQEnum);
1140 torture_rpc_tcase_add_test(tcase, "NetConnEnum", test_NetConnEnum);
1141 torture_rpc_tcase_add_test(tcase, "NetFileEnum", test_NetFileEnum);
1142 torture_rpc_tcase_add_test(tcase, "NetSessEnum", test_NetSessEnum);
1143 torture_rpc_tcase_add_test(tcase, "NetShareEnumAll", test_NetShareEnumAllFull);
1144 torture_rpc_tcase_add_test(tcase, "NetSrvGetInfo", test_NetSrvGetInfo);
1145 torture_rpc_tcase_add_test(tcase, "NetDiskEnum", test_NetDiskEnum);
1146 torture_rpc_tcase_add_test(tcase, "NetTransportEnum", test_NetTransportEnum);
1147 torture_rpc_tcase_add_test(tcase, "NetRemoteTOD", test_NetRemoteTOD);
1148 torture_rpc_tcase_add_test(tcase, "NetShareEnum", test_NetShareEnumFull);
1149 torture_rpc_tcase_add_test(tcase, "NetShareGetInfo", test_NetShareGetInfoAdminFull);
1150 torture_rpc_tcase_add_test(tcase, "NetShareAddSetDel",
1151 test_NetShareAddSetDel);
1152 torture_rpc_tcase_add_test(tcase, "NetNameValidate", test_NetNameValidate);
1154 tcase = torture_suite_add_anon_rpc_iface_tcase(suite,
1155 "srvsvc anonymous access",
1158 torture_rpc_tcase_add_test(tcase, "NetShareEnumAll",
1159 test_NetShareEnumAllAnon);
1160 torture_rpc_tcase_add_test(tcase, "NetShareEnum",
1161 test_NetShareEnumAnon);
1162 torture_rpc_tcase_add_test(tcase, "NetShareGetInfo",
1163 test_NetShareGetInfoAdminAnon);