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