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