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