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