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