s3-rpc: Avoid including every pipe's client and server stubs everywhere in samba.
[samba.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/cli_srvsvc.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_P(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_P(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         struct rpc_pipe_client *pipe_cli = NULL;
186         union srvsvc_NetShareInfo info;
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_open_pipe(ctx, r->in.server_name,
203                                    &ndr_table_srvsvc.syntax_id,
204                                    &pipe_cli);
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 = rpccli_srvsvc_NetShareAdd(pipe_cli, ctx,
219                                            r->in.server_name,
220                                            r->in.level,
221                                            &info,
222                                            r->out.parm_err,
223                                            &werr);
224         if (!W_ERROR_IS_OK(werr)) {
225                 goto done;
226         }
227
228  done:
229         return werr;
230 }
231
232 /****************************************************************
233 ****************************************************************/
234
235 WERROR NetShareAdd_l(struct libnetapi_ctx *ctx,
236                      struct NetShareAdd *r)
237 {
238         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareAdd);
239 }
240
241 /****************************************************************
242 ****************************************************************/
243
244 WERROR NetShareDel_r(struct libnetapi_ctx *ctx,
245                      struct NetShareDel *r)
246 {
247         WERROR werr;
248         NTSTATUS status;
249         struct rpc_pipe_client *pipe_cli = NULL;
250
251         if (!r->in.net_name) {
252                 return WERR_INVALID_PARAM;
253         }
254
255         werr = libnetapi_open_pipe(ctx, r->in.server_name,
256                                    &ndr_table_srvsvc.syntax_id,
257                                    &pipe_cli);
258         if (!W_ERROR_IS_OK(werr)) {
259                 goto done;
260         }
261
262         status = rpccli_srvsvc_NetShareDel(pipe_cli, ctx,
263                                            r->in.server_name,
264                                            r->in.net_name,
265                                            r->in.reserved,
266                                            &werr);
267         if (!NT_STATUS_IS_OK(status)) {
268                 werr = ntstatus_to_werror(status);
269                 goto done;
270         }
271
272  done:
273         return werr;
274 }
275
276 /****************************************************************
277 ****************************************************************/
278
279 WERROR NetShareDel_l(struct libnetapi_ctx *ctx,
280                      struct NetShareDel *r)
281 {
282         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareDel);
283 }
284
285 /****************************************************************
286 ****************************************************************/
287
288 WERROR NetShareEnum_r(struct libnetapi_ctx *ctx,
289                       struct NetShareEnum *r)
290 {
291         WERROR werr;
292         NTSTATUS status;
293         struct rpc_pipe_client *pipe_cli = NULL;
294         struct srvsvc_NetShareInfoCtr info_ctr;
295         struct srvsvc_NetShareCtr0 ctr0;
296         struct srvsvc_NetShareCtr1 ctr1;
297         struct srvsvc_NetShareCtr2 ctr2;
298         uint32_t i;
299
300         if (!r->out.buffer) {
301                 return WERR_INVALID_PARAM;
302         }
303
304         switch (r->in.level) {
305                 case 0:
306                 case 1:
307                 case 2:
308                         break;
309                 case 502:
310                 case 503:
311                         return WERR_NOT_SUPPORTED;
312                 default:
313                         return WERR_UNKNOWN_LEVEL;
314         }
315
316         ZERO_STRUCT(info_ctr);
317
318         werr = libnetapi_open_pipe(ctx, r->in.server_name,
319                                    &ndr_table_srvsvc.syntax_id,
320                                    &pipe_cli);
321         if (!W_ERROR_IS_OK(werr)) {
322                 goto done;
323         }
324
325         info_ctr.level = r->in.level;
326         switch (r->in.level) {
327                 case 0:
328                         ZERO_STRUCT(ctr0);
329                         info_ctr.ctr.ctr0 = &ctr0;
330                         break;
331                 case 1:
332                         ZERO_STRUCT(ctr1);
333                         info_ctr.ctr.ctr1 = &ctr1;
334                         break;
335                 case 2:
336                         ZERO_STRUCT(ctr2);
337                         info_ctr.ctr.ctr2 = &ctr2;
338                         break;
339         }
340
341         status = rpccli_srvsvc_NetShareEnumAll(pipe_cli, ctx,
342                                                r->in.server_name,
343                                                &info_ctr,
344                                                r->in.prefmaxlen,
345                                                r->out.total_entries,
346                                                r->out.resume_handle,
347                                                &werr);
348         if (NT_STATUS_IS_ERR(status)) {
349                 goto done;
350         }
351
352         for (i=0; i < info_ctr.ctr.ctr1->count; i++) {
353                 union srvsvc_NetShareInfo _i;
354                 switch (r->in.level) {
355                         case 0:
356                                 _i.info0 = &info_ctr.ctr.ctr0->array[i];
357                                 break;
358                         case 1:
359                                 _i.info1 = &info_ctr.ctr.ctr1->array[i];
360                                 break;
361                         case 2:
362                                 _i.info2 = &info_ctr.ctr.ctr2->array[i];
363                                 break;
364                 }
365
366                 status = map_srvsvc_share_info_to_SHARE_INFO_buffer(ctx,
367                                                                     r->in.level,
368                                                                     &_i,
369                                                                     r->out.buffer,
370                                                                     r->out.entries_read);
371                 if (!NT_STATUS_IS_OK(status)) {
372                         werr = ntstatus_to_werror(status);
373                 }
374         }
375
376  done:
377         return werr;
378 }
379
380 /****************************************************************
381 ****************************************************************/
382
383 WERROR NetShareEnum_l(struct libnetapi_ctx *ctx,
384                       struct NetShareEnum *r)
385 {
386         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareEnum);
387 }
388
389 /****************************************************************
390 ****************************************************************/
391
392 WERROR NetShareGetInfo_r(struct libnetapi_ctx *ctx,
393                          struct NetShareGetInfo *r)
394 {
395         WERROR werr;
396         NTSTATUS status;
397         struct rpc_pipe_client *pipe_cli = NULL;
398         union srvsvc_NetShareInfo info;
399         uint32_t num_entries = 0;
400
401         if (!r->in.net_name || !r->out.buffer) {
402                 return WERR_INVALID_PARAM;
403         }
404
405         switch (r->in.level) {
406                 case 0:
407                 case 1:
408                 case 2:
409                 case 501:
410                 case 1005:
411                         break;
412                 case 502:
413                 case 503:
414                         return WERR_NOT_SUPPORTED;
415                 default:
416                         return WERR_UNKNOWN_LEVEL;
417         }
418
419         werr = libnetapi_open_pipe(ctx, r->in.server_name,
420                                    &ndr_table_srvsvc.syntax_id,
421                                    &pipe_cli);
422         if (!W_ERROR_IS_OK(werr)) {
423                 goto done;
424         }
425
426         status = rpccli_srvsvc_NetShareGetInfo(pipe_cli, ctx,
427                                                r->in.server_name,
428                                                r->in.net_name,
429                                                r->in.level,
430                                                &info,
431                                                &werr);
432
433         if (!W_ERROR_IS_OK(werr)) {
434                 goto done;
435         }
436
437         status = map_srvsvc_share_info_to_SHARE_INFO_buffer(ctx,
438                                                             r->in.level,
439                                                             &info,
440                                                             r->out.buffer,
441                                                             &num_entries);
442         if (!NT_STATUS_IS_OK(status)) {
443                 werr = ntstatus_to_werror(status);
444         }
445
446  done:
447         return werr;
448 }
449
450 /****************************************************************
451 ****************************************************************/
452
453 WERROR NetShareGetInfo_l(struct libnetapi_ctx *ctx,
454                          struct NetShareGetInfo *r)
455 {
456         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareGetInfo);
457 }
458
459 /****************************************************************
460 ****************************************************************/
461
462 WERROR NetShareSetInfo_r(struct libnetapi_ctx *ctx,
463                          struct NetShareSetInfo *r)
464 {
465         WERROR werr;
466         NTSTATUS status;
467         struct rpc_pipe_client *pipe_cli = NULL;
468         union srvsvc_NetShareInfo info;
469
470         if (!r->in.buffer) {
471                 return WERR_INVALID_PARAM;
472         }
473
474         switch (r->in.level) {
475                 case 2:
476                 case 1004:
477                         break;
478                 case 1:
479                 case 502:
480                 case 503:
481                 case 1005:
482                 case 1006:
483                 case 1501:
484                         return WERR_NOT_SUPPORTED;
485                 default:
486                         return WERR_UNKNOWN_LEVEL;
487         }
488
489         werr = libnetapi_open_pipe(ctx, r->in.server_name,
490                                    &ndr_table_srvsvc.syntax_id,
491                                    &pipe_cli);
492         if (!W_ERROR_IS_OK(werr)) {
493                 goto done;
494         }
495
496         status = map_SHARE_INFO_buffer_to_srvsvc_share_info(ctx,
497                                                             r->in.buffer,
498                                                             r->in.level,
499                                                             &info);
500         if (!NT_STATUS_IS_OK(status)) {
501                 werr = ntstatus_to_werror(status);
502                 goto done;
503         }
504
505         status = rpccli_srvsvc_NetShareSetInfo(pipe_cli, ctx,
506                                                r->in.server_name,
507                                                r->in.net_name,
508                                                r->in.level,
509                                                &info,
510                                                r->out.parm_err,
511                                                &werr);
512         if (!W_ERROR_IS_OK(werr)) {
513                 goto done;
514         }
515
516  done:
517         return werr;
518 }
519
520 /****************************************************************
521 ****************************************************************/
522
523 WERROR NetShareSetInfo_l(struct libnetapi_ctx *ctx,
524                          struct NetShareSetInfo *r)
525 {
526         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareSetInfo);
527 }