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