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