• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source4/torture/rpc/
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/**************************/
30static bool test_NetCharDevGetInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
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
55static bool test_NetCharDevControl(struct dcerpc_pipe *p, struct torture_context *tctx,
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
79static 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
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/**************************/
145static bool test_NetCharDevQGetInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
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
172static bool test_NetCharDevQSetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
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
226static bool test_NetCharDevQEnum(struct torture_context *tctx,
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/**************************/
289static bool test_NetConnEnum(struct torture_context *tctx,
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/**************************/
339static bool test_NetFileEnum(struct torture_context *tctx,
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/**************************/
389static bool test_NetSessEnum(struct torture_context *tctx,
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/**************************/
455static bool test_NetShareCheck(struct dcerpc_pipe *p, struct torture_context *tctx,
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
476static bool test_NetShareGetInfo(struct torture_context *tctx,
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
525static bool test_NetShareGetInfoAdminFull(struct torture_context *tctx,
526					  struct dcerpc_pipe *p)
527{
528	return test_NetShareGetInfo(tctx, p, "ADMIN$", true);
529}
530
531static bool test_NetShareGetInfoAdminAnon(struct torture_context *tctx,
532					  struct dcerpc_pipe *p)
533{
534	return test_NetShareGetInfo(tctx, p, "ADMIN$", false);
535}
536
537static bool test_NetShareAddSetDel(struct torture_context *tctx,
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/**************************/
728static bool test_NetShareEnumAll(struct torture_context *tctx,
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
820static bool test_NetShareEnumAllFull(struct torture_context *tctx,
821			      struct dcerpc_pipe *p)
822{
823	return test_NetShareEnumAll(tctx, p, true);
824}
825
826static bool test_NetShareEnumAllAnon(struct torture_context *tctx,
827			      struct dcerpc_pipe *p)
828{
829	return test_NetShareEnumAll(tctx, p, false);
830}
831
832static bool test_NetShareEnum(struct torture_context *tctx,
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
904static bool test_NetShareEnumFull(struct torture_context *tctx,
905				  struct dcerpc_pipe *p)
906{
907	return test_NetShareEnum(tctx, p, true);
908}
909
910static bool test_NetShareEnumAnon(struct torture_context *tctx,
911				  struct dcerpc_pipe *p)
912{
913	return test_NetShareEnum(tctx, p, false);
914}
915
916/**************************/
917/* srvsvc_NetSrv          */
918/**************************/
919static bool test_NetSrvGetInfo(struct torture_context *tctx,
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/**************************/
947static bool test_NetDiskEnum(struct torture_context *tctx,
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/**************************/
982static bool test_NetTransportEnum(struct torture_context *tctx,
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/**************************/
1030static bool test_NetRemoteTOD(struct torture_context *tctx,
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
1052static bool test_NetNameValidate(struct torture_context *tctx,
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
1069again:
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
1144struct torture_suite *torture_rpc_srvsvc(TALLOC_CTX *mem_ctx)
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}
1182