Line data Source code
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 : #include "librpc/gen_ndr/ndr_security.h"
28 :
29 : /****************************************************************
30 : ****************************************************************/
31 :
32 96 : static NTSTATUS map_srvsvc_share_info_to_SHARE_INFO_buffer(TALLOC_CTX *mem_ctx,
33 : uint32_t level,
34 : union srvsvc_NetShareInfo *info,
35 : uint8_t **buffer,
36 : uint32_t *num_shares)
37 : {
38 0 : struct SHARE_INFO_0 i0;
39 0 : struct SHARE_INFO_1 i1;
40 0 : struct SHARE_INFO_2 i2;
41 0 : struct SHARE_INFO_501 i501;
42 0 : struct SHARE_INFO_1005 i1005;
43 :
44 0 : struct srvsvc_NetShareInfo0 *s0;
45 0 : struct srvsvc_NetShareInfo1 *s1;
46 0 : struct srvsvc_NetShareInfo2 *s2;
47 0 : struct srvsvc_NetShareInfo501 *s501;
48 0 : struct srvsvc_NetShareInfo1005 *s1005;
49 :
50 96 : if (!buffer) {
51 0 : return NT_STATUS_INVALID_PARAMETER;
52 : }
53 :
54 96 : switch (level) {
55 0 : case 0:
56 0 : s0 = info->info0;
57 :
58 0 : i0.shi0_netname = talloc_strdup(mem_ctx, s0->name);
59 :
60 0 : ADD_TO_ARRAY(mem_ctx, struct SHARE_INFO_0, i0,
61 : (struct SHARE_INFO_0 **)buffer,
62 : num_shares);
63 0 : break;
64 :
65 96 : case 1:
66 96 : s1 = info->info1;
67 :
68 96 : i1.shi1_netname = talloc_strdup(mem_ctx, s1->name);
69 96 : i1.shi1_type = s1->type;
70 96 : i1.shi1_remark = talloc_strdup(mem_ctx, s1->comment);
71 :
72 96 : ADD_TO_ARRAY(mem_ctx, struct SHARE_INFO_1, i1,
73 : (struct SHARE_INFO_1 **)buffer,
74 : num_shares);
75 96 : break;
76 :
77 0 : case 2:
78 0 : s2 = info->info2;
79 :
80 0 : i2.shi2_netname = talloc_strdup(mem_ctx, s2->name);
81 0 : i2.shi2_type = s2->type;
82 0 : i2.shi2_remark = talloc_strdup(mem_ctx, s2->comment);
83 0 : i2.shi2_permissions = s2->permissions;
84 0 : i2.shi2_max_uses = s2->max_users;
85 0 : i2.shi2_current_uses = s2->current_users;
86 0 : i2.shi2_path = talloc_strdup(mem_ctx, s2->path);
87 0 : i2.shi2_passwd = talloc_strdup(mem_ctx, s2->password);
88 :
89 0 : ADD_TO_ARRAY(mem_ctx, struct SHARE_INFO_2, i2,
90 : (struct SHARE_INFO_2 **)buffer,
91 : num_shares);
92 0 : break;
93 :
94 0 : case 501:
95 0 : s501 = info->info501;
96 :
97 0 : i501.shi501_netname = talloc_strdup(mem_ctx, s501->name);
98 0 : i501.shi501_type = s501->type;
99 0 : i501.shi501_remark = talloc_strdup(mem_ctx, s501->comment);
100 0 : i501.shi501_flags = s501->csc_policy;
101 :
102 0 : ADD_TO_ARRAY(mem_ctx, struct SHARE_INFO_501, i501,
103 : (struct SHARE_INFO_501 **)buffer,
104 : num_shares);
105 0 : break;
106 :
107 0 : case 1005:
108 0 : s1005 = info->info1005;
109 :
110 0 : i1005.shi1005_flags = s1005->dfs_flags;
111 :
112 0 : ADD_TO_ARRAY(mem_ctx, struct SHARE_INFO_1005, i1005,
113 : (struct SHARE_INFO_1005 **)buffer,
114 : num_shares);
115 0 : break;
116 :
117 0 : default:
118 0 : return NT_STATUS_INVALID_PARAMETER;
119 : }
120 :
121 96 : return NT_STATUS_OK;
122 : }
123 :
124 : /****************************************************************
125 : ****************************************************************/
126 :
127 0 : static NTSTATUS map_SHARE_INFO_buffer_to_srvsvc_share_info(TALLOC_CTX *mem_ctx,
128 : uint8_t *buffer,
129 : uint32_t level,
130 : union srvsvc_NetShareInfo *info)
131 : {
132 0 : struct SHARE_INFO_2 *i2 = NULL;
133 0 : struct SHARE_INFO_502 *i502 = NULL;
134 0 : struct SHARE_INFO_1004 *i1004 = NULL;
135 0 : struct srvsvc_NetShareInfo2 *s2 = NULL;
136 0 : struct srvsvc_NetShareInfo502 *s502 = NULL;
137 0 : struct srvsvc_NetShareInfo1004 *s1004 = NULL;
138 :
139 0 : if (!buffer) {
140 0 : return NT_STATUS_INVALID_PARAMETER;
141 : }
142 :
143 0 : switch (level) {
144 0 : case 2:
145 0 : i2 = (struct SHARE_INFO_2 *)buffer;
146 :
147 0 : s2 = talloc(mem_ctx, struct srvsvc_NetShareInfo2);
148 0 : NT_STATUS_HAVE_NO_MEMORY(s2);
149 :
150 0 : s2->name = i2->shi2_netname;
151 0 : s2->type = i2->shi2_type;
152 0 : s2->comment = i2->shi2_remark;
153 0 : s2->permissions = i2->shi2_permissions;
154 0 : s2->max_users = i2->shi2_max_uses;
155 0 : s2->current_users = i2->shi2_current_uses;
156 0 : s2->path = i2->shi2_path;
157 0 : s2->password = i2->shi2_passwd;
158 :
159 0 : info->info2 = s2;
160 :
161 0 : break;
162 :
163 0 : case 502:
164 0 : i502 = (struct SHARE_INFO_502 *)buffer;
165 :
166 0 : s502 = talloc(mem_ctx, struct srvsvc_NetShareInfo502);
167 0 : NT_STATUS_HAVE_NO_MEMORY(s502);
168 :
169 0 : s502->name = i502->shi502_netname;
170 0 : s502->type = i502->shi502_type;
171 0 : s502->comment = i502->shi502_remark;
172 0 : s502->permissions = i502->shi502_permissions;
173 0 : s502->max_users = i502->shi502_max_uses;
174 0 : s502->current_users = i502->shi502_current_uses;
175 0 : s502->path = i502->shi502_path;
176 0 : s502->password = i502->shi502_passwd;
177 0 : s502->sd_buf.sd_size =
178 0 : ndr_size_security_descriptor(i502->shi502_security_descriptor, 0);
179 0 : s502->sd_buf.sd = i502->shi502_security_descriptor;
180 :
181 0 : info->info502 = s502;
182 :
183 0 : break;
184 :
185 0 : case 1004:
186 0 : i1004 = (struct SHARE_INFO_1004 *)buffer;
187 :
188 0 : s1004 = talloc(mem_ctx, struct srvsvc_NetShareInfo1004);
189 0 : NT_STATUS_HAVE_NO_MEMORY(s1004);
190 :
191 0 : s1004->comment = i1004->shi1004_remark;
192 :
193 0 : info->info1004 = s1004;
194 :
195 0 : break;
196 0 : default:
197 0 : return NT_STATUS_INVALID_PARAMETER;
198 : }
199 :
200 0 : return NT_STATUS_OK;
201 : }
202 :
203 : /****************************************************************
204 : ****************************************************************/
205 :
206 0 : WERROR NetShareAdd_r(struct libnetapi_ctx *ctx,
207 : struct NetShareAdd *r)
208 : {
209 0 : WERROR werr;
210 0 : NTSTATUS status;
211 0 : union srvsvc_NetShareInfo info;
212 0 : struct dcerpc_binding_handle *b;
213 :
214 0 : if (!r->in.buffer) {
215 0 : return WERR_INVALID_PARAMETER;
216 : }
217 :
218 0 : switch (r->in.level) {
219 0 : case 2:
220 : case 502:
221 0 : break;
222 0 : case 503:
223 0 : return WERR_NOT_SUPPORTED;
224 0 : default:
225 0 : return WERR_INVALID_LEVEL;
226 : }
227 :
228 0 : werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
229 : &ndr_table_srvsvc,
230 : &b);
231 0 : if (!W_ERROR_IS_OK(werr)) {
232 0 : goto done;
233 : }
234 :
235 0 : status = map_SHARE_INFO_buffer_to_srvsvc_share_info(ctx,
236 : r->in.buffer,
237 : r->in.level,
238 : &info);
239 0 : if (!NT_STATUS_IS_OK(status)) {
240 0 : werr = ntstatus_to_werror(status);
241 0 : goto done;
242 : }
243 :
244 0 : status = dcerpc_srvsvc_NetShareAdd(b, talloc_tos(),
245 : r->in.server_name,
246 : r->in.level,
247 : &info,
248 : r->out.parm_err,
249 : &werr);
250 0 : if (!NT_STATUS_IS_OK(status)) {
251 0 : werr = ntstatus_to_werror(status);
252 0 : goto done;
253 : }
254 :
255 0 : if (!W_ERROR_IS_OK(werr)) {
256 0 : goto done;
257 : }
258 :
259 0 : done:
260 0 : return werr;
261 : }
262 :
263 : /****************************************************************
264 : ****************************************************************/
265 :
266 0 : WERROR NetShareAdd_l(struct libnetapi_ctx *ctx,
267 : struct NetShareAdd *r)
268 : {
269 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareAdd);
270 : }
271 :
272 : /****************************************************************
273 : ****************************************************************/
274 :
275 0 : WERROR NetShareDel_r(struct libnetapi_ctx *ctx,
276 : struct NetShareDel *r)
277 : {
278 0 : WERROR werr;
279 0 : NTSTATUS status;
280 0 : struct dcerpc_binding_handle *b;
281 :
282 0 : if (!r->in.net_name) {
283 0 : return WERR_INVALID_PARAMETER;
284 : }
285 :
286 0 : werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
287 : &ndr_table_srvsvc,
288 : &b);
289 0 : if (!W_ERROR_IS_OK(werr)) {
290 0 : goto done;
291 : }
292 :
293 0 : status = dcerpc_srvsvc_NetShareDel(b, talloc_tos(),
294 : r->in.server_name,
295 : r->in.net_name,
296 : r->in.reserved,
297 : &werr);
298 0 : if (!NT_STATUS_IS_OK(status)) {
299 0 : werr = ntstatus_to_werror(status);
300 0 : goto done;
301 : }
302 :
303 0 : done:
304 0 : return werr;
305 : }
306 :
307 : /****************************************************************
308 : ****************************************************************/
309 :
310 0 : WERROR NetShareDel_l(struct libnetapi_ctx *ctx,
311 : struct NetShareDel *r)
312 : {
313 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareDel);
314 : }
315 :
316 : /****************************************************************
317 : ****************************************************************/
318 :
319 4 : WERROR NetShareEnum_r(struct libnetapi_ctx *ctx,
320 : struct NetShareEnum *r)
321 : {
322 0 : WERROR werr;
323 0 : NTSTATUS status;
324 0 : struct srvsvc_NetShareInfoCtr info_ctr;
325 0 : struct srvsvc_NetShareCtr0 ctr0;
326 0 : struct srvsvc_NetShareCtr1 ctr1;
327 0 : struct srvsvc_NetShareCtr2 ctr2;
328 0 : uint32_t i;
329 0 : struct dcerpc_binding_handle *b;
330 :
331 4 : if (!r->out.buffer) {
332 0 : return WERR_INVALID_PARAMETER;
333 : }
334 :
335 4 : switch (r->in.level) {
336 4 : case 0:
337 : case 1:
338 : case 2:
339 4 : break;
340 0 : case 502:
341 : case 503:
342 0 : return WERR_NOT_SUPPORTED;
343 0 : default:
344 0 : return WERR_INVALID_LEVEL;
345 : }
346 :
347 4 : ZERO_STRUCT(info_ctr);
348 :
349 4 : werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
350 : &ndr_table_srvsvc,
351 : &b);
352 4 : if (!W_ERROR_IS_OK(werr)) {
353 0 : goto done;
354 : }
355 :
356 4 : info_ctr.level = r->in.level;
357 4 : switch (r->in.level) {
358 0 : case 0:
359 0 : ZERO_STRUCT(ctr0);
360 0 : info_ctr.ctr.ctr0 = &ctr0;
361 0 : break;
362 4 : case 1:
363 4 : ZERO_STRUCT(ctr1);
364 4 : info_ctr.ctr.ctr1 = &ctr1;
365 4 : break;
366 0 : case 2:
367 0 : ZERO_STRUCT(ctr2);
368 0 : info_ctr.ctr.ctr2 = &ctr2;
369 0 : break;
370 : }
371 :
372 4 : status = dcerpc_srvsvc_NetShareEnumAll(b, talloc_tos(),
373 : r->in.server_name,
374 : &info_ctr,
375 : r->in.prefmaxlen,
376 : r->out.total_entries,
377 : r->out.resume_handle,
378 : &werr);
379 4 : if (!NT_STATUS_IS_OK(status)) {
380 0 : werr = ntstatus_to_werror(status);
381 0 : goto done;
382 : }
383 :
384 4 : if (!W_ERROR_IS_OK(werr) && !W_ERROR_EQUAL(werr, WERR_MORE_DATA)) {
385 0 : goto done;
386 : }
387 :
388 100 : for (i=0; i < info_ctr.ctr.ctr1->count; i++) {
389 96 : union srvsvc_NetShareInfo _i = {0};
390 96 : switch (r->in.level) {
391 0 : case 0:
392 0 : _i.info0 = &info_ctr.ctr.ctr0->array[i];
393 0 : break;
394 96 : case 1:
395 96 : _i.info1 = &info_ctr.ctr.ctr1->array[i];
396 96 : break;
397 0 : case 2:
398 0 : _i.info2 = &info_ctr.ctr.ctr2->array[i];
399 0 : break;
400 : }
401 :
402 96 : status = map_srvsvc_share_info_to_SHARE_INFO_buffer(ctx,
403 : r->in.level,
404 : &_i,
405 : r->out.buffer,
406 : r->out.entries_read);
407 96 : if (!NT_STATUS_IS_OK(status)) {
408 0 : werr = ntstatus_to_werror(status);
409 0 : goto done;
410 : }
411 : }
412 :
413 4 : done:
414 4 : return werr;
415 : }
416 :
417 : /****************************************************************
418 : ****************************************************************/
419 :
420 4 : WERROR NetShareEnum_l(struct libnetapi_ctx *ctx,
421 : struct NetShareEnum *r)
422 : {
423 4 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareEnum);
424 : }
425 :
426 : /****************************************************************
427 : ****************************************************************/
428 :
429 0 : WERROR NetShareGetInfo_r(struct libnetapi_ctx *ctx,
430 : struct NetShareGetInfo *r)
431 : {
432 0 : WERROR werr;
433 0 : NTSTATUS status;
434 0 : union srvsvc_NetShareInfo info;
435 0 : uint32_t num_entries = 0;
436 0 : struct dcerpc_binding_handle *b;
437 :
438 0 : if (!r->in.net_name || !r->out.buffer) {
439 0 : return WERR_INVALID_PARAMETER;
440 : }
441 :
442 0 : switch (r->in.level) {
443 0 : case 0:
444 : case 1:
445 : case 2:
446 : case 501:
447 : case 1005:
448 0 : break;
449 0 : case 502:
450 : case 503:
451 0 : return WERR_NOT_SUPPORTED;
452 0 : default:
453 0 : return WERR_INVALID_LEVEL;
454 : }
455 :
456 0 : werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
457 : &ndr_table_srvsvc,
458 : &b);
459 0 : if (!W_ERROR_IS_OK(werr)) {
460 0 : goto done;
461 : }
462 :
463 0 : status = dcerpc_srvsvc_NetShareGetInfo(b, talloc_tos(),
464 : r->in.server_name,
465 : r->in.net_name,
466 : r->in.level,
467 : &info,
468 : &werr);
469 0 : if (!NT_STATUS_IS_OK(status)) {
470 0 : werr = ntstatus_to_werror(status);
471 0 : goto done;
472 : }
473 :
474 0 : if (!W_ERROR_IS_OK(werr)) {
475 0 : goto done;
476 : }
477 :
478 0 : status = map_srvsvc_share_info_to_SHARE_INFO_buffer(ctx,
479 : r->in.level,
480 : &info,
481 : r->out.buffer,
482 : &num_entries);
483 0 : if (!NT_STATUS_IS_OK(status)) {
484 0 : werr = ntstatus_to_werror(status);
485 : }
486 :
487 0 : done:
488 0 : return werr;
489 : }
490 :
491 : /****************************************************************
492 : ****************************************************************/
493 :
494 0 : WERROR NetShareGetInfo_l(struct libnetapi_ctx *ctx,
495 : struct NetShareGetInfo *r)
496 : {
497 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareGetInfo);
498 : }
499 :
500 : /****************************************************************
501 : ****************************************************************/
502 :
503 0 : WERROR NetShareSetInfo_r(struct libnetapi_ctx *ctx,
504 : struct NetShareSetInfo *r)
505 : {
506 0 : WERROR werr;
507 0 : NTSTATUS status;
508 0 : union srvsvc_NetShareInfo info;
509 0 : struct dcerpc_binding_handle *b;
510 :
511 0 : if (!r->in.buffer) {
512 0 : return WERR_INVALID_PARAMETER;
513 : }
514 :
515 0 : switch (r->in.level) {
516 0 : case 2:
517 : case 1004:
518 0 : break;
519 0 : case 1:
520 : case 502:
521 : case 503:
522 : case 1005:
523 : case 1006:
524 : case 1501:
525 0 : return WERR_NOT_SUPPORTED;
526 0 : default:
527 0 : return WERR_INVALID_LEVEL;
528 : }
529 :
530 0 : werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
531 : &ndr_table_srvsvc,
532 : &b);
533 0 : if (!W_ERROR_IS_OK(werr)) {
534 0 : goto done;
535 : }
536 :
537 0 : status = map_SHARE_INFO_buffer_to_srvsvc_share_info(ctx,
538 : r->in.buffer,
539 : r->in.level,
540 : &info);
541 0 : if (!NT_STATUS_IS_OK(status)) {
542 0 : werr = ntstatus_to_werror(status);
543 0 : goto done;
544 : }
545 :
546 0 : status = dcerpc_srvsvc_NetShareSetInfo(b, talloc_tos(),
547 : r->in.server_name,
548 : r->in.net_name,
549 : r->in.level,
550 : &info,
551 : r->out.parm_err,
552 : &werr);
553 0 : if (!NT_STATUS_IS_OK(status)) {
554 0 : werr = ntstatus_to_werror(status);
555 0 : goto done;
556 : }
557 :
558 0 : if (!W_ERROR_IS_OK(werr)) {
559 0 : goto done;
560 : }
561 :
562 0 : done:
563 0 : return werr;
564 : }
565 :
566 : /****************************************************************
567 : ****************************************************************/
568 :
569 0 : WERROR NetShareSetInfo_l(struct libnetapi_ctx *ctx,
570 : struct NetShareSetInfo *r)
571 : {
572 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareSetInfo);
573 : }
|