source: vendor/3.5.0/source3/lib/netapi/localgroup.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 33.2 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 * NetApi LocalGroup 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_samr.h"
27#include "../librpc/gen_ndr/cli_lsa.h"
28
29static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
30 struct rpc_pipe_client *pipe_cli,
31 struct policy_handle *domain_handle,
32 const char *group_name,
33 uint32_t access_rights,
34 struct policy_handle *alias_handle)
35{
36 NTSTATUS status;
37
38 struct lsa_String lsa_account_name;
39 struct samr_Ids user_rids, name_types;
40
41 init_lsa_String(&lsa_account_name, group_name);
42
43 status = rpccli_samr_LookupNames(pipe_cli, mem_ctx,
44 domain_handle,
45 1,
46 &lsa_account_name,
47 &user_rids,
48 &name_types);
49 if (!NT_STATUS_IS_OK(status)) {
50 return status;
51 }
52
53 switch (name_types.ids[0]) {
54 case SID_NAME_ALIAS:
55 case SID_NAME_WKN_GRP:
56 break;
57 default:
58 return NT_STATUS_INVALID_SID;
59 }
60
61 return rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
62 domain_handle,
63 access_rights,
64 user_rids.ids[0],
65 alias_handle);
66}
67
68/****************************************************************
69****************************************************************/
70
71static NTSTATUS libnetapi_samr_open_alias_queryinfo(TALLOC_CTX *mem_ctx,
72 struct rpc_pipe_client *pipe_cli,
73 struct policy_handle *handle,
74 uint32_t rid,
75 uint32_t access_rights,
76 enum samr_AliasInfoEnum level,
77 union samr_AliasInfo **alias_info)
78{
79 NTSTATUS status;
80 struct policy_handle alias_handle;
81 union samr_AliasInfo *_alias_info = NULL;
82
83 ZERO_STRUCT(alias_handle);
84
85 status = rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
86 handle,
87 access_rights,
88 rid,
89 &alias_handle);
90 if (!NT_STATUS_IS_OK(status)) {
91 goto done;
92 }
93
94 status = rpccli_samr_QueryAliasInfo(pipe_cli, mem_ctx,
95 &alias_handle,
96 level,
97 &_alias_info);
98 if (!NT_STATUS_IS_OK(status)) {
99 goto done;
100 }
101
102 *alias_info = _alias_info;
103
104 done:
105 if (is_valid_policy_hnd(&alias_handle)) {
106 rpccli_samr_Close(pipe_cli, mem_ctx, &alias_handle);
107 }
108
109 return status;
110}
111
112/****************************************************************
113****************************************************************/
114
115WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
116 struct NetLocalGroupAdd *r)
117{
118 struct rpc_pipe_client *pipe_cli = NULL;
119 NTSTATUS status;
120 WERROR werr;
121 struct lsa_String lsa_account_name;
122 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
123 struct dom_sid2 *domain_sid = NULL;
124 uint32_t rid;
125
126 struct LOCALGROUP_INFO_0 *info0 = NULL;
127 struct LOCALGROUP_INFO_1 *info1 = NULL;
128
129 const char *alias_name = NULL;
130
131 if (!r->in.buffer) {
132 return WERR_INVALID_PARAM;
133 }
134
135 switch (r->in.level) {
136 case 0:
137 info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
138 alias_name = info0->lgrpi0_name;
139 break;
140 case 1:
141 info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
142 alias_name = info1->lgrpi1_name;
143 break;
144 default:
145 werr = WERR_UNKNOWN_LEVEL;
146 goto done;
147 }
148
149 ZERO_STRUCT(connect_handle);
150 ZERO_STRUCT(builtin_handle);
151 ZERO_STRUCT(domain_handle);
152 ZERO_STRUCT(alias_handle);
153
154 werr = libnetapi_open_pipe(ctx, r->in.server_name,
155 &ndr_table_samr.syntax_id,
156 &pipe_cli);
157 if (!W_ERROR_IS_OK(werr)) {
158 goto done;
159 }
160
161 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
162 SAMR_ACCESS_LOOKUP_DOMAIN |
163 SAMR_ACCESS_ENUM_DOMAINS,
164 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
165 &connect_handle,
166 &builtin_handle);
167 if (!W_ERROR_IS_OK(werr)) {
168 goto done;
169 }
170
171 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
172 &builtin_handle,
173 alias_name,
174 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
175 &alias_handle);
176 if (ctx->disable_policy_handle_cache) {
177 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
178 }
179
180 if (NT_STATUS_IS_OK(status)) {
181 werr = WERR_ALIAS_EXISTS;
182 goto done;
183 }
184
185 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
186 SAMR_ACCESS_ENUM_DOMAINS |
187 SAMR_ACCESS_LOOKUP_DOMAIN,
188 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
189 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
190 &connect_handle,
191 &domain_handle,
192 &domain_sid);
193 if (!W_ERROR_IS_OK(werr)) {
194 goto done;
195 }
196
197 init_lsa_String(&lsa_account_name, alias_name);
198
199 status = rpccli_samr_CreateDomAlias(pipe_cli, ctx,
200 &domain_handle,
201 &lsa_account_name,
202 SEC_STD_DELETE |
203 SAMR_ALIAS_ACCESS_SET_INFO,
204 &alias_handle,
205 &rid);
206 if (!NT_STATUS_IS_OK(status)) {
207 werr = ntstatus_to_werror(status);
208 goto done;
209 }
210
211 if (r->in.level == 1 && info1->lgrpi1_comment) {
212
213 union samr_AliasInfo alias_info;
214
215 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
216
217 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
218 &alias_handle,
219 ALIASINFODESCRIPTION,
220 &alias_info);
221 if (!NT_STATUS_IS_OK(status)) {
222 werr = ntstatus_to_werror(status);
223 goto done;
224 }
225 }
226
227 werr = WERR_OK;
228
229 done:
230 if (is_valid_policy_hnd(&alias_handle)) {
231 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
232 }
233
234 if (ctx->disable_policy_handle_cache) {
235 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
236 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
237 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
238 }
239
240 return werr;
241}
242
243/****************************************************************
244****************************************************************/
245
246WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
247 struct NetLocalGroupAdd *r)
248{
249 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAdd);
250}
251
252/****************************************************************
253****************************************************************/
254
255
256WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
257 struct NetLocalGroupDel *r)
258{
259 struct rpc_pipe_client *pipe_cli = NULL;
260 NTSTATUS status;
261 WERROR werr;
262 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
263 struct dom_sid2 *domain_sid = NULL;
264
265 if (!r->in.group_name) {
266 return WERR_INVALID_PARAM;
267 }
268
269 ZERO_STRUCT(connect_handle);
270 ZERO_STRUCT(builtin_handle);
271 ZERO_STRUCT(domain_handle);
272 ZERO_STRUCT(alias_handle);
273
274 werr = libnetapi_open_pipe(ctx, r->in.server_name,
275 &ndr_table_samr.syntax_id,
276 &pipe_cli);
277 if (!W_ERROR_IS_OK(werr)) {
278 goto done;
279 }
280
281 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
282 SAMR_ACCESS_LOOKUP_DOMAIN |
283 SAMR_ACCESS_ENUM_DOMAINS,
284 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
285 &connect_handle,
286 &builtin_handle);
287 if (!W_ERROR_IS_OK(werr)) {
288 goto done;
289 }
290
291 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
292 &builtin_handle,
293 r->in.group_name,
294 SEC_STD_DELETE,
295 &alias_handle);
296
297 if (ctx->disable_policy_handle_cache) {
298 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
299 }
300
301 if (NT_STATUS_IS_OK(status)) {
302 goto delete_alias;
303 }
304
305 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
306 SAMR_ACCESS_ENUM_DOMAINS |
307 SAMR_ACCESS_LOOKUP_DOMAIN,
308 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
309 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
310 &connect_handle,
311 &domain_handle,
312 &domain_sid);
313 if (!W_ERROR_IS_OK(werr)) {
314 goto done;
315 }
316
317 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
318 &domain_handle,
319 r->in.group_name,
320 SEC_STD_DELETE,
321 &alias_handle);
322
323 if (ctx->disable_policy_handle_cache) {
324 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
325 }
326
327 if (!NT_STATUS_IS_OK(status)) {
328 werr = ntstatus_to_werror(status);
329 goto done;
330 }
331
332
333 delete_alias:
334 status = rpccli_samr_DeleteDomAlias(pipe_cli, ctx,
335 &alias_handle);
336 if (!NT_STATUS_IS_OK(status)) {
337 werr = ntstatus_to_werror(status);
338 goto done;
339 }
340
341 ZERO_STRUCT(alias_handle);
342
343 werr = WERR_OK;
344
345 done:
346 if (is_valid_policy_hnd(&alias_handle)) {
347 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
348 }
349
350 if (ctx->disable_policy_handle_cache) {
351 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
352 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
353 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
354 }
355
356 return werr;
357}
358
359/****************************************************************
360****************************************************************/
361
362WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
363 struct NetLocalGroupDel *r)
364{
365 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDel);
366}
367
368/****************************************************************
369****************************************************************/
370
371static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
372 const char *alias_name,
373 struct samr_AliasInfoAll *info,
374 uint32_t level,
375 uint32_t *entries_read,
376 uint8_t **buffer)
377{
378 struct LOCALGROUP_INFO_0 g0;
379 struct LOCALGROUP_INFO_1 g1;
380 struct LOCALGROUP_INFO_1002 g1002;
381
382 switch (level) {
383 case 0:
384 g0.lgrpi0_name = talloc_strdup(mem_ctx, alias_name);
385 W_ERROR_HAVE_NO_MEMORY(g0.lgrpi0_name);
386
387 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_0, g0,
388 (struct LOCALGROUP_INFO_0 **)buffer, entries_read);
389
390 break;
391 case 1:
392 g1.lgrpi1_name = talloc_strdup(mem_ctx, alias_name);
393 g1.lgrpi1_comment = talloc_strdup(mem_ctx, info->description.string);
394 W_ERROR_HAVE_NO_MEMORY(g1.lgrpi1_name);
395
396 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1, g1,
397 (struct LOCALGROUP_INFO_1 **)buffer, entries_read);
398
399 break;
400 case 1002:
401 g1002.lgrpi1002_comment = talloc_strdup(mem_ctx, info->description.string);
402
403 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1002, g1002,
404 (struct LOCALGROUP_INFO_1002 **)buffer, entries_read);
405
406 break;
407 default:
408 return WERR_UNKNOWN_LEVEL;
409 }
410
411 return WERR_OK;
412}
413
414/****************************************************************
415****************************************************************/
416
417WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
418 struct NetLocalGroupGetInfo *r)
419{
420 struct rpc_pipe_client *pipe_cli = NULL;
421 NTSTATUS status;
422 WERROR werr;
423 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
424 struct dom_sid2 *domain_sid = NULL;
425 union samr_AliasInfo *alias_info = NULL;
426 uint32_t entries_read = 0;
427
428 if (!r->in.group_name) {
429 return WERR_INVALID_PARAM;
430 }
431
432 switch (r->in.level) {
433 case 0:
434 case 1:
435 case 1002:
436 break;
437 default:
438 return WERR_UNKNOWN_LEVEL;
439 }
440
441 ZERO_STRUCT(connect_handle);
442 ZERO_STRUCT(builtin_handle);
443 ZERO_STRUCT(domain_handle);
444 ZERO_STRUCT(alias_handle);
445
446 werr = libnetapi_open_pipe(ctx, r->in.server_name,
447 &ndr_table_samr.syntax_id,
448 &pipe_cli);
449 if (!W_ERROR_IS_OK(werr)) {
450 goto done;
451 }
452
453 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
454 SAMR_ACCESS_LOOKUP_DOMAIN |
455 SAMR_ACCESS_ENUM_DOMAINS,
456 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
457 &connect_handle,
458 &builtin_handle);
459 if (!W_ERROR_IS_OK(werr)) {
460 goto done;
461 }
462
463 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
464 &builtin_handle,
465 r->in.group_name,
466 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
467 &alias_handle);
468
469 if (ctx->disable_policy_handle_cache) {
470 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
471 }
472
473 if (NT_STATUS_IS_OK(status)) {
474 goto query_alias;
475 }
476
477 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
478 SAMR_ACCESS_ENUM_DOMAINS |
479 SAMR_ACCESS_LOOKUP_DOMAIN,
480 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
481 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
482 &connect_handle,
483 &domain_handle,
484 &domain_sid);
485 if (!W_ERROR_IS_OK(werr)) {
486 goto done;
487 }
488
489 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
490 &domain_handle,
491 r->in.group_name,
492 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
493 &alias_handle);
494
495 if (ctx->disable_policy_handle_cache) {
496 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
497 }
498
499 if (!NT_STATUS_IS_OK(status)) {
500 werr = ntstatus_to_werror(status);
501 goto done;
502 }
503
504 query_alias:
505 status = rpccli_samr_QueryAliasInfo(pipe_cli, ctx,
506 &alias_handle,
507 ALIASINFOALL,
508 &alias_info);
509 if (!NT_STATUS_IS_OK(status)) {
510 werr = ntstatus_to_werror(status);
511 goto done;
512 }
513
514 werr = map_alias_info_to_buffer(ctx,
515 r->in.group_name,
516 &alias_info->all,
517 r->in.level, &entries_read,
518 r->out.buffer);
519
520 done:
521 if (is_valid_policy_hnd(&alias_handle)) {
522 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
523 }
524
525 if (ctx->disable_policy_handle_cache) {
526 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
527 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
528 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
529 }
530
531 return werr;
532}
533
534/****************************************************************
535****************************************************************/
536
537WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
538 struct NetLocalGroupGetInfo *r)
539{
540 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetInfo);
541}
542
543/****************************************************************
544****************************************************************/
545
546static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
547 uint32_t level,
548 uint8_t *buffer,
549 enum samr_AliasInfoEnum *alias_level,
550 union samr_AliasInfo **alias_info)
551{
552 struct LOCALGROUP_INFO_0 *info0;
553 struct LOCALGROUP_INFO_1 *info1;
554 struct LOCALGROUP_INFO_1002 *info1002;
555 union samr_AliasInfo *info = NULL;
556
557 info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
558 W_ERROR_HAVE_NO_MEMORY(info);
559
560 switch (level) {
561 case 0:
562 info0 = (struct LOCALGROUP_INFO_0 *)buffer;
563 init_lsa_String(&info->name, info0->lgrpi0_name);
564 *alias_level = ALIASINFONAME;
565 break;
566 case 1:
567 info1 = (struct LOCALGROUP_INFO_1 *)buffer;
568 /* group name will be ignored */
569 init_lsa_String(&info->description, info1->lgrpi1_comment);
570 *alias_level = ALIASINFODESCRIPTION;
571 break;
572 case 1002:
573 info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
574 init_lsa_String(&info->description, info1002->lgrpi1002_comment);
575 *alias_level = ALIASINFODESCRIPTION;
576 break;
577 }
578
579 *alias_info = info;
580
581 return WERR_OK;
582}
583
584/****************************************************************
585****************************************************************/
586
587WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
588 struct NetLocalGroupSetInfo *r)
589{
590 struct rpc_pipe_client *pipe_cli = NULL;
591 NTSTATUS status;
592 WERROR werr;
593 struct lsa_String lsa_account_name;
594 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
595 struct dom_sid2 *domain_sid = NULL;
596 enum samr_AliasInfoEnum alias_level = 0;
597 union samr_AliasInfo *alias_info = NULL;
598
599 if (!r->in.group_name) {
600 return WERR_INVALID_PARAM;
601 }
602
603 switch (r->in.level) {
604 case 0:
605 case 1:
606 case 1002:
607 break;
608 default:
609 return WERR_UNKNOWN_LEVEL;
610 }
611
612 ZERO_STRUCT(connect_handle);
613 ZERO_STRUCT(builtin_handle);
614 ZERO_STRUCT(domain_handle);
615 ZERO_STRUCT(alias_handle);
616
617 werr = libnetapi_open_pipe(ctx, r->in.server_name,
618 &ndr_table_samr.syntax_id,
619 &pipe_cli);
620 if (!W_ERROR_IS_OK(werr)) {
621 goto done;
622 }
623
624 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
625 SAMR_ACCESS_LOOKUP_DOMAIN |
626 SAMR_ACCESS_ENUM_DOMAINS,
627 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
628 &connect_handle,
629 &builtin_handle);
630 if (!W_ERROR_IS_OK(werr)) {
631 goto done;
632 }
633
634 init_lsa_String(&lsa_account_name, r->in.group_name);
635
636 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
637 &builtin_handle,
638 r->in.group_name,
639 SAMR_ALIAS_ACCESS_SET_INFO,
640 &alias_handle);
641
642 if (ctx->disable_policy_handle_cache) {
643 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
644 }
645
646 if (NT_STATUS_IS_OK(status)) {
647 goto set_alias;
648 }
649
650 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
651 SAMR_ACCESS_ENUM_DOMAINS |
652 SAMR_ACCESS_LOOKUP_DOMAIN,
653 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
654 &connect_handle,
655 &domain_handle,
656 &domain_sid);
657 if (!W_ERROR_IS_OK(werr)) {
658 goto done;
659 }
660
661 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
662 &domain_handle,
663 r->in.group_name,
664 SAMR_ALIAS_ACCESS_SET_INFO,
665 &alias_handle);
666 if (!NT_STATUS_IS_OK(status)) {
667 werr = ntstatus_to_werror(status);
668 goto done;
669 }
670
671 if (ctx->disable_policy_handle_cache) {
672 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
673 }
674
675 set_alias:
676
677 werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer,
678 &alias_level, &alias_info);
679 if (!W_ERROR_IS_OK(werr)) {
680 goto done;
681 }
682
683 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
684 &alias_handle,
685 alias_level,
686 alias_info);
687 if (!NT_STATUS_IS_OK(status)) {
688 werr = ntstatus_to_werror(status);
689 goto done;
690 }
691
692 werr = WERR_OK;
693
694 done:
695 if (is_valid_policy_hnd(&alias_handle)) {
696 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
697 }
698
699 if (ctx->disable_policy_handle_cache) {
700 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
701 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
702 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
703 }
704
705 return werr;
706}
707
708/****************************************************************
709****************************************************************/
710
711WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
712 struct NetLocalGroupSetInfo *r)
713{
714 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetInfo);
715}
716
717/****************************************************************
718****************************************************************/
719
720WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
721 struct NetLocalGroupEnum *r)
722{
723 struct rpc_pipe_client *pipe_cli = NULL;
724 NTSTATUS status;
725 WERROR werr;
726 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
727 struct dom_sid2 *domain_sid = NULL;
728 uint32_t entries_read = 0;
729 union samr_DomainInfo *domain_info = NULL;
730 union samr_DomainInfo *builtin_info = NULL;
731 struct samr_SamArray *domain_sam_array = NULL;
732 struct samr_SamArray *builtin_sam_array = NULL;
733 int i;
734
735 if (!r->out.buffer) {
736 return WERR_INVALID_PARAM;
737 }
738
739 switch (r->in.level) {
740 case 0:
741 case 1:
742 break;
743 default:
744 return WERR_UNKNOWN_LEVEL;
745 }
746
747 if (r->out.total_entries) {
748 *r->out.total_entries = 0;
749 }
750 if (r->out.entries_read) {
751 *r->out.entries_read = 0;
752 }
753
754 ZERO_STRUCT(connect_handle);
755 ZERO_STRUCT(builtin_handle);
756 ZERO_STRUCT(domain_handle);
757 ZERO_STRUCT(alias_handle);
758
759 werr = libnetapi_open_pipe(ctx, r->in.server_name,
760 &ndr_table_samr.syntax_id,
761 &pipe_cli);
762 if (!W_ERROR_IS_OK(werr)) {
763 goto done;
764 }
765
766 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
767 SAMR_ACCESS_LOOKUP_DOMAIN |
768 SAMR_ACCESS_ENUM_DOMAINS,
769 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
770 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
771 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
772 &connect_handle,
773 &builtin_handle);
774 if (!W_ERROR_IS_OK(werr)) {
775 goto done;
776 }
777
778 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
779 SAMR_ACCESS_LOOKUP_DOMAIN |
780 SAMR_ACCESS_ENUM_DOMAINS,
781 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
782 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
783 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
784 &connect_handle,
785 &domain_handle,
786 &domain_sid);
787 if (!W_ERROR_IS_OK(werr)) {
788 goto done;
789 }
790
791 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
792 &builtin_handle,
793 2,
794 &builtin_info);
795 if (!NT_STATUS_IS_OK(status)) {
796 werr = ntstatus_to_werror(status);
797 goto done;
798 }
799
800 if (r->out.total_entries) {
801 *r->out.total_entries += builtin_info->general.num_aliases;
802 }
803
804 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
805 &domain_handle,
806 2,
807 &domain_info);
808 if (!NT_STATUS_IS_OK(status)) {
809 werr = ntstatus_to_werror(status);
810 goto done;
811 }
812
813 if (r->out.total_entries) {
814 *r->out.total_entries += domain_info->general.num_aliases;
815 }
816
817 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
818 &builtin_handle,
819 r->in.resume_handle,
820 &builtin_sam_array,
821 r->in.prefmaxlen,
822 &entries_read);
823 if (!NT_STATUS_IS_OK(status)) {
824 werr = ntstatus_to_werror(status);
825 goto done;
826 }
827
828 for (i=0; i<builtin_sam_array->count; i++) {
829 union samr_AliasInfo *alias_info = NULL;
830
831 if (r->in.level == 1) {
832
833 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
834 &builtin_handle,
835 builtin_sam_array->entries[i].idx,
836 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
837 ALIASINFOALL,
838 &alias_info);
839 if (!NT_STATUS_IS_OK(status)) {
840 werr = ntstatus_to_werror(status);
841 goto done;
842 }
843 }
844
845 werr = map_alias_info_to_buffer(ctx,
846 builtin_sam_array->entries[i].name.string,
847 alias_info ? &alias_info->all : NULL,
848 r->in.level,
849 r->out.entries_read,
850 r->out.buffer);
851 }
852
853 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
854 &domain_handle,
855 r->in.resume_handle,
856 &domain_sam_array,
857 r->in.prefmaxlen,
858 &entries_read);
859 if (!NT_STATUS_IS_OK(status)) {
860 werr = ntstatus_to_werror(status);
861 goto done;
862 }
863
864 for (i=0; i<domain_sam_array->count; i++) {
865
866 union samr_AliasInfo *alias_info = NULL;
867
868 if (r->in.level == 1) {
869 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
870 &domain_handle,
871 domain_sam_array->entries[i].idx,
872 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
873 ALIASINFOALL,
874 &alias_info);
875 if (!NT_STATUS_IS_OK(status)) {
876 werr = ntstatus_to_werror(status);
877 goto done;
878 }
879 }
880
881 werr = map_alias_info_to_buffer(ctx,
882 domain_sam_array->entries[i].name.string,
883 alias_info ? &alias_info->all : NULL,
884 r->in.level,
885 r->out.entries_read,
886 r->out.buffer);
887 }
888
889 done:
890 if (ctx->disable_policy_handle_cache) {
891 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
892 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
893 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
894 }
895
896 return werr;
897}
898
899/****************************************************************
900****************************************************************/
901
902WERROR NetLocalGroupEnum_l(struct libnetapi_ctx *ctx,
903 struct NetLocalGroupEnum *r)
904{
905 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupEnum);
906}
907
908/****************************************************************
909****************************************************************/
910
911static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
912 struct rpc_pipe_client *lsa_pipe,
913 const char *name,
914 struct dom_sid *sid)
915{
916 NTSTATUS status;
917 struct policy_handle lsa_handle;
918
919 struct lsa_RefDomainList *domains = NULL;
920 struct lsa_TransSidArray3 sids;
921 uint32_t count = 0;
922
923 struct lsa_String names;
924 uint32_t num_names = 1;
925
926 if (!sid || !name) {
927 return NT_STATUS_INVALID_PARAMETER;
928 }
929
930 ZERO_STRUCT(sids);
931
932 init_lsa_String(&names, name);
933
934 status = rpccli_lsa_open_policy2(lsa_pipe, mem_ctx,
935 false,
936 STD_RIGHT_READ_CONTROL_ACCESS |
937 LSA_POLICY_VIEW_LOCAL_INFORMATION |
938 LSA_POLICY_LOOKUP_NAMES,
939 &lsa_handle);
940 NT_STATUS_NOT_OK_RETURN(status);
941
942 status = rpccli_lsa_LookupNames3(lsa_pipe, mem_ctx,
943 &lsa_handle,
944 num_names,
945 &names,
946 &domains,
947 &sids,
948 LSA_LOOKUP_NAMES_ALL, /* sure ? */
949 &count,
950 0, 0);
951 NT_STATUS_NOT_OK_RETURN(status);
952
953 if (count != 1 || sids.count != 1) {
954 return NT_STATUS_NONE_MAPPED;
955 }
956
957 sid_copy(sid, sids.sids[0].sid);
958
959 return NT_STATUS_OK;
960}
961
962/****************************************************************
963****************************************************************/
964
965static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
966 struct NetLocalGroupAddMembers *add,
967 struct NetLocalGroupDelMembers *del,
968 struct NetLocalGroupSetMembers *set)
969{
970 struct NetLocalGroupAddMembers *r = NULL;
971
972 struct rpc_pipe_client *pipe_cli = NULL;
973 struct rpc_pipe_client *lsa_pipe = NULL;
974 NTSTATUS status;
975 WERROR werr;
976 struct lsa_String lsa_account_name;
977 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
978 struct dom_sid2 *domain_sid = NULL;
979 struct dom_sid *member_sids = NULL;
980 int i = 0, k = 0;
981
982 struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
983 struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
984
985 struct dom_sid *add_sids = NULL;
986 struct dom_sid *del_sids = NULL;
987 size_t num_add_sids = 0;
988 size_t num_del_sids = 0;
989
990 if ((!add && !del && !set) || (add && del && set)) {
991 return WERR_INVALID_PARAM;
992 }
993
994 if (add) {
995 r = add;
996 }
997
998 if (del) {
999 r = (struct NetLocalGroupAddMembers *)del;
1000 }
1001
1002 if (set) {
1003 r = (struct NetLocalGroupAddMembers *)set;
1004 }
1005
1006 if (!r->in.group_name) {
1007 return WERR_INVALID_PARAM;
1008 }
1009
1010 switch (r->in.level) {
1011 case 0:
1012 case 3:
1013 break;
1014 default:
1015 return WERR_UNKNOWN_LEVEL;
1016 }
1017
1018 if (r->in.total_entries == 0 || !r->in.buffer) {
1019 return WERR_INVALID_PARAM;
1020 }
1021
1022 ZERO_STRUCT(connect_handle);
1023 ZERO_STRUCT(builtin_handle);
1024 ZERO_STRUCT(domain_handle);
1025 ZERO_STRUCT(alias_handle);
1026
1027 member_sids = TALLOC_ZERO_ARRAY(ctx, struct dom_sid,
1028 r->in.total_entries);
1029 W_ERROR_HAVE_NO_MEMORY(member_sids);
1030
1031 switch (r->in.level) {
1032 case 0:
1033 info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
1034 for (i=0; i < r->in.total_entries; i++) {
1035 sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
1036 }
1037 break;
1038 case 3:
1039 info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1040 break;
1041 default:
1042 break;
1043 }
1044
1045 if (r->in.level == 3) {
1046 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1047 &ndr_table_lsarpc.syntax_id,
1048 &lsa_pipe);
1049 if (!W_ERROR_IS_OK(werr)) {
1050 goto done;
1051 }
1052
1053 for (i=0; i < r->in.total_entries; i++) {
1054 status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1055 info3[i].lgrmi3_domainandname,
1056 &member_sids[i]);
1057 if (!NT_STATUS_IS_OK(status)) {
1058 werr = ntstatus_to_werror(status);
1059 goto done;
1060 }
1061 }
1062 TALLOC_FREE(lsa_pipe);
1063 }
1064
1065 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1066 &ndr_table_samr.syntax_id,
1067 &pipe_cli);
1068 if (!W_ERROR_IS_OK(werr)) {
1069 goto done;
1070 }
1071
1072 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1073 SAMR_ACCESS_LOOKUP_DOMAIN |
1074 SAMR_ACCESS_ENUM_DOMAINS,
1075 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1076 &connect_handle,
1077 &builtin_handle);
1078 if (!W_ERROR_IS_OK(werr)) {
1079 goto done;
1080 }
1081
1082 init_lsa_String(&lsa_account_name, r->in.group_name);
1083
1084 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1085 &builtin_handle,
1086 r->in.group_name,
1087 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1088 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1089 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1090 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1091 &alias_handle);
1092
1093 if (ctx->disable_policy_handle_cache) {
1094 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1095 }
1096
1097 if (NT_STATUS_IS_OK(status)) {
1098 goto modify_membership;
1099 }
1100
1101 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1102 SAMR_ACCESS_ENUM_DOMAINS |
1103 SAMR_ACCESS_LOOKUP_DOMAIN,
1104 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1105 &connect_handle,
1106 &domain_handle,
1107 &domain_sid);
1108 if (!W_ERROR_IS_OK(werr)) {
1109 goto done;
1110 }
1111
1112 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1113 &domain_handle,
1114 r->in.group_name,
1115 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1116 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1117 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1118 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1119 &alias_handle);
1120 if (!NT_STATUS_IS_OK(status)) {
1121 werr = ntstatus_to_werror(status);
1122 goto done;
1123 }
1124
1125 if (ctx->disable_policy_handle_cache) {
1126 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1127 }
1128
1129 modify_membership:
1130
1131 if (add) {
1132 for (i=0; i < r->in.total_entries; i++) {
1133 status = add_sid_to_array_unique(ctx, &member_sids[i],
1134 &add_sids,
1135 &num_add_sids);
1136 if (!NT_STATUS_IS_OK(status)) {
1137 werr = ntstatus_to_werror(status);
1138 goto done;
1139 }
1140 }
1141 }
1142
1143 if (del) {
1144 for (i=0; i < r->in.total_entries; i++) {
1145 status = add_sid_to_array_unique(ctx, &member_sids[i],
1146 &del_sids,
1147 &num_del_sids);
1148 if (!NT_STATUS_IS_OK(status)) {
1149 werr = ntstatus_to_werror(status);
1150 goto done;
1151 }
1152 }
1153 }
1154
1155 if (set) {
1156
1157 struct lsa_SidArray current_sids;
1158
1159 status = rpccli_samr_GetMembersInAlias(pipe_cli, ctx,
1160 &alias_handle,
1161 &current_sids);
1162 if (!NT_STATUS_IS_OK(status)) {
1163 werr = ntstatus_to_werror(status);
1164 goto done;
1165 }
1166
1167 /* add list */
1168
1169 for (i=0; i < r->in.total_entries; i++) {
1170 bool already_member = false;
1171 for (k=0; k < current_sids.num_sids; k++) {
1172 if (sid_equal(&member_sids[i],
1173 current_sids.sids[k].sid)) {
1174 already_member = true;
1175 break;
1176 }
1177 }
1178 if (!already_member) {
1179 status = add_sid_to_array_unique(ctx,
1180 &member_sids[i],
1181 &add_sids, &num_add_sids);
1182 if (!NT_STATUS_IS_OK(status)) {
1183 werr = ntstatus_to_werror(status);
1184 goto done;
1185 }
1186 }
1187 }
1188
1189 /* del list */
1190
1191 for (k=0; k < current_sids.num_sids; k++) {
1192 bool keep_member = false;
1193 for (i=0; i < r->in.total_entries; i++) {
1194 if (sid_equal(&member_sids[i],
1195 current_sids.sids[k].sid)) {
1196 keep_member = true;
1197 break;
1198 }
1199 }
1200 if (!keep_member) {
1201 status = add_sid_to_array_unique(ctx,
1202 current_sids.sids[k].sid,
1203 &del_sids, &num_del_sids);
1204 if (!NT_STATUS_IS_OK(status)) {
1205 werr = ntstatus_to_werror(status);
1206 goto done;
1207 }
1208 }
1209 }
1210 }
1211
1212 /* add list */
1213
1214 for (i=0; i < num_add_sids; i++) {
1215 status = rpccli_samr_AddAliasMember(pipe_cli, ctx,
1216 &alias_handle,
1217 &add_sids[i]);
1218 if (!NT_STATUS_IS_OK(status)) {
1219 werr = ntstatus_to_werror(status);
1220 goto done;
1221 }
1222 }
1223
1224 /* del list */
1225
1226 for (i=0; i < num_del_sids; i++) {
1227 status = rpccli_samr_DeleteAliasMember(pipe_cli, ctx,
1228 &alias_handle,
1229 &del_sids[i]);
1230 if (!NT_STATUS_IS_OK(status)) {
1231 werr = ntstatus_to_werror(status);
1232 goto done;
1233 }
1234 }
1235
1236 werr = WERR_OK;
1237
1238 done:
1239 if (is_valid_policy_hnd(&alias_handle)) {
1240 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
1241 }
1242
1243 if (ctx->disable_policy_handle_cache) {
1244 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1245 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1246 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1247 }
1248
1249 return werr;
1250}
1251
1252/****************************************************************
1253****************************************************************/
1254
1255WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1256 struct NetLocalGroupAddMembers *r)
1257{
1258 return NetLocalGroupModifyMembers_r(ctx, r, NULL, NULL);
1259}
1260
1261/****************************************************************
1262****************************************************************/
1263
1264WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1265 struct NetLocalGroupAddMembers *r)
1266{
1267 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAddMembers);
1268}
1269
1270/****************************************************************
1271****************************************************************/
1272
1273WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1274 struct NetLocalGroupDelMembers *r)
1275{
1276 return NetLocalGroupModifyMembers_r(ctx, NULL, r, NULL);
1277}
1278
1279/****************************************************************
1280****************************************************************/
1281
1282WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1283 struct NetLocalGroupDelMembers *r)
1284{
1285 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDelMembers);
1286}
1287
1288/****************************************************************
1289****************************************************************/
1290
1291WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1292 struct NetLocalGroupGetMembers *r)
1293{
1294 return WERR_NOT_SUPPORTED;
1295}
1296
1297/****************************************************************
1298****************************************************************/
1299
1300WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1301 struct NetLocalGroupGetMembers *r)
1302{
1303 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetMembers);
1304}
1305
1306/****************************************************************
1307****************************************************************/
1308
1309WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1310 struct NetLocalGroupSetMembers *r)
1311{
1312 return NetLocalGroupModifyMembers_r(ctx, NULL, NULL, r);
1313}
1314
1315/****************************************************************
1316****************************************************************/
1317
1318WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1319 struct NetLocalGroupSetMembers *r)
1320{
1321 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);
1322}
Note: See TracBrowser for help on using the repository browser.