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