1 | /*
|
---|
2 | Unix SMB/CIFS implementation.
|
---|
3 | test suite for srvsvc rpc operations
|
---|
4 |
|
---|
5 | Copyright (C) Stefan (metze) Metzmacher 2003
|
---|
6 |
|
---|
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.
|
---|
11 |
|
---|
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.
|
---|
16 |
|
---|
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/>.
|
---|
19 | */
|
---|
20 |
|
---|
21 | #include "includes.h"
|
---|
22 | #include "librpc/gen_ndr/ndr_srvsvc_c.h"
|
---|
23 | #include "torture/rpc/torture_rpc.h"
|
---|
24 |
|
---|
25 | /**************************/
|
---|
26 | /* srvsvc_NetCharDev */
|
---|
27 | /**************************/
|
---|
28 | static bool test_NetCharDevGetInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
|
---|
29 | const char *devname)
|
---|
30 | {
|
---|
31 | NTSTATUS status;
|
---|
32 | struct srvsvc_NetCharDevGetInfo r;
|
---|
33 | union srvsvc_NetCharDevInfo info;
|
---|
34 | uint32_t levels[] = {0, 1};
|
---|
35 | int i;
|
---|
36 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
37 |
|
---|
38 | r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
|
---|
39 | r.in.device_name = devname;
|
---|
40 | r.out.info = &info;
|
---|
41 |
|
---|
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");
|
---|
49 | }
|
---|
50 |
|
---|
51 | return true;
|
---|
52 | }
|
---|
53 |
|
---|
54 | static bool test_NetCharDevControl(struct dcerpc_pipe *p, struct torture_context *tctx,
|
---|
55 | const char *devname)
|
---|
56 | {
|
---|
57 | NTSTATUS status;
|
---|
58 | struct srvsvc_NetCharDevControl r;
|
---|
59 | uint32_t opcodes[] = {0, 1};
|
---|
60 | int i;
|
---|
61 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
62 |
|
---|
63 | r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
|
---|
64 | r.in.device_name = devname;
|
---|
65 |
|
---|
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_r(b, tctx, &r);
|
---|
72 | torture_assert_ntstatus_ok(tctx, status, "NetCharDevControl failed");
|
---|
73 | torture_assert_werr_ok(tctx, r.out.result, "NetCharDevControl failed");
|
---|
74 | }
|
---|
75 |
|
---|
76 | return true;
|
---|
77 | }
|
---|
78 |
|
---|
79 | static bool test_NetCharDevEnum(struct torture_context *tctx,
|
---|
80 | struct dcerpc_pipe *p)
|
---|
81 | {
|
---|
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;
|
---|
90 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
91 |
|
---|
92 | ZERO_STRUCT(info_ctr);
|
---|
93 |
|
---|
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;
|
---|
100 |
|
---|
101 | for (i=0;i<ARRAY_SIZE(levels);i++) {
|
---|
102 | int j;
|
---|
103 |
|
---|
104 | info_ctr.level = levels[i];
|
---|
105 |
|
---|
106 | switch(info_ctr.level) {
|
---|
107 | case 0:
|
---|
108 | ZERO_STRUCT(c0);
|
---|
109 | info_ctr.ctr.ctr0 = &c0;
|
---|
110 | break;
|
---|
111 | case 1:
|
---|
112 | ZERO_STRUCT(c1);
|
---|
113 | info_ctr.ctr.ctr0 = &c1;
|
---|
114 | break;
|
---|
115 | }
|
---|
116 |
|
---|
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));
|
---|
122 | continue;
|
---|
123 | }
|
---|
124 |
|
---|
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++) {
|
---|
128 | const char *device;
|
---|
129 | device = r.out.info_ctr->ctr.ctr1->array[j].device;
|
---|
130 | if (!test_NetCharDevGetInfo(p, tctx, device)) {
|
---|
131 | return false;
|
---|
132 | }
|
---|
133 | if (!test_NetCharDevControl(p, tctx, device)) {
|
---|
134 | return false;
|
---|
135 | }
|
---|
136 | }
|
---|
137 | }
|
---|
138 | }
|
---|
139 |
|
---|
140 | return true;
|
---|
141 | }
|
---|
142 |
|
---|
143 | /**************************/
|
---|
144 | /* srvsvc_NetCharDevQ */
|
---|
145 | /**************************/
|
---|
146 | static bool test_NetCharDevQGetInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
|
---|
147 | const char *devicequeue)
|
---|
148 | {
|
---|
149 | NTSTATUS status;
|
---|
150 | struct srvsvc_NetCharDevQGetInfo r;
|
---|
151 | union srvsvc_NetCharDevQInfo info;
|
---|
152 | uint32_t levels[] = {0, 1};
|
---|
153 | int i;
|
---|
154 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
155 |
|
---|
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");
|
---|
159 | r.out.info = &info;
|
---|
160 |
|
---|
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");
|
---|
168 | }
|
---|
169 |
|
---|
170 | return true;
|
---|
171 | }
|
---|
172 |
|
---|
173 | #if 0
|
---|
174 | static bool test_NetCharDevQSetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
---|
175 | const char *devicequeue)
|
---|
176 | {
|
---|
177 | NTSTATUS status;
|
---|
178 | struct srvsvc_NetCharDevQSetInfo r;
|
---|
179 | uint32_t parm_error;
|
---|
180 | uint32_t levels[] = {0, 1};
|
---|
181 | int i;
|
---|
182 | bool ret = true;
|
---|
183 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
184 |
|
---|
185 | r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
|
---|
186 | r.in.queue_name = devicequeue;
|
---|
187 |
|
---|
188 | for (i=0;i<ARRAY_SIZE(levels);i++) {
|
---|
189 | ZERO_STRUCT(r.out);
|
---|
190 | parm_error = 0;
|
---|
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) {
|
---|
195 | case 0:
|
---|
196 | r.in.info.info0 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo0);
|
---|
197 | r.in.info.info0->device = r.in.queue_name;
|
---|
198 | break;
|
---|
199 | case 1:
|
---|
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;
|
---|
206 | break;
|
---|
207 | default:
|
---|
208 | break;
|
---|
209 | }
|
---|
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));
|
---|
215 | ret = false;
|
---|
216 | continue;
|
---|
217 | }
|
---|
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));
|
---|
221 | continue;
|
---|
222 | }
|
---|
223 | }
|
---|
224 |
|
---|
225 | return ret;
|
---|
226 | }
|
---|
227 | #endif
|
---|
228 |
|
---|
229 | static bool test_NetCharDevQEnum(struct torture_context *tctx,
|
---|
230 | struct dcerpc_pipe *p)
|
---|
231 | {
|
---|
232 | NTSTATUS status;
|
---|
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};
|
---|
239 | int i;
|
---|
240 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
241 |
|
---|
242 | ZERO_STRUCT(info_ctr);
|
---|
243 |
|
---|
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;
|
---|
251 |
|
---|
252 | for (i=0;i<ARRAY_SIZE(levels);i++) {
|
---|
253 | int j;
|
---|
254 |
|
---|
255 | info_ctr.level = levels[i];
|
---|
256 |
|
---|
257 | switch (info_ctr.level) {
|
---|
258 | case 0:
|
---|
259 | ZERO_STRUCT(c0);
|
---|
260 | info_ctr.ctr.ctr0 = &c0;
|
---|
261 | break;
|
---|
262 | case 1:
|
---|
263 | ZERO_STRUCT(c1);
|
---|
264 | info_ctr.ctr.ctr1 = &c1;
|
---|
265 | break;
|
---|
266 | }
|
---|
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));
|
---|
272 | continue;
|
---|
273 | }
|
---|
274 |
|
---|
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++) {
|
---|
278 | const char *device;
|
---|
279 | device = r.out.info_ctr->ctr.ctr1->array[j].device;
|
---|
280 | if (!test_NetCharDevQGetInfo(p, tctx, device)) {
|
---|
281 | return false;
|
---|
282 | }
|
---|
283 | }
|
---|
284 | }
|
---|
285 | }
|
---|
286 |
|
---|
287 | return true;
|
---|
288 | }
|
---|
289 |
|
---|
290 | /**************************/
|
---|
291 | /* srvsvc_NetConn */
|
---|
292 | /**************************/
|
---|
293 | static bool test_NetConnEnum(struct torture_context *tctx,
|
---|
294 | struct dcerpc_pipe *p)
|
---|
295 | {
|
---|
296 | NTSTATUS status;
|
---|
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};
|
---|
303 | int i;
|
---|
304 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
305 |
|
---|
306 | ZERO_STRUCT(info_ctr);
|
---|
307 |
|
---|
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;
|
---|
315 |
|
---|
316 | for (i=0;i<ARRAY_SIZE(levels);i++) {
|
---|
317 | info_ctr.level = levels[i];
|
---|
318 |
|
---|
319 | switch (info_ctr.level) {
|
---|
320 | case 0:
|
---|
321 | ZERO_STRUCT(c0);
|
---|
322 | info_ctr.ctr.ctr0 = &c0;
|
---|
323 | break;
|
---|
324 | case 1:
|
---|
325 | ZERO_STRUCT(c1);
|
---|
326 | info_ctr.ctr.ctr1 = &c1;
|
---|
327 | break;
|
---|
328 | }
|
---|
329 |
|
---|
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));
|
---|
335 | }
|
---|
336 | }
|
---|
337 |
|
---|
338 | return true;
|
---|
339 | }
|
---|
340 |
|
---|
341 | /**************************/
|
---|
342 | /* srvsvc_NetFile */
|
---|
343 | /**************************/
|
---|
344 | static bool test_NetFileEnum(struct torture_context *tctx,
|
---|
345 | struct dcerpc_pipe *p)
|
---|
346 | {
|
---|
347 | NTSTATUS status;
|
---|
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};
|
---|
354 | int i;
|
---|
355 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
356 |
|
---|
357 | ZERO_STRUCT(info_ctr);
|
---|
358 |
|
---|
359 | r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
|
---|
360 | r.in.path = NULL;
|
---|
361 | r.in.user = NULL;
|
---|
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;
|
---|
367 |
|
---|
368 | for (i=0;i<ARRAY_SIZE(levels);i++) {
|
---|
369 | info_ctr.level = levels[i];
|
---|
370 |
|
---|
371 | switch (info_ctr.level) {
|
---|
372 | case 2:
|
---|
373 | ZERO_STRUCT(c2);
|
---|
374 | info_ctr.ctr.ctr2 = &c2;
|
---|
375 | break;
|
---|
376 | case 3:
|
---|
377 | ZERO_STRUCT(c3);
|
---|
378 | info_ctr.ctr.ctr3 = &c3;
|
---|
379 | break;
|
---|
380 | }
|
---|
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));
|
---|
386 | }
|
---|
387 | }
|
---|
388 |
|
---|
389 | return true;
|
---|
390 | }
|
---|
391 |
|
---|
392 | /**************************/
|
---|
393 | /* srvsvc_NetSess */
|
---|
394 | /**************************/
|
---|
395 | static bool test_NetSessEnum(struct torture_context *tctx,
|
---|
396 | struct dcerpc_pipe *p)
|
---|
397 | {
|
---|
398 | NTSTATUS status;
|
---|
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};
|
---|
408 | int i;
|
---|
409 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
410 |
|
---|
411 | ZERO_STRUCT(info_ctr);
|
---|
412 |
|
---|
413 | r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
|
---|
414 | r.in.client = NULL;
|
---|
415 | r.in.user = NULL;
|
---|
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;
|
---|
421 |
|
---|
422 | for (i=0;i<ARRAY_SIZE(levels);i++) {
|
---|
423 | info_ctr.level = levels[i];
|
---|
424 |
|
---|
425 | switch (info_ctr.level) {
|
---|
426 | case 0:
|
---|
427 | ZERO_STRUCT(c0);
|
---|
428 | info_ctr.ctr.ctr0 = &c0;
|
---|
429 | break;
|
---|
430 | case 1:
|
---|
431 | ZERO_STRUCT(c1);
|
---|
432 | info_ctr.ctr.ctr1 = &c1;
|
---|
433 | break;
|
---|
434 | case 2:
|
---|
435 | ZERO_STRUCT(c2);
|
---|
436 | info_ctr.ctr.ctr2 = &c2;
|
---|
437 | break;
|
---|
438 | case 10:
|
---|
439 | ZERO_STRUCT(c10);
|
---|
440 | info_ctr.ctr.ctr10 = &c10;
|
---|
441 | break;
|
---|
442 | case 502:
|
---|
443 | ZERO_STRUCT(c502);
|
---|
444 | info_ctr.ctr.ctr502 = &c502;
|
---|
445 | break;
|
---|
446 | }
|
---|
447 |
|
---|
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));
|
---|
453 | }
|
---|
454 | }
|
---|
455 |
|
---|
456 | return true;
|
---|
457 | }
|
---|
458 |
|
---|
459 | /**************************/
|
---|
460 | /* srvsvc_NetShare */
|
---|
461 | /**************************/
|
---|
462 | static bool test_NetShareCheck(struct dcerpc_pipe *p, struct torture_context *tctx,
|
---|
463 | const char *device_name)
|
---|
464 | {
|
---|
465 | NTSTATUS status;
|
---|
466 | struct srvsvc_NetShareCheck r;
|
---|
467 | enum srvsvc_ShareType type;
|
---|
468 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
469 |
|
---|
470 | r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
|
---|
471 | r.in.device_name = device_name;
|
---|
472 | r.out.type = &type;
|
---|
473 |
|
---|
474 | torture_comment(tctx,
|
---|
475 | "Testing NetShareCheck on device '%s'\n", r.in.device_name);
|
---|
476 |
|
---|
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");
|
---|
480 |
|
---|
481 | return true;
|
---|
482 | }
|
---|
483 |
|
---|
484 | static bool test_NetShareGetInfo(struct torture_context *tctx,
|
---|
485 | struct dcerpc_pipe *p,
|
---|
486 | const char *sharename, bool admin)
|
---|
487 | {
|
---|
488 | NTSTATUS status;
|
---|
489 | struct srvsvc_NetShareGetInfo r;
|
---|
490 | union srvsvc_NetShareInfo info;
|
---|
491 | struct {
|
---|
492 | uint32_t level;
|
---|
493 | WERROR anon_status;
|
---|
494 | WERROR admin_status;
|
---|
495 | } levels[] = {
|
---|
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 },
|
---|
502 | };
|
---|
503 | int i;
|
---|
504 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
505 |
|
---|
506 | r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
|
---|
507 | r.in.share_name = sharename;
|
---|
508 | r.out.info = &info;
|
---|
509 |
|
---|
510 | for (i=0;i<ARRAY_SIZE(levels);i++) {
|
---|
511 | WERROR expected;
|
---|
512 |
|
---|
513 | r.in.level = levels[i].level;
|
---|
514 | expected = levels[i].anon_status;
|
---|
515 | if (admin) expected = levels[i].admin_status;
|
---|
516 |
|
---|
517 | torture_comment(tctx, "Testing NetShareGetInfo level %u on share '%s'\n",
|
---|
518 | r.in.level, r.in.share_name);
|
---|
519 |
|
---|
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");
|
---|
523 |
|
---|
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)) {
|
---|
527 | return false;
|
---|
528 | }
|
---|
529 | }
|
---|
530 |
|
---|
531 | return true;
|
---|
532 | }
|
---|
533 |
|
---|
534 | static bool test_NetShareGetInfoAdminFull(struct torture_context *tctx,
|
---|
535 | struct dcerpc_pipe *p)
|
---|
536 | {
|
---|
537 | return test_NetShareGetInfo(tctx, p, "IPC$", true);
|
---|
538 | }
|
---|
539 |
|
---|
540 | static bool test_NetShareGetInfoAdminAnon(struct torture_context *tctx,
|
---|
541 | struct dcerpc_pipe *p)
|
---|
542 | {
|
---|
543 | return test_NetShareGetInfo(tctx, p, "IPC$", false);
|
---|
544 | }
|
---|
545 |
|
---|
546 | static bool test_NetShareAddSetDel(struct torture_context *tctx,
|
---|
547 | struct dcerpc_pipe *p)
|
---|
548 | {
|
---|
549 | NTSTATUS status;
|
---|
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;
|
---|
556 | struct {
|
---|
557 | uint32_t level;
|
---|
558 | WERROR expected;
|
---|
559 | } levels[] = {
|
---|
560 | { 0, WERR_UNKNOWN_LEVEL },
|
---|
561 | { 1, WERR_OK },
|
---|
562 | { 2, WERR_OK },
|
---|
563 | { 501, WERR_UNKNOWN_LEVEL },
|
---|
564 | { 502, WERR_OK },
|
---|
565 | { 1004, WERR_OK },
|
---|
566 | { 1005, WERR_OK },
|
---|
567 | { 1006, WERR_OK },
|
---|
568 | /* { 1007, WERR_OK }, */
|
---|
569 | { 1501, WERR_OK },
|
---|
570 | };
|
---|
571 | int i;
|
---|
572 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
573 |
|
---|
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");
|
---|
577 |
|
---|
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;
|
---|
587 |
|
---|
588 | a.in.info = &info;
|
---|
589 | a.in.level = 2;
|
---|
590 | a.in.parm_error = NULL;
|
---|
591 |
|
---|
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");
|
---|
595 |
|
---|
596 | r.in.parm_error = NULL;
|
---|
597 |
|
---|
598 | q.in.level = 502;
|
---|
599 |
|
---|
600 | for (i = 0; i < ARRAY_SIZE(levels); i++) {
|
---|
601 |
|
---|
602 | r.in.level = levels[i].level;
|
---|
603 | ZERO_STRUCT(r.out);
|
---|
604 |
|
---|
605 | torture_comment(tctx, "Testing NetShareSetInfo level %u on share '%s'\n",
|
---|
606 | r.in.level, r.in.share_name);
|
---|
607 |
|
---|
608 | switch (levels[i].level) {
|
---|
609 | case 0:
|
---|
610 | info.info0 = talloc(tctx, struct srvsvc_NetShareInfo0);
|
---|
611 | info.info0->name = r.in.share_name;
|
---|
612 | break;
|
---|
613 | case 1:
|
---|
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");
|
---|
618 | break;
|
---|
619 | case 2:
|
---|
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;
|
---|
629 | break;
|
---|
630 | case 501:
|
---|
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;
|
---|
636 | break;
|
---|
637 | case 502:
|
---|
638 | ZERO_STRUCT(sd_buf);
|
---|
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;
|
---|
649 | break;
|
---|
650 | case 1004:
|
---|
651 | info.info1004 = talloc(tctx, struct srvsvc_NetShareInfo1004);
|
---|
652 | info.info1004->comment = talloc_strdup(tctx, "test comment 1004");
|
---|
653 | break;
|
---|
654 | case 1005:
|
---|
655 | info.info1005 = talloc(tctx, struct srvsvc_NetShareInfo1005);
|
---|
656 | info.info1005->dfs_flags = 0;
|
---|
657 | break;
|
---|
658 | case 1006:
|
---|
659 | info.info1006 = talloc(tctx, struct srvsvc_NetShareInfo1006);
|
---|
660 | info.info1006->max_users = 1006;
|
---|
661 | break;
|
---|
662 | /* case 1007:
|
---|
663 | info.info1007 = talloc(tctx, struct srvsvc_NetShareInfo1007);
|
---|
664 | info.info1007->flags = 0;
|
---|
665 | info.info1007->alternate_directory_name = talloc_strdup(tctx, "test");
|
---|
666 | break;
|
---|
667 | */
|
---|
668 | case 1501:
|
---|
669 | info.info1501 = talloc_zero(tctx, struct sec_desc_buf);
|
---|
670 | break;
|
---|
671 | }
|
---|
672 |
|
---|
673 | r.in.info = &info;
|
---|
674 |
|
---|
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");
|
---|
678 |
|
---|
679 | q.in.share_name = r.in.share_name;
|
---|
680 | q.out.info = &info;
|
---|
681 |
|
---|
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");
|
---|
685 |
|
---|
686 | torture_assert_str_equal(tctx, q.out.info->info502->name, r.in.share_name,
|
---|
687 | "share name invalid");
|
---|
688 |
|
---|
689 | switch (levels[i].level) {
|
---|
690 | case 0:
|
---|
691 | break;
|
---|
692 | case 1:
|
---|
693 | torture_assert_str_equal(tctx, q.out.info->info502->comment, "test comment 1", "comment");
|
---|
694 | break;
|
---|
695 | case 2:
|
---|
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");
|
---|
699 | break;
|
---|
700 | case 501:
|
---|
701 | torture_assert_str_equal(tctx, q.out.info->info501->comment, "test comment 501", "comment");
|
---|
702 | break;
|
---|
703 | case 502:
|
---|
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");
|
---|
707 | break;
|
---|
708 | case 1004:
|
---|
709 | torture_assert_str_equal(tctx, q.out.info->info1004->comment, "test comment 1004",
|
---|
710 | "comment");
|
---|
711 | break;
|
---|
712 | case 1005:
|
---|
713 | break;
|
---|
714 | case 1006:
|
---|
715 | torture_assert_int_equal(tctx, q.out.info->info1006->max_users, 1006, "Max users");
|
---|
716 | break;
|
---|
717 | /* case 1007:
|
---|
718 | break;
|
---|
719 | */
|
---|
720 | case 1501:
|
---|
721 | break;
|
---|
722 | }
|
---|
723 | }
|
---|
724 |
|
---|
725 | d.in.share_name = r.in.share_name;
|
---|
726 | d.in.reserved = 0;
|
---|
727 |
|
---|
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");
|
---|
731 |
|
---|
732 | return true;
|
---|
733 | }
|
---|
734 |
|
---|
735 | /**************************/
|
---|
736 | /* srvsvc_NetShare */
|
---|
737 | /**************************/
|
---|
738 | static bool test_NetShareEnumAll(struct torture_context *tctx,
|
---|
739 | struct dcerpc_pipe *p,
|
---|
740 | bool admin)
|
---|
741 | {
|
---|
742 | NTSTATUS status;
|
---|
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;
|
---|
751 | struct {
|
---|
752 | uint32_t level;
|
---|
753 | WERROR anon_status;
|
---|
754 | WERROR admin_status;
|
---|
755 | } levels[] = {
|
---|
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 },
|
---|
761 | };
|
---|
762 | int i;
|
---|
763 | uint32_t resume_handle;
|
---|
764 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
765 |
|
---|
766 | ZERO_STRUCT(info_ctr);
|
---|
767 |
|
---|
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;
|
---|
775 |
|
---|
776 | for (i=0;i<ARRAY_SIZE(levels);i++) {
|
---|
777 |
|
---|
778 | int j;
|
---|
779 | WERROR expected;
|
---|
780 |
|
---|
781 | info_ctr.level = levels[i].level;
|
---|
782 |
|
---|
783 | switch (info_ctr.level) {
|
---|
784 | case 0:
|
---|
785 | ZERO_STRUCT(c0);
|
---|
786 | info_ctr.ctr.ctr0 = &c0;
|
---|
787 | break;
|
---|
788 | case 1:
|
---|
789 | ZERO_STRUCT(c1);
|
---|
790 | info_ctr.ctr.ctr1 = &c1;
|
---|
791 | break;
|
---|
792 | case 2:
|
---|
793 | ZERO_STRUCT(c2);
|
---|
794 | info_ctr.ctr.ctr2 = &c2;
|
---|
795 | break;
|
---|
796 | case 501:
|
---|
797 | ZERO_STRUCT(c501);
|
---|
798 | info_ctr.ctr.ctr501 = &c501;
|
---|
799 | break;
|
---|
800 | case 502:
|
---|
801 | ZERO_STRUCT(c502);
|
---|
802 | info_ctr.ctr.ctr502 = &c502;
|
---|
803 | break;
|
---|
804 | }
|
---|
805 |
|
---|
806 | expected = levels[i].anon_status;
|
---|
807 | if (admin) expected = levels[i].admin_status;
|
---|
808 |
|
---|
809 | resume_handle = 0;
|
---|
810 |
|
---|
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");
|
---|
815 |
|
---|
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++) {
|
---|
819 | const char *name;
|
---|
820 | name = r.out.info_ctr->ctr.ctr2->array[j].name;
|
---|
821 | if (!test_NetShareGetInfo(tctx, p, name, admin)) {
|
---|
822 | return false;
|
---|
823 | }
|
---|
824 | }
|
---|
825 | }
|
---|
826 | }
|
---|
827 |
|
---|
828 | return true;
|
---|
829 | }
|
---|
830 |
|
---|
831 | static bool test_NetShareEnumAllFull(struct torture_context *tctx,
|
---|
832 | struct dcerpc_pipe *p)
|
---|
833 | {
|
---|
834 | return test_NetShareEnumAll(tctx, p, true);
|
---|
835 | }
|
---|
836 |
|
---|
837 | static bool test_NetShareEnumAllAnon(struct torture_context *tctx,
|
---|
838 | struct dcerpc_pipe *p)
|
---|
839 | {
|
---|
840 | return test_NetShareEnumAll(tctx, p, false);
|
---|
841 | }
|
---|
842 |
|
---|
843 | static bool test_NetShareEnum(struct torture_context *tctx,
|
---|
844 | struct dcerpc_pipe *p, bool admin)
|
---|
845 | {
|
---|
846 | NTSTATUS status;
|
---|
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;
|
---|
855 | struct {
|
---|
856 | uint32_t level;
|
---|
857 | WERROR anon_status;
|
---|
858 | WERROR admin_status;
|
---|
859 | } levels[] = {
|
---|
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 },
|
---|
865 | };
|
---|
866 | int i;
|
---|
867 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
868 |
|
---|
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;
|
---|
875 |
|
---|
876 | for (i=0;i<ARRAY_SIZE(levels);i++) {
|
---|
877 | WERROR expected;
|
---|
878 |
|
---|
879 | info_ctr.level = levels[i].level;
|
---|
880 |
|
---|
881 | switch (info_ctr.level) {
|
---|
882 | case 0:
|
---|
883 | ZERO_STRUCT(c0);
|
---|
884 | info_ctr.ctr.ctr0 = &c0;
|
---|
885 | break;
|
---|
886 | case 1:
|
---|
887 | ZERO_STRUCT(c1);
|
---|
888 | info_ctr.ctr.ctr1 = &c1;
|
---|
889 | break;
|
---|
890 | case 2:
|
---|
891 | ZERO_STRUCT(c2);
|
---|
892 | info_ctr.ctr.ctr2 = &c2;
|
---|
893 | break;
|
---|
894 | case 501:
|
---|
895 | ZERO_STRUCT(c501);
|
---|
896 | info_ctr.ctr.ctr501 = &c501;
|
---|
897 | break;
|
---|
898 | case 502:
|
---|
899 | ZERO_STRUCT(c502);
|
---|
900 | info_ctr.ctr.ctr502 = &c502;
|
---|
901 | break;
|
---|
902 | }
|
---|
903 |
|
---|
904 | expected = levels[i].anon_status;
|
---|
905 | if (admin) expected = levels[i].admin_status;
|
---|
906 |
|
---|
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");
|
---|
911 | }
|
---|
912 |
|
---|
913 | return true;
|
---|
914 | }
|
---|
915 |
|
---|
916 | static bool test_NetShareEnumFull(struct torture_context *tctx,
|
---|
917 | struct dcerpc_pipe *p)
|
---|
918 | {
|
---|
919 | return test_NetShareEnum(tctx, p, true);
|
---|
920 | }
|
---|
921 |
|
---|
922 | static bool test_NetShareEnumAnon(struct torture_context *tctx,
|
---|
923 | struct dcerpc_pipe *p)
|
---|
924 | {
|
---|
925 | return test_NetShareEnum(tctx, p, false);
|
---|
926 | }
|
---|
927 |
|
---|
928 | /**************************/
|
---|
929 | /* srvsvc_NetSrv */
|
---|
930 | /**************************/
|
---|
931 | static bool test_NetSrvGetInfo(struct torture_context *tctx,
|
---|
932 | struct dcerpc_pipe *p)
|
---|
933 | {
|
---|
934 | NTSTATUS status;
|
---|
935 | struct srvsvc_NetSrvGetInfo r;
|
---|
936 | union srvsvc_NetSrvInfo info;
|
---|
937 | uint32_t levels[] = {100, 101, 102, 502, 503};
|
---|
938 | int i;
|
---|
939 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
940 |
|
---|
941 | r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
|
---|
942 |
|
---|
943 | for (i=0;i<ARRAY_SIZE(levels);i++) {
|
---|
944 | r.in.level = levels[i];
|
---|
945 | r.out.info = &info;
|
---|
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));
|
---|
951 | }
|
---|
952 | }
|
---|
953 |
|
---|
954 | return true;
|
---|
955 | }
|
---|
956 |
|
---|
957 | /**************************/
|
---|
958 | /* srvsvc_NetDisk */
|
---|
959 | /**************************/
|
---|
960 | static bool test_NetDiskEnum(struct torture_context *tctx,
|
---|
961 | struct dcerpc_pipe *p)
|
---|
962 | {
|
---|
963 | NTSTATUS status;
|
---|
964 | struct srvsvc_NetDiskEnum r;
|
---|
965 | struct srvsvc_NetDiskInfo info;
|
---|
966 | uint32_t totalentries = 0;
|
---|
967 | uint32_t levels[] = {0};
|
---|
968 | int i;
|
---|
969 | uint32_t resume_handle=0;
|
---|
970 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
971 |
|
---|
972 | ZERO_STRUCT(info);
|
---|
973 |
|
---|
974 | r.in.server_unc = NULL;
|
---|
975 | r.in.resume_handle = &resume_handle;
|
---|
976 | r.in.info = &info;
|
---|
977 | r.out.info = &info;
|
---|
978 | r.out.totalentries = &totalentries;
|
---|
979 | r.out.resume_handle = &resume_handle;
|
---|
980 |
|
---|
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");
|
---|
988 | }
|
---|
989 |
|
---|
990 | return true;
|
---|
991 | }
|
---|
992 |
|
---|
993 | /**************************/
|
---|
994 | /* srvsvc_NetTransport */
|
---|
995 | /**************************/
|
---|
996 | static bool test_NetTransportEnum(struct torture_context *tctx,
|
---|
997 | struct dcerpc_pipe *p)
|
---|
998 | {
|
---|
999 | NTSTATUS status;
|
---|
1000 | struct srvsvc_NetTransportEnum r;
|
---|
1001 | struct srvsvc_NetTransportInfoCtr transports;
|
---|
1002 | struct srvsvc_NetTransportCtr0 ctr0;
|
---|
1003 | struct srvsvc_NetTransportCtr1 ctr1;
|
---|
1004 |
|
---|
1005 | uint32_t totalentries = 0;
|
---|
1006 | uint32_t levels[] = {0, 1};
|
---|
1007 | int i;
|
---|
1008 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
1009 |
|
---|
1010 | ZERO_STRUCT(transports);
|
---|
1011 |
|
---|
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;
|
---|
1018 |
|
---|
1019 | for (i=0;i<ARRAY_SIZE(levels);i++) {
|
---|
1020 | transports.level = levels[i];
|
---|
1021 | switch (transports.level) {
|
---|
1022 | case 0:
|
---|
1023 | ZERO_STRUCT(ctr0);
|
---|
1024 | transports.ctr.ctr0 = &ctr0;
|
---|
1025 | break;
|
---|
1026 | case 1:
|
---|
1027 | ZERO_STRUCT(ctr1);
|
---|
1028 | transports.ctr.ctr1 = &ctr1;
|
---|
1029 | break;
|
---|
1030 | }
|
---|
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));
|
---|
1036 | }
|
---|
1037 | }
|
---|
1038 |
|
---|
1039 | return true;
|
---|
1040 | }
|
---|
1041 |
|
---|
1042 | /**************************/
|
---|
1043 | /* srvsvc_NetRemoteTOD */
|
---|
1044 | /**************************/
|
---|
1045 | static bool test_NetRemoteTOD(struct torture_context *tctx,
|
---|
1046 | struct dcerpc_pipe *p)
|
---|
1047 | {
|
---|
1048 | NTSTATUS status;
|
---|
1049 | struct srvsvc_NetRemoteTOD r;
|
---|
1050 | struct srvsvc_NetRemoteTODInfo *info = NULL;
|
---|
1051 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
1052 |
|
---|
1053 | r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
|
---|
1054 | r.out.info = &info;
|
---|
1055 |
|
---|
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");
|
---|
1060 |
|
---|
1061 | return true;
|
---|
1062 | }
|
---|
1063 |
|
---|
1064 | /**************************/
|
---|
1065 | /* srvsvc_NetName */
|
---|
1066 | /**************************/
|
---|
1067 |
|
---|
1068 | static bool test_NetNameValidate(struct torture_context *tctx,
|
---|
1069 | struct dcerpc_pipe *p)
|
---|
1070 | {
|
---|
1071 | NTSTATUS status;
|
---|
1072 | struct srvsvc_NetNameValidate r;
|
---|
1073 | char *invalidc;
|
---|
1074 | char *name;
|
---|
1075 | int i, n, min, max;
|
---|
1076 | struct dcerpc_binding_handle *b = p->binding_handle;
|
---|
1077 |
|
---|
1078 | r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
|
---|
1079 | r.in.flags = 0x0;
|
---|
1080 |
|
---|
1081 | d_printf("Testing NetNameValidate\n");
|
---|
1082 |
|
---|
1083 | /* valid path types only between 1 and 13 */
|
---|
1084 | for (i = 1; i < 14; i++) {
|
---|
1085 |
|
---|
1086 | again:
|
---|
1087 | /* let's limit ourselves to a maximum of 4096 bytes */
|
---|
1088 | r.in.name = name = talloc_array(tctx, char, 4097);
|
---|
1089 | max = 4096;
|
---|
1090 | min = 0;
|
---|
1091 | n = max;
|
---|
1092 |
|
---|
1093 | while (1) {
|
---|
1094 |
|
---|
1095 | /* Find maximum length accepted by this type */
|
---|
1096 | ZERO_STRUCT(r.out);
|
---|
1097 | r.in.name_type = i;
|
---|
1098 | memset(name, 'A', n);
|
---|
1099 | name[n] = '\0';
|
---|
1100 |
|
---|
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",
|
---|
1104 | nt_errstr(status));
|
---|
1105 | break;
|
---|
1106 | }
|
---|
1107 |
|
---|
1108 | if (W_ERROR_IS_OK(r.out.result)) {
|
---|
1109 | min = n;
|
---|
1110 | n += (max - min + 1)/2;
|
---|
1111 | continue;
|
---|
1112 |
|
---|
1113 | } else {
|
---|
1114 | if ((min + 1) >= max) break; /* found it */
|
---|
1115 |
|
---|
1116 | max = n;
|
---|
1117 | n -= (max - min)/2;
|
---|
1118 | continue;
|
---|
1119 | }
|
---|
1120 | }
|
---|
1121 |
|
---|
1122 | talloc_free(name);
|
---|
1123 |
|
---|
1124 | d_printf("Maximum length for type %2d, flags %08x: %d\n", i, r.in.flags, max);
|
---|
1125 |
|
---|
1126 | /* find invalid chars for this type check only ASCII between 0x20 and 0x7e */
|
---|
1127 |
|
---|
1128 | invalidc = talloc_strdup(tctx, "");
|
---|
1129 |
|
---|
1130 | for (n = 0x20; n < 0x7e; n++) {
|
---|
1131 | r.in.name = name = talloc_asprintf(tctx, "%c", (char)n);
|
---|
1132 |
|
---|
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",
|
---|
1136 | nt_errstr(status));
|
---|
1137 | break;
|
---|
1138 | }
|
---|
1139 |
|
---|
1140 | if (!W_ERROR_IS_OK(r.out.result)) {
|
---|
1141 | invalidc = talloc_asprintf_append_buffer(invalidc, "%c", (char)n);
|
---|
1142 | }
|
---|
1143 |
|
---|
1144 | talloc_free(name);
|
---|
1145 | }
|
---|
1146 |
|
---|
1147 | d_printf(" Invalid chars for type %2d, flags %08x: \"%s\"\n", i, r.in.flags, invalidc);
|
---|
1148 |
|
---|
1149 | /* only two values are accepted for flags: 0x0 and 0x80000000 */
|
---|
1150 | if (r.in.flags == 0x0) {
|
---|
1151 | r.in.flags = 0x80000000;
|
---|
1152 | goto again;
|
---|
1153 | }
|
---|
1154 |
|
---|
1155 | r.in.flags = 0x0;
|
---|
1156 | }
|
---|
1157 |
|
---|
1158 | return true;
|
---|
1159 | }
|
---|
1160 |
|
---|
1161 | struct torture_suite *torture_rpc_srvsvc(TALLOC_CTX *mem_ctx)
|
---|
1162 | {
|
---|
1163 | struct torture_suite *suite = torture_suite_create(mem_ctx, "srvsvc");
|
---|
1164 | struct torture_rpc_tcase *tcase;
|
---|
1165 | struct torture_test *test;
|
---|
1166 |
|
---|
1167 | tcase = torture_suite_add_rpc_iface_tcase(suite, "srvsvc (admin access)", &ndr_table_srvsvc);
|
---|
1168 |
|
---|
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);
|
---|
1185 |
|
---|
1186 | tcase = torture_suite_add_anon_rpc_iface_tcase(suite,
|
---|
1187 | "srvsvc anonymous access",
|
---|
1188 | &ndr_table_srvsvc);
|
---|
1189 |
|
---|
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);
|
---|
1196 |
|
---|
1197 | return suite;
|
---|
1198 | }
|
---|