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