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_NetFileInfoCtr info_ctr
;
345 struct srvsvc_NetFileCtr2 c2
;
346 struct srvsvc_NetFileCtr3 c3
;
347 uint32_t totalentries
= 0;
348 uint32_t levels
[] = {2, 3};
351 ZERO_STRUCT(info_ctr
);
353 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
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
) {
368 info_ctr
.ctr
.ctr2
= &c2
;
372 info_ctr
.ctr
.ctr3
= &c3
;
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
));
386 /**************************/
388 /**************************/
389 static bool test_NetSessEnum(struct torture_context
*tctx
,
390 struct dcerpc_pipe
*p
)
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};
404 ZERO_STRUCT(info_ctr
);
406 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
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
) {
421 info_ctr
.ctr
.ctr0
= &c0
;
425 info_ctr
.ctr
.ctr1
= &c1
;
429 info_ctr
.ctr
.ctr2
= &c2
;
433 info_ctr
.ctr
.ctr10
= &c10
;
437 info_ctr
.ctr
.ctr502
= &c502
;
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
));
452 /**************************/
453 /* srvsvc_NetShare */
454 /**************************/
455 static bool test_NetShareCheck(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
456 const char *device_name
)
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
;
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");
476 static bool test_NetShareGetInfo(struct torture_context
*tctx
,
477 struct dcerpc_pipe
*p
,
478 const char *sharename
, bool admin
)
481 struct srvsvc_NetShareGetInfo r
;
482 union srvsvc_NetShareInfo info
;
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
},
497 r
.in
.server_unc
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
498 r
.in
.share_name
= sharename
;
501 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
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
)) {
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
)
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
;
551 { 0, WERR_UNKNOWN_LEVEL
},
554 { 501, WERR_UNKNOWN_LEVEL
},
559 /* { 1007, WERR_OK }, */
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
;
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
;
590 for (i
= 0; i
< ARRAY_SIZE(levels
); i
++) {
592 r
.in
.level
= levels
[i
].level
;
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
) {
600 info
.info0
= talloc(tctx
, struct srvsvc_NetShareInfo0
);
601 info
.info0
->name
= r
.in
.share_name
;
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");
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
;
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;
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
;
641 info
.info1004
= talloc(tctx
, struct srvsvc_NetShareInfo1004
);
642 info
.info1004
->comment
= talloc_strdup(tctx
, "test comment 1004");
645 info
.info1005
= talloc(tctx
, struct srvsvc_NetShareInfo1005
);
646 info
.info1005
->dfs_flags
= 0;
649 info
.info1006
= talloc(tctx
, struct srvsvc_NetShareInfo1006
);
650 info
.info1006
->max_users
= 1006;
653 info.info1007 = talloc(tctx, struct srvsvc_NetShareInfo1007);
654 info.info1007->flags = 0;
655 info.info1007->alternate_directory_name = talloc_strdup(tctx, "test");
659 info
.info1501
= talloc_zero(tctx
, struct sec_desc_buf
);
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
;
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
) {
683 torture_assert_str_equal(tctx
, q
.out
.info
->info502
->comment
, "test comment 1", "comment");
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");
691 torture_assert_str_equal(tctx
, q
.out
.info
->info501
->comment
, "test comment 501", "comment");
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");
699 torture_assert_str_equal(tctx
, q
.out
.info
->info1004
->comment
, "test comment 1004",
705 torture_assert_int_equal(tctx
, q
.out
.info
->info1006
->max_users
, 1006, "Max users");
715 d
.in
.share_name
= r
.in
.share_name
;
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");
725 /**************************/
726 /* srvsvc_NetShare */
727 /**************************/
728 static bool test_NetShareEnumAll(struct torture_context
*tctx
,
729 struct dcerpc_pipe
*p
,
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;
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
},
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
++) {
770 info_ctr
.level
= levels
[i
].level
;
772 switch (info_ctr
.level
) {
775 info_ctr
.ctr
.ctr0
= &c0
;
779 info_ctr
.ctr
.ctr1
= &c1
;
783 info_ctr
.ctr
.ctr2
= &c2
;
787 info_ctr
.ctr
.ctr501
= &c501
;
791 info_ctr
.ctr
.ctr502
= &c502
;
795 expected
= levels
[i
].anon_status
;
796 if (admin
) expected
= levels
[i
].admin_status
;
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
++) {
809 name
= r
.out
.info_ctr
->ctr
.ctr2
->array
[j
].name
;
810 if (!test_NetShareGetInfo(tctx
, p
, name
, admin
)) {
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
)
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;
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
},
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
++) {
867 info_ctr
.level
= levels
[i
].level
;
869 switch (info_ctr
.level
) {
872 info_ctr
.ctr
.ctr0
= &c0
;
876 info_ctr
.ctr
.ctr1
= &c1
;
880 info_ctr
.ctr
.ctr2
= &c2
;
884 info_ctr
.ctr
.ctr501
= &c501
;
888 info_ctr
.ctr
.ctr502
= &c502
;
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");
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 /**************************/
918 /**************************/
919 static bool test_NetSrvGetInfo(struct torture_context
*tctx
,
920 struct dcerpc_pipe
*p
)
923 struct srvsvc_NetSrvGetInfo r
;
924 union srvsvc_NetSrvInfo info
;
925 uint32_t levels
[] = {100, 101, 102, 502, 503};
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
];
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
));
944 /**************************/
946 /**************************/
947 static bool test_NetDiskEnum(struct torture_context
*tctx
,
948 struct dcerpc_pipe
*p
)
951 struct srvsvc_NetDiskEnum r
;
952 struct srvsvc_NetDiskInfo info
;
953 uint32_t totalentries
= 0;
954 uint32_t levels
[] = {0};
956 uint32_t resume_handle
=0;
960 r
.in
.server_unc
= NULL
;
961 r
.in
.resume_handle
= &resume_handle
;
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");
979 /**************************/
980 /* srvsvc_NetTransport */
981 /**************************/
982 static bool test_NetTransportEnum(struct torture_context
*tctx
,
983 struct dcerpc_pipe
*p
)
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};
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
) {
1009 transports
.ctr
.ctr0
= &ctr0
;
1013 transports
.ctr
.ctr1
= &ctr1
;
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
));
1027 /**************************/
1028 /* srvsvc_NetRemoteTOD */
1029 /**************************/
1030 static bool test_NetRemoteTOD(struct torture_context
*tctx
,
1031 struct dcerpc_pipe
*p
)
1034 struct srvsvc_NetRemoteTOD r
;
1035 struct srvsvc_NetRemoteTODInfo
*info
= NULL
;
1037 r
.in
.server_unc
= talloc_asprintf(tctx
,"\\\\%s",dcerpc_server_name(p
));
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");
1048 /**************************/
1049 /* srvsvc_NetName */
1050 /**************************/
1052 static bool test_NetNameValidate(struct torture_context
*tctx
,
1053 struct dcerpc_pipe
*p
)
1056 struct srvsvc_NetNameValidate r
;
1061 r
.in
.server_unc
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1064 d_printf("testing NetNameValidate\n");
1066 /* valid path types only between 1 and 13 */
1067 for (i
= 1; i
< 14; i
++) {
1070 /* let's limit ourselves to a maximum of 4096 bytes */
1071 r
.in
.name
= name
= talloc_array(tctx
, char, 4097);
1078 /* Find maximum length accepted by this type */
1081 memset(name
, 'A', n
);
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",
1091 if (W_ERROR_IS_OK(r
.out
.result
)) {
1093 n
+= (max
- min
+ 1)/2;
1097 if ((min
+ 1) >= max
) break; /* found it */
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",
1123 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1124 invalidc
= talloc_asprintf_append_buffer(invalidc
, "%c", (char)n
);
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;
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",
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
);