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