samba-3.5.8 for ARM
[tomato.git] / release / src-rt-6.x.4708 / router / samba-3.5.8 / source4 / torture / rpc / srvsvc.c
blob82a8a678541c973b8af0e204267491a28451d80b
1 /*
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/>.
21 #include "includes.h"
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,
31 const char *devname)
33 NTSTATUS status;
34 struct srvsvc_NetCharDevGetInfo r;
35 union srvsvc_NetCharDevInfo info;
36 uint32_t levels[] = {0, 1};
37 int i;
39 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
40 r.in.device_name = devname;
41 r.out.info = &info;
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");
52 return true;
55 static bool test_NetCharDevControl(struct dcerpc_pipe *p, struct torture_context *tctx,
56 const char *devname)
58 NTSTATUS status;
59 struct srvsvc_NetCharDevControl r;
60 uint32_t opcodes[] = {0, 1};
61 int i;
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++) {
67 ZERO_STRUCT(r.out);
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");
76 return true;
79 static bool test_NetCharDevEnum(struct torture_context *tctx,
80 struct dcerpc_pipe *p)
82 NTSTATUS status;
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};
89 int i;
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++) {
101 int j;
103 info_ctr.level = levels[i];
105 switch(info_ctr.level) {
106 case 0:
107 ZERO_STRUCT(c0);
108 info_ctr.ctr.ctr0 = &c0;
109 break;
110 case 1:
111 ZERO_STRUCT(c1);
112 info_ctr.ctr.ctr0 = &c1;
113 break;
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));
121 continue;
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++) {
127 const char *device;
128 device = r.out.info_ctr->ctr.ctr1->array[j].device;
129 if (!test_NetCharDevGetInfo(p, tctx, device)) {
130 return false;
132 if (!test_NetCharDevControl(p, tctx, device)) {
133 return false;
139 return true;
142 /**************************/
143 /* srvsvc_NetCharDevQ */
144 /**************************/
145 static bool test_NetCharDevQGetInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
146 const char *devicequeue)
148 NTSTATUS status;
149 struct srvsvc_NetCharDevQGetInfo r;
150 union srvsvc_NetCharDevQInfo info;
151 uint32_t levels[] = {0, 1};
152 int i;
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");
157 r.out.info = &info;
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");
168 return true;
171 #if 0
172 static bool test_NetCharDevQSetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
173 const char *devicequeue)
175 NTSTATUS status;
176 struct srvsvc_NetCharDevQSetInfo r;
177 uint32_t parm_error;
178 uint32_t levels[] = {0, 1};
179 int i;
180 bool ret = true;
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++) {
186 ZERO_STRUCT(r.out);
187 parm_error = 0;
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) {
192 case 0:
193 r.in.info.info0 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo0);
194 r.in.info.info0->device = r.in.queue_name;
195 break;
196 case 1:
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;
203 break;
204 default:
205 break;
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));
212 ret = false;
213 continue;
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));
218 continue;
222 return ret;
224 #endif
226 static bool test_NetCharDevQEnum(struct torture_context *tctx,
227 struct dcerpc_pipe *p)
229 NTSTATUS status;
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};
236 int i;
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++) {
249 int j;
251 info_ctr.level = levels[i];
253 switch (info_ctr.level) {
254 case 0:
255 ZERO_STRUCT(c0);
256 info_ctr.ctr.ctr0 = &c0;
257 break;
258 case 1:
259 ZERO_STRUCT(c1);
260 info_ctr.ctr.ctr1 = &c1;
261 break;
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));
268 continue;
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++) {
274 const char *device;
275 device = r.out.info_ctr->ctr.ctr1->array[j].device;
276 if (!test_NetCharDevQGetInfo(p, tctx, device)) {
277 return false;
283 return true;
286 /**************************/
287 /* srvsvc_NetConn */
288 /**************************/
289 static bool test_NetConnEnum(struct torture_context *tctx,
290 struct dcerpc_pipe *p)
292 NTSTATUS status;
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};
299 int i;
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) {
315 case 0:
316 ZERO_STRUCT(c0);
317 info_ctr.ctr.ctr0 = &c0;
318 break;
319 case 1:
320 ZERO_STRUCT(c1);
321 info_ctr.ctr.ctr1 = &c1;
322 break;
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));
333 return true;
336 /**************************/
337 /* srvsvc_NetFile */
338 /**************************/
339 static bool test_NetFileEnum(struct torture_context *tctx,
340 struct dcerpc_pipe *p)
342 NTSTATUS status;
343 struct srvsvc_NetFileEnum r;
344 struct srvsvc_NetFileInfoCtr info_ctr;
345 struct srvsvc_NetFileCtr2 c2;
346 struct srvsvc_NetFileCtr3 c3;
347 uint32_t totalentries = 0;
348 uint32_t levels[] = {2, 3};
349 int i;
351 ZERO_STRUCT(info_ctr);
353 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
354 r.in.path = NULL;
355 r.in.user = NULL;
356 r.in.info_ctr = &info_ctr;
357 r.in.max_buffer = (uint32_t)4096;
358 r.in.resume_handle = NULL;
359 r.out.totalentries = &totalentries;
360 r.out.info_ctr = &info_ctr;
362 for (i=0;i<ARRAY_SIZE(levels);i++) {
363 info_ctr.level = levels[i];
365 switch (info_ctr.level) {
366 case 2:
367 ZERO_STRUCT(c2);
368 info_ctr.ctr.ctr2 = &c2;
369 break;
370 case 3:
371 ZERO_STRUCT(c3);
372 info_ctr.ctr.ctr3 = &c3;
373 break;
375 torture_comment(tctx, "testing NetFileEnum level %u\n", info_ctr.level);
376 status = dcerpc_srvsvc_NetFileEnum(p, tctx, &r);
377 torture_assert_ntstatus_ok(tctx, status, "NetFileEnum failed");
378 if (!W_ERROR_IS_OK(r.out.result)) {
379 torture_comment(tctx, "NetFileEnum failed: %s\n", win_errstr(r.out.result));
383 return true;
386 /**************************/
387 /* srvsvc_NetSess */
388 /**************************/
389 static bool test_NetSessEnum(struct torture_context *tctx,
390 struct dcerpc_pipe *p)
392 NTSTATUS status;
393 struct srvsvc_NetSessEnum r;
394 struct srvsvc_NetSessInfoCtr info_ctr;
395 struct srvsvc_NetSessCtr0 c0;
396 struct srvsvc_NetSessCtr1 c1;
397 struct srvsvc_NetSessCtr2 c2;
398 struct srvsvc_NetSessCtr10 c10;
399 struct srvsvc_NetSessCtr502 c502;
400 uint32_t totalentries = 0;
401 uint32_t levels[] = {0, 1, 2, 10, 502};
402 int i;
404 ZERO_STRUCT(info_ctr);
406 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
407 r.in.client = NULL;
408 r.in.user = NULL;
409 r.in.info_ctr = &info_ctr;
410 r.in.max_buffer = (uint32_t)-1;
411 r.in.resume_handle = NULL;
412 r.out.totalentries = &totalentries;
413 r.out.info_ctr = &info_ctr;
415 for (i=0;i<ARRAY_SIZE(levels);i++) {
416 info_ctr.level = levels[i];
418 switch (info_ctr.level) {
419 case 0:
420 ZERO_STRUCT(c0);
421 info_ctr.ctr.ctr0 = &c0;
422 break;
423 case 1:
424 ZERO_STRUCT(c1);
425 info_ctr.ctr.ctr1 = &c1;
426 break;
427 case 2:
428 ZERO_STRUCT(c2);
429 info_ctr.ctr.ctr2 = &c2;
430 break;
431 case 10:
432 ZERO_STRUCT(c10);
433 info_ctr.ctr.ctr10 = &c10;
434 break;
435 case 502:
436 ZERO_STRUCT(c502);
437 info_ctr.ctr.ctr502 = &c502;
438 break;
441 torture_comment(tctx, "testing NetSessEnum level %u\n", info_ctr.level);
442 status = dcerpc_srvsvc_NetSessEnum(p, tctx, &r);
443 torture_assert_ntstatus_ok(tctx, status, "NetSessEnum failed");
444 if (!W_ERROR_IS_OK(r.out.result)) {
445 torture_comment(tctx, "NetSessEnum failed: %s\n", win_errstr(r.out.result));
449 return true;
452 /**************************/
453 /* srvsvc_NetShare */
454 /**************************/
455 static bool test_NetShareCheck(struct dcerpc_pipe *p, struct torture_context *tctx,
456 const char *device_name)
458 NTSTATUS status;
459 struct srvsvc_NetShareCheck r;
460 enum srvsvc_ShareType type;
462 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
463 r.in.device_name = device_name;
464 r.out.type = &type;
466 torture_comment(tctx,
467 "testing NetShareCheck on device '%s'\n", r.in.device_name);
469 status = dcerpc_srvsvc_NetShareCheck(p, tctx, &r);
470 torture_assert_ntstatus_ok(tctx, status, "dcerpc_srvsvc_NetShareCheck failed");
471 torture_assert_werr_ok(tctx, r.out.result, "NetShareCheck failed");
473 return true;
476 static bool test_NetShareGetInfo(struct torture_context *tctx,
477 struct dcerpc_pipe *p,
478 const char *sharename, bool admin)
480 NTSTATUS status;
481 struct srvsvc_NetShareGetInfo r;
482 union srvsvc_NetShareInfo info;
483 struct {
484 uint32_t level;
485 WERROR anon_status;
486 WERROR admin_status;
487 } levels[] = {
488 { 0, WERR_OK, WERR_OK },
489 { 1, WERR_OK, WERR_OK },
490 { 2, WERR_ACCESS_DENIED, WERR_OK },
491 { 501, WERR_OK, WERR_OK },
492 { 502, WERR_ACCESS_DENIED, WERR_OK },
493 { 1005, WERR_OK, WERR_OK },
495 int i;
497 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
498 r.in.share_name = sharename;
499 r.out.info = &info;
501 for (i=0;i<ARRAY_SIZE(levels);i++) {
502 WERROR expected;
504 r.in.level = levels[i].level;
505 expected = levels[i].anon_status;
506 if (admin) expected = levels[i].admin_status;
508 torture_comment(tctx, "testing NetShareGetInfo level %u on share '%s'\n",
509 r.in.level, r.in.share_name);
511 status = dcerpc_srvsvc_NetShareGetInfo(p, tctx, &r);
512 torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed");
513 torture_assert_werr_equal(tctx, r.out.result, expected, "NetShareGetInfo failed");
515 if (r.in.level != 2) continue;
516 if (!r.out.info->info2 || !r.out.info->info2->path) continue;
517 if (!test_NetShareCheck(p, tctx, r.out.info->info2->path)) {
518 return false;
522 return true;
525 static bool test_NetShareGetInfoAdminFull(struct torture_context *tctx,
526 struct dcerpc_pipe *p)
528 return test_NetShareGetInfo(tctx, p, "ADMIN$", true);
531 static bool test_NetShareGetInfoAdminAnon(struct torture_context *tctx,
532 struct dcerpc_pipe *p)
534 return test_NetShareGetInfo(tctx, p, "ADMIN$", false);
537 static bool test_NetShareAddSetDel(struct torture_context *tctx,
538 struct dcerpc_pipe *p)
540 NTSTATUS status;
541 struct srvsvc_NetShareAdd a;
542 struct srvsvc_NetShareSetInfo r;
543 struct srvsvc_NetShareGetInfo q;
544 struct srvsvc_NetShareDel d;
545 struct sec_desc_buf sd_buf;
546 union srvsvc_NetShareInfo info;
547 struct {
548 uint32_t level;
549 WERROR expected;
550 } levels[] = {
551 { 0, WERR_UNKNOWN_LEVEL },
552 { 1, WERR_OK },
553 { 2, WERR_OK },
554 { 501, WERR_UNKNOWN_LEVEL },
555 { 502, WERR_OK },
556 { 1004, WERR_OK },
557 { 1005, WERR_OK },
558 { 1006, WERR_OK },
559 /* { 1007, WERR_OK }, */
560 { 1501, WERR_OK },
562 int i;
564 a.in.server_unc = r.in.server_unc = q.in.server_unc = d.in.server_unc =
565 talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
566 r.in.share_name = talloc_strdup(tctx, "testshare");
568 info.info2 = talloc(tctx, struct srvsvc_NetShareInfo2);
569 info.info2->name = r.in.share_name;
570 info.info2->type = STYPE_DISKTREE;
571 info.info2->comment = talloc_strdup(tctx, "test comment");
572 info.info2->permissions = 123434566;
573 info.info2->max_users = -1;
574 info.info2->current_users = 0;
575 info.info2->path = talloc_strdup(tctx, "C:\\");
576 info.info2->password = NULL;
578 a.in.info = &info;
579 a.in.level = 2;
580 a.in.parm_error = NULL;
582 status = dcerpc_srvsvc_NetShareAdd(p, tctx, &a);
583 torture_assert_ntstatus_ok(tctx, status, "NetShareAdd level 2 on share 'testshare' failed");
584 torture_assert_werr_ok(tctx, a.out.result, "NetShareAdd level 2 on share 'testshare' failed");
586 r.in.parm_error = NULL;
588 q.in.level = 502;
590 for (i = 0; i < ARRAY_SIZE(levels); i++) {
592 r.in.level = levels[i].level;
593 ZERO_STRUCT(r.out);
595 torture_comment(tctx, "testing NetShareSetInfo level %u on share '%s'\n",
596 r.in.level, r.in.share_name);
598 switch (levels[i].level) {
599 case 0:
600 info.info0 = talloc(tctx, struct srvsvc_NetShareInfo0);
601 info.info0->name = r.in.share_name;
602 break;
603 case 1:
604 info.info1 = talloc(tctx, struct srvsvc_NetShareInfo1);
605 info.info1->name = r.in.share_name;
606 info.info1->type = STYPE_DISKTREE;
607 info.info1->comment = talloc_strdup(tctx, "test comment 1");
608 break;
609 case 2:
610 info.info2 = talloc(tctx, struct srvsvc_NetShareInfo2);
611 info.info2->name = r.in.share_name;
612 info.info2->type = STYPE_DISKTREE;
613 info.info2->comment = talloc_strdup(tctx, "test comment 2");
614 info.info2->permissions = 0;
615 info.info2->max_users = 2;
616 info.info2->current_users = 1;
617 info.info2->path = talloc_strdup(tctx, "::BLaH::"); /* "C:\\"); */
618 info.info2->password = NULL;
619 break;
620 case 501:
621 info.info501 = talloc(tctx, struct srvsvc_NetShareInfo501);
622 info.info501->name = r.in.share_name;
623 info.info501->type = STYPE_DISKTREE;
624 info.info501->comment = talloc_strdup(tctx, "test comment 501");
625 info.info501->csc_policy = 0;
626 break;
627 case 502:
628 ZERO_STRUCT(sd_buf);
629 info.info502 = talloc(tctx, struct srvsvc_NetShareInfo502);
630 info.info502->name = r.in.share_name;
631 info.info502->type = STYPE_DISKTREE;
632 info.info502->comment = talloc_strdup(tctx, "test comment 502");
633 info.info502->permissions = 0;
634 info.info502->max_users = 502;
635 info.info502->current_users = 1;
636 info.info502->path = talloc_strdup(tctx, "C:\\");
637 info.info502->password = NULL;
638 info.info502->sd_buf = sd_buf;
639 break;
640 case 1004:
641 info.info1004 = talloc(tctx, struct srvsvc_NetShareInfo1004);
642 info.info1004->comment = talloc_strdup(tctx, "test comment 1004");
643 break;
644 case 1005:
645 info.info1005 = talloc(tctx, struct srvsvc_NetShareInfo1005);
646 info.info1005->dfs_flags = 0;
647 break;
648 case 1006:
649 info.info1006 = talloc(tctx, struct srvsvc_NetShareInfo1006);
650 info.info1006->max_users = 1006;
651 break;
652 /* case 1007:
653 info.info1007 = talloc(tctx, struct srvsvc_NetShareInfo1007);
654 info.info1007->flags = 0;
655 info.info1007->alternate_directory_name = talloc_strdup(tctx, "test");
656 break;
658 case 1501:
659 info.info1501 = talloc_zero(tctx, struct sec_desc_buf);
660 break;
663 r.in.info = &info;
665 status = dcerpc_srvsvc_NetShareSetInfo(p, tctx, &r);
666 torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed");
667 torture_assert_werr_equal(tctx, r.out.result, levels[i].expected, "NetShareSetInfo failed");
669 q.in.share_name = r.in.share_name;
670 q.out.info = &info;
672 status = dcerpc_srvsvc_NetShareGetInfo(p, tctx, &q);
673 torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed");
674 torture_assert_werr_ok(tctx, q.out.result, "NetShareGetInfo failed");
676 torture_assert_str_equal(tctx, q.out.info->info502->name, r.in.share_name,
677 "share name invalid");
679 switch (levels[i].level) {
680 case 0:
681 break;
682 case 1:
683 torture_assert_str_equal(tctx, q.out.info->info502->comment, "test comment 1", "comment");
684 break;
685 case 2:
686 torture_assert_str_equal(tctx, q.out.info->info2->comment, "test comment 2", "comment");
687 torture_assert_int_equal(tctx, q.out.info->info2->max_users, 2, "max users");
688 torture_assert_str_equal(tctx, q.out.info->info2->path, "C:\\", "path");
689 break;
690 case 501:
691 torture_assert_str_equal(tctx, q.out.info->info501->comment, "test comment 501", "comment");
692 break;
693 case 502:
694 torture_assert_str_equal(tctx, q.out.info->info502->comment, "test comment 502", "comment");
695 torture_assert_int_equal(tctx, q.out.info->info502->max_users, 502, "max users");
696 torture_assert_str_equal(tctx, q.out.info->info502->path, "C:\\", "path");
697 break;
698 case 1004:
699 torture_assert_str_equal(tctx, q.out.info->info1004->comment, "test comment 1004",
700 "comment");
701 break;
702 case 1005:
703 break;
704 case 1006:
705 torture_assert_int_equal(tctx, q.out.info->info1006->max_users, 1006, "Max users");
706 break;
707 /* case 1007:
708 break;
710 case 1501:
711 break;
715 d.in.share_name = r.in.share_name;
716 d.in.reserved = 0;
718 status = dcerpc_srvsvc_NetShareDel(p, tctx, &d);
719 torture_assert_ntstatus_ok(tctx, status, "NetShareDel on share 'testshare502' failed");
720 torture_assert_werr_ok(tctx, a.out.result, "NetShareDel on share 'testshare502' failed");
722 return true;
725 /**************************/
726 /* srvsvc_NetShare */
727 /**************************/
728 static bool test_NetShareEnumAll(struct torture_context *tctx,
729 struct dcerpc_pipe *p,
730 bool admin)
732 NTSTATUS status;
733 struct srvsvc_NetShareEnumAll r;
734 struct srvsvc_NetShareInfoCtr info_ctr;
735 struct srvsvc_NetShareCtr0 c0;
736 struct srvsvc_NetShareCtr1 c1;
737 struct srvsvc_NetShareCtr2 c2;
738 struct srvsvc_NetShareCtr501 c501;
739 struct srvsvc_NetShareCtr502 c502;
740 uint32_t totalentries = 0;
741 struct {
742 uint32_t level;
743 WERROR anon_status;
744 WERROR admin_status;
745 } levels[] = {
746 { 0, WERR_OK, WERR_OK },
747 { 1, WERR_OK, WERR_OK },
748 { 2, WERR_ACCESS_DENIED, WERR_OK },
749 { 501, WERR_ACCESS_DENIED, WERR_OK },
750 { 502, WERR_ACCESS_DENIED, WERR_OK },
752 int i;
753 uint32_t resume_handle;
755 ZERO_STRUCT(info_ctr);
757 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
758 r.in.info_ctr = &info_ctr;
759 r.in.max_buffer = (uint32_t)-1;
760 r.in.resume_handle = &resume_handle;
761 r.out.resume_handle = &resume_handle;
762 r.out.totalentries = &totalentries;
763 r.out.info_ctr = &info_ctr;
765 for (i=0;i<ARRAY_SIZE(levels);i++) {
767 int j;
768 WERROR expected;
770 info_ctr.level = levels[i].level;
772 switch (info_ctr.level) {
773 case 0:
774 ZERO_STRUCT(c0);
775 info_ctr.ctr.ctr0 = &c0;
776 break;
777 case 1:
778 ZERO_STRUCT(c1);
779 info_ctr.ctr.ctr1 = &c1;
780 break;
781 case 2:
782 ZERO_STRUCT(c2);
783 info_ctr.ctr.ctr2 = &c2;
784 break;
785 case 501:
786 ZERO_STRUCT(c501);
787 info_ctr.ctr.ctr501 = &c501;
788 break;
789 case 502:
790 ZERO_STRUCT(c502);
791 info_ctr.ctr.ctr502 = &c502;
792 break;
795 expected = levels[i].anon_status;
796 if (admin) expected = levels[i].admin_status;
798 resume_handle = 0;
800 torture_comment(tctx, "testing NetShareEnumAll level %u\n", info_ctr.level);
801 status = dcerpc_srvsvc_NetShareEnumAll(p, tctx, &r);
802 torture_assert_ntstatus_ok(tctx, status, "NetShareEnumAll failed");
803 torture_assert_werr_equal(tctx, r.out.result, expected, "NetShareEnumAll failed");
805 /* call srvsvc_NetShareGetInfo for each returned share */
806 if (info_ctr.level == 2 && r.out.info_ctr->ctr.ctr2) {
807 for (j=0;j<r.out.info_ctr->ctr.ctr2->count;j++) {
808 const char *name;
809 name = r.out.info_ctr->ctr.ctr2->array[j].name;
810 if (!test_NetShareGetInfo(tctx, p, name, admin)) {
811 return false;
817 return true;
820 static bool test_NetShareEnumAllFull(struct torture_context *tctx,
821 struct dcerpc_pipe *p)
823 return test_NetShareEnumAll(tctx, p, true);
826 static bool test_NetShareEnumAllAnon(struct torture_context *tctx,
827 struct dcerpc_pipe *p)
829 return test_NetShareEnumAll(tctx, p, false);
832 static bool test_NetShareEnum(struct torture_context *tctx,
833 struct dcerpc_pipe *p, bool admin)
835 NTSTATUS status;
836 struct srvsvc_NetShareEnum r;
837 struct srvsvc_NetShareInfoCtr info_ctr;
838 struct srvsvc_NetShareCtr0 c0;
839 struct srvsvc_NetShareCtr1 c1;
840 struct srvsvc_NetShareCtr2 c2;
841 struct srvsvc_NetShareCtr501 c501;
842 struct srvsvc_NetShareCtr502 c502;
843 uint32_t totalentries = 0;
844 struct {
845 uint32_t level;
846 WERROR anon_status;
847 WERROR admin_status;
848 } levels[] = {
849 { 0, WERR_OK, WERR_OK },
850 { 1, WERR_OK, WERR_OK },
851 { 2, WERR_ACCESS_DENIED, WERR_OK },
852 { 501, WERR_UNKNOWN_LEVEL, WERR_UNKNOWN_LEVEL },
853 { 502, WERR_ACCESS_DENIED, WERR_OK },
855 int i;
857 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
858 r.in.info_ctr = &info_ctr;
859 r.in.max_buffer = (uint32_t)-1;
860 r.in.resume_handle = NULL;
861 r.out.totalentries = &totalentries;
862 r.out.info_ctr = &info_ctr;
864 for (i=0;i<ARRAY_SIZE(levels);i++) {
865 WERROR expected;
867 info_ctr.level = levels[i].level;
869 switch (info_ctr.level) {
870 case 0:
871 ZERO_STRUCT(c0);
872 info_ctr.ctr.ctr0 = &c0;
873 break;
874 case 1:
875 ZERO_STRUCT(c1);
876 info_ctr.ctr.ctr1 = &c1;
877 break;
878 case 2:
879 ZERO_STRUCT(c2);
880 info_ctr.ctr.ctr2 = &c2;
881 break;
882 case 501:
883 ZERO_STRUCT(c501);
884 info_ctr.ctr.ctr501 = &c501;
885 break;
886 case 502:
887 ZERO_STRUCT(c502);
888 info_ctr.ctr.ctr502 = &c502;
889 break;
892 expected = levels[i].anon_status;
893 if (admin) expected = levels[i].admin_status;
895 torture_comment(tctx, "testing NetShareEnum level %u\n", info_ctr.level);
896 status = dcerpc_srvsvc_NetShareEnum(p, tctx, &r);
897 torture_assert_ntstatus_ok(tctx, status, "NetShareEnum failed");
898 torture_assert_werr_equal(tctx, r.out.result, expected, "NetShareEnum failed");
901 return true;
904 static bool test_NetShareEnumFull(struct torture_context *tctx,
905 struct dcerpc_pipe *p)
907 return test_NetShareEnum(tctx, p, true);
910 static bool test_NetShareEnumAnon(struct torture_context *tctx,
911 struct dcerpc_pipe *p)
913 return test_NetShareEnum(tctx, p, false);
916 /**************************/
917 /* srvsvc_NetSrv */
918 /**************************/
919 static bool test_NetSrvGetInfo(struct torture_context *tctx,
920 struct dcerpc_pipe *p)
922 NTSTATUS status;
923 struct srvsvc_NetSrvGetInfo r;
924 union srvsvc_NetSrvInfo info;
925 uint32_t levels[] = {100, 101, 102, 502, 503};
926 int i;
928 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
930 for (i=0;i<ARRAY_SIZE(levels);i++) {
931 r.in.level = levels[i];
932 r.out.info = &info;
933 torture_comment(tctx, "testing NetSrvGetInfo level %u\n", r.in.level);
934 status = dcerpc_srvsvc_NetSrvGetInfo(p, tctx, &r);
935 torture_assert_ntstatus_ok(tctx, status, "NetSrvGetInfo failed");
936 if (!W_ERROR_IS_OK(r.out.result)) {
937 torture_comment(tctx, "NetSrvGetInfo failed: %s\n", win_errstr(r.out.result));
941 return true;
944 /**************************/
945 /* srvsvc_NetDisk */
946 /**************************/
947 static bool test_NetDiskEnum(struct torture_context *tctx,
948 struct dcerpc_pipe *p)
950 NTSTATUS status;
951 struct srvsvc_NetDiskEnum r;
952 struct srvsvc_NetDiskInfo info;
953 uint32_t totalentries = 0;
954 uint32_t levels[] = {0};
955 int i;
956 uint32_t resume_handle=0;
958 ZERO_STRUCT(info);
960 r.in.server_unc = NULL;
961 r.in.resume_handle = &resume_handle;
962 r.in.info = &info;
963 r.out.info = &info;
964 r.out.totalentries = &totalentries;
965 r.out.resume_handle = &resume_handle;
967 for (i=0;i<ARRAY_SIZE(levels);i++) {
968 ZERO_STRUCTP(r.out.info);
969 r.in.level = levels[i];
970 torture_comment(tctx, "testing NetDiskEnum level %u\n", r.in.level);
971 status = dcerpc_srvsvc_NetDiskEnum(p, tctx, &r);
972 torture_assert_ntstatus_ok(tctx, status, "NetDiskEnum failed");
973 torture_assert_werr_ok(tctx, r.out.result, "NetDiskEnum failed");
976 return true;
979 /**************************/
980 /* srvsvc_NetTransport */
981 /**************************/
982 static bool test_NetTransportEnum(struct torture_context *tctx,
983 struct dcerpc_pipe *p)
985 NTSTATUS status;
986 struct srvsvc_NetTransportEnum r;
987 struct srvsvc_NetTransportInfoCtr transports;
988 struct srvsvc_NetTransportCtr0 ctr0;
989 struct srvsvc_NetTransportCtr1 ctr1;
991 uint32_t totalentries = 0;
992 uint32_t levels[] = {0, 1};
993 int i;
995 ZERO_STRUCT(transports);
997 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s", dcerpc_server_name(p));
998 r.in.transports = &transports;
999 r.in.max_buffer = (uint32_t)-1;
1000 r.in.resume_handle = NULL;
1001 r.out.totalentries = &totalentries;
1002 r.out.transports = &transports;
1004 for (i=0;i<ARRAY_SIZE(levels);i++) {
1005 transports.level = levels[i];
1006 switch (transports.level) {
1007 case 0:
1008 ZERO_STRUCT(ctr0);
1009 transports.ctr.ctr0 = &ctr0;
1010 break;
1011 case 1:
1012 ZERO_STRUCT(ctr1);
1013 transports.ctr.ctr1 = &ctr1;
1014 break;
1016 torture_comment(tctx, "testing NetTransportEnum level %u\n", transports.level);
1017 status = dcerpc_srvsvc_NetTransportEnum(p, tctx, &r);
1018 torture_assert_ntstatus_ok(tctx, status, "NetTransportEnum failed");
1019 if (!W_ERROR_IS_OK(r.out.result)) {
1020 torture_comment(tctx, "unexpected result: %s\n", win_errstr(r.out.result));
1024 return true;
1027 /**************************/
1028 /* srvsvc_NetRemoteTOD */
1029 /**************************/
1030 static bool test_NetRemoteTOD(struct torture_context *tctx,
1031 struct dcerpc_pipe *p)
1033 NTSTATUS status;
1034 struct srvsvc_NetRemoteTOD r;
1035 struct srvsvc_NetRemoteTODInfo *info = NULL;
1037 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
1038 r.out.info = &info;
1040 torture_comment(tctx, "testing NetRemoteTOD\n");
1041 status = dcerpc_srvsvc_NetRemoteTOD(p, tctx, &r);
1042 torture_assert_ntstatus_ok(tctx, status, "NetRemoteTOD failed");
1043 torture_assert_werr_ok(tctx, r.out.result, "NetRemoteTOD failed");
1045 return true;
1048 /**************************/
1049 /* srvsvc_NetName */
1050 /**************************/
1052 static bool test_NetNameValidate(struct torture_context *tctx,
1053 struct dcerpc_pipe *p)
1055 NTSTATUS status;
1056 struct srvsvc_NetNameValidate r;
1057 char *invalidc;
1058 char *name;
1059 int i, n, min, max;
1061 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1062 r.in.flags = 0x0;
1064 d_printf("testing NetNameValidate\n");
1066 /* valid path types only between 1 and 13 */
1067 for (i = 1; i < 14; i++) {
1069 again:
1070 /* let's limit ourselves to a maximum of 4096 bytes */
1071 r.in.name = name = talloc_array(tctx, char, 4097);
1072 max = 4096;
1073 min = 0;
1074 n = max;
1076 while (1) {
1078 /* Find maximum length accepted by this type */
1079 ZERO_STRUCT(r.out);
1080 r.in.name_type = i;
1081 memset(name, 'A', n);
1082 name[n] = '\0';
1084 status = dcerpc_srvsvc_NetNameValidate(p, tctx, &r);
1085 if (!NT_STATUS_IS_OK(status)) {
1086 d_printf("NetNameValidate failed while checking maximum size (%s)\n",
1087 nt_errstr(status));
1088 break;
1091 if (W_ERROR_IS_OK(r.out.result)) {
1092 min = n;
1093 n += (max - min + 1)/2;
1094 continue;
1096 } else {
1097 if ((min + 1) >= max) break; /* found it */
1099 max = n;
1100 n -= (max - min)/2;
1101 continue;
1105 talloc_free(name);
1107 d_printf("Maximum length for type %2d, flags %08x: %d\n", i, r.in.flags, max);
1109 /* find invalid chars for this type check only ASCII between 0x20 and 0x7e */
1111 invalidc = talloc_strdup(tctx, "");
1113 for (n = 0x20; n < 0x7e; n++) {
1114 r.in.name = name = talloc_asprintf(tctx, "%c", (char)n);
1116 status = dcerpc_srvsvc_NetNameValidate(p, tctx, &r);
1117 if (!NT_STATUS_IS_OK(status)) {
1118 d_printf("NetNameValidate failed while checking valid chars (%s)\n",
1119 nt_errstr(status));
1120 break;
1123 if (!W_ERROR_IS_OK(r.out.result)) {
1124 invalidc = talloc_asprintf_append_buffer(invalidc, "%c", (char)n);
1127 talloc_free(name);
1130 d_printf(" Invalid chars for type %2d, flags %08x: \"%s\"\n", i, r.in.flags, invalidc);
1132 /* only two values are accepted for flags: 0x0 and 0x80000000 */
1133 if (r.in.flags == 0x0) {
1134 r.in.flags = 0x80000000;
1135 goto again;
1138 r.in.flags = 0x0;
1141 return true;
1144 struct torture_suite *torture_rpc_srvsvc(TALLOC_CTX *mem_ctx)
1146 struct torture_suite *suite = torture_suite_create(mem_ctx, "SRVSVC");
1147 struct torture_rpc_tcase *tcase;
1148 struct torture_test *test;
1150 tcase = torture_suite_add_rpc_iface_tcase(suite, "srvsvc (admin access)", &ndr_table_srvsvc);
1152 torture_rpc_tcase_add_test(tcase, "NetCharDevEnum", test_NetCharDevEnum);
1153 torture_rpc_tcase_add_test(tcase, "NetCharDevQEnum", test_NetCharDevQEnum);
1154 torture_rpc_tcase_add_test(tcase, "NetConnEnum", test_NetConnEnum);
1155 torture_rpc_tcase_add_test(tcase, "NetFileEnum", test_NetFileEnum);
1156 torture_rpc_tcase_add_test(tcase, "NetSessEnum", test_NetSessEnum);
1157 torture_rpc_tcase_add_test(tcase, "NetShareEnumAll", test_NetShareEnumAllFull);
1158 torture_rpc_tcase_add_test(tcase, "NetSrvGetInfo", test_NetSrvGetInfo);
1159 torture_rpc_tcase_add_test(tcase, "NetDiskEnum", test_NetDiskEnum);
1160 torture_rpc_tcase_add_test(tcase, "NetTransportEnum", test_NetTransportEnum);
1161 torture_rpc_tcase_add_test(tcase, "NetRemoteTOD", test_NetRemoteTOD);
1162 torture_rpc_tcase_add_test(tcase, "NetShareEnum", test_NetShareEnumFull);
1163 torture_rpc_tcase_add_test(tcase, "NetShareGetInfo", test_NetShareGetInfoAdminFull);
1164 test = torture_rpc_tcase_add_test(tcase, "NetShareAddSetDel",
1165 test_NetShareAddSetDel);
1166 test->dangerous = true;
1167 torture_rpc_tcase_add_test(tcase, "NetNameValidate", test_NetNameValidate);
1169 tcase = torture_suite_add_anon_rpc_iface_tcase(suite,
1170 "srvsvc anonymous access",
1171 &ndr_table_srvsvc);
1173 torture_rpc_tcase_add_test(tcase, "NetShareEnumAll",
1174 test_NetShareEnumAllAnon);
1175 torture_rpc_tcase_add_test(tcase, "NetShareEnum",
1176 test_NetShareEnumAnon);
1177 torture_rpc_tcase_add_test(tcase, "NetShareGetInfo",
1178 test_NetShareGetInfoAdminAnon);
1180 return suite;