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 "librpc/gen_ndr/ndr_srvsvc_c.h"
23 #include "torture/rpc/torture_rpc.h"
25 /**************************/
26 /* srvsvc_NetCharDev */
27 /**************************/
28 static bool test_NetCharDevGetInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
32 struct srvsvc_NetCharDevGetInfo r
;
33 union srvsvc_NetCharDevInfo info
;
34 uint32_t levels
[] = {0, 1};
36 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
38 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
39 r
.in
.device_name
= devname
;
42 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
43 r
.in
.level
= levels
[i
];
44 torture_comment(tctx
, "Testing NetCharDevGetInfo level %u on device '%s'\n",
45 r
.in
.level
, r
.in
.device_name
);
46 status
= dcerpc_srvsvc_NetCharDevGetInfo_r(b
, tctx
, &r
);
47 torture_assert_ntstatus_ok(tctx
, status
, "NetCharDevGetInfo failed");
48 torture_assert_werr_ok(tctx
, r
.out
.result
, "NetCharDevGetInfo failed");
54 static bool test_NetCharDevControl(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
58 struct srvsvc_NetCharDevControl r
;
59 uint32_t opcodes
[] = {0, 1};
61 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
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_r(b
, 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};
90 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
92 ZERO_STRUCT(info_ctr
);
94 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
95 r
.in
.info_ctr
= &info_ctr
;
96 r
.in
.max_buffer
= (uint32_t)-1;
97 r
.in
.resume_handle
= NULL
;
98 r
.out
.info_ctr
= &info_ctr
;
99 r
.out
.totalentries
= &totalentries
;
101 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
104 info_ctr
.level
= levels
[i
];
106 switch(info_ctr
.level
) {
109 info_ctr
.ctr
.ctr0
= &c0
;
113 info_ctr
.ctr
.ctr0
= &c1
;
117 torture_comment(tctx
, "Testing NetCharDevEnum level %u\n", info_ctr
.level
);
118 status
= dcerpc_srvsvc_NetCharDevEnum_r(b
, tctx
, &r
);
119 torture_assert_ntstatus_ok(tctx
, status
, "NetCharDevEnum failed");
120 if (!W_ERROR_IS_OK(r
.out
.result
)) {
121 torture_comment(tctx
, "NetCharDevEnum failed: %s\n", win_errstr(r
.out
.result
));
125 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */
126 if (info_ctr
.level
== 1) {
127 for (j
=0;j
<r
.out
.info_ctr
->ctr
.ctr1
->count
;j
++) {
129 device
= r
.out
.info_ctr
->ctr
.ctr1
->array
[j
].device
;
130 if (!test_NetCharDevGetInfo(p
, tctx
, device
)) {
133 if (!test_NetCharDevControl(p
, tctx
, device
)) {
143 /**************************/
144 /* srvsvc_NetCharDevQ */
145 /**************************/
146 static bool test_NetCharDevQGetInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
147 const char *devicequeue
)
150 struct srvsvc_NetCharDevQGetInfo r
;
151 union srvsvc_NetCharDevQInfo info
;
152 uint32_t levels
[] = {0, 1};
154 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
156 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
157 r
.in
.queue_name
= devicequeue
;
158 r
.in
.user
= talloc_asprintf(tctx
,"Administrator");
161 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
162 r
.in
.level
= levels
[i
];
163 torture_comment(tctx
, "Testing NetCharDevQGetInfo level %u on devicequeue '%s'\n",
164 r
.in
.level
, r
.in
.queue_name
);
165 status
= dcerpc_srvsvc_NetCharDevQGetInfo_r(b
, tctx
, &r
);
166 torture_assert_ntstatus_ok(tctx
, status
, "NetCharDevQGetInfo failed");
167 torture_assert_werr_ok(tctx
, r
.out
.result
, "NetCharDevQGetInfo failed");
174 static bool test_NetCharDevQSetInfo(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
175 const char *devicequeue
)
178 struct srvsvc_NetCharDevQSetInfo r
;
180 uint32_t levels
[] = {0, 1};
183 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
185 r
.in
.server_unc
= talloc_asprintf(mem_ctx
,"\\\\%s",dcerpc_server_name(p
));
186 r
.in
.queue_name
= devicequeue
;
188 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
191 r
.in
.level
= levels
[i
];
192 d_printf("testing NetCharDevQSetInfo level %u on devicequeue '%s'\n",
193 r
.in
.level
, devicequeue
);
194 switch (r
.in
.level
) {
196 r
.in
.info
.info0
= talloc(mem_ctx
, struct srvsvc_NetCharDevQInfo0
);
197 r
.in
.info
.info0
->device
= r
.in
.queue_name
;
200 r
.in
.info
.info1
= talloc(mem_ctx
, struct srvsvc_NetCharDevQInfo1
);
201 r
.in
.info
.info1
->device
= r
.in
.queue_name
;
202 r
.in
.info
.info1
->priority
= 0x000;
203 r
.in
.info
.info1
->devices
= r
.in
.queue_name
;
204 r
.in
.info
.info1
->users
= 0x000;
205 r
.in
.info
.info1
->num_ahead
= 0x000;
210 r
.in
.parm_error
= &parm_error
;
211 status
= dcerpc_srvsvc_NetCharDevQSetInfo_r(b
, mem_ctx
, &r
);
212 if (!NT_STATUS_IS_OK(status
)) {
213 d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n",
214 r
.in
.level
, r
.in
.queue_name
, nt_errstr(status
));
218 if (!W_ERROR_IS_OK(r
.out
.result
)) {
219 d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n",
220 r
.in
.level
, r
.in
.queue_name
, win_errstr(r
.out
.result
));
229 static bool test_NetCharDevQEnum(struct torture_context
*tctx
,
230 struct dcerpc_pipe
*p
)
233 struct srvsvc_NetCharDevQEnum r
;
234 struct srvsvc_NetCharDevQInfoCtr info_ctr
;
235 struct srvsvc_NetCharDevQCtr0 c0
;
236 struct srvsvc_NetCharDevQCtr1 c1
;
237 uint32_t totalentries
= 0;
238 uint32_t levels
[] = {0, 1};
240 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
242 ZERO_STRUCT(info_ctr
);
244 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
245 r
.in
.user
= talloc_asprintf(tctx
,"%s","Administrator");
246 r
.in
.info_ctr
= &info_ctr
;
247 r
.in
.max_buffer
= (uint32_t)-1;
248 r
.in
.resume_handle
= NULL
;
249 r
.out
.totalentries
= &totalentries
;
250 r
.out
.info_ctr
= &info_ctr
;
252 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
255 info_ctr
.level
= levels
[i
];
257 switch (info_ctr
.level
) {
260 info_ctr
.ctr
.ctr0
= &c0
;
264 info_ctr
.ctr
.ctr1
= &c1
;
267 torture_comment(tctx
, "Testing NetCharDevQEnum level %u\n", info_ctr
.level
);
268 status
= dcerpc_srvsvc_NetCharDevQEnum_r(b
, tctx
, &r
);
269 torture_assert_ntstatus_ok(tctx
, status
, "NetCharDevQEnum failed");
270 if (!W_ERROR_IS_OK(r
.out
.result
)) {
271 torture_comment(tctx
, "NetCharDevQEnum failed: %s\n", win_errstr(r
.out
.result
));
275 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */
276 if (info_ctr
.level
== 1) {
277 for (j
=0;j
<r
.out
.info_ctr
->ctr
.ctr1
->count
;j
++) {
279 device
= r
.out
.info_ctr
->ctr
.ctr1
->array
[j
].device
;
280 if (!test_NetCharDevQGetInfo(p
, tctx
, device
)) {
290 /**************************/
292 /**************************/
293 static bool test_NetConnEnum(struct torture_context
*tctx
,
294 struct dcerpc_pipe
*p
)
297 struct srvsvc_NetConnEnum r
;
298 struct srvsvc_NetConnInfoCtr info_ctr
;
299 struct srvsvc_NetConnCtr0 c0
;
300 struct srvsvc_NetConnCtr1 c1
;
301 uint32_t totalentries
= 0;
302 uint32_t levels
[] = {0, 1};
304 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
306 ZERO_STRUCT(info_ctr
);
308 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
309 r
.in
.path
= talloc_asprintf(tctx
,"%s","IPC$");
310 r
.in
.info_ctr
= &info_ctr
;
311 r
.in
.max_buffer
= (uint32_t)-1;
312 r
.in
.resume_handle
= NULL
;
313 r
.out
.totalentries
= &totalentries
;
314 r
.out
.info_ctr
= &info_ctr
;
316 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
317 info_ctr
.level
= levels
[i
];
319 switch (info_ctr
.level
) {
322 info_ctr
.ctr
.ctr0
= &c0
;
326 info_ctr
.ctr
.ctr1
= &c1
;
330 torture_comment(tctx
, "Testing NetConnEnum level %u\n", info_ctr
.level
);
331 status
= dcerpc_srvsvc_NetConnEnum_r(b
, tctx
, &r
);
332 torture_assert_ntstatus_ok(tctx
, status
, "NetConnEnum failed");
333 if (!W_ERROR_IS_OK(r
.out
.result
)) {
334 torture_comment(tctx
, "NetConnEnum failed: %s\n", win_errstr(r
.out
.result
));
341 /**************************/
343 /**************************/
344 static bool test_NetFileEnum(struct torture_context
*tctx
,
345 struct dcerpc_pipe
*p
)
348 struct srvsvc_NetFileEnum r
;
349 struct srvsvc_NetFileInfoCtr info_ctr
;
350 struct srvsvc_NetFileCtr2 c2
;
351 struct srvsvc_NetFileCtr3 c3
;
352 uint32_t totalentries
= 0;
353 uint32_t levels
[] = {2, 3};
355 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
357 ZERO_STRUCT(info_ctr
);
359 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
362 r
.in
.info_ctr
= &info_ctr
;
363 r
.in
.max_buffer
= (uint32_t)4096;
364 r
.in
.resume_handle
= NULL
;
365 r
.out
.totalentries
= &totalentries
;
366 r
.out
.info_ctr
= &info_ctr
;
368 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
369 info_ctr
.level
= levels
[i
];
371 switch (info_ctr
.level
) {
374 info_ctr
.ctr
.ctr2
= &c2
;
378 info_ctr
.ctr
.ctr3
= &c3
;
381 torture_comment(tctx
, "Testing NetFileEnum level %u\n", info_ctr
.level
);
382 status
= dcerpc_srvsvc_NetFileEnum_r(b
, tctx
, &r
);
383 torture_assert_ntstatus_ok(tctx
, status
, "NetFileEnum failed");
384 if (!W_ERROR_IS_OK(r
.out
.result
)) {
385 torture_comment(tctx
, "NetFileEnum failed: %s\n", win_errstr(r
.out
.result
));
392 /**************************/
394 /**************************/
395 static bool test_NetSessEnum(struct torture_context
*tctx
,
396 struct dcerpc_pipe
*p
)
399 struct srvsvc_NetSessEnum r
;
400 struct srvsvc_NetSessInfoCtr info_ctr
;
401 struct srvsvc_NetSessCtr0 c0
;
402 struct srvsvc_NetSessCtr1 c1
;
403 struct srvsvc_NetSessCtr2 c2
;
404 struct srvsvc_NetSessCtr10 c10
;
405 struct srvsvc_NetSessCtr502 c502
;
406 uint32_t totalentries
= 0;
407 uint32_t levels
[] = {0, 1, 2, 10, 502};
409 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
411 ZERO_STRUCT(info_ctr
);
413 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
416 r
.in
.info_ctr
= &info_ctr
;
417 r
.in
.max_buffer
= (uint32_t)-1;
418 r
.in
.resume_handle
= NULL
;
419 r
.out
.totalentries
= &totalentries
;
420 r
.out
.info_ctr
= &info_ctr
;
422 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
423 info_ctr
.level
= levels
[i
];
425 switch (info_ctr
.level
) {
428 info_ctr
.ctr
.ctr0
= &c0
;
432 info_ctr
.ctr
.ctr1
= &c1
;
436 info_ctr
.ctr
.ctr2
= &c2
;
440 info_ctr
.ctr
.ctr10
= &c10
;
444 info_ctr
.ctr
.ctr502
= &c502
;
448 torture_comment(tctx
, "Testing NetSessEnum level %u\n", info_ctr
.level
);
449 status
= dcerpc_srvsvc_NetSessEnum_r(b
, tctx
, &r
);
450 torture_assert_ntstatus_ok(tctx
, status
, "NetSessEnum failed");
451 if (!W_ERROR_IS_OK(r
.out
.result
)) {
452 torture_comment(tctx
, "NetSessEnum failed: %s\n", win_errstr(r
.out
.result
));
459 /**************************/
460 /* srvsvc_NetShare */
461 /**************************/
462 static bool test_NetShareCheck(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
463 const char *device_name
)
466 struct srvsvc_NetShareCheck r
;
467 enum srvsvc_ShareType type
;
468 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
470 r
.in
.server_unc
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
471 r
.in
.device_name
= device_name
;
474 torture_comment(tctx
,
475 "Testing NetShareCheck on device '%s'\n", r
.in
.device_name
);
477 status
= dcerpc_srvsvc_NetShareCheck_r(b
, tctx
, &r
);
478 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_srvsvc_NetShareCheck failed");
479 torture_assert_werr_ok(tctx
, r
.out
.result
, "NetShareCheck failed");
484 static bool test_NetShareGetInfo(struct torture_context
*tctx
,
485 struct dcerpc_pipe
*p
,
486 const char *sharename
, bool admin
)
489 struct srvsvc_NetShareGetInfo r
;
490 union srvsvc_NetShareInfo info
;
496 { 0, WERR_OK
, WERR_OK
},
497 { 1, WERR_OK
, WERR_OK
},
498 { 2, WERR_ACCESS_DENIED
, WERR_OK
},
499 { 501, WERR_OK
, WERR_OK
},
500 { 502, WERR_ACCESS_DENIED
, WERR_OK
},
501 { 1005, WERR_OK
, WERR_OK
},
504 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
506 r
.in
.server_unc
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
507 r
.in
.share_name
= sharename
;
510 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
513 r
.in
.level
= levels
[i
].level
;
514 expected
= levels
[i
].anon_status
;
515 if (admin
) expected
= levels
[i
].admin_status
;
517 torture_comment(tctx
, "Testing NetShareGetInfo level %u on share '%s'\n",
518 r
.in
.level
, r
.in
.share_name
);
520 status
= dcerpc_srvsvc_NetShareGetInfo_r(b
, tctx
, &r
);
521 torture_assert_ntstatus_ok(tctx
, status
, "NetShareGetInfo failed");
522 torture_assert_werr_equal(tctx
, r
.out
.result
, expected
, "NetShareGetInfo failed");
524 if (r
.in
.level
!= 2) continue;
525 if (!r
.out
.info
->info2
|| !r
.out
.info
->info2
->path
) continue;
526 if (!test_NetShareCheck(p
, tctx
, r
.out
.info
->info2
->path
)) {
534 static bool test_NetShareGetInfoAdminFull(struct torture_context
*tctx
,
535 struct dcerpc_pipe
*p
)
537 return test_NetShareGetInfo(tctx
, p
, "IPC$", true);
540 static bool test_NetShareGetInfoAdminAnon(struct torture_context
*tctx
,
541 struct dcerpc_pipe
*p
)
543 return test_NetShareGetInfo(tctx
, p
, "IPC$", false);
546 static bool test_NetShareAddSetDel(struct torture_context
*tctx
,
547 struct dcerpc_pipe
*p
)
550 struct srvsvc_NetShareAdd a
;
551 struct srvsvc_NetShareSetInfo r
;
552 struct srvsvc_NetShareGetInfo q
;
553 struct srvsvc_NetShareDel d
;
554 struct sec_desc_buf sd_buf
;
555 union srvsvc_NetShareInfo info
;
560 { 0, WERR_UNKNOWN_LEVEL
},
563 { 501, WERR_UNKNOWN_LEVEL
},
568 /* { 1007, WERR_OK }, */
572 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
574 a
.in
.server_unc
= r
.in
.server_unc
= q
.in
.server_unc
= d
.in
.server_unc
=
575 talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
576 r
.in
.share_name
= talloc_strdup(tctx
, "testshare");
578 info
.info2
= talloc(tctx
, struct srvsvc_NetShareInfo2
);
579 info
.info2
->name
= r
.in
.share_name
;
580 info
.info2
->type
= STYPE_DISKTREE
;
581 info
.info2
->comment
= talloc_strdup(tctx
, "test comment");
582 info
.info2
->permissions
= 123434566;
583 info
.info2
->max_users
= -1;
584 info
.info2
->current_users
= 0;
585 info
.info2
->path
= talloc_strdup(tctx
, "C:\\");
586 info
.info2
->password
= NULL
;
590 a
.in
.parm_error
= NULL
;
592 status
= dcerpc_srvsvc_NetShareAdd_r(b
, tctx
, &a
);
593 torture_assert_ntstatus_ok(tctx
, status
, "NetShareAdd level 2 on share 'testshare' failed");
594 torture_assert_werr_ok(tctx
, a
.out
.result
, "NetShareAdd level 2 on share 'testshare' failed");
596 r
.in
.parm_error
= NULL
;
600 for (i
= 0; i
< ARRAY_SIZE(levels
); i
++) {
602 r
.in
.level
= levels
[i
].level
;
605 torture_comment(tctx
, "Testing NetShareSetInfo level %u on share '%s'\n",
606 r
.in
.level
, r
.in
.share_name
);
608 switch (levels
[i
].level
) {
610 info
.info0
= talloc(tctx
, struct srvsvc_NetShareInfo0
);
611 info
.info0
->name
= r
.in
.share_name
;
614 info
.info1
= talloc(tctx
, struct srvsvc_NetShareInfo1
);
615 info
.info1
->name
= r
.in
.share_name
;
616 info
.info1
->type
= STYPE_DISKTREE
;
617 info
.info1
->comment
= talloc_strdup(tctx
, "test comment 1");
620 info
.info2
= talloc(tctx
, struct srvsvc_NetShareInfo2
);
621 info
.info2
->name
= r
.in
.share_name
;
622 info
.info2
->type
= STYPE_DISKTREE
;
623 info
.info2
->comment
= talloc_strdup(tctx
, "test comment 2");
624 info
.info2
->permissions
= 0;
625 info
.info2
->max_users
= 2;
626 info
.info2
->current_users
= 1;
627 info
.info2
->path
= talloc_strdup(tctx
, "::BLaH::"); /* "C:\\"); */
628 info
.info2
->password
= NULL
;
631 info
.info501
= talloc(tctx
, struct srvsvc_NetShareInfo501
);
632 info
.info501
->name
= r
.in
.share_name
;
633 info
.info501
->type
= STYPE_DISKTREE
;
634 info
.info501
->comment
= talloc_strdup(tctx
, "test comment 501");
635 info
.info501
->csc_policy
= 0;
639 info
.info502
= talloc(tctx
, struct srvsvc_NetShareInfo502
);
640 info
.info502
->name
= r
.in
.share_name
;
641 info
.info502
->type
= STYPE_DISKTREE
;
642 info
.info502
->comment
= talloc_strdup(tctx
, "test comment 502");
643 info
.info502
->permissions
= 0;
644 info
.info502
->max_users
= 502;
645 info
.info502
->current_users
= 1;
646 info
.info502
->path
= talloc_strdup(tctx
, "C:\\");
647 info
.info502
->password
= NULL
;
648 info
.info502
->sd_buf
= sd_buf
;
651 info
.info1004
= talloc(tctx
, struct srvsvc_NetShareInfo1004
);
652 info
.info1004
->comment
= talloc_strdup(tctx
, "test comment 1004");
655 info
.info1005
= talloc(tctx
, struct srvsvc_NetShareInfo1005
);
656 info
.info1005
->dfs_flags
= 0;
659 info
.info1006
= talloc(tctx
, struct srvsvc_NetShareInfo1006
);
660 info
.info1006
->max_users
= 1006;
663 info.info1007 = talloc(tctx, struct srvsvc_NetShareInfo1007);
664 info.info1007->flags = 0;
665 info.info1007->alternate_directory_name = talloc_strdup(tctx, "test");
669 info
.info1501
= talloc_zero(tctx
, struct sec_desc_buf
);
675 status
= dcerpc_srvsvc_NetShareSetInfo_r(b
, tctx
, &r
);
676 torture_assert_ntstatus_ok(tctx
, status
, "NetShareGetInfo failed");
677 torture_assert_werr_equal(tctx
, r
.out
.result
, levels
[i
].expected
, "NetShareSetInfo failed");
679 q
.in
.share_name
= r
.in
.share_name
;
682 status
= dcerpc_srvsvc_NetShareGetInfo_r(b
, tctx
, &q
);
683 torture_assert_ntstatus_ok(tctx
, status
, "NetShareGetInfo failed");
684 torture_assert_werr_ok(tctx
, q
.out
.result
, "NetShareGetInfo failed");
686 torture_assert_str_equal(tctx
, q
.out
.info
->info502
->name
, r
.in
.share_name
,
687 "share name invalid");
689 switch (levels
[i
].level
) {
693 torture_assert_str_equal(tctx
, q
.out
.info
->info502
->comment
, "test comment 1", "comment");
696 torture_assert_str_equal(tctx
, q
.out
.info
->info2
->comment
, "test comment 2", "comment");
697 torture_assert_int_equal(tctx
, q
.out
.info
->info2
->max_users
, 2, "max users");
698 torture_assert_str_equal(tctx
, q
.out
.info
->info2
->path
, "C:\\", "path");
701 torture_assert_str_equal(tctx
, q
.out
.info
->info501
->comment
, "test comment 501", "comment");
704 torture_assert_str_equal(tctx
, q
.out
.info
->info502
->comment
, "test comment 502", "comment");
705 torture_assert_int_equal(tctx
, q
.out
.info
->info502
->max_users
, 502, "max users");
706 torture_assert_str_equal(tctx
, q
.out
.info
->info502
->path
, "C:\\", "path");
709 torture_assert_str_equal(tctx
, q
.out
.info
->info1004
->comment
, "test comment 1004",
715 torture_assert_int_equal(tctx
, q
.out
.info
->info1006
->max_users
, 1006, "Max users");
725 d
.in
.share_name
= r
.in
.share_name
;
728 status
= dcerpc_srvsvc_NetShareDel_r(b
, tctx
, &d
);
729 torture_assert_ntstatus_ok(tctx
, status
, "NetShareDel on share 'testshare502' failed");
730 torture_assert_werr_ok(tctx
, a
.out
.result
, "NetShareDel on share 'testshare502' failed");
735 /**************************/
736 /* srvsvc_NetShare */
737 /**************************/
738 static bool test_NetShareEnumAll(struct torture_context
*tctx
,
739 struct dcerpc_pipe
*p
,
743 struct srvsvc_NetShareEnumAll r
;
744 struct srvsvc_NetShareInfoCtr info_ctr
;
745 struct srvsvc_NetShareCtr0 c0
;
746 struct srvsvc_NetShareCtr1 c1
;
747 struct srvsvc_NetShareCtr2 c2
;
748 struct srvsvc_NetShareCtr501 c501
;
749 struct srvsvc_NetShareCtr502 c502
;
750 uint32_t totalentries
= 0;
756 { 0, WERR_OK
, WERR_OK
},
757 { 1, WERR_OK
, WERR_OK
},
758 { 2, WERR_ACCESS_DENIED
, WERR_OK
},
759 { 501, WERR_ACCESS_DENIED
, WERR_OK
},
760 { 502, WERR_ACCESS_DENIED
, WERR_OK
},
763 uint32_t resume_handle
;
764 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
766 ZERO_STRUCT(info_ctr
);
768 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
769 r
.in
.info_ctr
= &info_ctr
;
770 r
.in
.max_buffer
= (uint32_t)-1;
771 r
.in
.resume_handle
= &resume_handle
;
772 r
.out
.resume_handle
= &resume_handle
;
773 r
.out
.totalentries
= &totalentries
;
774 r
.out
.info_ctr
= &info_ctr
;
776 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
781 info_ctr
.level
= levels
[i
].level
;
783 switch (info_ctr
.level
) {
786 info_ctr
.ctr
.ctr0
= &c0
;
790 info_ctr
.ctr
.ctr1
= &c1
;
794 info_ctr
.ctr
.ctr2
= &c2
;
798 info_ctr
.ctr
.ctr501
= &c501
;
802 info_ctr
.ctr
.ctr502
= &c502
;
806 expected
= levels
[i
].anon_status
;
807 if (admin
) expected
= levels
[i
].admin_status
;
811 torture_comment(tctx
, "Testing NetShareEnumAll level %u\n", info_ctr
.level
);
812 status
= dcerpc_srvsvc_NetShareEnumAll_r(b
, tctx
, &r
);
813 torture_assert_ntstatus_ok(tctx
, status
, "NetShareEnumAll failed");
814 torture_assert_werr_equal(tctx
, r
.out
.result
, expected
, "NetShareEnumAll failed");
816 /* call srvsvc_NetShareGetInfo for each returned share */
817 if (info_ctr
.level
== 2 && r
.out
.info_ctr
->ctr
.ctr2
) {
818 for (j
=0;j
<r
.out
.info_ctr
->ctr
.ctr2
->count
;j
++) {
820 name
= r
.out
.info_ctr
->ctr
.ctr2
->array
[j
].name
;
821 if (!test_NetShareGetInfo(tctx
, p
, name
, admin
)) {
831 static bool test_NetShareEnumAllFull(struct torture_context
*tctx
,
832 struct dcerpc_pipe
*p
)
834 return test_NetShareEnumAll(tctx
, p
, true);
837 static bool test_NetShareEnumAllAnon(struct torture_context
*tctx
,
838 struct dcerpc_pipe
*p
)
840 return test_NetShareEnumAll(tctx
, p
, false);
843 static bool test_NetShareEnum(struct torture_context
*tctx
,
844 struct dcerpc_pipe
*p
, bool admin
)
847 struct srvsvc_NetShareEnum r
;
848 struct srvsvc_NetShareInfoCtr info_ctr
;
849 struct srvsvc_NetShareCtr0 c0
;
850 struct srvsvc_NetShareCtr1 c1
;
851 struct srvsvc_NetShareCtr2 c2
;
852 struct srvsvc_NetShareCtr501 c501
;
853 struct srvsvc_NetShareCtr502 c502
;
854 uint32_t totalentries
= 0;
860 { 0, WERR_OK
, WERR_OK
},
861 { 1, WERR_OK
, WERR_OK
},
862 { 2, WERR_ACCESS_DENIED
, WERR_OK
},
863 { 501, WERR_UNKNOWN_LEVEL
, WERR_UNKNOWN_LEVEL
},
864 { 502, WERR_ACCESS_DENIED
, WERR_OK
},
867 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
869 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
870 r
.in
.info_ctr
= &info_ctr
;
871 r
.in
.max_buffer
= (uint32_t)-1;
872 r
.in
.resume_handle
= NULL
;
873 r
.out
.totalentries
= &totalentries
;
874 r
.out
.info_ctr
= &info_ctr
;
876 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
879 info_ctr
.level
= levels
[i
].level
;
881 switch (info_ctr
.level
) {
884 info_ctr
.ctr
.ctr0
= &c0
;
888 info_ctr
.ctr
.ctr1
= &c1
;
892 info_ctr
.ctr
.ctr2
= &c2
;
896 info_ctr
.ctr
.ctr501
= &c501
;
900 info_ctr
.ctr
.ctr502
= &c502
;
904 expected
= levels
[i
].anon_status
;
905 if (admin
) expected
= levels
[i
].admin_status
;
907 torture_comment(tctx
, "Testing NetShareEnum level %u\n", info_ctr
.level
);
908 status
= dcerpc_srvsvc_NetShareEnum_r(b
, tctx
, &r
);
909 torture_assert_ntstatus_ok(tctx
, status
, "NetShareEnum failed");
910 torture_assert_werr_equal(tctx
, r
.out
.result
, expected
, "NetShareEnum failed");
916 static bool test_NetShareEnumFull(struct torture_context
*tctx
,
917 struct dcerpc_pipe
*p
)
919 return test_NetShareEnum(tctx
, p
, true);
922 static bool test_NetShareEnumAnon(struct torture_context
*tctx
,
923 struct dcerpc_pipe
*p
)
925 return test_NetShareEnum(tctx
, p
, false);
928 /**************************/
930 /**************************/
931 static bool test_NetSrvGetInfo(struct torture_context
*tctx
,
932 struct dcerpc_pipe
*p
)
935 struct srvsvc_NetSrvGetInfo r
;
936 union srvsvc_NetSrvInfo info
;
937 uint32_t levels
[] = {100, 101, 102, 502, 503};
939 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
941 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
943 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
944 r
.in
.level
= levels
[i
];
946 torture_comment(tctx
, "Testing NetSrvGetInfo level %u\n", r
.in
.level
);
947 status
= dcerpc_srvsvc_NetSrvGetInfo_r(b
, tctx
, &r
);
948 torture_assert_ntstatus_ok(tctx
, status
, "NetSrvGetInfo failed");
949 if (!W_ERROR_IS_OK(r
.out
.result
)) {
950 torture_comment(tctx
, "NetSrvGetInfo failed: %s\n", win_errstr(r
.out
.result
));
957 /**************************/
959 /**************************/
960 static bool test_NetDiskEnum(struct torture_context
*tctx
,
961 struct dcerpc_pipe
*p
)
964 struct srvsvc_NetDiskEnum r
;
965 struct srvsvc_NetDiskInfo info
;
966 uint32_t totalentries
= 0;
967 uint32_t levels
[] = {0};
969 uint32_t resume_handle
=0;
970 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
974 r
.in
.server_unc
= NULL
;
975 r
.in
.resume_handle
= &resume_handle
;
978 r
.out
.totalentries
= &totalentries
;
979 r
.out
.resume_handle
= &resume_handle
;
981 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
982 ZERO_STRUCTP(r
.out
.info
);
983 r
.in
.level
= levels
[i
];
984 torture_comment(tctx
, "Testing NetDiskEnum level %u\n", r
.in
.level
);
985 status
= dcerpc_srvsvc_NetDiskEnum_r(b
, tctx
, &r
);
986 torture_assert_ntstatus_ok(tctx
, status
, "NetDiskEnum failed");
987 torture_assert_werr_ok(tctx
, r
.out
.result
, "NetDiskEnum failed");
993 /**************************/
994 /* srvsvc_NetTransport */
995 /**************************/
996 static bool test_NetTransportEnum(struct torture_context
*tctx
,
997 struct dcerpc_pipe
*p
)
1000 struct srvsvc_NetTransportEnum r
;
1001 struct srvsvc_NetTransportInfoCtr transports
;
1002 struct srvsvc_NetTransportCtr0 ctr0
;
1003 struct srvsvc_NetTransportCtr1 ctr1
;
1005 uint32_t totalentries
= 0;
1006 uint32_t levels
[] = {0, 1};
1008 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1010 ZERO_STRUCT(transports
);
1012 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s", dcerpc_server_name(p
));
1013 r
.in
.transports
= &transports
;
1014 r
.in
.max_buffer
= (uint32_t)-1;
1015 r
.in
.resume_handle
= NULL
;
1016 r
.out
.totalentries
= &totalentries
;
1017 r
.out
.transports
= &transports
;
1019 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1020 transports
.level
= levels
[i
];
1021 switch (transports
.level
) {
1024 transports
.ctr
.ctr0
= &ctr0
;
1028 transports
.ctr
.ctr1
= &ctr1
;
1031 torture_comment(tctx
, "Testing NetTransportEnum level %u\n", transports
.level
);
1032 status
= dcerpc_srvsvc_NetTransportEnum_r(b
, tctx
, &r
);
1033 torture_assert_ntstatus_ok(tctx
, status
, "NetTransportEnum failed");
1034 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1035 torture_comment(tctx
, "unexpected result: %s\n", win_errstr(r
.out
.result
));
1042 /**************************/
1043 /* srvsvc_NetRemoteTOD */
1044 /**************************/
1045 static bool test_NetRemoteTOD(struct torture_context
*tctx
,
1046 struct dcerpc_pipe
*p
)
1049 struct srvsvc_NetRemoteTOD r
;
1050 struct srvsvc_NetRemoteTODInfo
*info
= NULL
;
1051 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1053 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
1056 torture_comment(tctx
, "Testing NetRemoteTOD\n");
1057 status
= dcerpc_srvsvc_NetRemoteTOD_r(b
, tctx
, &r
);
1058 torture_assert_ntstatus_ok(tctx
, status
, "NetRemoteTOD failed");
1059 torture_assert_werr_ok(tctx
, r
.out
.result
, "NetRemoteTOD failed");
1064 /**************************/
1065 /* srvsvc_NetName */
1066 /**************************/
1068 static bool test_NetNameValidate(struct torture_context
*tctx
,
1069 struct dcerpc_pipe
*p
)
1072 struct srvsvc_NetNameValidate r
;
1076 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1078 r
.in
.server_unc
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1081 d_printf("Testing NetNameValidate\n");
1083 /* valid path types only between 1 and 13 */
1084 for (i
= 1; i
< 14; i
++) {
1087 /* let's limit ourselves to a maximum of 4096 bytes */
1088 r
.in
.name
= name
= talloc_array(tctx
, char, 4097);
1095 /* Find maximum length accepted by this type */
1098 memset(name
, 'A', n
);
1101 status
= dcerpc_srvsvc_NetNameValidate_r(b
, tctx
, &r
);
1102 if (!NT_STATUS_IS_OK(status
)) {
1103 d_printf("NetNameValidate failed while checking maximum size (%s)\n",
1108 if (W_ERROR_IS_OK(r
.out
.result
)) {
1110 n
+= (max
- min
+ 1)/2;
1114 if ((min
+ 1) >= max
) break; /* found it */
1124 d_printf("Maximum length for type %2d, flags %08x: %d\n", i
, r
.in
.flags
, max
);
1126 /* find invalid chars for this type check only ASCII between 0x20 and 0x7e */
1128 invalidc
= talloc_strdup(tctx
, "");
1130 for (n
= 0x20; n
< 0x7e; n
++) {
1131 r
.in
.name
= name
= talloc_asprintf(tctx
, "%c", (char)n
);
1133 status
= dcerpc_srvsvc_NetNameValidate_r(b
, tctx
, &r
);
1134 if (!NT_STATUS_IS_OK(status
)) {
1135 d_printf("NetNameValidate failed while checking valid chars (%s)\n",
1140 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1141 invalidc
= talloc_asprintf_append_buffer(invalidc
, "%c", (char)n
);
1147 d_printf(" Invalid chars for type %2d, flags %08x: \"%s\"\n", i
, r
.in
.flags
, invalidc
);
1149 /* only two values are accepted for flags: 0x0 and 0x80000000 */
1150 if (r
.in
.flags
== 0x0) {
1151 r
.in
.flags
= 0x80000000;
1161 struct torture_suite
*torture_rpc_srvsvc(TALLOC_CTX
*mem_ctx
)
1163 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "srvsvc");
1164 struct torture_rpc_tcase
*tcase
;
1165 struct torture_test
*test
;
1167 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "srvsvc (admin access)", &ndr_table_srvsvc
);
1169 torture_rpc_tcase_add_test(tcase
, "NetCharDevEnum", test_NetCharDevEnum
);
1170 torture_rpc_tcase_add_test(tcase
, "NetCharDevQEnum", test_NetCharDevQEnum
);
1171 torture_rpc_tcase_add_test(tcase
, "NetConnEnum", test_NetConnEnum
);
1172 torture_rpc_tcase_add_test(tcase
, "NetFileEnum", test_NetFileEnum
);
1173 torture_rpc_tcase_add_test(tcase
, "NetSessEnum", test_NetSessEnum
);
1174 torture_rpc_tcase_add_test(tcase
, "NetShareEnumAll", test_NetShareEnumAllFull
);
1175 torture_rpc_tcase_add_test(tcase
, "NetSrvGetInfo", test_NetSrvGetInfo
);
1176 torture_rpc_tcase_add_test(tcase
, "NetDiskEnum", test_NetDiskEnum
);
1177 torture_rpc_tcase_add_test(tcase
, "NetTransportEnum", test_NetTransportEnum
);
1178 torture_rpc_tcase_add_test(tcase
, "NetRemoteTOD", test_NetRemoteTOD
);
1179 torture_rpc_tcase_add_test(tcase
, "NetShareEnum", test_NetShareEnumFull
);
1180 torture_rpc_tcase_add_test(tcase
, "NetShareGetInfo", test_NetShareGetInfoAdminFull
);
1181 test
= torture_rpc_tcase_add_test(tcase
, "NetShareAddSetDel",
1182 test_NetShareAddSetDel
);
1183 test
->dangerous
= true;
1184 torture_rpc_tcase_add_test(tcase
, "NetNameValidate", test_NetNameValidate
);
1186 tcase
= torture_suite_add_anon_rpc_iface_tcase(suite
,
1187 "srvsvc anonymous access",
1190 torture_rpc_tcase_add_test(tcase
, "NetShareEnumAll",
1191 test_NetShareEnumAllAnon
);
1192 torture_rpc_tcase_add_test(tcase
, "NetShareEnum",
1193 test_NetShareEnumAnon
);
1194 torture_rpc_tcase_add_test(tcase
, "NetShareGetInfo",
1195 test_NetShareGetInfoAdminAnon
);