Merge commit 'release-4-0-0alpha15' into master4-tmp
[kai/samba-autobuild/.git] / source3 / lib / netapi / share.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  NetApi Share Support
4  *  Copyright (C) Guenther Deschner 2008
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "includes.h"
21
22 #include "librpc/gen_ndr/libnetapi.h"
23 #include "lib/netapi/netapi.h"
24 #include "lib/netapi/netapi_private.h"
25 #include "lib/netapi/libnetapi.h"
26 #include "../librpc/gen_ndr/ndr_srvsvc_c.h"
27
28 /****************************************************************
29 ****************************************************************/
30
31 static NTSTATUS map_srvsvc_share_info_to_SHARE_INFO_buffer(TALLOC_CTX *mem_ctx,
32                                                            uint32_t level,
33                                                            union srvsvc_NetShareInfo *info,
34                                                            uint8_t **buffer,
35                                                            uint32_t *num_shares)
36 {
37         struct SHARE_INFO_0 i0;
38         struct SHARE_INFO_1 i1;
39         struct SHARE_INFO_2 i2;
40         struct SHARE_INFO_501 i501;
41         struct SHARE_INFO_1005 i1005;
42
43         struct srvsvc_NetShareInfo0 *s0;
44         struct srvsvc_NetShareInfo1 *s1;
45         struct srvsvc_NetShareInfo2 *s2;
46         struct srvsvc_NetShareInfo501 *s501;
47         struct srvsvc_NetShareInfo1005 *s1005;
48
49         if (!buffer) {
50                 return NT_STATUS_INVALID_PARAMETER;
51         }
52
53         switch (level) {
54                 case 0:
55                         s0 = info->info0;
56
57                         i0.shi0_netname         = talloc_strdup(mem_ctx, s0->name);
58
59                         ADD_TO_ARRAY(mem_ctx, struct SHARE_INFO_0, i0,
60                                      (struct SHARE_INFO_0 **)buffer,
61                                      num_shares);
62                         break;
63
64                 case 1:
65                         s1 = info->info1;
66
67                         i1.shi1_netname         = talloc_strdup(mem_ctx, s1->name);
68                         i1.shi1_type            = s1->type;
69                         i1.shi1_remark          = talloc_strdup(mem_ctx, s1->comment);
70
71                         ADD_TO_ARRAY(mem_ctx, struct SHARE_INFO_1, i1,
72                                      (struct SHARE_INFO_1 **)buffer,
73                                      num_shares);
74                         break;
75
76                 case 2:
77                         s2 = info->info2;
78
79                         i2.shi2_netname         = talloc_strdup(mem_ctx, s2->name);
80                         i2.shi2_type            = s2->type;
81                         i2.shi2_remark          = talloc_strdup(mem_ctx, s2->comment);
82                         i2.shi2_permissions     = s2->permissions;
83                         i2.shi2_max_uses        = s2->max_users;
84                         i2.shi2_current_uses    = s2->current_users;
85                         i2.shi2_path            = talloc_strdup(mem_ctx, s2->path);
86                         i2.shi2_passwd          = talloc_strdup(mem_ctx, s2->password);
87
88                         ADD_TO_ARRAY(mem_ctx, struct SHARE_INFO_2, i2,
89                                      (struct SHARE_INFO_2 **)buffer,
90                                      num_shares);
91                         break;
92
93                 case 501:
94                         s501 = info->info501;
95
96                         i501.shi501_netname             = talloc_strdup(mem_ctx, s501->name);
97                         i501.shi501_type                = s501->type;
98                         i501.shi501_remark              = talloc_strdup(mem_ctx, s501->comment);
99                         i501.shi501_flags               = s501->csc_policy;
100
101                         ADD_TO_ARRAY(mem_ctx, struct SHARE_INFO_501, i501,
102                                      (struct SHARE_INFO_501 **)buffer,
103                                      num_shares);
104                         break;
105
106                 case 1005:
107                         s1005 = info->info1005;
108
109                         i1005.shi1005_flags             = s1005->dfs_flags;
110
111                         ADD_TO_ARRAY(mem_ctx, struct SHARE_INFO_1005, i1005,
112                                      (struct SHARE_INFO_1005 **)buffer,
113                                      num_shares);
114                         break;
115
116                 default:
117                         return NT_STATUS_INVALID_PARAMETER;
118         }
119
120         return NT_STATUS_OK;
121 }
122
123 /****************************************************************
124 ****************************************************************/
125
126 static NTSTATUS map_SHARE_INFO_buffer_to_srvsvc_share_info(TALLOC_CTX *mem_ctx,
127                                                            uint8_t *buffer,
128                                                            uint32_t level,
129                                                            union srvsvc_NetShareInfo *info)
130 {
131         struct SHARE_INFO_2 *i2 = NULL;
132         struct SHARE_INFO_1004 *i1004 = NULL;
133         struct srvsvc_NetShareInfo2 *s2 = NULL;
134         struct srvsvc_NetShareInfo1004 *s1004 = NULL;
135
136         if (!buffer) {
137                 return NT_STATUS_INVALID_PARAMETER;
138         }
139
140         switch (level) {
141                 case 2:
142                         i2 = (struct SHARE_INFO_2 *)buffer;
143
144                         s2 = talloc(mem_ctx, struct srvsvc_NetShareInfo2);
145                         NT_STATUS_HAVE_NO_MEMORY(s2);
146
147                         s2->name                = i2->shi2_netname;
148                         s2->type                = i2->shi2_type;
149                         s2->comment             = i2->shi2_remark;
150                         s2->permissions         = i2->shi2_permissions;
151                         s2->max_users           = i2->shi2_max_uses;
152                         s2->current_users       = i2->shi2_current_uses;
153                         s2->path                = i2->shi2_path;
154                         s2->password            = i2->shi2_passwd;
155
156                         info->info2 = s2;
157
158                         break;
159                 case 1004:
160                         i1004 = (struct SHARE_INFO_1004 *)buffer;
161
162                         s1004 = talloc(mem_ctx, struct srvsvc_NetShareInfo1004);
163                         NT_STATUS_HAVE_NO_MEMORY(s1004);
164
165                         s1004->comment          = i1004->shi1004_remark;
166
167                         info->info1004 = s1004;
168
169                         break;
170                 default:
171                         return NT_STATUS_INVALID_PARAMETER;
172         }
173
174         return NT_STATUS_OK;
175 }
176
177 /****************************************************************
178 ****************************************************************/
179
180 WERROR NetShareAdd_r(struct libnetapi_ctx *ctx,
181                      struct NetShareAdd *r)
182 {
183         WERROR werr;
184         NTSTATUS status;
185         union srvsvc_NetShareInfo info;
186         struct dcerpc_binding_handle *b;
187
188         if (!r->in.buffer) {
189                 return WERR_INVALID_PARAM;
190         }
191
192         switch (r->in.level) {
193                 case 2:
194                         break;
195                 case 502:
196                 case 503:
197                         return WERR_NOT_SUPPORTED;
198                 default:
199                         return WERR_UNKNOWN_LEVEL;
200         }
201
202         werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
203                                             &ndr_table_srvsvc.syntax_id,
204                                             &b);
205         if (!W_ERROR_IS_OK(werr)) {
206                 goto done;
207         }
208
209         status = map_SHARE_INFO_buffer_to_srvsvc_share_info(ctx,
210                                                             r->in.buffer,
211                                                             r->in.level,
212                                                             &info);
213         if (!NT_STATUS_IS_OK(status)) {
214                 werr = ntstatus_to_werror(status);
215                 goto done;
216         }
217
218         status = dcerpc_srvsvc_NetShareAdd(b, talloc_tos(),
219                                            r->in.server_name,
220                                            r->in.level,
221                                            &info,
222                                            r->out.parm_err,
223                                            &werr);
224         if (!NT_STATUS_IS_OK(status)) {
225                 werr = ntstatus_to_werror(status);
226                 goto done;
227         }
228
229         if (!W_ERROR_IS_OK(werr)) {
230                 goto done;
231         }
232
233  done:
234         return werr;
235 }
236
237 /****************************************************************
238 ****************************************************************/
239
240 WERROR NetShareAdd_l(struct libnetapi_ctx *ctx,
241                      struct NetShareAdd *r)
242 {
243         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareAdd);
244 }
245
246 /****************************************************************
247 ****************************************************************/
248
249 WERROR NetShareDel_r(struct libnetapi_ctx *ctx,
250                      struct NetShareDel *r)
251 {
252         WERROR werr;
253         NTSTATUS status;
254         struct dcerpc_binding_handle *b;
255
256         if (!r->in.net_name) {
257                 return WERR_INVALID_PARAM;
258         }
259
260         werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
261                                             &ndr_table_srvsvc.syntax_id,
262                                             &b);
263         if (!W_ERROR_IS_OK(werr)) {
264                 goto done;
265         }
266
267         status = dcerpc_srvsvc_NetShareDel(b, talloc_tos(),
268                                            r->in.server_name,
269                                            r->in.net_name,
270                                            r->in.reserved,
271                                            &werr);
272         if (!NT_STATUS_IS_OK(status)) {
273                 werr = ntstatus_to_werror(status);
274                 goto done;
275         }
276
277  done:
278         return werr;
279 }
280
281 /****************************************************************
282 ****************************************************************/
283
284 WERROR NetShareDel_l(struct libnetapi_ctx *ctx,
285                      struct NetShareDel *r)
286 {
287         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareDel);
288 }
289
290 /****************************************************************
291 ****************************************************************/
292
293 WERROR NetShareEnum_r(struct libnetapi_ctx *ctx,
294                       struct NetShareEnum *r)
295 {
296         WERROR werr;
297         NTSTATUS status;
298         struct srvsvc_NetShareInfoCtr info_ctr;
299         struct srvsvc_NetShareCtr0 ctr0;
300         struct srvsvc_NetShareCtr1 ctr1;
301         struct srvsvc_NetShareCtr2 ctr2;
302         uint32_t i;
303         struct dcerpc_binding_handle *b;
304
305         if (!r->out.buffer) {
306                 return WERR_INVALID_PARAM;
307         }
308
309         switch (r->in.level) {
310                 case 0:
311                 case 1:
312                 case 2:
313                         break;
314                 case 502:
315                 case 503:
316                         return WERR_NOT_SUPPORTED;
317                 default:
318                         return WERR_UNKNOWN_LEVEL;
319         }
320
321         ZERO_STRUCT(info_ctr);
322
323         werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
324                                             &ndr_table_srvsvc.syntax_id,
325                                             &b);
326         if (!W_ERROR_IS_OK(werr)) {
327                 goto done;
328         }
329
330         info_ctr.level = r->in.level;
331         switch (r->in.level) {
332                 case 0:
333                         ZERO_STRUCT(ctr0);
334                         info_ctr.ctr.ctr0 = &ctr0;
335                         break;
336                 case 1:
337                         ZERO_STRUCT(ctr1);
338                         info_ctr.ctr.ctr1 = &ctr1;
339                         break;
340                 case 2:
341                         ZERO_STRUCT(ctr2);
342                         info_ctr.ctr.ctr2 = &ctr2;
343                         break;
344         }
345
346         status = dcerpc_srvsvc_NetShareEnumAll(b, talloc_tos(),
347                                                r->in.server_name,
348                                                &info_ctr,
349                                                r->in.prefmaxlen,
350                                                r->out.total_entries,
351                                                r->out.resume_handle,
352                                                &werr);
353         if (!NT_STATUS_IS_OK(status)) {
354                 werr = ntstatus_to_werror(status);
355                 goto done;
356         }
357
358         if (!W_ERROR_IS_OK(werr) && !W_ERROR_EQUAL(werr, WERR_MORE_DATA)) {
359                 goto done;
360         }
361
362         for (i=0; i < info_ctr.ctr.ctr1->count; i++) {
363                 union srvsvc_NetShareInfo _i;
364                 switch (r->in.level) {
365                         case 0:
366                                 _i.info0 = &info_ctr.ctr.ctr0->array[i];
367                                 break;
368                         case 1:
369                                 _i.info1 = &info_ctr.ctr.ctr1->array[i];
370                                 break;
371                         case 2:
372                                 _i.info2 = &info_ctr.ctr.ctr2->array[i];
373                                 break;
374                 }
375
376                 status = map_srvsvc_share_info_to_SHARE_INFO_buffer(ctx,
377                                                                     r->in.level,
378                                                                     &_i,
379                                                                     r->out.buffer,
380                                                                     r->out.entries_read);
381                 if (!NT_STATUS_IS_OK(status)) {
382                         werr = ntstatus_to_werror(status);
383                         goto done;
384                 }
385         }
386
387  done:
388         return werr;
389 }
390
391 /****************************************************************
392 ****************************************************************/
393
394 WERROR NetShareEnum_l(struct libnetapi_ctx *ctx,
395                       struct NetShareEnum *r)
396 {
397         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareEnum);
398 }
399
400 /****************************************************************
401 ****************************************************************/
402
403 WERROR NetShareGetInfo_r(struct libnetapi_ctx *ctx,
404                          struct NetShareGetInfo *r)
405 {
406         WERROR werr;
407         NTSTATUS status;
408         union srvsvc_NetShareInfo info;
409         uint32_t num_entries = 0;
410         struct dcerpc_binding_handle *b;
411
412         if (!r->in.net_name || !r->out.buffer) {
413                 return WERR_INVALID_PARAM;
414         }
415
416         switch (r->in.level) {
417                 case 0:
418                 case 1:
419                 case 2:
420                 case 501:
421                 case 1005:
422                         break;
423                 case 502:
424                 case 503:
425                         return WERR_NOT_SUPPORTED;
426                 default:
427                         return WERR_UNKNOWN_LEVEL;
428         }
429
430         werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
431                                             &ndr_table_srvsvc.syntax_id,
432                                             &b);
433         if (!W_ERROR_IS_OK(werr)) {
434                 goto done;
435         }
436
437         status = dcerpc_srvsvc_NetShareGetInfo(b, talloc_tos(),
438                                                r->in.server_name,
439                                                r->in.net_name,
440                                                r->in.level,
441                                                &info,
442                                                &werr);
443         if (!NT_STATUS_IS_OK(status)) {
444                 werr = ntstatus_to_werror(status);
445                 goto done;
446         }
447
448         if (!W_ERROR_IS_OK(werr)) {
449                 goto done;
450         }
451
452         status = map_srvsvc_share_info_to_SHARE_INFO_buffer(ctx,
453                                                             r->in.level,
454                                                             &info,
455                                                             r->out.buffer,
456                                                             &num_entries);
457         if (!NT_STATUS_IS_OK(status)) {
458                 werr = ntstatus_to_werror(status);
459         }
460
461  done:
462         return werr;
463 }
464
465 /****************************************************************
466 ****************************************************************/
467
468 WERROR NetShareGetInfo_l(struct libnetapi_ctx *ctx,
469                          struct NetShareGetInfo *r)
470 {
471         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareGetInfo);
472 }
473
474 /****************************************************************
475 ****************************************************************/
476
477 WERROR NetShareSetInfo_r(struct libnetapi_ctx *ctx,
478                          struct NetShareSetInfo *r)
479 {
480         WERROR werr;
481         NTSTATUS status;
482         union srvsvc_NetShareInfo info;
483         struct dcerpc_binding_handle *b;
484
485         if (!r->in.buffer) {
486                 return WERR_INVALID_PARAM;
487         }
488
489         switch (r->in.level) {
490                 case 2:
491                 case 1004:
492                         break;
493                 case 1:
494                 case 502:
495                 case 503:
496                 case 1005:
497                 case 1006:
498                 case 1501:
499                         return WERR_NOT_SUPPORTED;
500                 default:
501                         return WERR_UNKNOWN_LEVEL;
502         }
503
504         werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
505                                             &ndr_table_srvsvc.syntax_id,
506                                             &b);
507         if (!W_ERROR_IS_OK(werr)) {
508                 goto done;
509         }
510
511         status = map_SHARE_INFO_buffer_to_srvsvc_share_info(ctx,
512                                                             r->in.buffer,
513                                                             r->in.level,
514                                                             &info);
515         if (!NT_STATUS_IS_OK(status)) {
516                 werr = ntstatus_to_werror(status);
517                 goto done;
518         }
519
520         status = dcerpc_srvsvc_NetShareSetInfo(b, talloc_tos(),
521                                                r->in.server_name,
522                                                r->in.net_name,
523                                                r->in.level,
524                                                &info,
525                                                r->out.parm_err,
526                                                &werr);
527         if (!NT_STATUS_IS_OK(status)) {
528                 werr = ntstatus_to_werror(status);
529                 goto done;
530         }
531
532         if (!W_ERROR_IS_OK(werr)) {
533                 goto done;
534         }
535
536  done:
537         return werr;
538 }
539
540 /****************************************************************
541 ****************************************************************/
542
543 WERROR NetShareSetInfo_l(struct libnetapi_ctx *ctx,
544                          struct NetShareSetInfo *r)
545 {
546         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareSetInfo);
547 }