/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- test_NetCharDevGetInfo
- test_NetCharDevControl
- test_NetCharDevEnum
- test_NetCharDevQGetInfo
- test_NetCharDevQSetInfo
- test_NetCharDevQEnum
- test_NetConnEnum
- test_NetFileEnum
- test_NetSessEnum
- test_NetShareCheck
- test_NetShareGetInfo
- test_NetShareGetInfoAdminFull
- test_NetShareGetInfoAdminAnon
- test_NetShareAddSetDel
- test_NetShareEnumAll
- test_NetShareEnumAllFull
- test_NetShareEnumAllAnon
- test_NetShareEnum
- test_NetShareEnumFull
- test_NetShareEnumAnon
- test_NetSrvGetInfo
- test_NetDiskEnum
- test_NetTransportEnum
- test_NetRemoteTOD
- test_NetNameValidate
- torture_rpc_srvsvc
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 "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"
26
27 /**************************/
28 /* srvsvc_NetCharDev */
29 /**************************/
30 static bool test_NetCharDevGetInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
31 const char *devname)
32 {
33 NTSTATUS status;
34 struct srvsvc_NetCharDevGetInfo r;
35 union srvsvc_NetCharDevInfo info;
36 uint32_t levels[] = {0, 1};
37 int i;
38
39 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
40 r.in.device_name = devname;
41 r.out.info = &info;
42
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");
50 }
51
52 return true;
53 }
54
55 static bool test_NetCharDevControl(struct dcerpc_pipe *p, struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
56 const char *devname)
57 {
58 NTSTATUS status;
59 struct srvsvc_NetCharDevControl r;
60 uint32_t opcodes[] = {0, 1};
61 int i;
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(p, 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,
/* [<][>][^][v][top][bottom][index][help] */
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
91 ZERO_STRUCT(info_ctr);
92
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;
99
100 for (i=0;i<ARRAY_SIZE(levels);i++) {
101 int j;
102
103 info_ctr.level = levels[i];
104
105 switch(info_ctr.level) {
106 case 0:
107 ZERO_STRUCT(c0);
108 info_ctr.ctr.ctr0 = &c0;
109 break;
110 case 1:
111 ZERO_STRUCT(c1);
112 info_ctr.ctr.ctr0 = &c1;
113 break;
114 }
115
116 torture_comment(tctx, "testing NetCharDevEnum level %u\n", info_ctr.level);
117 status = dcerpc_srvsvc_NetCharDevEnum(p, tctx, &r);
118 torture_assert_ntstatus_ok(tctx, status, "NetCharDevEnum failed");
119 if (!W_ERROR_IS_OK(r.out.result)) {
120 torture_comment(tctx, "NetCharDevEnum failed: %s\n", win_errstr(r.out.result));
121 continue;
122 }
123
124 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */
125 if (info_ctr.level == 1) {
126 for (j=0;j<r.out.info_ctr->ctr.ctr1->count;j++) {
127 const char *device;
128 device = r.out.info_ctr->ctr.ctr1->array[j].device;
129 if (!test_NetCharDevGetInfo(p, tctx, device)) {
130 return false;
131 }
132 if (!test_NetCharDevControl(p, tctx, device)) {
133 return false;
134 }
135 }
136 }
137 }
138
139 return true;
140 }
141
142 /**************************/
143 /* srvsvc_NetCharDevQ */
144 /**************************/
145 static bool test_NetCharDevQGetInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
146 const char *devicequeue)
147 {
148 NTSTATUS status;
149 struct srvsvc_NetCharDevQGetInfo r;
150 union srvsvc_NetCharDevQInfo info;
151 uint32_t levels[] = {0, 1};
152 int i;
153
154 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
155 r.in.queue_name = devicequeue;
156 r.in.user = talloc_asprintf(tctx,"Administrator");
157 r.out.info = &info;
158
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");
166 }
167
168 return true;
169 }
170
171 #if 0
172 static bool test_NetCharDevQSetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
173 const char *devicequeue)
174 {
175 NTSTATUS status;
176 struct srvsvc_NetCharDevQSetInfo r;
177 uint32_t parm_error;
178 uint32_t levels[] = {0, 1};
179 int i;
180 bool ret = true;
181
182 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
183 r.in.queue_name = devicequeue;
184
185 for (i=0;i<ARRAY_SIZE(levels);i++) {
186 ZERO_STRUCT(r.out);
187 parm_error = 0;
188 r.in.level = levels[i];
189 d_printf("testing NetCharDevQSetInfo level %u on devicequeue '%s'\n",
190 r.in.level, devicequeue);
191 switch (r.in.level) {
192 case 0:
193 r.in.info.info0 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo0);
194 r.in.info.info0->device = r.in.queue_name;
195 break;
196 case 1:
197 r.in.info.info1 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo1);
198 r.in.info.info1->device = r.in.queue_name;
199 r.in.info.info1->priority = 0x000;
200 r.in.info.info1->devices = r.in.queue_name;
201 r.in.info.info1->users = 0x000;
202 r.in.info.info1->num_ahead = 0x000;
203 break;
204 default:
205 break;
206 }
207 r.in.parm_error = &parm_error;
208 status = dcerpc_srvsvc_NetCharDevQSetInfo(p, mem_ctx, &r);
209 if (!NT_STATUS_IS_OK(status)) {
210 d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n",
211 r.in.level, r.in.queue_name, nt_errstr(status));
212 ret = false;
213 continue;
214 }
215 if (!W_ERROR_IS_OK(r.out.result)) {
216 d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n",
217 r.in.level, r.in.queue_name, win_errstr(r.out.result));
218 continue;
219 }
220 }
221
222 return ret;
223 }
224 #endif
225
226 static bool test_NetCharDevQEnum(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
227 struct dcerpc_pipe *p)
228 {
229 NTSTATUS status;
230 struct srvsvc_NetCharDevQEnum r;
231 struct srvsvc_NetCharDevQInfoCtr info_ctr;
232 struct srvsvc_NetCharDevQCtr0 c0;
233 struct srvsvc_NetCharDevQCtr1 c1;
234 uint32_t totalentries = 0;
235 uint32_t levels[] = {0, 1};
236 int i;
237
238 ZERO_STRUCT(info_ctr);
239
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;
247
248 for (i=0;i<ARRAY_SIZE(levels);i++) {
249 int j;
250
251 info_ctr.level = levels[i];
252
253 switch (info_ctr.level) {
254 case 0:
255 ZERO_STRUCT(c0);
256 info_ctr.ctr.ctr0 = &c0;
257 break;
258 case 1:
259 ZERO_STRUCT(c1);
260 info_ctr.ctr.ctr1 = &c1;
261 break;
262 }
263 torture_comment(tctx, "testing NetCharDevQEnum level %u\n", info_ctr.level);
264 status = dcerpc_srvsvc_NetCharDevQEnum(p, tctx, &r);
265 torture_assert_ntstatus_ok(tctx, status, "NetCharDevQEnum failed");
266 if (!W_ERROR_IS_OK(r.out.result)) {
267 torture_comment(tctx, "NetCharDevQEnum failed: %s\n", win_errstr(r.out.result));
268 continue;
269 }
270
271 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */
272 if (info_ctr.level == 1) {
273 for (j=0;j<r.out.info_ctr->ctr.ctr1->count;j++) {
274 const char *device;
275 device = r.out.info_ctr->ctr.ctr1->array[j].device;
276 if (!test_NetCharDevQGetInfo(p, tctx, device)) {
277 return false;
278 }
279 }
280 }
281 }
282
283 return true;
284 }
285
286 /**************************/
287 /* srvsvc_NetConn */
288 /**************************/
289 static bool test_NetConnEnum(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
290 struct dcerpc_pipe *p)
291 {
292 NTSTATUS status;
293 struct srvsvc_NetConnEnum r;
294 struct srvsvc_NetConnInfoCtr info_ctr;
295 struct srvsvc_NetConnCtr0 c0;
296 struct srvsvc_NetConnCtr1 c1;
297 uint32_t totalentries = 0;
298 uint32_t levels[] = {0, 1};
299 int i;
300
301 ZERO_STRUCT(info_ctr);
302
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;
310
311 for (i=0;i<ARRAY_SIZE(levels);i++) {
312 info_ctr.level = levels[i];
313
314 switch (info_ctr.level) {
315 case 0:
316 ZERO_STRUCT(c0);
317 info_ctr.ctr.ctr0 = &c0;
318 break;
319 case 1:
320 ZERO_STRUCT(c1);
321 info_ctr.ctr.ctr1 = &c1;
322 break;
323 }
324
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));
330 }
331 }
332
333 return true;
334 }
335
336 /**************************/
337 /* srvsvc_NetFile */
338 /**************************/
339 static bool test_NetFileEnum(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
340 struct dcerpc_pipe *p)
341 {
342 NTSTATUS status;
343 struct srvsvc_NetFileEnum r;
344 struct srvsvc_NetFileInfoCtr info_ctr;
345 struct srvsvc_NetFileCtr2 c2;
346 struct srvsvc_NetFileCtr3 c3;
347 uint32_t totalentries = 0;
348 uint32_t levels[] = {2, 3};
349 int i;
350
351 ZERO_STRUCT(info_ctr);
352
353 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
354 r.in.path = NULL;
355 r.in.user = NULL;
356 r.in.info_ctr = &info_ctr;
357 r.in.max_buffer = (uint32_t)4096;
358 r.in.resume_handle = NULL;
359 r.out.totalentries = &totalentries;
360 r.out.info_ctr = &info_ctr;
361
362 for (i=0;i<ARRAY_SIZE(levels);i++) {
363 info_ctr.level = levels[i];
364
365 switch (info_ctr.level) {
366 case 2:
367 ZERO_STRUCT(c2);
368 info_ctr.ctr.ctr2 = &c2;
369 break;
370 case 3:
371 ZERO_STRUCT(c3);
372 info_ctr.ctr.ctr3 = &c3;
373 break;
374 }
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));
380 }
381 }
382
383 return true;
384 }
385
386 /**************************/
387 /* srvsvc_NetSess */
388 /**************************/
389 static bool test_NetSessEnum(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
390 struct dcerpc_pipe *p)
391 {
392 NTSTATUS status;
393 struct srvsvc_NetSessEnum r;
394 struct srvsvc_NetSessInfoCtr info_ctr;
395 struct srvsvc_NetSessCtr0 c0;
396 struct srvsvc_NetSessCtr1 c1;
397 struct srvsvc_NetSessCtr2 c2;
398 struct srvsvc_NetSessCtr10 c10;
399 struct srvsvc_NetSessCtr502 c502;
400 uint32_t totalentries = 0;
401 uint32_t levels[] = {0, 1, 2, 10, 502};
402 int i;
403
404 ZERO_STRUCT(info_ctr);
405
406 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
407 r.in.client = NULL;
408 r.in.user = NULL;
409 r.in.info_ctr = &info_ctr;
410 r.in.max_buffer = (uint32_t)-1;
411 r.in.resume_handle = NULL;
412 r.out.totalentries = &totalentries;
413 r.out.info_ctr = &info_ctr;
414
415 for (i=0;i<ARRAY_SIZE(levels);i++) {
416 info_ctr.level = levels[i];
417
418 switch (info_ctr.level) {
419 case 0:
420 ZERO_STRUCT(c0);
421 info_ctr.ctr.ctr0 = &c0;
422 break;
423 case 1:
424 ZERO_STRUCT(c1);
425 info_ctr.ctr.ctr1 = &c1;
426 break;
427 case 2:
428 ZERO_STRUCT(c2);
429 info_ctr.ctr.ctr2 = &c2;
430 break;
431 case 10:
432 ZERO_STRUCT(c10);
433 info_ctr.ctr.ctr10 = &c10;
434 break;
435 case 502:
436 ZERO_STRUCT(c502);
437 info_ctr.ctr.ctr502 = &c502;
438 break;
439 }
440
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));
446 }
447 }
448
449 return true;
450 }
451
452 /**************************/
453 /* srvsvc_NetShare */
454 /**************************/
455 static bool test_NetShareCheck(struct dcerpc_pipe *p, struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
456 const char *device_name)
457 {
458 NTSTATUS status;
459 struct srvsvc_NetShareCheck r;
460 enum srvsvc_ShareType type;
461
462 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
463 r.in.device_name = device_name;
464 r.out.type = &type;
465
466 torture_comment(tctx,
467 "testing NetShareCheck on device '%s'\n", r.in.device_name);
468
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");
472
473 return true;
474 }
475
476 static bool test_NetShareGetInfo(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
477 struct dcerpc_pipe *p,
478 const char *sharename, bool admin)
479 {
480 NTSTATUS status;
481 struct srvsvc_NetShareGetInfo r;
482 union srvsvc_NetShareInfo info;
483 struct {
484 uint32_t level;
485 WERROR anon_status;
486 WERROR admin_status;
487 } levels[] = {
488 { 0, WERR_OK, WERR_OK },
489 { 1, WERR_OK, WERR_OK },
490 { 2, WERR_ACCESS_DENIED, WERR_OK },
491 { 501, WERR_OK, WERR_OK },
492 { 502, WERR_ACCESS_DENIED, WERR_OK },
493 { 1005, WERR_OK, WERR_OK },
494 };
495 int i;
496
497 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
498 r.in.share_name = sharename;
499 r.out.info = &info;
500
501 for (i=0;i<ARRAY_SIZE(levels);i++) {
502 WERROR expected;
503
504 r.in.level = levels[i].level;
505 expected = levels[i].anon_status;
506 if (admin) expected = levels[i].admin_status;
507
508 torture_comment(tctx, "testing NetShareGetInfo level %u on share '%s'\n",
509 r.in.level, r.in.share_name);
510
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");
514
515 if (r.in.level != 2) continue;
516 if (!r.out.info->info2 || !r.out.info->info2->path) continue;
517 if (!test_NetShareCheck(p, tctx, r.out.info->info2->path)) {
518 return false;
519 }
520 }
521
522 return true;
523 }
524
525 static bool test_NetShareGetInfoAdminFull(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
526 struct dcerpc_pipe *p)
527 {
528 return test_NetShareGetInfo(tctx, p, "ADMIN$", true);
529 }
530
531 static bool test_NetShareGetInfoAdminAnon(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
532 struct dcerpc_pipe *p)
533 {
534 return test_NetShareGetInfo(tctx, p, "ADMIN$", false);
535 }
536
537 static bool test_NetShareAddSetDel(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
538 struct dcerpc_pipe *p)
539 {
540 NTSTATUS status;
541 struct srvsvc_NetShareAdd a;
542 struct srvsvc_NetShareSetInfo r;
543 struct srvsvc_NetShareGetInfo q;
544 struct srvsvc_NetShareDel d;
545 struct sec_desc_buf sd_buf;
546 union srvsvc_NetShareInfo info;
547 struct {
548 uint32_t level;
549 WERROR expected;
550 } levels[] = {
551 { 0, WERR_UNKNOWN_LEVEL },
552 { 1, WERR_OK },
553 { 2, WERR_OK },
554 { 501, WERR_UNKNOWN_LEVEL },
555 { 502, WERR_OK },
556 { 1004, WERR_OK },
557 { 1005, WERR_OK },
558 { 1006, WERR_OK },
559 /* { 1007, WERR_OK }, */
560 { 1501, WERR_OK },
561 };
562 int i;
563
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");
567
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;
577
578 a.in.info = &info;
579 a.in.level = 2;
580 a.in.parm_error = NULL;
581
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");
585
586 r.in.parm_error = NULL;
587
588 q.in.level = 502;
589
590 for (i = 0; i < ARRAY_SIZE(levels); i++) {
591
592 r.in.level = levels[i].level;
593 ZERO_STRUCT(r.out);
594
595 torture_comment(tctx, "testing NetShareSetInfo level %u on share '%s'\n",
596 r.in.level, r.in.share_name);
597
598 switch (levels[i].level) {
599 case 0:
600 info.info0 = talloc(tctx, struct srvsvc_NetShareInfo0);
601 info.info0->name = r.in.share_name;
602 break;
603 case 1:
604 info.info1 = talloc(tctx, struct srvsvc_NetShareInfo1);
605 info.info1->name = r.in.share_name;
606 info.info1->type = STYPE_DISKTREE;
607 info.info1->comment = talloc_strdup(tctx, "test comment 1");
608 break;
609 case 2:
610 info.info2 = talloc(tctx, struct srvsvc_NetShareInfo2);
611 info.info2->name = r.in.share_name;
612 info.info2->type = STYPE_DISKTREE;
613 info.info2->comment = talloc_strdup(tctx, "test comment 2");
614 info.info2->permissions = 0;
615 info.info2->max_users = 2;
616 info.info2->current_users = 1;
617 info.info2->path = talloc_strdup(tctx, "::BLaH::"); /* "C:\\"); */
618 info.info2->password = NULL;
619 break;
620 case 501:
621 info.info501 = talloc(tctx, struct srvsvc_NetShareInfo501);
622 info.info501->name = r.in.share_name;
623 info.info501->type = STYPE_DISKTREE;
624 info.info501->comment = talloc_strdup(tctx, "test comment 501");
625 info.info501->csc_policy = 0;
626 break;
627 case 502:
628 ZERO_STRUCT(sd_buf);
629 info.info502 = talloc(tctx, struct srvsvc_NetShareInfo502);
630 info.info502->name = r.in.share_name;
631 info.info502->type = STYPE_DISKTREE;
632 info.info502->comment = talloc_strdup(tctx, "test comment 502");
633 info.info502->permissions = 0;
634 info.info502->max_users = 502;
635 info.info502->current_users = 1;
636 info.info502->path = talloc_strdup(tctx, "C:\\");
637 info.info502->password = NULL;
638 info.info502->sd_buf = sd_buf;
639 break;
640 case 1004:
641 info.info1004 = talloc(tctx, struct srvsvc_NetShareInfo1004);
642 info.info1004->comment = talloc_strdup(tctx, "test comment 1004");
643 break;
644 case 1005:
645 info.info1005 = talloc(tctx, struct srvsvc_NetShareInfo1005);
646 info.info1005->dfs_flags = 0;
647 break;
648 case 1006:
649 info.info1006 = talloc(tctx, struct srvsvc_NetShareInfo1006);
650 info.info1006->max_users = 1006;
651 break;
652 /* case 1007:
653 info.info1007 = talloc(tctx, struct srvsvc_NetShareInfo1007);
654 info.info1007->flags = 0;
655 info.info1007->alternate_directory_name = talloc_strdup(tctx, "test");
656 break;
657 */
658 case 1501:
659 info.info1501 = talloc_zero(tctx, struct sec_desc_buf);
660 break;
661 }
662
663 r.in.info = &info;
664
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");
668
669 q.in.share_name = r.in.share_name;
670 q.out.info = &info;
671
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");
675
676 torture_assert_str_equal(tctx, q.out.info->info502->name, r.in.share_name,
677 "share name invalid");
678
679 switch (levels[i].level) {
680 case 0:
681 break;
682 case 1:
683 torture_assert_str_equal(tctx, q.out.info->info502->comment, "test comment 1", "comment");
684 break;
685 case 2:
686 torture_assert_str_equal(tctx, q.out.info->info2->comment, "test comment 2", "comment");
687 torture_assert_int_equal(tctx, q.out.info->info2->max_users, 2, "max users");
688 torture_assert_str_equal(tctx, q.out.info->info2->path, "C:\\", "path");
689 break;
690 case 501:
691 torture_assert_str_equal(tctx, q.out.info->info501->comment, "test comment 501", "comment");
692 break;
693 case 502:
694 torture_assert_str_equal(tctx, q.out.info->info502->comment, "test comment 502", "comment");
695 torture_assert_int_equal(tctx, q.out.info->info502->max_users, 502, "max users");
696 torture_assert_str_equal(tctx, q.out.info->info502->path, "C:\\", "path");
697 break;
698 case 1004:
699 torture_assert_str_equal(tctx, q.out.info->info1004->comment, "test comment 1004",
700 "comment");
701 break;
702 case 1005:
703 break;
704 case 1006:
705 torture_assert_int_equal(tctx, q.out.info->info1006->max_users, 1006, "Max users");
706 break;
707 /* case 1007:
708 break;
709 */
710 case 1501:
711 break;
712 }
713 }
714
715 d.in.share_name = r.in.share_name;
716 d.in.reserved = 0;
717
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");
721
722 return true;
723 }
724
725 /**************************/
726 /* srvsvc_NetShare */
727 /**************************/
728 static bool test_NetShareEnumAll(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
729 struct dcerpc_pipe *p,
730 bool admin)
731 {
732 NTSTATUS status;
733 struct srvsvc_NetShareEnumAll r;
734 struct srvsvc_NetShareInfoCtr info_ctr;
735 struct srvsvc_NetShareCtr0 c0;
736 struct srvsvc_NetShareCtr1 c1;
737 struct srvsvc_NetShareCtr2 c2;
738 struct srvsvc_NetShareCtr501 c501;
739 struct srvsvc_NetShareCtr502 c502;
740 uint32_t totalentries = 0;
741 struct {
742 uint32_t level;
743 WERROR anon_status;
744 WERROR admin_status;
745 } levels[] = {
746 { 0, WERR_OK, WERR_OK },
747 { 1, WERR_OK, WERR_OK },
748 { 2, WERR_ACCESS_DENIED, WERR_OK },
749 { 501, WERR_ACCESS_DENIED, WERR_OK },
750 { 502, WERR_ACCESS_DENIED, WERR_OK },
751 };
752 int i;
753 uint32_t resume_handle;
754
755 ZERO_STRUCT(info_ctr);
756
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;
764
765 for (i=0;i<ARRAY_SIZE(levels);i++) {
766
767 int j;
768 WERROR expected;
769
770 info_ctr.level = levels[i].level;
771
772 switch (info_ctr.level) {
773 case 0:
774 ZERO_STRUCT(c0);
775 info_ctr.ctr.ctr0 = &c0;
776 break;
777 case 1:
778 ZERO_STRUCT(c1);
779 info_ctr.ctr.ctr1 = &c1;
780 break;
781 case 2:
782 ZERO_STRUCT(c2);
783 info_ctr.ctr.ctr2 = &c2;
784 break;
785 case 501:
786 ZERO_STRUCT(c501);
787 info_ctr.ctr.ctr501 = &c501;
788 break;
789 case 502:
790 ZERO_STRUCT(c502);
791 info_ctr.ctr.ctr502 = &c502;
792 break;
793 }
794
795 expected = levels[i].anon_status;
796 if (admin) expected = levels[i].admin_status;
797
798 resume_handle = 0;
799
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");
804
805 /* call srvsvc_NetShareGetInfo for each returned share */
806 if (info_ctr.level == 2 && r.out.info_ctr->ctr.ctr2) {
807 for (j=0;j<r.out.info_ctr->ctr.ctr2->count;j++) {
808 const char *name;
809 name = r.out.info_ctr->ctr.ctr2->array[j].name;
810 if (!test_NetShareGetInfo(tctx, p, name, admin)) {
811 return false;
812 }
813 }
814 }
815 }
816
817 return true;
818 }
819
820 static bool test_NetShareEnumAllFull(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
821 struct dcerpc_pipe *p)
822 {
823 return test_NetShareEnumAll(tctx, p, true);
824 }
825
826 static bool test_NetShareEnumAllAnon(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
827 struct dcerpc_pipe *p)
828 {
829 return test_NetShareEnumAll(tctx, p, false);
830 }
831
832 static bool test_NetShareEnum(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
833 struct dcerpc_pipe *p, bool admin)
834 {
835 NTSTATUS status;
836 struct srvsvc_NetShareEnum r;
837 struct srvsvc_NetShareInfoCtr info_ctr;
838 struct srvsvc_NetShareCtr0 c0;
839 struct srvsvc_NetShareCtr1 c1;
840 struct srvsvc_NetShareCtr2 c2;
841 struct srvsvc_NetShareCtr501 c501;
842 struct srvsvc_NetShareCtr502 c502;
843 uint32_t totalentries = 0;
844 struct {
845 uint32_t level;
846 WERROR anon_status;
847 WERROR admin_status;
848 } levels[] = {
849 { 0, WERR_OK, WERR_OK },
850 { 1, WERR_OK, WERR_OK },
851 { 2, WERR_ACCESS_DENIED, WERR_OK },
852 { 501, WERR_UNKNOWN_LEVEL, WERR_UNKNOWN_LEVEL },
853 { 502, WERR_ACCESS_DENIED, WERR_OK },
854 };
855 int i;
856
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;
863
864 for (i=0;i<ARRAY_SIZE(levels);i++) {
865 WERROR expected;
866
867 info_ctr.level = levels[i].level;
868
869 switch (info_ctr.level) {
870 case 0:
871 ZERO_STRUCT(c0);
872 info_ctr.ctr.ctr0 = &c0;
873 break;
874 case 1:
875 ZERO_STRUCT(c1);
876 info_ctr.ctr.ctr1 = &c1;
877 break;
878 case 2:
879 ZERO_STRUCT(c2);
880 info_ctr.ctr.ctr2 = &c2;
881 break;
882 case 501:
883 ZERO_STRUCT(c501);
884 info_ctr.ctr.ctr501 = &c501;
885 break;
886 case 502:
887 ZERO_STRUCT(c502);
888 info_ctr.ctr.ctr502 = &c502;
889 break;
890 }
891
892 expected = levels[i].anon_status;
893 if (admin) expected = levels[i].admin_status;
894
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");
899 }
900
901 return true;
902 }
903
904 static bool test_NetShareEnumFull(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
905 struct dcerpc_pipe *p)
906 {
907 return test_NetShareEnum(tctx, p, true);
908 }
909
910 static bool test_NetShareEnumAnon(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
911 struct dcerpc_pipe *p)
912 {
913 return test_NetShareEnum(tctx, p, false);
914 }
915
916 /**************************/
917 /* srvsvc_NetSrv */
918 /**************************/
919 static bool test_NetSrvGetInfo(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
920 struct dcerpc_pipe *p)
921 {
922 NTSTATUS status;
923 struct srvsvc_NetSrvGetInfo r;
924 union srvsvc_NetSrvInfo info;
925 uint32_t levels[] = {100, 101, 102, 502, 503};
926 int i;
927
928 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
929
930 for (i=0;i<ARRAY_SIZE(levels);i++) {
931 r.in.level = levels[i];
932 r.out.info = &info;
933 torture_comment(tctx, "testing NetSrvGetInfo level %u\n", r.in.level);
934 status = dcerpc_srvsvc_NetSrvGetInfo(p, tctx, &r);
935 torture_assert_ntstatus_ok(tctx, status, "NetSrvGetInfo failed");
936 if (!W_ERROR_IS_OK(r.out.result)) {
937 torture_comment(tctx, "NetSrvGetInfo failed: %s\n", win_errstr(r.out.result));
938 }
939 }
940
941 return true;
942 }
943
944 /**************************/
945 /* srvsvc_NetDisk */
946 /**************************/
947 static bool test_NetDiskEnum(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
948 struct dcerpc_pipe *p)
949 {
950 NTSTATUS status;
951 struct srvsvc_NetDiskEnum r;
952 struct srvsvc_NetDiskInfo info;
953 uint32_t totalentries = 0;
954 uint32_t levels[] = {0};
955 int i;
956 uint32_t resume_handle=0;
957
958 ZERO_STRUCT(info);
959
960 r.in.server_unc = NULL;
961 r.in.resume_handle = &resume_handle;
962 r.in.info = &info;
963 r.out.info = &info;
964 r.out.totalentries = &totalentries;
965 r.out.resume_handle = &resume_handle;
966
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");
974 }
975
976 return true;
977 }
978
979 /**************************/
980 /* srvsvc_NetTransport */
981 /**************************/
982 static bool test_NetTransportEnum(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
983 struct dcerpc_pipe *p)
984 {
985 NTSTATUS status;
986 struct srvsvc_NetTransportEnum r;
987 struct srvsvc_NetTransportInfoCtr transports;
988 struct srvsvc_NetTransportCtr0 ctr0;
989 struct srvsvc_NetTransportCtr1 ctr1;
990
991 uint32_t totalentries = 0;
992 uint32_t levels[] = {0, 1};
993 int i;
994
995 ZERO_STRUCT(transports);
996
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;
1003
1004 for (i=0;i<ARRAY_SIZE(levels);i++) {
1005 transports.level = levels[i];
1006 switch (transports.level) {
1007 case 0:
1008 ZERO_STRUCT(ctr0);
1009 transports.ctr.ctr0 = &ctr0;
1010 break;
1011 case 1:
1012 ZERO_STRUCT(ctr1);
1013 transports.ctr.ctr1 = &ctr1;
1014 break;
1015 }
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));
1021 }
1022 }
1023
1024 return true;
1025 }
1026
1027 /**************************/
1028 /* srvsvc_NetRemoteTOD */
1029 /**************************/
1030 static bool test_NetRemoteTOD(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
1031 struct dcerpc_pipe *p)
1032 {
1033 NTSTATUS status;
1034 struct srvsvc_NetRemoteTOD r;
1035 struct srvsvc_NetRemoteTODInfo *info = NULL;
1036
1037 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
1038 r.out.info = &info;
1039
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");
1044
1045 return true;
1046 }
1047
1048 /**************************/
1049 /* srvsvc_NetName */
1050 /**************************/
1051
1052 static bool test_NetNameValidate(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
1053 struct dcerpc_pipe *p)
1054 {
1055 NTSTATUS status;
1056 struct srvsvc_NetNameValidate r;
1057 char *invalidc;
1058 char *name;
1059 int i, n, min, max;
1060
1061 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1062 r.in.flags = 0x0;
1063
1064 d_printf("testing NetNameValidate\n");
1065
1066 /* valid path types only between 1 and 13 */
1067 for (i = 1; i < 14; i++) {
1068
1069 again:
1070 /* let's limit ourselves to a maximum of 4096 bytes */
1071 r.in.name = name = talloc_array(tctx, char, 4097);
1072 max = 4096;
1073 min = 0;
1074 n = max;
1075
1076 while (1) {
1077
1078 /* Find maximum length accepted by this type */
1079 ZERO_STRUCT(r.out);
1080 r.in.name_type = i;
1081 memset(name, 'A', n);
1082 name[n] = '\0';
1083
1084 status = dcerpc_srvsvc_NetNameValidate(p, tctx, &r);
1085 if (!NT_STATUS_IS_OK(status)) {
1086 d_printf("NetNameValidate failed while checking maximum size (%s)\n",
1087 nt_errstr(status));
1088 break;
1089 }
1090
1091 if (W_ERROR_IS_OK(r.out.result)) {
1092 min = n;
1093 n += (max - min + 1)/2;
1094 continue;
1095
1096 } else {
1097 if ((min + 1) >= max) break; /* found it */
1098
1099 max = n;
1100 n -= (max - min)/2;
1101 continue;
1102 }
1103 }
1104
1105 talloc_free(name);
1106
1107 d_printf("Maximum length for type %2d, flags %08x: %d\n", i, r.in.flags, max);
1108
1109 /* find invalid chars for this type check only ASCII between 0x20 and 0x7e */
1110
1111 invalidc = talloc_strdup(tctx, "");
1112
1113 for (n = 0x20; n < 0x7e; n++) {
1114 r.in.name = name = talloc_asprintf(tctx, "%c", (char)n);
1115
1116 status = dcerpc_srvsvc_NetNameValidate(p, tctx, &r);
1117 if (!NT_STATUS_IS_OK(status)) {
1118 d_printf("NetNameValidate failed while checking valid chars (%s)\n",
1119 nt_errstr(status));
1120 break;
1121 }
1122
1123 if (!W_ERROR_IS_OK(r.out.result)) {
1124 invalidc = talloc_asprintf_append_buffer(invalidc, "%c", (char)n);
1125 }
1126
1127 talloc_free(name);
1128 }
1129
1130 d_printf(" Invalid chars for type %2d, flags %08x: \"%s\"\n", i, r.in.flags, invalidc);
1131
1132 /* only two values are accepted for flags: 0x0 and 0x80000000 */
1133 if (r.in.flags == 0x0) {
1134 r.in.flags = 0x80000000;
1135 goto again;
1136 }
1137
1138 r.in.flags = 0x0;
1139 }
1140
1141 return true;
1142 }
1143
1144 struct torture_suite *torture_rpc_srvsvc(TALLOC_CTX *mem_ctx)
/* [<][>][^][v][top][bottom][index][help] */
1145 {
1146 struct torture_suite *suite = torture_suite_create(mem_ctx, "SRVSVC");
1147 struct torture_rpc_tcase *tcase;
1148 struct torture_test *test;
1149
1150 tcase = torture_suite_add_rpc_iface_tcase(suite, "srvsvc (admin access)", &ndr_table_srvsvc);
1151
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);
1168
1169 tcase = torture_suite_add_anon_rpc_iface_tcase(suite,
1170 "srvsvc anonymous access",
1171 &ndr_table_srvsvc);
1172
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);
1179
1180 return suite;
1181 }