• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source4/rpc_server/srvsvc/
1/*
2   Unix SMB/CIFS implementation.
3
4   endpoint server for the srvsvc pipe
5
6   Copyright (C) Stefan (metze) Metzmacher 2004-2006
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program.  If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "includes.h"
23#include "ntvfs/ntvfs.h"
24#include "rpc_server/dcerpc_server.h"
25#include "librpc/gen_ndr/ndr_srvsvc.h"
26#include "rpc_server/common/common.h"
27#include "auth/auth.h"
28#include "libcli/security/security.h"
29#include "system/time.h"
30#include "rpc_server/srvsvc/proto.h"
31#include "param/param.h"
32
33#define SRVSVC_CHECK_ADMIN_ACCESS do { \
34	struct security_token *t = dce_call->conn->auth_state.session_info->security_token; \
35	if (!security_token_has_builtin_administrators(t) && \
36	    !security_token_has_sid_string(t, SID_BUILTIN_SERVER_OPERATORS)) { \
37	    	return WERR_ACCESS_DENIED; \
38	} \
39} while (0)
40
41/*
42  srvsvc_NetCharDevEnum
43*/
44static WERROR dcesrv_srvsvc_NetCharDevEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
45				      struct srvsvc_NetCharDevEnum *r)
46{
47	*r->out.totalentries = 0;
48
49	switch (r->in.info_ctr->level) {
50	case 0:
51		r->out.info_ctr->ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetCharDevCtr0);
52		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr0);
53
54		r->out.info_ctr->ctr.ctr0->count = 0;
55		r->out.info_ctr->ctr.ctr0->array = NULL;
56
57		return WERR_NOT_SUPPORTED;
58
59	case 1:
60		r->out.info_ctr->ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetCharDevCtr1);
61		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr1);
62
63		r->out.info_ctr->ctr.ctr1->count = 0;
64		r->out.info_ctr->ctr.ctr1->array = NULL;
65
66		return WERR_NOT_SUPPORTED;
67
68	default:
69		return WERR_UNKNOWN_LEVEL;
70	}
71
72	return WERR_OK;
73}
74
75
76/*
77  srvsvc_NetCharDevGetInfo
78*/
79static WERROR dcesrv_srvsvc_NetCharDevGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
80		       struct srvsvc_NetCharDevGetInfo *r)
81{
82	ZERO_STRUCTP(r->out.info);
83
84	switch (r->in.level) {
85	case 0:
86	{
87		return WERR_NOT_SUPPORTED;
88	}
89	case 1:
90	{
91		return WERR_NOT_SUPPORTED;
92	}
93	default:
94		return WERR_UNKNOWN_LEVEL;
95	}
96
97	return WERR_UNKNOWN_LEVEL;
98}
99
100
101/*
102  srvsvc_NetCharDevControl
103*/
104static WERROR dcesrv_srvsvc_NetCharDevControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
105		       struct srvsvc_NetCharDevControl *r)
106{
107	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
108}
109
110
111/*
112  srvsvc_NetCharDevQEnum
113*/
114static WERROR dcesrv_srvsvc_NetCharDevQEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
115				     struct srvsvc_NetCharDevQEnum *r)
116{
117	*r->out.totalentries = 0;
118
119	switch (r->in.info_ctr->level) {
120	case 0:
121	{
122		r->out.info_ctr->ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetCharDevQCtr0);
123		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr0);
124
125		r->out.info_ctr->ctr.ctr0->count = 0;
126		r->out.info_ctr->ctr.ctr0->array = NULL;
127
128		return WERR_NOT_SUPPORTED;
129	}
130	case 1:
131	{
132		r->out.info_ctr->ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetCharDevQCtr1);
133		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr1);
134
135		r->out.info_ctr->ctr.ctr1->count = 0;
136		r->out.info_ctr->ctr.ctr1->array = NULL;
137
138		return WERR_NOT_SUPPORTED;
139	}
140	default:
141		return WERR_UNKNOWN_LEVEL;
142	}
143
144	return WERR_UNKNOWN_LEVEL;
145}
146
147
148/*
149  srvsvc_NetCharDevQGetInfo
150*/
151static WERROR dcesrv_srvsvc_NetCharDevQGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
152					struct srvsvc_NetCharDevQGetInfo *r)
153{
154	ZERO_STRUCTP(r->out.info);
155
156	switch (r->in.level) {
157	case 0:
158	{
159		return WERR_NOT_SUPPORTED;
160	}
161	case 1:
162	{
163		return WERR_NOT_SUPPORTED;
164	}
165	default:
166		return WERR_UNKNOWN_LEVEL;
167	}
168
169	return WERR_UNKNOWN_LEVEL;
170}
171
172
173/*
174  srvsvc_NetCharDevQSetInfo
175*/
176static WERROR dcesrv_srvsvc_NetCharDevQSetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
177		       struct srvsvc_NetCharDevQSetInfo *r)
178{
179	switch (r->in.level) {
180	case 0:
181	{
182		if (r->in.parm_error) {
183			r->out.parm_error = r->in.parm_error;
184		}
185		return WERR_NOT_SUPPORTED;
186	}
187	case 1:
188	{
189		if (r->in.parm_error) {
190			r->out.parm_error = r->in.parm_error;
191		}
192		return WERR_NOT_SUPPORTED;
193	}
194	default:
195		return WERR_UNKNOWN_LEVEL;
196	}
197
198	return WERR_UNKNOWN_LEVEL;
199}
200
201
202/*
203  srvsvc_NetCharDevQPurge
204*/
205static WERROR dcesrv_srvsvc_NetCharDevQPurge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
206		       struct srvsvc_NetCharDevQPurge *r)
207{
208	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
209}
210
211
212/*
213  srvsvc_NetCharDevQPurgeSelf
214*/
215static WERROR dcesrv_srvsvc_NetCharDevQPurgeSelf(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
216					  struct srvsvc_NetCharDevQPurgeSelf *r)
217{
218	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
219}
220
221
222/*
223  srvsvc_NetConnEnum
224*/
225static WERROR dcesrv_srvsvc_NetConnEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
226		       struct srvsvc_NetConnEnum *r)
227{
228	*r->out.totalentries = 0;
229
230	switch (r->in.info_ctr->level) {
231	case 0:
232	{
233		r->out.info_ctr->ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetConnCtr0);
234		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr0);
235
236		r->out.info_ctr->ctr.ctr0->count = 0;
237		r->out.info_ctr->ctr.ctr0->array = NULL;
238
239		return WERR_NOT_SUPPORTED;
240	}
241	case 1:
242	{
243		r->out.info_ctr->ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetConnCtr1);
244		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr1);
245
246		r->out.info_ctr->ctr.ctr1->count = 0;
247		r->out.info_ctr->ctr.ctr1->array = NULL;
248
249		return WERR_NOT_SUPPORTED;
250	}
251	default:
252		return WERR_UNKNOWN_LEVEL;
253	}
254
255	return WERR_UNKNOWN_LEVEL;
256}
257
258
259/*
260  srvsvc_NetFileEnum
261*/
262static WERROR dcesrv_srvsvc_NetFileEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
263				 struct srvsvc_NetFileEnum *r)
264{
265	*r->out.totalentries = 0;
266
267	switch (r->in.info_ctr->level) {
268	case 2:
269	{
270		r->out.info_ctr->ctr.ctr2 = talloc(mem_ctx, struct srvsvc_NetFileCtr2);
271		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr2);
272
273		r->out.info_ctr->ctr.ctr2->count = 0;
274		r->out.info_ctr->ctr.ctr2->array = NULL;
275
276		return WERR_NOT_SUPPORTED;
277	}
278	case 3:
279	{
280		r->out.info_ctr->ctr.ctr3 = talloc(mem_ctx, struct srvsvc_NetFileCtr3);
281		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr3);
282
283		r->out.info_ctr->ctr.ctr3->count = 0;
284		r->out.info_ctr->ctr.ctr3->array = NULL;
285
286		return WERR_NOT_SUPPORTED;
287	}
288	default:
289		return WERR_UNKNOWN_LEVEL;
290	}
291
292	return WERR_UNKNOWN_LEVEL;
293}
294
295
296/*
297  srvsvc_NetFileGetInfo
298*/
299static WERROR dcesrv_srvsvc_NetFileGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
300				    struct srvsvc_NetFileGetInfo *r)
301{
302	ZERO_STRUCTP(r->out.info);
303
304	switch (r->in.level) {
305	case 2:
306	{
307		return WERR_NOT_SUPPORTED;
308	}
309	case 3:
310	{
311		return WERR_NOT_SUPPORTED;
312	}
313	default:
314		return WERR_UNKNOWN_LEVEL;
315	}
316
317	return WERR_UNKNOWN_LEVEL;
318}
319
320
321/*
322  srvsvc_NetFileClose
323*/
324static WERROR dcesrv_srvsvc_NetFileClose(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
325		       struct srvsvc_NetFileClose *r)
326{
327	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
328}
329
330
331/*
332  srvsvc_NetSessEnum
333*/
334static WERROR dcesrv_srvsvc_NetSessEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
335		       struct srvsvc_NetSessEnum *r)
336{
337	*r->out.totalentries = 0;
338
339	switch (r->in.info_ctr->level) {
340	case 0:
341	{
342		r->out.info_ctr->ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetSessCtr0);
343		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr0);
344
345		r->out.info_ctr->ctr.ctr0->count = 0;
346		r->out.info_ctr->ctr.ctr0->array = NULL;
347
348		return WERR_NOT_SUPPORTED;
349	}
350	case 1:
351	{
352		r->out.info_ctr->ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetSessCtr1);
353		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr1);
354
355		r->out.info_ctr->ctr.ctr1->count = 0;
356		r->out.info_ctr->ctr.ctr1->array = NULL;
357
358		return WERR_NOT_SUPPORTED;
359	}
360	case 2:
361	{
362		r->out.info_ctr->ctr.ctr2 = talloc(mem_ctx, struct srvsvc_NetSessCtr2);
363		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr2);
364
365		r->out.info_ctr->ctr.ctr2->count = 0;
366		r->out.info_ctr->ctr.ctr2->array = NULL;
367
368		return WERR_NOT_SUPPORTED;
369	}
370	case 10:
371	{
372		r->out.info_ctr->ctr.ctr10 = talloc(mem_ctx, struct srvsvc_NetSessCtr10);
373		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr10);
374
375		r->out.info_ctr->ctr.ctr10->count = 0;
376		r->out.info_ctr->ctr.ctr10->array = NULL;
377
378		return WERR_NOT_SUPPORTED;
379	}
380	case 502:
381	{
382		r->out.info_ctr->ctr.ctr502 = talloc(mem_ctx, struct srvsvc_NetSessCtr502);
383		W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr502);
384
385		r->out.info_ctr->ctr.ctr502->count = 0;
386		r->out.info_ctr->ctr.ctr502->array = NULL;
387
388		return WERR_NOT_SUPPORTED;
389	}
390	default:
391		return WERR_UNKNOWN_LEVEL;
392	}
393
394	return WERR_UNKNOWN_LEVEL;
395}
396
397
398/*
399  srvsvc_NetSessDel
400*/
401static WERROR dcesrv_srvsvc_NetSessDel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
402		       struct srvsvc_NetSessDel *r)
403{
404	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
405}
406
407
408/*
409  srvsvc_NetShareAdd
410*/
411static WERROR dcesrv_srvsvc_NetShareAdd(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
412		       struct srvsvc_NetShareAdd *r)
413{
414	switch (r->in.level) {
415	case 0:
416	{
417		if (r->in.parm_error) {
418			r->out.parm_error = r->in.parm_error;
419		}
420		return WERR_NOT_SUPPORTED;
421	}
422	case 1:
423	{
424		if (r->in.parm_error) {
425			r->out.parm_error = r->in.parm_error;
426		}
427		return WERR_NOT_SUPPORTED;
428	}
429	case 2:
430	{
431		NTSTATUS nterr;
432		struct share_info *info;
433		struct share_context *sctx;
434		int count = 8;
435		int i;
436
437		nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);
438		if (!NT_STATUS_IS_OK(nterr)) {
439			return ntstatus_to_werror(nterr);
440		}
441
442		/* there are no more than 8 options in struct srvsvc_NetShareInfo2 */
443		info = talloc_array(mem_ctx, struct share_info, count);
444		W_ERROR_HAVE_NO_MEMORY(info);
445
446		i = 0;
447
448		info[i].name = SHARE_TYPE;
449		info[i].type = SHARE_INFO_STRING;
450		switch (r->in.info->info2->type) {
451		case 0x00:
452			info[i].value = talloc_strdup(info, "DISK");
453			break;
454		case 0x01:
455			info[i].value = talloc_strdup(info, "PRINTER");
456			break;
457		case 0x03:
458			info[i].value = talloc_strdup(info, "IPC");
459			break;
460		default:
461			return WERR_INVALID_PARAM;
462		}
463		W_ERROR_HAVE_NO_MEMORY(info[i].value);
464		i++;
465
466		if (r->in.info->info2->path && r->in.info->info2->path[0]) {
467			info[i].name = SHARE_PATH;
468			info[i].type = SHARE_INFO_STRING;
469
470			/* Windows will send a path in a form of C:\example\path */
471			if (r->in.info->info2->path[1] == ':') {
472				info[i].value = talloc_strdup(info, &r->in.info->info2->path[2]);
473			} else {
474				/* very strange let's try to set as is */
475				info[i].value = talloc_strdup(info, r->in.info->info2->path);
476			}
477			W_ERROR_HAVE_NO_MEMORY(info[i].value);
478			all_string_sub((char *)info[i].value, "\\", "/", 0);
479
480			i++;
481		}
482
483		if (r->in.info->info2->comment && r->in.info->info2->comment[0]) {
484			info[i].name = SHARE_COMMENT;
485			info[i].type = SHARE_INFO_STRING;
486			info[i].value = talloc_strdup(info, r->in.info->info2->comment);
487			W_ERROR_HAVE_NO_MEMORY(info[i].value);
488
489			i++;
490		}
491
492		if (r->in.info->info2->password && r->in.info->info2->password[0]) {
493			info[i].name = SHARE_PASSWORD;
494			info[i].type = SHARE_INFO_STRING;
495			info[i].value = talloc_strdup(info, r->in.info->info2->password);
496			W_ERROR_HAVE_NO_MEMORY(info[i].value);
497
498			i++;
499		}
500
501		info[i].name = SHARE_MAX_CONNECTIONS;
502		info[i].type = SHARE_INFO_INT;
503		info[i].value = talloc(info, int);
504		*((int *)info[i].value) = r->in.info->info2->max_users;
505		i++;
506
507		/* TODO: security descriptor */
508
509		nterr = share_create(sctx, r->in.info->info2->name, info, i);
510		if (!NT_STATUS_IS_OK(nterr)) {
511			return ntstatus_to_werror(nterr);
512		}
513
514		if (r->in.parm_error) {
515			r->out.parm_error = r->in.parm_error;
516		}
517
518		return WERR_OK;
519	}
520	case 501:
521	{
522		if (r->in.parm_error) {
523			r->out.parm_error = r->in.parm_error;
524		}
525		return WERR_NOT_SUPPORTED;
526	}
527	case 502:
528	{
529		NTSTATUS nterr;
530		struct share_info *info;
531		struct share_context *sctx;
532		int count = 10;
533		int i;
534
535		nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);
536		if (!NT_STATUS_IS_OK(nterr)) {
537			return ntstatus_to_werror(nterr);
538		}
539
540		/* there are no more than 10 options in struct srvsvc_NetShareInfo502 */
541		info = talloc_array(mem_ctx, struct share_info, count);
542		W_ERROR_HAVE_NO_MEMORY(info);
543
544		i = 0;
545
546		info[i].name = SHARE_TYPE;
547		info[i].type = SHARE_INFO_STRING;
548		switch (r->in.info->info502->type) {
549		case 0x00:
550			info[i].value = talloc_strdup(info, "DISK");
551			break;
552		case 0x01:
553			info[i].value = talloc_strdup(info, "PRINTER");
554			break;
555		case 0x03:
556			info[i].value = talloc_strdup(info, "IPC");
557			break;
558		default:
559			return WERR_INVALID_PARAM;
560		}
561		W_ERROR_HAVE_NO_MEMORY(info[i].value);
562		i++;
563
564		if (r->in.info->info502->path && r->in.info->info502->path[0]) {
565			info[i].name = SHARE_PATH;
566			info[i].type = SHARE_INFO_STRING;
567
568			/* Windows will send a path in a form of C:\example\path */
569			if (r->in.info->info502->path[1] == ':') {
570				info[i].value = talloc_strdup(info, &r->in.info->info502->path[2]);
571			} else {
572				/* very strange let's try to set as is */
573				info[i].value = talloc_strdup(info, r->in.info->info502->path);
574			}
575			W_ERROR_HAVE_NO_MEMORY(info[i].value);
576			all_string_sub((char *)info[i].value, "\\", "/", 0);
577
578			i++;
579		}
580
581		if (r->in.info->info502->comment && r->in.info->info502->comment[0]) {
582			info[i].name = SHARE_COMMENT;
583			info[i].type = SHARE_INFO_STRING;
584			info[i].value = talloc_strdup(info, r->in.info->info502->comment);
585			W_ERROR_HAVE_NO_MEMORY(info[i].value);
586
587			i++;
588		}
589
590		if (r->in.info->info502->password && r->in.info->info502->password[0]) {
591			info[i].name = SHARE_PASSWORD;
592			info[i].type = SHARE_INFO_STRING;
593			info[i].value = talloc_strdup(info, r->in.info->info502->password);
594			W_ERROR_HAVE_NO_MEMORY(info[i].value);
595
596			i++;
597		}
598
599		info[i].name = SHARE_MAX_CONNECTIONS;
600		info[i].type = SHARE_INFO_INT;
601		info[i].value = talloc(info, int);
602		*((int *)info[i].value) = r->in.info->info502->max_users;
603		i++;
604
605		/* TODO: security descriptor */
606
607		nterr = share_create(sctx, r->in.info->info502->name, info, i);
608		if (!NT_STATUS_IS_OK(nterr)) {
609			return ntstatus_to_werror(nterr);
610		}
611
612		if (r->in.parm_error) {
613			r->out.parm_error = r->in.parm_error;
614		}
615
616		return WERR_OK;
617	}
618	default:
619		return WERR_UNKNOWN_LEVEL;
620	}
621
622	return WERR_UNKNOWN_LEVEL;
623}
624
625static WERROR dcesrv_srvsvc_fiel_ShareInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
626				    struct share_config *scfg, uint32_t level,
627				    union srvsvc_NetShareInfo *info)
628{
629	struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx;
630
631	switch (level) {
632	case 0:
633	{
634		info->info0->name	= talloc_strdup(mem_ctx, scfg->name);
635		W_ERROR_HAVE_NO_MEMORY(info->info0->name);
636
637		return WERR_OK;
638	}
639	case 1:
640	{
641		info->info1->name	= talloc_strdup(mem_ctx, scfg->name);
642		W_ERROR_HAVE_NO_MEMORY(info->info1->name);
643		info->info1->type	= dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg);
644		info->info1->comment	= talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, ""));
645		W_ERROR_HAVE_NO_MEMORY(info->info1->comment);
646
647		return WERR_OK;
648	}
649	case 2:
650	{
651		info->info2->name		= talloc_strdup(mem_ctx, scfg->name);
652		W_ERROR_HAVE_NO_MEMORY(info->info2->name);
653		info->info2->type		= dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg);
654		info->info2->comment		= talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, ""));
655		W_ERROR_HAVE_NO_MEMORY(info->info2->comment);
656		info->info2->permissions 	= dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, scfg);
657		info->info2->max_users		= share_int_option(scfg, SHARE_MAX_CONNECTIONS, SHARE_MAX_CONNECTIONS_DEFAULT);
658		info->info2->current_users	= dcesrv_common_get_share_current_users(mem_ctx, dce_ctx, scfg);
659		info->info2->path		= dcesrv_common_get_share_path(mem_ctx, dce_ctx, scfg);
660		W_ERROR_HAVE_NO_MEMORY(info->info2->path);
661		info->info2->password		= talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_PASSWORD, NULL));
662
663		return WERR_OK;
664	}
665	case 501:
666	{
667		info->info501->name		= talloc_strdup(mem_ctx, scfg->name);
668		W_ERROR_HAVE_NO_MEMORY(info->info501->name);
669		info->info501->type		= dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg);
670		info->info501->comment		= talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, ""));
671		W_ERROR_HAVE_NO_MEMORY(info->info501->comment);
672		info->info501->csc_policy	= share_int_option(scfg, SHARE_CSC_POLICY, SHARE_CSC_POLICY_DEFAULT);
673
674		return WERR_OK;
675	}
676	case 502:
677	{
678		info->info502->name		= talloc_strdup(mem_ctx, scfg->name);
679		W_ERROR_HAVE_NO_MEMORY(info->info502->name);
680		info->info502->type		= dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg);
681		info->info502->comment		= talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, ""));
682		W_ERROR_HAVE_NO_MEMORY(info->info502->comment);
683		info->info502->permissions	= dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, scfg);
684		info->info502->max_users	= share_int_option(scfg, SHARE_MAX_CONNECTIONS, SHARE_MAX_CONNECTIONS_DEFAULT);
685		info->info502->current_users	= dcesrv_common_get_share_current_users(mem_ctx, dce_ctx, scfg);
686		info->info502->path		= dcesrv_common_get_share_path(mem_ctx, dce_ctx, scfg);
687		W_ERROR_HAVE_NO_MEMORY(info->info502->path);
688		info->info502->password		= talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_PASSWORD, NULL));
689		info->info502->sd_buf.sd	= dcesrv_common_get_security_descriptor(mem_ctx, dce_ctx, scfg);
690
691		return WERR_OK;
692	}
693	case 1005:
694	{
695		info->info1005->dfs_flags	= dcesrv_common_get_share_dfs_flags(mem_ctx, dce_ctx, scfg);
696
697		return WERR_OK;
698	}
699	default:
700		return WERR_UNKNOWN_LEVEL;
701	}
702
703	return WERR_UNKNOWN_LEVEL;
704}
705
706/*
707  srvsvc_NetShareEnumAll
708*/
709static WERROR dcesrv_srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
710				     struct srvsvc_NetShareEnumAll *r)
711{
712	NTSTATUS nterr;
713	int numshares = 0;
714	const char **snames;
715	struct share_context *sctx;
716	struct share_config *scfg;
717
718	*r->out.totalentries = 0;
719
720	/* TODO: - paging of results
721	 */
722
723	nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);
724	if (!NT_STATUS_IS_OK(nterr)) {
725		return ntstatus_to_werror(nterr);
726	}
727
728	nterr = share_list_all(mem_ctx, sctx, &numshares, &snames);
729	if (!NT_STATUS_IS_OK(nterr)) {
730		return ntstatus_to_werror(nterr);
731	}
732
733	switch (r->in.info_ctr->level) {
734	case 0:
735	{
736		int i;
737		struct srvsvc_NetShareCtr0 *ctr0;
738
739		ctr0 = talloc(mem_ctx, struct srvsvc_NetShareCtr0);
740		W_ERROR_HAVE_NO_MEMORY(ctr0);
741
742		ctr0->count = numshares;
743		ctr0->array = NULL;
744
745		if (ctr0->count == 0) {
746			r->out.info_ctr->ctr.ctr0	= ctr0;
747			return WERR_OK;
748		}
749
750		ctr0->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo0, ctr0->count);
751		W_ERROR_HAVE_NO_MEMORY(ctr0->array);
752
753		for (i = 0; i < ctr0->count; i++) {
754			WERROR status;
755			union srvsvc_NetShareInfo info;
756
757			nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg);
758			if (!NT_STATUS_IS_OK(nterr)) {
759				DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i]));
760				return WERR_GENERAL_FAILURE;
761			}
762			info.info0 = &ctr0->array[i];
763			status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info);
764			if (!W_ERROR_IS_OK(status)) {
765				return status;
766			}
767			talloc_free(scfg);
768		}
769		talloc_free(snames);
770
771		r->out.info_ctr->ctr.ctr0	= ctr0;
772		*r->out.totalentries		= r->out.info_ctr->ctr.ctr0->count;
773		return WERR_OK;
774	}
775	case 1:
776	{
777		int i;
778		struct srvsvc_NetShareCtr1 *ctr1;
779
780		ctr1 = talloc(mem_ctx, struct srvsvc_NetShareCtr1);
781		W_ERROR_HAVE_NO_MEMORY(ctr1);
782
783		ctr1->count = numshares;
784		ctr1->array = NULL;
785
786		if (ctr1->count == 0) {
787			r->out.info_ctr->ctr.ctr1	= ctr1;
788			return WERR_OK;
789		}
790
791		ctr1->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo1, ctr1->count);
792		W_ERROR_HAVE_NO_MEMORY(ctr1->array);
793
794		for (i=0; i < ctr1->count; i++) {
795			WERROR status;
796			union srvsvc_NetShareInfo info;
797
798			nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg);
799			if (!NT_STATUS_IS_OK(nterr)) {
800				DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i]));
801				return WERR_GENERAL_FAILURE;
802			}
803			info.info1 = &ctr1->array[i];
804			status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info);
805			if (!W_ERROR_IS_OK(status)) {
806				return status;
807			}
808			talloc_free(scfg);
809		}
810		talloc_free(snames);
811
812		r->out.info_ctr->ctr.ctr1	= ctr1;
813		*r->out.totalentries		= r->out.info_ctr->ctr.ctr1->count;
814
815		return WERR_OK;
816	}
817	case 2:
818	{
819		int i;
820		struct srvsvc_NetShareCtr2 *ctr2;
821
822		SRVSVC_CHECK_ADMIN_ACCESS;
823
824		ctr2 = talloc(mem_ctx, struct srvsvc_NetShareCtr2);
825		W_ERROR_HAVE_NO_MEMORY(ctr2);
826
827		ctr2->count = numshares;
828		ctr2->array = NULL;
829
830		if (ctr2->count == 0) {
831			r->out.info_ctr->ctr.ctr2	= ctr2;
832			return WERR_OK;
833		}
834
835		ctr2->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo2, ctr2->count);
836		W_ERROR_HAVE_NO_MEMORY(ctr2->array);
837
838		for (i=0; i < ctr2->count; i++) {
839			WERROR status;
840			union srvsvc_NetShareInfo info;
841
842			nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg);
843			if (!NT_STATUS_IS_OK(nterr)) {
844				DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i]));
845				return WERR_GENERAL_FAILURE;
846			}
847			info.info2 = &ctr2->array[i];
848			status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info);
849			if (!W_ERROR_IS_OK(status)) {
850				return status;
851			}
852			talloc_free(scfg);
853		}
854		talloc_free(snames);
855
856		r->out.info_ctr->ctr.ctr2	= ctr2;
857		*r->out.totalentries		= r->out.info_ctr->ctr.ctr2->count;
858
859		return WERR_OK;
860	}
861	case 501:
862	{
863		int i;
864		struct srvsvc_NetShareCtr501 *ctr501;
865
866		SRVSVC_CHECK_ADMIN_ACCESS;
867
868		ctr501 = talloc(mem_ctx, struct srvsvc_NetShareCtr501);
869		W_ERROR_HAVE_NO_MEMORY(ctr501);
870
871		ctr501->count = numshares;
872		ctr501->array = NULL;
873
874		if (ctr501->count == 0) {
875			r->out.info_ctr->ctr.ctr501	= ctr501;
876			return WERR_OK;
877		}
878
879		ctr501->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo501, ctr501->count);
880		W_ERROR_HAVE_NO_MEMORY(ctr501->array);
881
882		for (i=0; i < ctr501->count; i++) {
883			WERROR status;
884			union srvsvc_NetShareInfo info;
885
886			nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg);
887			if (!NT_STATUS_IS_OK(nterr)) {
888				DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i]));
889				return WERR_GENERAL_FAILURE;
890			}
891			info.info501 = &ctr501->array[i];
892			status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info);
893			if (!W_ERROR_IS_OK(status)) {
894				return status;
895			}
896			talloc_free(scfg);
897		}
898		talloc_free(snames);
899
900		r->out.info_ctr->ctr.ctr501	= ctr501;
901		*r->out.totalentries		= r->out.info_ctr->ctr.ctr501->count;
902
903		return WERR_OK;
904	}
905	case 502:
906	{
907		int i;
908		struct srvsvc_NetShareCtr502 *ctr502;
909
910		SRVSVC_CHECK_ADMIN_ACCESS;
911
912		ctr502 = talloc(mem_ctx, struct srvsvc_NetShareCtr502);
913		W_ERROR_HAVE_NO_MEMORY(ctr502);
914
915		ctr502->count = numshares;
916		ctr502->array = NULL;
917
918		if (ctr502->count == 0) {
919			r->out.info_ctr->ctr.ctr502	= ctr502;
920			return WERR_OK;
921		}
922
923		ctr502->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo502, ctr502->count);
924		W_ERROR_HAVE_NO_MEMORY(ctr502->array);
925
926		for (i=0; i < ctr502->count; i++) {
927			WERROR status;
928			union srvsvc_NetShareInfo info;
929
930			nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg);
931			if (!NT_STATUS_IS_OK(nterr)) {
932				DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i]));
933				return WERR_GENERAL_FAILURE;
934			}
935			info.info502 = &ctr502->array[i];
936			status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info);
937			if (!W_ERROR_IS_OK(status)) {
938				return status;
939			}
940			talloc_free(scfg);
941		}
942		talloc_free(snames);
943
944		r->out.info_ctr->ctr.ctr502	= ctr502;
945		*r->out.totalentries		= r->out.info_ctr->ctr.ctr502->count;
946
947		return WERR_OK;
948	}
949	default:
950		return WERR_UNKNOWN_LEVEL;
951	}
952
953	return WERR_UNKNOWN_LEVEL;
954}
955
956
957/*
958  srvsvc_NetShareGetInfo
959*/
960static WERROR dcesrv_srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
961				     struct srvsvc_NetShareGetInfo *r)
962{
963	NTSTATUS nterr;
964	struct share_context *sctx = NULL;
965	struct share_config *scfg = NULL;
966
967	ZERO_STRUCTP(r->out.info);
968
969	/* TODO: - access check
970	 */
971
972	if (strcmp("", r->in.share_name) == 0) {
973		return WERR_INVALID_PARAM;
974	}
975
976	nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);
977	if (!NT_STATUS_IS_OK(nterr)) {
978		return ntstatus_to_werror(nterr);
979	}
980
981	nterr = share_get_config(mem_ctx, sctx, r->in.share_name, &scfg);
982	if (!NT_STATUS_IS_OK(nterr)) {
983		return ntstatus_to_werror(nterr);
984	}
985
986	switch (r->in.level) {
987	case 0:
988	{
989		WERROR status;
990		union srvsvc_NetShareInfo info;
991
992		info.info0 = talloc(mem_ctx, struct srvsvc_NetShareInfo0);
993		W_ERROR_HAVE_NO_MEMORY(info.info0);
994
995		status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info);
996		if (!W_ERROR_IS_OK(status)) {
997			return status;
998		}
999
1000		r->out.info->info0 = info.info0;
1001		return WERR_OK;
1002	}
1003	case 1:
1004	{
1005		WERROR status;
1006		union srvsvc_NetShareInfo info;
1007
1008		info.info1 = talloc(mem_ctx, struct srvsvc_NetShareInfo1);
1009		W_ERROR_HAVE_NO_MEMORY(info.info1);
1010
1011		status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info);
1012		if (!W_ERROR_IS_OK(status)) {
1013			return status;
1014		}
1015
1016		r->out.info->info1 = info.info1;
1017		return WERR_OK;
1018	}
1019	case 2:
1020	{
1021		WERROR status;
1022		union srvsvc_NetShareInfo info;
1023
1024		SRVSVC_CHECK_ADMIN_ACCESS;
1025
1026		info.info2 = talloc(mem_ctx, struct srvsvc_NetShareInfo2);
1027		W_ERROR_HAVE_NO_MEMORY(info.info2);
1028
1029		status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info);
1030		if (!W_ERROR_IS_OK(status)) {
1031			return status;
1032		}
1033
1034		r->out.info->info2 = info.info2;
1035		return WERR_OK;
1036	}
1037	case 501:
1038	{
1039		WERROR status;
1040		union srvsvc_NetShareInfo info;
1041
1042		info.info501 = talloc(mem_ctx, struct srvsvc_NetShareInfo501);
1043		W_ERROR_HAVE_NO_MEMORY(info.info501);
1044
1045		status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info);
1046		if (!W_ERROR_IS_OK(status)) {
1047			return status;
1048		}
1049
1050		r->out.info->info501 = info.info501;
1051		return WERR_OK;
1052	}
1053	case 502:
1054	{
1055		WERROR status;
1056		union srvsvc_NetShareInfo info;
1057
1058		SRVSVC_CHECK_ADMIN_ACCESS;
1059
1060		info.info502 = talloc(mem_ctx, struct srvsvc_NetShareInfo502);
1061		W_ERROR_HAVE_NO_MEMORY(info.info502);
1062
1063		status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info);
1064		if (!W_ERROR_IS_OK(status)) {
1065			return status;
1066		}
1067
1068		r->out.info->info502 = info.info502;
1069		return WERR_OK;
1070	}
1071	case 1005:
1072	{
1073		WERROR status;
1074		union srvsvc_NetShareInfo info;
1075
1076		info.info1005 = talloc(mem_ctx, struct srvsvc_NetShareInfo1005);
1077		W_ERROR_HAVE_NO_MEMORY(info.info1005);
1078
1079		status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info);
1080		if (!W_ERROR_IS_OK(status)) {
1081			return status;
1082		}
1083
1084		r->out.info->info1005 = info.info1005;
1085		return WERR_OK;
1086	}
1087	default:
1088		return WERR_UNKNOWN_LEVEL;
1089	}
1090
1091	return WERR_UNKNOWN_LEVEL;
1092}
1093
1094static WERROR dcesrv_srvsvc_fill_share_info(struct share_info *info, int *count,
1095					const char *share_name, int level,
1096					const char *name,
1097					const char *path,
1098					const char *comment,
1099					const char *password,
1100					enum srvsvc_ShareType type,
1101					int32_t max_users,
1102					uint32_t csc_policy,
1103					struct security_descriptor *sd)
1104{
1105	int i = 0;
1106
1107	if (level == 501) {
1108		info[i].name = SHARE_CSC_POLICY;
1109		info[i].type = SHARE_INFO_INT;
1110		info[i].value = talloc(info, int);
1111		*((int *)info[i].value) = csc_policy;
1112		i++;
1113	}
1114
1115	switch(level) {
1116
1117	case 502:
1118		/* TODO: check if unknown is csc_policy */
1119
1120		/* TODO: security descriptor */
1121
1122	case 2:
1123		if (path && path[0]) {
1124			info[i].name = SHARE_PATH;
1125			info[i].type = SHARE_INFO_STRING;
1126
1127			/* Windows will send a path in a form of C:\example\path */
1128			if (path[1] == ':') {
1129				info[i].value = talloc_strdup(info, &path[2]);
1130			} else {
1131				/* very strange let's try to set as is */
1132				info[i].value = talloc_strdup(info, path);
1133			}
1134			W_ERROR_HAVE_NO_MEMORY(info[i].value);
1135			all_string_sub((char *)info[i].value, "\\", "/", 0);
1136
1137			i++;
1138		}
1139
1140		if (password && password[0]) {
1141			info[i].name = SHARE_PASSWORD;
1142			info[i].type = SHARE_INFO_STRING;
1143			info[i].value = talloc_strdup(info, password);
1144			W_ERROR_HAVE_NO_MEMORY(info[i].value);
1145
1146			i++;
1147		}
1148
1149		info[i].name = SHARE_MAX_CONNECTIONS;
1150		info[i].type = SHARE_INFO_INT;
1151		info[i].value = talloc(info, int);
1152		*((int *)info[i].value) = max_users;
1153		i++;
1154
1155	case 501:
1156	case 1:
1157		info[i].name = SHARE_TYPE;
1158		info[i].type = SHARE_INFO_STRING;
1159		switch (type) {
1160		case 0x00:
1161			info[i].value = talloc_strdup(info, "DISK");
1162			break;
1163		case 0x01:
1164			info[i].value = talloc_strdup(info, "PRINTER");
1165			break;
1166		case 0x03:
1167			info[i].value = talloc_strdup(info, "IPC");
1168			break;
1169		default:
1170			return WERR_INVALID_PARAM;
1171		}
1172		W_ERROR_HAVE_NO_MEMORY(info[i].value);
1173		i++;
1174
1175	case 1004:
1176		if (comment) {
1177			info[i].name = SHARE_COMMENT;
1178			info[i].type = SHARE_INFO_STRING;
1179			info[i].value = talloc_strdup(info, comment);
1180			W_ERROR_HAVE_NO_MEMORY(info[i].value);
1181
1182			i++;
1183		}
1184	case 0:
1185		if (name &&
1186		    strcasecmp(share_name, name) != 0) {
1187			info[i].name = SHARE_NAME;
1188			info[i].type = SHARE_INFO_STRING;
1189			info[i].value = talloc_strdup(info, name);
1190			W_ERROR_HAVE_NO_MEMORY(info[i].value);
1191			i++;
1192		}
1193
1194		break;
1195
1196	default:
1197		return WERR_UNKNOWN_LEVEL;
1198	}
1199
1200	*count = i;
1201
1202	return WERR_OK;
1203}
1204
1205/*
1206  srvsvc_NetShareSetInfo
1207*/
1208static WERROR dcesrv_srvsvc_NetShareSetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1209		       struct srvsvc_NetShareSetInfo *r)
1210{
1211	NTSTATUS nterr;
1212	WERROR status;
1213	struct share_context *sctx = NULL;
1214	struct share_info *info;
1215	int count;
1216
1217	/* TODO: - access check
1218	 */
1219
1220	/* there are no more than 10 options in all struct srvsvc_NetShareInfoXXX */
1221	info = talloc_array(mem_ctx, struct share_info, 10);
1222	W_ERROR_HAVE_NO_MEMORY(info);
1223
1224	ZERO_STRUCT(r->out);
1225
1226	if (strcmp("", r->in.share_name) == 0) {
1227		return WERR_INVALID_PARAM;
1228	}
1229
1230	nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);
1231	if (!NT_STATUS_IS_OK(nterr)) {
1232		return ntstatus_to_werror(nterr);
1233	}
1234
1235	switch (r->in.level) {
1236	case 0:
1237	{
1238		status = dcesrv_srvsvc_fill_share_info(info, &count,
1239					r->in.share_name, r->in.level,
1240					r->in.info->info0->name,
1241					NULL,
1242					NULL,
1243					NULL,
1244					0,
1245					0,
1246					0,
1247					NULL);
1248		if (!W_ERROR_EQUAL(status, WERR_OK)) {
1249			return status;
1250		}
1251		break;
1252	}
1253	case 1:
1254	{
1255		status = dcesrv_srvsvc_fill_share_info(info, &count,
1256					r->in.share_name, r->in.level,
1257					r->in.info->info1->name,
1258					NULL,
1259					r->in.info->info1->comment,
1260					NULL,
1261					r->in.info->info1->type,
1262					0,
1263					0,
1264					NULL);
1265		if (!W_ERROR_EQUAL(status, WERR_OK)) {
1266			return status;
1267		}
1268		break;
1269	}
1270	case 2:
1271	{
1272		status = dcesrv_srvsvc_fill_share_info(info, &count,
1273					r->in.share_name, r->in.level,
1274					r->in.info->info2->name,
1275					r->in.info->info2->path,
1276					r->in.info->info2->comment,
1277					r->in.info->info2->password,
1278					r->in.info->info2->type,
1279					r->in.info->info2->max_users,
1280					0,
1281					NULL);
1282		if (!W_ERROR_EQUAL(status, WERR_OK)) {
1283			return status;
1284		}
1285		break;
1286	}
1287	case 501:
1288	{
1289		status = dcesrv_srvsvc_fill_share_info(info, &count,
1290					r->in.share_name, r->in.level,
1291					r->in.info->info501->name,
1292					NULL,
1293					r->in.info->info501->comment,
1294					NULL,
1295					r->in.info->info501->type,
1296					0,
1297					r->in.info->info501->csc_policy,
1298					NULL);
1299		if (!W_ERROR_EQUAL(status, WERR_OK)) {
1300			return status;
1301		}
1302		break;
1303	}
1304	case 502:
1305	{
1306		status = dcesrv_srvsvc_fill_share_info(info, &count,
1307					r->in.share_name, r->in.level,
1308					r->in.info->info502->name,
1309					r->in.info->info502->path,
1310					r->in.info->info502->comment,
1311					r->in.info->info502->password,
1312					r->in.info->info502->type,
1313					r->in.info->info502->max_users,
1314					0,
1315					r->in.info->info502->sd_buf.sd);
1316		if (!W_ERROR_EQUAL(status, WERR_OK)) {
1317			return status;
1318		}
1319		break;
1320	}
1321	case 1004:
1322	{
1323		status = dcesrv_srvsvc_fill_share_info(info, &count,
1324					r->in.share_name, r->in.level,
1325					NULL,
1326					NULL,
1327					r->in.info->info1004->comment,
1328					NULL,
1329					0,
1330					0,
1331					0,
1332					NULL);
1333		if (!W_ERROR_EQUAL(status, WERR_OK)) {
1334			return status;
1335		}
1336		break;
1337	}
1338	case 1005:
1339	{
1340		/* r->in.info.dfs_flags; */
1341
1342		if (r->in.parm_error) {
1343			r->out.parm_error = r->in.parm_error;
1344		}
1345
1346		return WERR_OK;
1347	}
1348	default:
1349		return WERR_UNKNOWN_LEVEL;
1350	}
1351
1352	nterr = share_set(sctx, r->in.share_name, info, count);
1353	if (!NT_STATUS_IS_OK(nterr)) {
1354		return ntstatus_to_werror(nterr);
1355	}
1356
1357	if (r->in.parm_error) {
1358		r->out.parm_error = r->in.parm_error;
1359	}
1360
1361	return WERR_OK;
1362}
1363
1364
1365/*
1366  srvsvc_NetShareDelSticky
1367*/
1368static WERROR dcesrv_srvsvc_NetShareDelSticky(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1369		       struct srvsvc_NetShareDelSticky *r)
1370{
1371	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1372}
1373
1374
1375/*
1376  srvsvc_NetShareCheck
1377*/
1378static WERROR dcesrv_srvsvc_NetShareCheck(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1379		       struct srvsvc_NetShareCheck *r)
1380{
1381	NTSTATUS nterr;
1382	struct share_context *sctx = NULL;
1383	struct share_config *scfg = NULL;
1384	char *device;
1385	const char **names;
1386	int count, i;
1387
1388	*r->out.type = 0;
1389
1390	/* TODO: - access check
1391	 */
1392
1393	if (strcmp("", r->in.device_name) == 0) {
1394		*r->out.type = STYPE_IPC;
1395		return WERR_OK;
1396	}
1397
1398	/* copy the path skipping C:\ */
1399	if (strncasecmp(r->in.device_name, "C:", 2) == 0) {
1400		device = talloc_strdup(mem_ctx, &r->in.device_name[2]);
1401	} else {
1402		/* no chance we have a share that doesn't start with C:\ */
1403		return WERR_DEVICE_NOT_SHARED;
1404	}
1405	all_string_sub(device, "\\", "/", 0);
1406
1407	nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);
1408	if (!NT_STATUS_IS_OK(nterr)) {
1409		return ntstatus_to_werror(nterr);
1410	}
1411
1412	nterr = share_list_all(mem_ctx, sctx, &count, &names);
1413	if (!NT_STATUS_IS_OK(nterr)) {
1414		return ntstatus_to_werror(nterr);
1415	}
1416
1417	for (i = 0; i < count; i++) {
1418		const char *path;
1419		const char *type;
1420
1421		nterr = share_get_config(mem_ctx, sctx, names[i], &scfg);
1422		if (!NT_STATUS_IS_OK(nterr)) {
1423			return ntstatus_to_werror(nterr);
1424		}
1425		path = share_string_option(scfg, SHARE_PATH, NULL);
1426		if (!path) continue;
1427
1428		if (strcmp(device, path) == 0) {
1429			type = share_string_option(scfg, SHARE_TYPE, NULL);
1430			if (!type) continue;
1431
1432			if (strcmp(type, "DISK") == 0) {
1433				*r->out.type = STYPE_DISKTREE;
1434				return WERR_OK;
1435			}
1436
1437			if (strcmp(type, "IPC") == 0) {
1438				*r->out.type = STYPE_IPC;
1439				return WERR_OK;
1440			}
1441
1442			if (strcmp(type, "PRINTER") == 0) {
1443				*r->out.type = STYPE_PRINTQ;
1444				return WERR_OK;
1445			}
1446		}
1447	}
1448
1449	return WERR_DEVICE_NOT_SHARED;
1450}
1451
1452
1453/*
1454  srvsvc_NetSrvGetInfo
1455*/
1456static WERROR dcesrv_srvsvc_NetSrvGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1457		       struct srvsvc_NetSrvGetInfo *r)
1458{
1459	struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx;
1460	struct dcerpc_server_info *server_info = lp_dcerpc_server_info(mem_ctx, dce_ctx->lp_ctx);
1461
1462	ZERO_STRUCTP(r->out.info);
1463
1464	switch (r->in.level) {
1465	case 100:
1466	{
1467		struct srvsvc_NetSrvInfo100 *info100;
1468
1469		info100 = talloc(mem_ctx, struct srvsvc_NetSrvInfo100);
1470		W_ERROR_HAVE_NO_MEMORY(info100);
1471
1472		info100->platform_id	= dcesrv_common_get_platform_id(mem_ctx, dce_ctx);
1473		info100->server_name	= dcesrv_common_get_server_name(mem_ctx, dce_ctx, r->in.server_unc);
1474		W_ERROR_HAVE_NO_MEMORY(info100->server_name);
1475
1476		r->out.info->info100 = info100;
1477		return WERR_OK;
1478	}
1479	case 101:
1480	{
1481		struct srvsvc_NetSrvInfo101 *info101;
1482
1483		info101 = talloc(mem_ctx, struct srvsvc_NetSrvInfo101);
1484		W_ERROR_HAVE_NO_MEMORY(info101);
1485
1486		info101->platform_id	= dcesrv_common_get_platform_id(mem_ctx, dce_ctx);
1487		info101->server_name	= dcesrv_common_get_server_name(mem_ctx, dce_ctx, r->in.server_unc);
1488		W_ERROR_HAVE_NO_MEMORY(info101->server_name);
1489
1490		info101->version_major	= server_info->version_major;
1491		info101->version_minor	= server_info->version_minor;
1492		info101->server_type	= dcesrv_common_get_server_type(mem_ctx, dce_call->event_ctx, dce_ctx);
1493		info101->comment	= talloc_strdup(mem_ctx, lp_serverstring(dce_ctx->lp_ctx));
1494		W_ERROR_HAVE_NO_MEMORY(info101->comment);
1495
1496		r->out.info->info101 = info101;
1497		return WERR_OK;
1498	}
1499	case 102:
1500	{
1501		struct srvsvc_NetSrvInfo102 *info102;
1502
1503		info102 = talloc(mem_ctx, struct srvsvc_NetSrvInfo102);
1504		W_ERROR_HAVE_NO_MEMORY(info102);
1505
1506		info102->platform_id	= dcesrv_common_get_platform_id(mem_ctx, dce_ctx);
1507		info102->server_name	= dcesrv_common_get_server_name(mem_ctx, dce_ctx, r->in.server_unc);
1508		W_ERROR_HAVE_NO_MEMORY(info102->server_name);
1509
1510		info102->version_major	= server_info->version_major;
1511		info102->version_minor	= server_info->version_minor;
1512		info102->server_type	= dcesrv_common_get_server_type(mem_ctx, dce_call->event_ctx, dce_ctx);
1513		info102->comment	= talloc_strdup(mem_ctx, lp_serverstring(dce_ctx->lp_ctx));
1514		W_ERROR_HAVE_NO_MEMORY(info102->comment);
1515
1516		info102->users		= dcesrv_common_get_users(mem_ctx, dce_ctx);
1517		info102->disc		= dcesrv_common_get_disc(mem_ctx, dce_ctx);
1518		info102->hidden		= dcesrv_common_get_hidden(mem_ctx, dce_ctx);
1519		info102->announce	= dcesrv_common_get_announce(mem_ctx, dce_ctx);
1520		info102->anndelta	= dcesrv_common_get_anndelta(mem_ctx, dce_ctx);
1521		info102->licenses	= dcesrv_common_get_licenses(mem_ctx, dce_ctx);
1522		info102->userpath	= dcesrv_common_get_userpath(mem_ctx, dce_ctx);
1523		W_ERROR_HAVE_NO_MEMORY(info102->userpath);
1524
1525		r->out.info->info102 = info102;
1526		return WERR_OK;
1527	}
1528	default:
1529		return WERR_UNKNOWN_LEVEL;
1530	}
1531
1532	return WERR_UNKNOWN_LEVEL;
1533}
1534
1535
1536/*
1537  srvsvc_NetSrvSetInfo
1538*/
1539static WERROR dcesrv_srvsvc_NetSrvSetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1540		       struct srvsvc_NetSrvSetInfo *r)
1541{
1542	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1543}
1544
1545
1546/*
1547  srvsvc_NetDiskEnum
1548*/
1549static WERROR dcesrv_srvsvc_NetDiskEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1550		       struct srvsvc_NetDiskEnum *r)
1551{
1552	r->out.info->disks = NULL;
1553	r->out.info->count = 0;
1554	*r->out.totalentries = 0;
1555
1556	switch (r->in.level) {
1557	case 0:
1558	{
1559		/* we can safely hardcode the reply and report we have only one disk (C:) */
1560		/* for some reason Windows wants 2 entries with the second being empty */
1561		r->out.info->disks = talloc_array(mem_ctx, struct srvsvc_NetDiskInfo0, 2);
1562		W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
1563		r->out.info->count = 2;
1564
1565		r->out.info->disks[0].disk = talloc_strdup(mem_ctx, "C:");
1566		W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[0].disk);
1567
1568		r->out.info->disks[1].disk = talloc_strdup(mem_ctx, "");
1569		W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[1].disk);
1570
1571		*r->out.totalentries = 1;
1572		r->out.resume_handle = r->in.resume_handle;
1573
1574		return WERR_OK;
1575	}
1576	default:
1577		return WERR_UNKNOWN_LEVEL;
1578	}
1579
1580	return WERR_UNKNOWN_LEVEL;
1581}
1582
1583
1584/*
1585  srvsvc_NetServerStatisticsGet
1586*/
1587static WERROR dcesrv_srvsvc_NetServerStatisticsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1588		       struct srvsvc_NetServerStatisticsGet *r)
1589{
1590	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1591}
1592
1593
1594/*
1595  srvsvc_NetTransportAdd
1596*/
1597static WERROR dcesrv_srvsvc_NetTransportAdd(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1598		       struct srvsvc_NetTransportAdd *r)
1599{
1600	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1601}
1602
1603
1604/*
1605  srvsvc_NetTransportEnum
1606*/
1607static WERROR dcesrv_srvsvc_NetTransportEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1608		       struct srvsvc_NetTransportEnum *r)
1609{
1610	r->out.transports->level = r->in.transports->level;
1611	*r->out.totalentries = 0;
1612	if (r->out.resume_handle) {
1613		*r->out.resume_handle = 0;
1614	}
1615
1616	switch (r->in.transports->level) {
1617	case 0:
1618	{
1619		r->out.transports->ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetTransportCtr0);
1620		W_ERROR_HAVE_NO_MEMORY(r->out.transports->ctr.ctr0);
1621
1622		r->out.transports->ctr.ctr0->count = 0;
1623		r->out.transports->ctr.ctr0->array = NULL;
1624
1625		return WERR_NOT_SUPPORTED;
1626	}
1627	case 1:
1628	{
1629		r->out.transports->ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetTransportCtr1);
1630		W_ERROR_HAVE_NO_MEMORY(r->out.transports->ctr.ctr1);
1631
1632		r->out.transports->ctr.ctr1->count = 0;
1633		r->out.transports->ctr.ctr1->array = NULL;
1634
1635		return WERR_NOT_SUPPORTED;
1636	}
1637	case 2:
1638	{
1639		r->out.transports->ctr.ctr2 = talloc(mem_ctx, struct srvsvc_NetTransportCtr2);
1640		W_ERROR_HAVE_NO_MEMORY(r->out.transports->ctr.ctr2);
1641
1642		r->out.transports->ctr.ctr2->count = 0;
1643		r->out.transports->ctr.ctr2->array = NULL;
1644
1645		return WERR_NOT_SUPPORTED;
1646	}
1647	case 3:
1648	{
1649		r->out.transports->ctr.ctr3 = talloc(mem_ctx, struct srvsvc_NetTransportCtr3);
1650		W_ERROR_HAVE_NO_MEMORY(r->out.transports->ctr.ctr3);
1651
1652		r->out.transports->ctr.ctr3->count = 0;
1653		r->out.transports->ctr.ctr3->array = NULL;
1654
1655		return WERR_NOT_SUPPORTED;
1656	}
1657	default:
1658		return WERR_UNKNOWN_LEVEL;
1659	}
1660
1661	return WERR_UNKNOWN_LEVEL;
1662}
1663
1664/*
1665  srvsvc_NetTransportDel
1666*/
1667static WERROR dcesrv_srvsvc_NetTransportDel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1668		       struct srvsvc_NetTransportDel *r)
1669{
1670	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1671}
1672
1673
1674/*
1675  srvsvc_NetRemoteTOD
1676*/
1677static WERROR dcesrv_srvsvc_NetRemoteTOD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1678		       struct srvsvc_NetRemoteTOD *r)
1679{
1680	struct timeval tval;
1681	time_t t;
1682	struct tm tm;
1683	struct srvsvc_NetRemoteTODInfo *info;
1684
1685	info = talloc(mem_ctx, struct srvsvc_NetRemoteTODInfo);
1686	W_ERROR_HAVE_NO_MEMORY(info);
1687
1688	GetTimeOfDay(&tval);
1689	t = tval.tv_sec;
1690
1691	gmtime_r(&t, &tm);
1692
1693	info->elapsed	= t;
1694	/* TODO: fake the uptime: just return the milliseconds till 0:00:00 today */
1695	info->msecs	= (tm.tm_hour*60*60*1000)
1696			+ (tm.tm_min*60*1000)
1697			+ (tm.tm_sec*1000)
1698			+ (tval.tv_usec/1000);
1699	info->hours	= tm.tm_hour;
1700	info->mins	= tm.tm_min;
1701	info->secs	= tm.tm_sec;
1702	info->hunds	= tval.tv_usec/10000;
1703	info->timezone	= get_time_zone(t)/60;
1704	info->tinterval	= 310; /* just return the same as windows */
1705	info->day	= tm.tm_mday;
1706	info->month	= tm.tm_mon + 1;
1707	info->year	= tm.tm_year + 1900;
1708	info->weekday	= tm.tm_wday;
1709
1710	*r->out.info = info;
1711
1712	return WERR_OK;
1713}
1714
1715/*
1716  srvsvc_NetPathType
1717*/
1718static WERROR dcesrv_srvsvc_NetPathType(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1719		       struct srvsvc_NetPathType *r)
1720{
1721	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1722}
1723
1724
1725/*
1726  srvsvc_NetPathCanonicalize
1727*/
1728static WERROR dcesrv_srvsvc_NetPathCanonicalize(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1729		       struct srvsvc_NetPathCanonicalize *r)
1730{
1731	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1732}
1733
1734
1735/*
1736  srvsvc_NetPathCompare
1737*/
1738static WERROR dcesrv_srvsvc_NetPathCompare(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1739		       struct srvsvc_NetPathCompare *r)
1740{
1741	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1742}
1743
1744
1745/*
1746  srvsvc_NetNameValidate
1747*/
1748static WERROR dcesrv_srvsvc_NetNameValidate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1749		       struct srvsvc_NetNameValidate *r)
1750{
1751	int len;
1752
1753	if ((r->in.flags != 0x0) && (r->in.flags != 0x80000000)) {
1754		return WERR_INVALID_NAME;
1755	}
1756
1757	switch (r->in.name_type) {
1758	case 1:
1759	case 2:
1760	case 3:
1761	case 4:
1762	case 5:
1763	case 6:
1764	case 7:
1765	case 8:
1766		return WERR_NOT_SUPPORTED;
1767
1768	case 9: /* validate share name */
1769
1770		len = strlen_m(r->in.name);
1771		if ((r->in.flags == 0x0) && (len > 81)) {
1772			return WERR_INVALID_NAME;
1773		}
1774		if ((r->in.flags == 0x80000000) && (len > 13)) {
1775			return WERR_INVALID_NAME;
1776		}
1777		if (! dcesrv_common_validate_share_name(mem_ctx, r->in.name)) {
1778			return WERR_INVALID_NAME;
1779		}
1780		return WERR_OK;
1781
1782	case 10:
1783	case 11:
1784	case 12:
1785	case 13:
1786		return WERR_NOT_SUPPORTED;
1787	default:
1788		return WERR_INVALID_PARAM;
1789	}
1790
1791	return WERR_INVALID_PARAM;
1792}
1793
1794
1795/*
1796  srvsvc_NetPRNameCompare
1797*/
1798static WERROR dcesrv_srvsvc_NetPRNameCompare(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1799		       struct srvsvc_NetPRNameCompare *r)
1800{
1801	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1802}
1803
1804
1805/*
1806  srvsvc_NetShareEnum
1807*/
1808static WERROR dcesrv_srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1809		       struct srvsvc_NetShareEnum *r)
1810{
1811	NTSTATUS nterr;
1812	int numshares = 0;
1813	const char **snames;
1814	struct share_context *sctx;
1815	struct share_config *scfg;
1816	struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx;
1817
1818	*r->out.totalentries = 0;
1819
1820	/* TODO: - paging of results
1821	 */
1822
1823	nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);
1824	if (!NT_STATUS_IS_OK(nterr)) {
1825		return ntstatus_to_werror(nterr);
1826	}
1827
1828	nterr = share_list_all(mem_ctx, sctx, &numshares, &snames);
1829	if (!NT_STATUS_IS_OK(nterr)) {
1830		return ntstatus_to_werror(nterr);
1831	}
1832
1833	switch (r->in.info_ctr->level) {
1834	case 0:
1835	{
1836		int i, y = 0;
1837		int count;
1838		struct srvsvc_NetShareCtr0 *ctr0;
1839
1840		ctr0 = talloc(mem_ctx, struct srvsvc_NetShareCtr0);
1841		W_ERROR_HAVE_NO_MEMORY(ctr0);
1842
1843		count = numshares;
1844		ctr0->count = count;
1845		ctr0->array = NULL;
1846
1847		if (ctr0->count == 0) {
1848			r->out.info_ctr->ctr.ctr0	= ctr0;
1849			return WERR_OK;
1850		}
1851
1852		ctr0->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo0, count);
1853		W_ERROR_HAVE_NO_MEMORY(ctr0->array);
1854
1855		for (i=0; i < count; i++) {
1856			WERROR status;
1857			union srvsvc_NetShareInfo info;
1858			enum srvsvc_ShareType type;
1859
1860			nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg);
1861			if (!NT_STATUS_IS_OK(nterr)) {
1862				DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i]));
1863				return WERR_GENERAL_FAILURE;
1864			}
1865
1866			type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg);
1867			if (type & STYPE_HIDDEN) {
1868				ctr0->count--;
1869				talloc_free(scfg);
1870				continue;
1871			}
1872
1873			info.info0 = &ctr0->array[y];
1874			status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info);
1875			W_ERROR_NOT_OK_RETURN(status);
1876			talloc_free(scfg);
1877			y++;
1878		}
1879		talloc_free(snames);
1880
1881		r->out.info_ctr->ctr.ctr0	= ctr0;
1882		*r->out.totalentries		= r->out.info_ctr->ctr.ctr0->count;
1883
1884		return WERR_OK;
1885	}
1886	case 1:
1887	{
1888		int i, y = 0;
1889		int count;
1890		struct srvsvc_NetShareCtr1 *ctr1;
1891
1892		ctr1 = talloc(mem_ctx, struct srvsvc_NetShareCtr1);
1893		W_ERROR_HAVE_NO_MEMORY(ctr1);
1894
1895		count = numshares;
1896		ctr1->count = count;
1897		ctr1->array = NULL;
1898
1899		if (ctr1->count == 0) {
1900			r->out.info_ctr->ctr.ctr1	= ctr1;
1901			return WERR_OK;
1902		}
1903
1904		ctr1->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo1, count);
1905		W_ERROR_HAVE_NO_MEMORY(ctr1->array);
1906
1907		for (i=0; i < count; i++) {
1908			WERROR status;
1909			union srvsvc_NetShareInfo info;
1910			enum srvsvc_ShareType type;
1911
1912			nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg);
1913			if (!NT_STATUS_IS_OK(nterr)) {
1914				DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i]));
1915				return WERR_GENERAL_FAILURE;
1916			}
1917
1918			type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg);
1919			if (type & STYPE_HIDDEN) {
1920				ctr1->count--;
1921				talloc_free(scfg);
1922				continue;
1923			}
1924
1925			info.info1 = &ctr1->array[y];
1926			status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info);
1927			W_ERROR_NOT_OK_RETURN(status);
1928			talloc_free(scfg);
1929			y++;
1930		}
1931		talloc_free(snames);
1932
1933		r->out.info_ctr->ctr.ctr1	= ctr1;
1934		*r->out.totalentries		= r->out.info_ctr->ctr.ctr1->count;
1935
1936		return WERR_OK;
1937	}
1938	case 2:
1939	{
1940		int i, y = 0;
1941		int count;
1942		struct srvsvc_NetShareCtr2 *ctr2;
1943
1944		SRVSVC_CHECK_ADMIN_ACCESS;
1945
1946		ctr2 = talloc(mem_ctx, struct srvsvc_NetShareCtr2);
1947		W_ERROR_HAVE_NO_MEMORY(ctr2);
1948
1949		count = numshares;
1950		ctr2->count = count;
1951		ctr2->array = NULL;
1952
1953		if (ctr2->count == 0) {
1954			r->out.info_ctr->ctr.ctr2	= ctr2;
1955			return WERR_OK;
1956		}
1957
1958		ctr2->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo2, count);
1959		W_ERROR_HAVE_NO_MEMORY(ctr2->array);
1960
1961		for (i=0; i < count; i++) {
1962			WERROR status;
1963			union srvsvc_NetShareInfo info;
1964			enum srvsvc_ShareType type;
1965
1966			nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg);
1967			if (!NT_STATUS_IS_OK(nterr)) {
1968				DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i]));
1969				return WERR_GENERAL_FAILURE;
1970			}
1971
1972			type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg);
1973			if (type & STYPE_HIDDEN) {
1974				ctr2->count--;
1975				talloc_free(scfg);
1976				continue;
1977			}
1978
1979			info.info2 = &ctr2->array[y];
1980			status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info);
1981			W_ERROR_NOT_OK_RETURN(status);
1982			talloc_free(scfg);
1983			y++;
1984		}
1985		talloc_free(snames);
1986
1987		r->out.info_ctr->ctr.ctr2	= ctr2;
1988		*r->out.totalentries		= r->out.info_ctr->ctr.ctr2->count;
1989
1990		return WERR_OK;
1991	}
1992	case 502:
1993	{
1994		int i, y = 0;
1995		int count;
1996		struct srvsvc_NetShareCtr502 *ctr502;
1997
1998		SRVSVC_CHECK_ADMIN_ACCESS;
1999
2000		ctr502 = talloc(mem_ctx, struct srvsvc_NetShareCtr502);
2001		W_ERROR_HAVE_NO_MEMORY(ctr502);
2002
2003		count = numshares;
2004		ctr502->count = count;
2005		ctr502->array = NULL;
2006
2007		if (ctr502->count == 0) {
2008			r->out.info_ctr->ctr.ctr502	= ctr502;
2009			return WERR_OK;
2010		}
2011
2012		ctr502->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo502, count);
2013		W_ERROR_HAVE_NO_MEMORY(ctr502->array);
2014
2015		for (i=0; i < count; i++) {
2016			WERROR status;
2017			union srvsvc_NetShareInfo info;
2018			enum srvsvc_ShareType type;
2019
2020			nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg);
2021			if (!NT_STATUS_IS_OK(nterr)) {
2022				DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i]));
2023				return WERR_GENERAL_FAILURE;
2024			}
2025
2026		       	type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg);
2027			if (type & STYPE_HIDDEN) {
2028				ctr502->count--;
2029				talloc_free(scfg);
2030				continue;
2031			}
2032
2033			info.info502 = &ctr502->array[y];
2034			status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info);
2035			W_ERROR_NOT_OK_RETURN(status);
2036			talloc_free(scfg);
2037			y++;
2038		}
2039		talloc_free(snames);
2040
2041		r->out.info_ctr->ctr.ctr502	= ctr502;
2042		*r->out.totalentries		= r->out.info_ctr->ctr.ctr502->count;
2043
2044		return WERR_OK;
2045	}
2046	default:
2047		return WERR_UNKNOWN_LEVEL;
2048	}
2049
2050	return WERR_UNKNOWN_LEVEL;
2051}
2052
2053
2054/*
2055  srvsvc_NetShareDelStart
2056*/
2057static WERROR dcesrv_srvsvc_NetShareDelStart(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2058		       struct srvsvc_NetShareDelStart *r)
2059{
2060	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2061}
2062
2063
2064/*
2065  srvsvc_NetShareDelCommit
2066*/
2067static WERROR dcesrv_srvsvc_NetShareDelCommit(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2068		       struct srvsvc_NetShareDelCommit *r)
2069{
2070	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2071}
2072
2073
2074/*
2075  srvsvc_NetGetFileSecurity
2076*/
2077static WERROR dcesrv_srvsvc_NetGetFileSecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2078		       struct srvsvc_NetGetFileSecurity *r)
2079{
2080	struct sec_desc_buf *sd_buf;
2081	struct ntvfs_context *ntvfs_ctx = NULL;
2082	struct ntvfs_request *ntvfs_req;
2083	union smb_fileinfo *io;
2084	NTSTATUS nt_status;
2085
2086	nt_status = srvsvc_create_ntvfs_context(dce_call, mem_ctx, r->in.share, &ntvfs_ctx);
2087	if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status);
2088
2089	ntvfs_req = ntvfs_request_create(ntvfs_ctx, mem_ctx,
2090					 dce_call->conn->auth_state.session_info,
2091					 0,
2092					 dce_call->time,
2093					 NULL, NULL, 0);
2094	W_ERROR_HAVE_NO_MEMORY(ntvfs_req);
2095
2096	sd_buf = talloc(mem_ctx, struct sec_desc_buf);
2097	W_ERROR_HAVE_NO_MEMORY(sd_buf);
2098
2099	io = talloc(mem_ctx, union smb_fileinfo);
2100	W_ERROR_HAVE_NO_MEMORY(io);
2101
2102	io->query_secdesc.level			= RAW_FILEINFO_SEC_DESC;
2103	io->query_secdesc.in.file.path		= r->in.file;
2104	io->query_secdesc.in.secinfo_flags	= r->in.securityinformation;
2105
2106	nt_status = ntvfs_qpathinfo(ntvfs_req, io);
2107	if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status);
2108
2109	sd_buf->sd = io->query_secdesc.out.sd;
2110
2111	*r->out.sd_buf = sd_buf;
2112	return WERR_OK;
2113}
2114
2115
2116/*
2117  srvsvc_NetSetFileSecurity
2118*/
2119static WERROR dcesrv_srvsvc_NetSetFileSecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2120		       struct srvsvc_NetSetFileSecurity *r)
2121{
2122	struct ntvfs_context *ntvfs_ctx;
2123	struct ntvfs_request *ntvfs_req;
2124	union smb_setfileinfo *io;
2125	NTSTATUS nt_status;
2126
2127	nt_status = srvsvc_create_ntvfs_context(dce_call, mem_ctx, r->in.share, &ntvfs_ctx);
2128	if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status);
2129
2130	ntvfs_req = ntvfs_request_create(ntvfs_ctx, mem_ctx,
2131					 dce_call->conn->auth_state.session_info,
2132					 0,
2133					 dce_call->time,
2134					 NULL, NULL, 0);
2135	W_ERROR_HAVE_NO_MEMORY(ntvfs_req);
2136
2137	io = talloc(mem_ctx, union smb_setfileinfo);
2138	W_ERROR_HAVE_NO_MEMORY(io);
2139
2140	io->set_secdesc.level			= RAW_FILEINFO_SEC_DESC;
2141	io->set_secdesc.in.file.path		= r->in.file;
2142	io->set_secdesc.in.secinfo_flags	= r->in.securityinformation;
2143	io->set_secdesc.in.sd			= r->in.sd_buf->sd;
2144
2145	nt_status = ntvfs_setpathinfo(ntvfs_req, io);
2146	if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status);
2147
2148	return WERR_OK;
2149}
2150
2151
2152/*
2153  srvsvc_NetServerTransportAddEx
2154*/
2155static WERROR dcesrv_srvsvc_NetServerTransportAddEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2156		       struct srvsvc_NetServerTransportAddEx *r)
2157{
2158	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2159}
2160
2161
2162/*
2163  srvsvc_NetServerSetServiceBitsEx
2164*/
2165static WERROR dcesrv_srvsvc_NetServerSetServiceBitsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2166		       struct srvsvc_NetServerSetServiceBitsEx *r)
2167{
2168	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2169}
2170
2171
2172/*
2173  srvsvc_NETRDFSGETVERSION
2174*/
2175static WERROR dcesrv_srvsvc_NETRDFSGETVERSION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2176		       struct srvsvc_NETRDFSGETVERSION *r)
2177{
2178	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2179}
2180
2181
2182/*
2183  srvsvc_NETRDFSCREATELOCALPARTITION
2184*/
2185static WERROR dcesrv_srvsvc_NETRDFSCREATELOCALPARTITION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2186		       struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2187{
2188	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2189}
2190
2191
2192/*
2193  srvsvc_NETRDFSDELETELOCALPARTITION
2194*/
2195static WERROR dcesrv_srvsvc_NETRDFSDELETELOCALPARTITION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2196		       struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2197{
2198	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2199}
2200
2201
2202/*
2203  srvsvc_NETRDFSSETLOCALVOLUMESTATE
2204*/
2205static WERROR dcesrv_srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2206		       struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2207{
2208	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2209}
2210
2211
2212/*
2213  srvsvc_NETRDFSSETSERVERINFO
2214*/
2215static WERROR dcesrv_srvsvc_NETRDFSSETSERVERINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2216		       struct srvsvc_NETRDFSSETSERVERINFO *r)
2217{
2218	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2219}
2220
2221
2222/*
2223  srvsvc_NETRDFSCREATEEXITPOINT
2224*/
2225static WERROR dcesrv_srvsvc_NETRDFSCREATEEXITPOINT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2226		       struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2227{
2228	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2229}
2230
2231
2232/*
2233  srvsvc_NETRDFSDELETEEXITPOINT
2234*/
2235static WERROR dcesrv_srvsvc_NETRDFSDELETEEXITPOINT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2236		       struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2237{
2238	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2239}
2240
2241
2242/*
2243  srvsvc_NETRDFSMODIFYPREFIX
2244*/
2245static WERROR dcesrv_srvsvc_NETRDFSMODIFYPREFIX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2246		       struct srvsvc_NETRDFSMODIFYPREFIX *r)
2247{
2248	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2249}
2250
2251
2252/*
2253  srvsvc_NETRDFSFIXLOCALVOLUME
2254*/
2255static WERROR dcesrv_srvsvc_NETRDFSFIXLOCALVOLUME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2256		       struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2257{
2258	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2259}
2260
2261
2262/*
2263  srvsvc_NETRDFSMANAGERREPORTSITEINFO
2264*/
2265static WERROR dcesrv_srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2266		       struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2267{
2268	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2269}
2270
2271
2272/*
2273  srvsvc_NETRSERVERTRANSPORTDELEX
2274*/
2275static WERROR dcesrv_srvsvc_NETRSERVERTRANSPORTDELEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2276		       struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2277{
2278	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2279}
2280
2281/*
2282  srvsvc_NetShareDel
2283*/
2284static WERROR dcesrv_srvsvc_NetShareDel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2285		       struct srvsvc_NetShareDel *r)
2286{
2287	NTSTATUS nterr;
2288	struct share_context *sctx;
2289
2290	nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);
2291	if (!NT_STATUS_IS_OK(nterr)) {
2292		return ntstatus_to_werror(nterr);
2293	}
2294
2295	nterr = share_remove(sctx, r->in.share_name);
2296	if (!NT_STATUS_IS_OK(nterr)) {
2297		return ntstatus_to_werror(nterr);
2298	}
2299
2300	return WERR_OK;
2301}
2302
2303/*
2304  srvsvc_NetSetServiceBits
2305*/
2306static WERROR dcesrv_srvsvc_NetSetServiceBits(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2307		       struct srvsvc_NetSetServiceBits *r)
2308{
2309	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2310}
2311
2312/*
2313  srvsvc_NETRPRNAMECANONICALIZE
2314*/
2315static WERROR dcesrv_srvsvc_NETRPRNAMECANONICALIZE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2316		       struct srvsvc_NETRPRNAMECANONICALIZE *r)
2317{
2318	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2319}
2320
2321/* include the generated boilerplate */
2322#include "librpc/gen_ndr/ndr_srvsvc_s.c"
2323