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, struct torture_context *tctx,
34 struct srvsvc_NetCharDevGetInfo r;
35 union srvsvc_NetCharDevInfo info;
36 uint32_t levels[] = {0, 1};
39 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
40 r.in.device_name = devname;
43 for (i=0;i<ARRAY_SIZE(levels);i++) {
44 r.in.level = levels[i];
45 torture_comment(tctx, "testing NetCharDevGetInfo level %u on device '%s'\n",
46 r.in.level, r.in.device_name);
47 status = dcerpc_srvsvc_NetCharDevGetInfo(p, tctx, &r);
48 torture_assert_ntstatus_ok(tctx, status, "NetCharDevGetInfo failed");
49 torture_assert_werr_ok(tctx, r.out.result, "NetCharDevGetInfo failed");
55 static bool test_NetCharDevControl(struct dcerpc_pipe *p, struct torture_context *tctx,
59 struct srvsvc_NetCharDevControl r;
60 uint32_t opcodes[] = {0, 1};
63 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
64 r.in.device_name = devname;
66 for (i=0;i<ARRAY_SIZE(opcodes);i++) {
68 r.in.opcode = opcodes[i];
69 torture_comment(tctx, "testing NetCharDevControl opcode %u on device '%s'\n",
70 r.in.opcode, r.in.device_name);
71 status = dcerpc_srvsvc_NetCharDevControl(p, tctx, &r);
72 torture_assert_ntstatus_ok(tctx, status, "NetCharDevControl failed");
73 torture_assert_werr_ok(tctx, r.out.result, "NetCharDevControl failed");
79 static bool test_NetCharDevEnum(struct torture_context *tctx,
80 struct dcerpc_pipe *p)
83 struct srvsvc_NetCharDevEnum r;
84 struct srvsvc_NetCharDevInfoCtr info_ctr;
85 struct srvsvc_NetCharDevCtr0 c0;
86 struct srvsvc_NetCharDevCtr0 c1;
87 uint32_t totalentries = 0;
88 uint32_t levels[] = {0, 1};
91 ZERO_STRUCT(info_ctr);
93 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
94 r.in.info_ctr = &info_ctr;
95 r.in.max_buffer = (uint32_t)-1;
96 r.in.resume_handle = NULL;
97 r.out.info_ctr = &info_ctr;
98 r.out.totalentries = &totalentries;
100 for (i=0;i<ARRAY_SIZE(levels);i++) {
103 info_ctr.level = levels[i];
105 switch(info_ctr.level) {
108 info_ctr.ctr.ctr0 = &c0;
112 info_ctr.ctr.ctr0 = &c1;
116 torture_comment(tctx, "testing NetCharDevEnum level %u\n", info_ctr.level);
117 status = dcerpc_srvsvc_NetCharDevEnum(p, tctx, &r);
118 torture_assert_ntstatus_ok(tctx, status, "NetCharDevEnum failed");
119 if (!W_ERROR_IS_OK(r.out.result)) {
120 torture_comment(tctx, "NetCharDevEnum failed: %s\n", win_errstr(r.out.result));
124 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */
125 if (info_ctr.level == 1) {
126 for (j=0;j<r.out.info_ctr->ctr.ctr1->count;j++) {
128 device = r.out.info_ctr->ctr.ctr1->array[j].device;
129 if (!test_NetCharDevGetInfo(p, tctx, device)) {
132 if (!test_NetCharDevControl(p, tctx, device)) {
142 /**************************/
143 /* srvsvc_NetCharDevQ */
144 /**************************/
145 static bool test_NetCharDevQGetInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
146 const char *devicequeue)
149 struct srvsvc_NetCharDevQGetInfo r;
150 union srvsvc_NetCharDevQInfo info;
151 uint32_t levels[] = {0, 1};
154 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
155 r.in.queue_name = devicequeue;
156 r.in.user = talloc_asprintf(tctx,"Administrator");
159 for (i=0;i<ARRAY_SIZE(levels);i++) {
160 r.in.level = levels[i];
161 torture_comment(tctx, "testing NetCharDevQGetInfo level %u on devicequeue '%s'\n",
162 r.in.level, r.in.queue_name);
163 status = dcerpc_srvsvc_NetCharDevQGetInfo(p, tctx, &r);
164 torture_assert_ntstatus_ok(tctx, status, "NetCharDevQGetInfo failed");
165 torture_assert_werr_ok(tctx, r.out.result, "NetCharDevQGetInfo failed");
172 static bool test_NetCharDevQSetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
173 const char *devicequeue)
176 struct srvsvc_NetCharDevQSetInfo r;
178 uint32_t levels[] = {0, 1};
182 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
183 r.in.queue_name = devicequeue;
185 for (i=0;i<ARRAY_SIZE(levels);i++) {
188 r.in.level = levels[i];
189 d_printf("testing NetCharDevQSetInfo level %u on devicequeue '%s'\n",
190 r.in.level, devicequeue);
191 switch (r.in.level) {
193 r.in.info.info0 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo0);
194 r.in.info.info0->device = r.in.queue_name;
197 r.in.info.info1 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo1);
198 r.in.info.info1->device = r.in.queue_name;
199 r.in.info.info1->priority = 0x000;
200 r.in.info.info1->devices = r.in.queue_name;
201 r.in.info.info1->users = 0x000;
202 r.in.info.info1->num_ahead = 0x000;
207 r.in.parm_error = &parm_error;
208 status = dcerpc_srvsvc_NetCharDevQSetInfo(p, mem_ctx, &r);
209 if (!NT_STATUS_IS_OK(status)) {
210 d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n",
211 r.in.level, r.in.queue_name, nt_errstr(status));
215 if (!W_ERROR_IS_OK(r.out.result)) {
216 d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n",
217 r.in.level, r.in.queue_name, win_errstr(r.out.result));
226 static bool test_NetCharDevQEnum(struct torture_context *tctx,
227 struct dcerpc_pipe *p)
230 struct srvsvc_NetCharDevQEnum r;
231 struct srvsvc_NetCharDevQInfoCtr info_ctr;
232 struct srvsvc_NetCharDevQCtr0 c0;
233 struct srvsvc_NetCharDevQCtr1 c1;
234 uint32_t totalentries = 0;
235 uint32_t levels[] = {0, 1};
238 ZERO_STRUCT(info_ctr);
240 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
241 r.in.user = talloc_asprintf(tctx,"%s","Administrator");
242 r.in.info_ctr = &info_ctr;
243 r.in.max_buffer = (uint32_t)-1;
244 r.in.resume_handle = NULL;
245 r.out.totalentries = &totalentries;
246 r.out.info_ctr = &info_ctr;
248 for (i=0;i<ARRAY_SIZE(levels);i++) {
251 info_ctr.level = levels[i];
253 switch (info_ctr.level) {
256 info_ctr.ctr.ctr0 = &c0;
260 info_ctr.ctr.ctr1 = &c1;
263 torture_comment(tctx, "testing NetCharDevQEnum level %u\n", info_ctr.level);
264 status = dcerpc_srvsvc_NetCharDevQEnum(p, tctx, &r);
265 torture_assert_ntstatus_ok(tctx, status, "NetCharDevQEnum failed");
266 if (!W_ERROR_IS_OK(r.out.result)) {
267 torture_comment(tctx, "NetCharDevQEnum failed: %s\n", win_errstr(r.out.result));
271 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */
272 if (info_ctr.level == 1) {
273 for (j=0;j<r.out.info_ctr->ctr.ctr1->count;j++) {
275 device = r.out.info_ctr->ctr.ctr1->array[j].device;
276 if (!test_NetCharDevQGetInfo(p, tctx, device)) {
286 /**************************/
288 /**************************/
289 static bool test_NetConnEnum(struct torture_context *tctx,
290 struct dcerpc_pipe *p)
293 struct srvsvc_NetConnEnum r;
294 struct srvsvc_NetConnInfoCtr info_ctr;
295 struct srvsvc_NetConnCtr0 c0;
296 struct srvsvc_NetConnCtr1 c1;
297 uint32_t totalentries = 0;
298 uint32_t levels[] = {0, 1};
301 ZERO_STRUCT(info_ctr);
303 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
304 r.in.path = talloc_asprintf(tctx,"%s","ADMIN$");
305 r.in.info_ctr = &info_ctr;
306 r.in.max_buffer = (uint32_t)-1;
307 r.in.resume_handle = NULL;
308 r.out.totalentries = &totalentries;
309 r.out.info_ctr = &info_ctr;
311 for (i=0;i<ARRAY_SIZE(levels);i++) {
312 info_ctr.level = levels[i];
314 switch (info_ctr.level) {
317 info_ctr.ctr.ctr0 = &c0;
321 info_ctr.ctr.ctr1 = &c1;
325 torture_comment(tctx, "testing NetConnEnum level %u\n", info_ctr.level);
326 status = dcerpc_srvsvc_NetConnEnum(p, tctx, &r);
327 torture_assert_ntstatus_ok(tctx, status, "NetConnEnum failed");
328 if (!W_ERROR_IS_OK(r.out.result)) {
329 torture_comment(tctx, "NetConnEnum failed: %s\n", win_errstr(r.out.result));
336 /**************************/
338 /**************************/
339 static bool test_NetFileEnum(struct torture_context *tctx,
340 struct dcerpc_pipe *p)
343 struct srvsvc_NetFileEnum r;
344 struct srvsvc_NetFileCtr3 c3;
345 uint32_t levels[] = {2, 3};
348 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
352 r.in.ctr.ctr3->count = 0;
353 r.in.ctr.ctr3->array = NULL;
354 r.in.max_buffer = (uint32_t)4096;
355 r.in.resume_handle = NULL;
357 for (i=0;i<ARRAY_SIZE(levels);i++) {
359 r.in.level = levels[i];
360 torture_comment(tctx, "testing NetFileEnum level %u\n", r.in.level);
361 status = dcerpc_srvsvc_NetFileEnum(p, tctx, &r);
362 torture_assert_ntstatus_ok(tctx, status, "NetFileEnum failed");
363 if (!W_ERROR_IS_OK(r.out.result)) {
364 torture_comment(tctx, "NetFileEnum failed: %s\n", win_errstr(r.out.result));
371 /**************************/
373 /**************************/
374 static bool test_NetSessEnum(struct torture_context *tctx,
375 struct dcerpc_pipe *p)
378 struct srvsvc_NetSessEnum r;
379 struct srvsvc_NetSessCtr0 c0;
380 uint32_t levels[] = {0, 1, 2, 10, 502};
383 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
387 r.in.ctr.ctr0->count = 0;
388 r.in.ctr.ctr0->array = NULL;
389 r.in.max_buffer = (uint32_t)-1;
390 r.in.resume_handle = NULL;
392 for (i=0;i<ARRAY_SIZE(levels);i++) {
394 r.in.level = levels[i];
395 torture_comment(tctx, "testing NetSessEnum level %u\n", r.in.level);
396 status = dcerpc_srvsvc_NetSessEnum(p, tctx, &r);
397 torture_assert_ntstatus_ok(tctx, status, "NetSessEnum failed");
398 if (!W_ERROR_IS_OK(r.out.result)) {
399 torture_comment(tctx, "NetSessEnum failed: %s\n", win_errstr(r.out.result));
406 /**************************/
407 /* srvsvc_NetShare */
408 /**************************/
409 static bool test_NetShareCheck(struct dcerpc_pipe *p, struct torture_context *tctx,
410 const char *device_name)
413 struct srvsvc_NetShareCheck r;
414 enum srvsvc_ShareType type;
416 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
417 r.in.device_name = device_name;
420 torture_comment(tctx,
421 "testing NetShareCheck on device '%s'\n", r.in.device_name);
423 status = dcerpc_srvsvc_NetShareCheck(p, tctx, &r);
424 torture_assert_ntstatus_ok(tctx, status, "dcerpc_srvsvc_NetShareCheck failed");
425 torture_assert_werr_ok(tctx, r.out.result, "NetShareCheck failed");
430 static bool test_NetShareGetInfo(struct torture_context *tctx,
431 struct dcerpc_pipe *p,
432 const char *sharename, bool admin)
435 struct srvsvc_NetShareGetInfo r;
436 union srvsvc_NetShareInfo info;
442 { 0, WERR_OK, WERR_OK },
443 { 1, WERR_OK, WERR_OK },
444 { 2, WERR_ACCESS_DENIED, WERR_OK },
445 { 501, WERR_OK, WERR_OK },
446 { 502, WERR_ACCESS_DENIED, WERR_OK },
447 { 1005, WERR_OK, WERR_OK },
451 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
452 r.in.share_name = sharename;
455 for (i=0;i<ARRAY_SIZE(levels);i++) {
458 r.in.level = levels[i].level;
459 expected = levels[i].anon_status;
460 if (admin) expected = levels[i].admin_status;
462 torture_comment(tctx, "testing NetShareGetInfo level %u on share '%s'\n",
463 r.in.level, r.in.share_name);
465 status = dcerpc_srvsvc_NetShareGetInfo(p, tctx, &r);
466 torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed");
467 torture_assert_werr_equal(tctx, r.out.result, expected, "NetShareGetInfo failed");
469 if (r.in.level != 2) continue;
470 if (!r.out.info->info2 || !r.out.info->info2->path) continue;
471 if (!test_NetShareCheck(p, tctx, r.out.info->info2->path)) {
479 static bool test_NetShareGetInfoAdminFull(struct torture_context *tctx,
480 struct dcerpc_pipe *p)
482 return test_NetShareGetInfo(tctx, p, "ADMIN$", true);
485 static bool test_NetShareGetInfoAdminAnon(struct torture_context *tctx,
486 struct dcerpc_pipe *p)
488 return test_NetShareGetInfo(tctx, p, "ADMIN$", false);
491 static bool test_NetShareAddSetDel(struct torture_context *tctx,
492 struct dcerpc_pipe *p)
495 struct srvsvc_NetShareAdd a;
496 struct srvsvc_NetShareSetInfo r;
497 struct srvsvc_NetShareGetInfo q;
498 struct srvsvc_NetShareDel d;
499 struct sec_desc_buf sd_buf;
500 union srvsvc_NetShareInfo info;
505 { 0, WERR_UNKNOWN_LEVEL },
508 { 501, WERR_UNKNOWN_LEVEL },
513 /* { 1007, WERR_OK }, */
518 a.in.server_unc = r.in.server_unc = q.in.server_unc = d.in.server_unc =
519 talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
520 r.in.share_name = talloc_strdup(tctx, "testshare");
522 info.info2 = talloc(tctx, struct srvsvc_NetShareInfo2);
523 info.info2->name = r.in.share_name;
524 info.info2->type = STYPE_DISKTREE;
525 info.info2->comment = talloc_strdup(tctx, "test comment");
526 info.info2->permissions = 123434566;
527 info.info2->max_users = -1;
528 info.info2->current_users = 0;
529 info.info2->path = talloc_strdup(tctx, "C:\\");
530 info.info2->password = NULL;
534 a.in.parm_error = NULL;
536 status = dcerpc_srvsvc_NetShareAdd(p, tctx, &a);
537 torture_assert_ntstatus_ok(tctx, status, "NetShareAdd level 2 on share 'testshare' failed");
538 torture_assert_werr_ok(tctx, a.out.result, "NetShareAdd level 2 on share 'testshare' failed");
540 r.in.parm_error = NULL;
544 for (i = 0; i < ARRAY_SIZE(levels); i++) {
546 r.in.level = levels[i].level;
549 torture_comment(tctx, "testing NetShareSetInfo level %u on share '%s'\n",
550 r.in.level, r.in.share_name);
552 switch (levels[i].level) {
554 info.info0 = talloc(tctx, struct srvsvc_NetShareInfo0);
555 info.info0->name = r.in.share_name;
558 info.info1 = talloc(tctx, struct srvsvc_NetShareInfo1);
559 info.info1->name = r.in.share_name;
560 info.info1->type = STYPE_DISKTREE;
561 info.info1->comment = talloc_strdup(tctx, "test comment 1");
564 info.info2 = talloc(tctx, struct srvsvc_NetShareInfo2);
565 info.info2->name = r.in.share_name;
566 info.info2->type = STYPE_DISKTREE;
567 info.info2->comment = talloc_strdup(tctx, "test comment 2");
568 info.info2->permissions = 0;
569 info.info2->max_users = 2;
570 info.info2->current_users = 1;
571 info.info2->path = talloc_strdup(tctx, "::BLaH::"); /* "C:\\"); */
572 info.info2->password = NULL;
575 info.info501 = talloc(tctx, struct srvsvc_NetShareInfo501);
576 info.info501->name = r.in.share_name;
577 info.info501->type = STYPE_DISKTREE;
578 info.info501->comment = talloc_strdup(tctx, "test comment 501");
579 info.info501->csc_policy = 0;
583 info.info502 = talloc(tctx, struct srvsvc_NetShareInfo502);
584 info.info502->name = r.in.share_name;
585 info.info502->type = STYPE_DISKTREE;
586 info.info502->comment = talloc_strdup(tctx, "test comment 502");
587 info.info502->permissions = 0;
588 info.info502->max_users = 502;
589 info.info502->current_users = 1;
590 info.info502->path = talloc_strdup(tctx, "C:\\");
591 info.info502->password = NULL;
592 info.info502->sd_buf = sd_buf;
595 info.info1004 = talloc(tctx, struct srvsvc_NetShareInfo1004);
596 info.info1004->comment = talloc_strdup(tctx, "test comment 1004");
599 info.info1005 = talloc(tctx, struct srvsvc_NetShareInfo1005);
600 info.info1005->dfs_flags = 0;
603 info.info1006 = talloc(tctx, struct srvsvc_NetShareInfo1006);
604 info.info1006->max_users = 1006;
607 info.info1007 = talloc(tctx, struct srvsvc_NetShareInfo1007);
608 info.info1007->flags = 0;
609 info.info1007->alternate_directory_name = talloc_strdup(tctx, "test");
613 info.info1501 = talloc_zero(tctx, struct sec_desc_buf);
619 status = dcerpc_srvsvc_NetShareSetInfo(p, tctx, &r);
620 torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed");
621 torture_assert_werr_equal(tctx, r.out.result, levels[i].expected, "NetShareSetInfo failed");
623 q.in.share_name = r.in.share_name;
626 status = dcerpc_srvsvc_NetShareGetInfo(p, tctx, &q);
627 torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed");
628 torture_assert_werr_ok(tctx, q.out.result, "NetShareGetInfo failed");
630 torture_assert_str_equal(tctx, q.out.info->info502->name, r.in.share_name,
631 "share name invalid");
633 switch (levels[i].level) {
637 torture_assert_str_equal(tctx, q.out.info->info502->comment, "test comment 1", "comment");
640 torture_assert_str_equal(tctx, q.out.info->info2->comment, "test comment 2", "comment");
641 torture_assert_int_equal(tctx, q.out.info->info2->max_users, 2, "max users");
642 torture_assert_str_equal(tctx, q.out.info->info2->path, "C:\\", "path");
645 torture_assert_str_equal(tctx, q.out.info->info501->comment, "test comment 501", "comment");
648 torture_assert_str_equal(tctx, q.out.info->info502->comment, "test comment 502", "comment");
649 torture_assert_int_equal(tctx, q.out.info->info502->max_users, 502, "max users");
650 torture_assert_str_equal(tctx, q.out.info->info502->path, "C:\\", "path");
653 torture_assert_str_equal(tctx, q.out.info->info1004->comment, "test comment 1004",
659 torture_assert_int_equal(tctx, q.out.info->info1006->max_users, 1006, "Max users");
669 d.in.share_name = r.in.share_name;
672 status = dcerpc_srvsvc_NetShareDel(p, tctx, &d);
673 torture_assert_ntstatus_ok(tctx, status, "NetShareDel on share 'testshare502' failed");
674 torture_assert_werr_ok(tctx, a.out.result, "NetShareDel on share 'testshare502' failed");
679 /**************************/
680 /* srvsvc_NetShare */
681 /**************************/
682 static bool test_NetShareEnumAll(struct torture_context *tctx,
683 struct dcerpc_pipe *p,
687 struct srvsvc_NetShareEnumAll r;
688 struct srvsvc_NetShareCtr0 c0;
694 { 0, WERR_OK, WERR_OK },
695 { 1, WERR_OK, WERR_OK },
696 { 2, WERR_ACCESS_DENIED, WERR_OK },
697 { 501, WERR_ACCESS_DENIED, WERR_OK },
698 { 502, WERR_ACCESS_DENIED, WERR_OK },
701 uint32_t resume_handle;
705 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
707 r.in.max_buffer = (uint32_t)-1;
708 r.in.resume_handle = &resume_handle;
709 r.out.resume_handle = &resume_handle;
711 for (i=0;i<ARRAY_SIZE(levels);i++) {
715 r.in.level = levels[i].level;
716 expected = levels[i].anon_status;
717 if (admin) expected = levels[i].admin_status;
722 torture_comment(tctx, "testing NetShareEnumAll level %u\n", r.in.level);
723 status = dcerpc_srvsvc_NetShareEnumAll(p, tctx, &r);
724 torture_assert_ntstatus_ok(tctx, status, "NetShareEnumAll failed");
725 torture_assert_werr_equal(tctx, r.out.result, expected, "NetShareEnumAll failed");
727 /* call srvsvc_NetShareGetInfo for each returned share */
728 if (r.in.level == 2 && r.out.ctr.ctr2) {
729 for (j=0;j<r.out.ctr.ctr2->count;j++) {
731 name = r.out.ctr.ctr2->array[j].name;
732 if (!test_NetShareGetInfo(tctx, p, name, admin)) {
742 static bool test_NetShareEnumAllFull(struct torture_context *tctx,
743 struct dcerpc_pipe *p)
745 return test_NetShareEnumAll(tctx, p, true);
748 static bool test_NetShareEnumAllAnon(struct torture_context *tctx,
749 struct dcerpc_pipe *p)
751 return test_NetShareEnumAll(tctx, p, false);
754 static bool test_NetShareEnum(struct torture_context *tctx,
755 struct dcerpc_pipe *p, bool admin)
758 struct srvsvc_NetShareEnum r;
759 struct srvsvc_NetShareCtr0 c0;
765 { 0, WERR_OK, WERR_OK },
766 { 1, WERR_OK, WERR_OK },
767 { 2, WERR_ACCESS_DENIED, WERR_OK },
768 { 501, WERR_UNKNOWN_LEVEL, WERR_UNKNOWN_LEVEL },
769 { 502, WERR_ACCESS_DENIED, WERR_OK },
773 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
775 r.in.ctr.ctr0->count = 0;
776 r.in.ctr.ctr0->array = NULL;
777 r.in.max_buffer = (uint32_t)-1;
778 r.in.resume_handle = NULL;
780 for (i=0;i<ARRAY_SIZE(levels);i++) {
783 r.in.level = levels[i].level;
784 expected = levels[i].anon_status;
785 if (admin) expected = levels[i].admin_status;
789 torture_comment(tctx, "testing NetShareEnum level %u\n", r.in.level);
790 status = dcerpc_srvsvc_NetShareEnum(p, tctx, &r);
791 torture_assert_ntstatus_ok(tctx, status, "NetShareEnum failed");
792 torture_assert_werr_equal(tctx, r.out.result, expected, "NetShareEnum failed");
798 static bool test_NetShareEnumFull(struct torture_context *tctx,
799 struct dcerpc_pipe *p)
801 return test_NetShareEnum(tctx, p, true);
804 static bool test_NetShareEnumAnon(struct torture_context *tctx,
805 struct dcerpc_pipe *p)
807 return test_NetShareEnum(tctx, p, false);
810 /**************************/
812 /**************************/
813 static bool test_NetSrvGetInfo(struct torture_context *tctx,
814 struct dcerpc_pipe *p)
817 struct srvsvc_NetSrvGetInfo r;
818 union srvsvc_NetSrvInfo info;
819 uint32_t levels[] = {100, 101, 102, 502, 503};
822 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
824 for (i=0;i<ARRAY_SIZE(levels);i++) {
825 r.in.level = levels[i];
827 torture_comment(tctx, "testing NetSrvGetInfo level %u\n", r.in.level);
828 status = dcerpc_srvsvc_NetSrvGetInfo(p, tctx, &r);
829 torture_assert_ntstatus_ok(tctx, status, "NetSrvGetInfo failed");
830 if (!W_ERROR_IS_OK(r.out.result)) {
831 torture_comment(tctx, "NetSrvGetInfo failed: %s\n", win_errstr(r.out.result));
838 /**************************/
840 /**************************/
841 static bool test_NetDiskEnum(struct torture_context *tctx,
842 struct dcerpc_pipe *p)
845 struct srvsvc_NetDiskEnum r;
846 struct srvsvc_NetDiskInfo info;
847 uint32_t totalentries = 0;
848 uint32_t levels[] = {0};
850 uint32_t resume_handle=0;
854 r.in.server_unc = NULL;
855 r.in.resume_handle = &resume_handle;
858 r.out.totalentries = &totalentries;
859 r.out.resume_handle = &resume_handle;
861 for (i=0;i<ARRAY_SIZE(levels);i++) {
862 ZERO_STRUCTP(r.out.info);
863 r.in.level = levels[i];
864 torture_comment(tctx, "testing NetDiskEnum level %u\n", r.in.level);
865 status = dcerpc_srvsvc_NetDiskEnum(p, tctx, &r);
866 torture_assert_ntstatus_ok(tctx, status, "NetDiskEnum failed");
867 torture_assert_werr_ok(tctx, r.out.result, "NetDiskEnum failed");
873 /**************************/
874 /* srvsvc_NetTransport */
875 /**************************/
876 static bool test_NetTransportEnum(struct torture_context *tctx,
877 struct dcerpc_pipe *p)
880 struct srvsvc_NetTransportEnum r;
881 struct srvsvc_NetTransportInfoCtr transports;
882 struct srvsvc_NetTransportCtr0 ctr0;
883 struct srvsvc_NetTransportCtr1 ctr1;
885 uint32_t totalentries = 0;
886 uint32_t levels[] = {0, 1};
889 ZERO_STRUCT(transports);
891 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s", dcerpc_server_name(p));
892 r.in.transports = &transports;
893 r.in.max_buffer = (uint32_t)-1;
894 r.in.resume_handle = NULL;
895 r.out.totalentries = &totalentries;
896 r.out.transports = &transports;
898 for (i=0;i<ARRAY_SIZE(levels);i++) {
899 transports.level = levels[i];
900 switch (transports.level) {
903 transports.ctr.ctr0 = &ctr0;
907 transports.ctr.ctr1 = &ctr1;
910 torture_comment(tctx, "testing NetTransportEnum level %u\n", transports.level);
911 status = dcerpc_srvsvc_NetTransportEnum(p, tctx, &r);
912 torture_assert_ntstatus_ok(tctx, status, "NetTransportEnum failed");
913 if (!W_ERROR_IS_OK(r.out.result)) {
914 torture_comment(tctx, "unexpected result: %s\n", win_errstr(r.out.result));
921 /**************************/
922 /* srvsvc_NetRemoteTOD */
923 /**************************/
924 static bool test_NetRemoteTOD(struct torture_context *tctx,
925 struct dcerpc_pipe *p)
928 struct srvsvc_NetRemoteTOD r;
929 struct srvsvc_NetRemoteTODInfo *info = NULL;
931 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
934 torture_comment(tctx, "testing NetRemoteTOD\n");
935 status = dcerpc_srvsvc_NetRemoteTOD(p, tctx, &r);
936 torture_assert_ntstatus_ok(tctx, status, "NetRemoteTOD failed");
937 torture_assert_werr_ok(tctx, r.out.result, "NetRemoteTOD failed");
942 /**************************/
944 /**************************/
946 static bool test_NetNameValidate(struct torture_context *tctx,
947 struct dcerpc_pipe *p)
950 struct srvsvc_NetNameValidate r;
955 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
958 d_printf("testing NetNameValidate\n");
960 /* valid path types only between 1 and 13 */
961 for (i = 1; i < 14; i++) {
964 /* let's limit ourselves to a maximum of 4096 bytes */
965 r.in.name = name = talloc_array(tctx, char, 4097);
972 /* Find maximum length accepted by this type */
975 memset(name, 'A', n);
978 status = dcerpc_srvsvc_NetNameValidate(p, tctx, &r);
979 if (!NT_STATUS_IS_OK(status)) {
980 d_printf("NetNameValidate failed while checking maximum size (%s)\n",
985 if (W_ERROR_IS_OK(r.out.result)) {
987 n += (max - min + 1)/2;
991 if ((min + 1) >= max) break; /* found it */
1001 d_printf("Maximum length for type %2d, flags %08x: %d\n", i, r.in.flags, max);
1003 /* find invalid chars for this type check only ASCII between 0x20 and 0x7e */
1005 invalidc = talloc_strdup(tctx, "");
1007 for (n = 0x20; n < 0x7e; n++) {
1008 r.in.name = name = talloc_asprintf(tctx, "%c", (char)n);
1010 status = dcerpc_srvsvc_NetNameValidate(p, tctx, &r);
1011 if (!NT_STATUS_IS_OK(status)) {
1012 d_printf("NetNameValidate failed while checking valid chars (%s)\n",
1017 if (!W_ERROR_IS_OK(r.out.result)) {
1018 invalidc = talloc_asprintf_append_buffer(invalidc, "%c", (char)n);
1024 d_printf(" Invalid chars for type %2d, flags %08x: \"%s\"\n", i, r.in.flags, invalidc);
1026 /* only two values are accepted for flags: 0x0 and 0x80000000 */
1027 if (r.in.flags == 0x0) {
1028 r.in.flags = 0x80000000;
1038 struct torture_suite *torture_rpc_srvsvc(TALLOC_CTX *mem_ctx)
1040 struct torture_suite *suite = torture_suite_create(mem_ctx, "SRVSVC");
1041 struct torture_rpc_tcase *tcase;
1042 struct torture_test *test;
1044 tcase = torture_suite_add_rpc_iface_tcase(suite, "srvsvc (admin access)", &ndr_table_srvsvc);
1046 torture_rpc_tcase_add_test(tcase, "NetCharDevEnum", test_NetCharDevEnum);
1047 torture_rpc_tcase_add_test(tcase, "NetCharDevQEnum", test_NetCharDevQEnum);
1048 torture_rpc_tcase_add_test(tcase, "NetConnEnum", test_NetConnEnum);
1049 torture_rpc_tcase_add_test(tcase, "NetFileEnum", test_NetFileEnum);
1050 torture_rpc_tcase_add_test(tcase, "NetSessEnum", test_NetSessEnum);
1051 torture_rpc_tcase_add_test(tcase, "NetShareEnumAll", test_NetShareEnumAllFull);
1052 torture_rpc_tcase_add_test(tcase, "NetSrvGetInfo", test_NetSrvGetInfo);
1053 torture_rpc_tcase_add_test(tcase, "NetDiskEnum", test_NetDiskEnum);
1054 torture_rpc_tcase_add_test(tcase, "NetTransportEnum", test_NetTransportEnum);
1055 torture_rpc_tcase_add_test(tcase, "NetRemoteTOD", test_NetRemoteTOD);
1056 torture_rpc_tcase_add_test(tcase, "NetShareEnum", test_NetShareEnumFull);
1057 torture_rpc_tcase_add_test(tcase, "NetShareGetInfo", test_NetShareGetInfoAdminFull);
1058 test = torture_rpc_tcase_add_test(tcase, "NetShareAddSetDel",
1059 test_NetShareAddSetDel);
1060 test->dangerous = true;
1061 torture_rpc_tcase_add_test(tcase, "NetNameValidate", test_NetNameValidate);
1063 tcase = torture_suite_add_anon_rpc_iface_tcase(suite,
1064 "srvsvc anonymous access",
1067 torture_rpc_tcase_add_test(tcase, "NetShareEnumAll",
1068 test_NetShareEnumAllAnon);
1069 torture_rpc_tcase_add_test(tcase, "NetShareEnum",
1070 test_NetShareEnumAnon);
1071 torture_rpc_tcase_add_test(tcase, "NetShareGetInfo",
1072 test_NetShareGetInfoAdminAnon);