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