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