2 * Unix SMB/CIFS implementation.
3 * NetApi LocalGroup Support
4 * Copyright (C) Guenther Deschner 2008
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.
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.
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/>.
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 #include "rpc_client/cli_lsarpc.h"
29 #include "rpc_client/init_lsa.h"
31 static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
32 struct rpc_pipe_client *pipe_cli,
33 struct policy_handle *domain_handle,
34 const char *group_name,
35 uint32_t access_rights,
36 struct policy_handle *alias_handle)
40 struct lsa_String lsa_account_name;
41 struct samr_Ids user_rids, name_types;
43 init_lsa_String(&lsa_account_name, group_name);
45 status = rpccli_samr_LookupNames(pipe_cli, mem_ctx,
51 if (!NT_STATUS_IS_OK(status)) {
55 switch (name_types.ids[0]) {
57 case SID_NAME_WKN_GRP:
60 return NT_STATUS_INVALID_SID;
63 return rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
70 /****************************************************************
71 ****************************************************************/
73 static NTSTATUS libnetapi_samr_open_alias_queryinfo(TALLOC_CTX *mem_ctx,
74 struct rpc_pipe_client *pipe_cli,
75 struct policy_handle *handle,
77 uint32_t access_rights,
78 enum samr_AliasInfoEnum level,
79 union samr_AliasInfo **alias_info)
82 struct policy_handle alias_handle;
83 union samr_AliasInfo *_alias_info = NULL;
85 ZERO_STRUCT(alias_handle);
87 status = rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
92 if (!NT_STATUS_IS_OK(status)) {
96 status = rpccli_samr_QueryAliasInfo(pipe_cli, mem_ctx,
100 if (!NT_STATUS_IS_OK(status)) {
104 *alias_info = _alias_info;
107 if (is_valid_policy_hnd(&alias_handle)) {
108 rpccli_samr_Close(pipe_cli, mem_ctx, &alias_handle);
114 /****************************************************************
115 ****************************************************************/
117 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
118 struct NetLocalGroupAdd *r)
120 struct rpc_pipe_client *pipe_cli = NULL;
123 struct lsa_String lsa_account_name;
124 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
125 struct dom_sid2 *domain_sid = NULL;
128 struct LOCALGROUP_INFO_0 *info0 = NULL;
129 struct LOCALGROUP_INFO_1 *info1 = NULL;
131 const char *alias_name = NULL;
134 return WERR_INVALID_PARAM;
137 switch (r->in.level) {
139 info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
140 alias_name = info0->lgrpi0_name;
143 info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
144 alias_name = info1->lgrpi1_name;
147 werr = WERR_UNKNOWN_LEVEL;
151 ZERO_STRUCT(connect_handle);
152 ZERO_STRUCT(builtin_handle);
153 ZERO_STRUCT(domain_handle);
154 ZERO_STRUCT(alias_handle);
156 werr = libnetapi_open_pipe(ctx, r->in.server_name,
157 &ndr_table_samr.syntax_id,
159 if (!W_ERROR_IS_OK(werr)) {
163 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
164 SAMR_ACCESS_LOOKUP_DOMAIN |
165 SAMR_ACCESS_ENUM_DOMAINS,
166 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
169 if (!W_ERROR_IS_OK(werr)) {
173 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
176 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
178 if (ctx->disable_policy_handle_cache) {
179 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
182 if (NT_STATUS_IS_OK(status)) {
183 werr = WERR_ALIAS_EXISTS;
187 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
188 SAMR_ACCESS_ENUM_DOMAINS |
189 SAMR_ACCESS_LOOKUP_DOMAIN,
190 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
191 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
195 if (!W_ERROR_IS_OK(werr)) {
199 init_lsa_String(&lsa_account_name, alias_name);
201 status = rpccli_samr_CreateDomAlias(pipe_cli, ctx,
205 SAMR_ALIAS_ACCESS_SET_INFO,
208 if (!NT_STATUS_IS_OK(status)) {
209 werr = ntstatus_to_werror(status);
213 if (r->in.level == 1 && info1->lgrpi1_comment) {
215 union samr_AliasInfo alias_info;
217 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
219 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
221 ALIASINFODESCRIPTION,
223 if (!NT_STATUS_IS_OK(status)) {
224 werr = ntstatus_to_werror(status);
232 if (is_valid_policy_hnd(&alias_handle)) {
233 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
236 if (ctx->disable_policy_handle_cache) {
237 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
238 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
239 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
245 /****************************************************************
246 ****************************************************************/
248 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
249 struct NetLocalGroupAdd *r)
251 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAdd);
254 /****************************************************************
255 ****************************************************************/
258 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
259 struct NetLocalGroupDel *r)
261 struct rpc_pipe_client *pipe_cli = NULL;
264 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
265 struct dom_sid2 *domain_sid = NULL;
267 if (!r->in.group_name) {
268 return WERR_INVALID_PARAM;
271 ZERO_STRUCT(connect_handle);
272 ZERO_STRUCT(builtin_handle);
273 ZERO_STRUCT(domain_handle);
274 ZERO_STRUCT(alias_handle);
276 werr = libnetapi_open_pipe(ctx, r->in.server_name,
277 &ndr_table_samr.syntax_id,
279 if (!W_ERROR_IS_OK(werr)) {
283 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
284 SAMR_ACCESS_LOOKUP_DOMAIN |
285 SAMR_ACCESS_ENUM_DOMAINS,
286 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
289 if (!W_ERROR_IS_OK(werr)) {
293 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
299 if (ctx->disable_policy_handle_cache) {
300 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
303 if (NT_STATUS_IS_OK(status)) {
307 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
308 SAMR_ACCESS_ENUM_DOMAINS |
309 SAMR_ACCESS_LOOKUP_DOMAIN,
310 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
311 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
315 if (!W_ERROR_IS_OK(werr)) {
319 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
325 if (ctx->disable_policy_handle_cache) {
326 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
329 if (!NT_STATUS_IS_OK(status)) {
330 werr = ntstatus_to_werror(status);
336 status = rpccli_samr_DeleteDomAlias(pipe_cli, ctx,
338 if (!NT_STATUS_IS_OK(status)) {
339 werr = ntstatus_to_werror(status);
343 ZERO_STRUCT(alias_handle);
348 if (is_valid_policy_hnd(&alias_handle)) {
349 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
352 if (ctx->disable_policy_handle_cache) {
353 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
354 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
355 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
361 /****************************************************************
362 ****************************************************************/
364 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
365 struct NetLocalGroupDel *r)
367 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDel);
370 /****************************************************************
371 ****************************************************************/
373 static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
374 const char *alias_name,
375 struct samr_AliasInfoAll *info,
377 uint32_t *entries_read,
380 struct LOCALGROUP_INFO_0 g0;
381 struct LOCALGROUP_INFO_1 g1;
382 struct LOCALGROUP_INFO_1002 g1002;
386 g0.lgrpi0_name = talloc_strdup(mem_ctx, alias_name);
387 W_ERROR_HAVE_NO_MEMORY(g0.lgrpi0_name);
389 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_0, g0,
390 (struct LOCALGROUP_INFO_0 **)buffer, entries_read);
394 g1.lgrpi1_name = talloc_strdup(mem_ctx, alias_name);
395 g1.lgrpi1_comment = talloc_strdup(mem_ctx, info->description.string);
396 W_ERROR_HAVE_NO_MEMORY(g1.lgrpi1_name);
398 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1, g1,
399 (struct LOCALGROUP_INFO_1 **)buffer, entries_read);
403 g1002.lgrpi1002_comment = talloc_strdup(mem_ctx, info->description.string);
405 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1002, g1002,
406 (struct LOCALGROUP_INFO_1002 **)buffer, entries_read);
410 return WERR_UNKNOWN_LEVEL;
416 /****************************************************************
417 ****************************************************************/
419 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
420 struct NetLocalGroupGetInfo *r)
422 struct rpc_pipe_client *pipe_cli = NULL;
425 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
426 struct dom_sid2 *domain_sid = NULL;
427 union samr_AliasInfo *alias_info = NULL;
428 uint32_t entries_read = 0;
430 if (!r->in.group_name) {
431 return WERR_INVALID_PARAM;
434 switch (r->in.level) {
440 return WERR_UNKNOWN_LEVEL;
443 ZERO_STRUCT(connect_handle);
444 ZERO_STRUCT(builtin_handle);
445 ZERO_STRUCT(domain_handle);
446 ZERO_STRUCT(alias_handle);
448 werr = libnetapi_open_pipe(ctx, r->in.server_name,
449 &ndr_table_samr.syntax_id,
451 if (!W_ERROR_IS_OK(werr)) {
455 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
456 SAMR_ACCESS_LOOKUP_DOMAIN |
457 SAMR_ACCESS_ENUM_DOMAINS,
458 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
461 if (!W_ERROR_IS_OK(werr)) {
465 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
468 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
471 if (ctx->disable_policy_handle_cache) {
472 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
475 if (NT_STATUS_IS_OK(status)) {
479 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
480 SAMR_ACCESS_ENUM_DOMAINS |
481 SAMR_ACCESS_LOOKUP_DOMAIN,
482 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
483 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
487 if (!W_ERROR_IS_OK(werr)) {
491 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
494 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
497 if (ctx->disable_policy_handle_cache) {
498 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
501 if (!NT_STATUS_IS_OK(status)) {
502 werr = ntstatus_to_werror(status);
507 status = rpccli_samr_QueryAliasInfo(pipe_cli, ctx,
511 if (!NT_STATUS_IS_OK(status)) {
512 werr = ntstatus_to_werror(status);
516 werr = map_alias_info_to_buffer(ctx,
519 r->in.level, &entries_read,
523 if (is_valid_policy_hnd(&alias_handle)) {
524 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
527 if (ctx->disable_policy_handle_cache) {
528 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
529 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
530 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
536 /****************************************************************
537 ****************************************************************/
539 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
540 struct NetLocalGroupGetInfo *r)
542 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetInfo);
545 /****************************************************************
546 ****************************************************************/
548 static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
551 enum samr_AliasInfoEnum *alias_level,
552 union samr_AliasInfo **alias_info)
554 struct LOCALGROUP_INFO_0 *info0;
555 struct LOCALGROUP_INFO_1 *info1;
556 struct LOCALGROUP_INFO_1002 *info1002;
557 union samr_AliasInfo *info = NULL;
559 info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
560 W_ERROR_HAVE_NO_MEMORY(info);
564 info0 = (struct LOCALGROUP_INFO_0 *)buffer;
565 init_lsa_String(&info->name, info0->lgrpi0_name);
566 *alias_level = ALIASINFONAME;
569 info1 = (struct LOCALGROUP_INFO_1 *)buffer;
570 /* group name will be ignored */
571 init_lsa_String(&info->description, info1->lgrpi1_comment);
572 *alias_level = ALIASINFODESCRIPTION;
575 info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
576 init_lsa_String(&info->description, info1002->lgrpi1002_comment);
577 *alias_level = ALIASINFODESCRIPTION;
586 /****************************************************************
587 ****************************************************************/
589 WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
590 struct NetLocalGroupSetInfo *r)
592 struct rpc_pipe_client *pipe_cli = NULL;
595 struct lsa_String lsa_account_name;
596 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
597 struct dom_sid2 *domain_sid = NULL;
598 enum samr_AliasInfoEnum alias_level = 0;
599 union samr_AliasInfo *alias_info = NULL;
601 if (!r->in.group_name) {
602 return WERR_INVALID_PARAM;
605 switch (r->in.level) {
611 return WERR_UNKNOWN_LEVEL;
614 ZERO_STRUCT(connect_handle);
615 ZERO_STRUCT(builtin_handle);
616 ZERO_STRUCT(domain_handle);
617 ZERO_STRUCT(alias_handle);
619 werr = libnetapi_open_pipe(ctx, r->in.server_name,
620 &ndr_table_samr.syntax_id,
622 if (!W_ERROR_IS_OK(werr)) {
626 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
627 SAMR_ACCESS_LOOKUP_DOMAIN |
628 SAMR_ACCESS_ENUM_DOMAINS,
629 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
632 if (!W_ERROR_IS_OK(werr)) {
636 init_lsa_String(&lsa_account_name, r->in.group_name);
638 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
641 SAMR_ALIAS_ACCESS_SET_INFO,
644 if (ctx->disable_policy_handle_cache) {
645 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
648 if (NT_STATUS_IS_OK(status)) {
652 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
653 SAMR_ACCESS_ENUM_DOMAINS |
654 SAMR_ACCESS_LOOKUP_DOMAIN,
655 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
659 if (!W_ERROR_IS_OK(werr)) {
663 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
666 SAMR_ALIAS_ACCESS_SET_INFO,
668 if (!NT_STATUS_IS_OK(status)) {
669 werr = ntstatus_to_werror(status);
673 if (ctx->disable_policy_handle_cache) {
674 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
679 werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer,
680 &alias_level, &alias_info);
681 if (!W_ERROR_IS_OK(werr)) {
685 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
689 if (!NT_STATUS_IS_OK(status)) {
690 werr = ntstatus_to_werror(status);
697 if (is_valid_policy_hnd(&alias_handle)) {
698 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
701 if (ctx->disable_policy_handle_cache) {
702 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
703 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
704 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
710 /****************************************************************
711 ****************************************************************/
713 WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
714 struct NetLocalGroupSetInfo *r)
716 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetInfo);
719 /****************************************************************
720 ****************************************************************/
722 WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
723 struct NetLocalGroupEnum *r)
725 struct rpc_pipe_client *pipe_cli = NULL;
728 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
729 struct dom_sid2 *domain_sid = NULL;
730 uint32_t entries_read = 0;
731 union samr_DomainInfo *domain_info = NULL;
732 union samr_DomainInfo *builtin_info = NULL;
733 struct samr_SamArray *domain_sam_array = NULL;
734 struct samr_SamArray *builtin_sam_array = NULL;
737 if (!r->out.buffer) {
738 return WERR_INVALID_PARAM;
741 switch (r->in.level) {
746 return WERR_UNKNOWN_LEVEL;
749 if (r->out.total_entries) {
750 *r->out.total_entries = 0;
752 if (r->out.entries_read) {
753 *r->out.entries_read = 0;
756 ZERO_STRUCT(connect_handle);
757 ZERO_STRUCT(builtin_handle);
758 ZERO_STRUCT(domain_handle);
759 ZERO_STRUCT(alias_handle);
761 werr = libnetapi_open_pipe(ctx, r->in.server_name,
762 &ndr_table_samr.syntax_id,
764 if (!W_ERROR_IS_OK(werr)) {
768 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
769 SAMR_ACCESS_LOOKUP_DOMAIN |
770 SAMR_ACCESS_ENUM_DOMAINS,
771 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
772 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
773 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
776 if (!W_ERROR_IS_OK(werr)) {
780 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
781 SAMR_ACCESS_LOOKUP_DOMAIN |
782 SAMR_ACCESS_ENUM_DOMAINS,
783 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
784 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
785 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
789 if (!W_ERROR_IS_OK(werr)) {
793 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
797 if (!NT_STATUS_IS_OK(status)) {
798 werr = ntstatus_to_werror(status);
802 if (r->out.total_entries) {
803 *r->out.total_entries += builtin_info->general.num_aliases;
806 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
810 if (!NT_STATUS_IS_OK(status)) {
811 werr = ntstatus_to_werror(status);
815 if (r->out.total_entries) {
816 *r->out.total_entries += domain_info->general.num_aliases;
819 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
825 if (!NT_STATUS_IS_OK(status)) {
826 werr = ntstatus_to_werror(status);
830 for (i=0; i<builtin_sam_array->count; i++) {
831 union samr_AliasInfo *alias_info = NULL;
833 if (r->in.level == 1) {
835 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
837 builtin_sam_array->entries[i].idx,
838 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
841 if (!NT_STATUS_IS_OK(status)) {
842 werr = ntstatus_to_werror(status);
847 werr = map_alias_info_to_buffer(ctx,
848 builtin_sam_array->entries[i].name.string,
849 alias_info ? &alias_info->all : NULL,
855 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
861 if (!NT_STATUS_IS_OK(status)) {
862 werr = ntstatus_to_werror(status);
866 for (i=0; i<domain_sam_array->count; i++) {
868 union samr_AliasInfo *alias_info = NULL;
870 if (r->in.level == 1) {
871 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
873 domain_sam_array->entries[i].idx,
874 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
877 if (!NT_STATUS_IS_OK(status)) {
878 werr = ntstatus_to_werror(status);
883 werr = map_alias_info_to_buffer(ctx,
884 domain_sam_array->entries[i].name.string,
885 alias_info ? &alias_info->all : NULL,
892 if (ctx->disable_policy_handle_cache) {
893 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
894 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
895 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
901 /****************************************************************
902 ****************************************************************/
904 WERROR NetLocalGroupEnum_l(struct libnetapi_ctx *ctx,
905 struct NetLocalGroupEnum *r)
907 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupEnum);
910 /****************************************************************
911 ****************************************************************/
913 static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
914 struct rpc_pipe_client *lsa_pipe,
919 struct policy_handle lsa_handle;
921 struct lsa_RefDomainList *domains = NULL;
922 struct lsa_TransSidArray3 sids;
925 struct lsa_String names;
926 uint32_t num_names = 1;
929 return NT_STATUS_INVALID_PARAMETER;
934 init_lsa_String(&names, name);
936 status = rpccli_lsa_open_policy2(lsa_pipe, mem_ctx,
938 SEC_STD_READ_CONTROL |
939 LSA_POLICY_VIEW_LOCAL_INFORMATION |
940 LSA_POLICY_LOOKUP_NAMES,
942 NT_STATUS_NOT_OK_RETURN(status);
944 status = rpccli_lsa_LookupNames3(lsa_pipe, mem_ctx,
950 LSA_LOOKUP_NAMES_ALL, /* sure ? */
953 NT_STATUS_NOT_OK_RETURN(status);
955 if (count != 1 || sids.count != 1) {
956 return NT_STATUS_NONE_MAPPED;
959 sid_copy(sid, sids.sids[0].sid);
964 /****************************************************************
965 ****************************************************************/
967 static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
968 struct NetLocalGroupAddMembers *add,
969 struct NetLocalGroupDelMembers *del,
970 struct NetLocalGroupSetMembers *set)
972 struct NetLocalGroupAddMembers *r = NULL;
974 struct rpc_pipe_client *pipe_cli = NULL;
975 struct rpc_pipe_client *lsa_pipe = NULL;
978 struct lsa_String lsa_account_name;
979 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
980 struct dom_sid2 *domain_sid = NULL;
981 struct dom_sid *member_sids = NULL;
984 struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
985 struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
987 struct dom_sid *add_sids = NULL;
988 struct dom_sid *del_sids = NULL;
989 size_t num_add_sids = 0;
990 size_t num_del_sids = 0;
992 if ((!add && !del && !set) || (add && del && set)) {
993 return WERR_INVALID_PARAM;
1001 r = (struct NetLocalGroupAddMembers *)del;
1005 r = (struct NetLocalGroupAddMembers *)set;
1008 if (!r->in.group_name) {
1009 return WERR_INVALID_PARAM;
1012 switch (r->in.level) {
1017 return WERR_UNKNOWN_LEVEL;
1020 if (r->in.total_entries == 0 || !r->in.buffer) {
1021 return WERR_INVALID_PARAM;
1024 ZERO_STRUCT(connect_handle);
1025 ZERO_STRUCT(builtin_handle);
1026 ZERO_STRUCT(domain_handle);
1027 ZERO_STRUCT(alias_handle);
1029 member_sids = TALLOC_ZERO_ARRAY(ctx, struct dom_sid,
1030 r->in.total_entries);
1031 W_ERROR_HAVE_NO_MEMORY(member_sids);
1033 switch (r->in.level) {
1035 info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
1036 for (i=0; i < r->in.total_entries; i++) {
1037 sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
1041 info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1047 if (r->in.level == 3) {
1048 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1049 &ndr_table_lsarpc.syntax_id,
1051 if (!W_ERROR_IS_OK(werr)) {
1055 for (i=0; i < r->in.total_entries; i++) {
1056 status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1057 info3[i].lgrmi3_domainandname,
1059 if (!NT_STATUS_IS_OK(status)) {
1060 werr = ntstatus_to_werror(status);
1064 TALLOC_FREE(lsa_pipe);
1067 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1068 &ndr_table_samr.syntax_id,
1070 if (!W_ERROR_IS_OK(werr)) {
1074 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1075 SAMR_ACCESS_LOOKUP_DOMAIN |
1076 SAMR_ACCESS_ENUM_DOMAINS,
1077 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1080 if (!W_ERROR_IS_OK(werr)) {
1084 init_lsa_String(&lsa_account_name, r->in.group_name);
1086 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1089 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1090 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1091 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1092 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1095 if (ctx->disable_policy_handle_cache) {
1096 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1099 if (NT_STATUS_IS_OK(status)) {
1100 goto modify_membership;
1103 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1104 SAMR_ACCESS_ENUM_DOMAINS |
1105 SAMR_ACCESS_LOOKUP_DOMAIN,
1106 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1110 if (!W_ERROR_IS_OK(werr)) {
1114 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1117 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1118 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1119 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1120 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1122 if (!NT_STATUS_IS_OK(status)) {
1123 werr = ntstatus_to_werror(status);
1127 if (ctx->disable_policy_handle_cache) {
1128 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1134 for (i=0; i < r->in.total_entries; i++) {
1135 status = add_sid_to_array_unique(ctx, &member_sids[i],
1138 if (!NT_STATUS_IS_OK(status)) {
1139 werr = ntstatus_to_werror(status);
1146 for (i=0; i < r->in.total_entries; i++) {
1147 status = add_sid_to_array_unique(ctx, &member_sids[i],
1150 if (!NT_STATUS_IS_OK(status)) {
1151 werr = ntstatus_to_werror(status);
1159 struct lsa_SidArray current_sids;
1161 status = rpccli_samr_GetMembersInAlias(pipe_cli, ctx,
1164 if (!NT_STATUS_IS_OK(status)) {
1165 werr = ntstatus_to_werror(status);
1171 for (i=0; i < r->in.total_entries; i++) {
1172 bool already_member = false;
1173 for (k=0; k < current_sids.num_sids; k++) {
1174 if (sid_equal(&member_sids[i],
1175 current_sids.sids[k].sid)) {
1176 already_member = true;
1180 if (!already_member) {
1181 status = add_sid_to_array_unique(ctx,
1183 &add_sids, &num_add_sids);
1184 if (!NT_STATUS_IS_OK(status)) {
1185 werr = ntstatus_to_werror(status);
1193 for (k=0; k < current_sids.num_sids; k++) {
1194 bool keep_member = false;
1195 for (i=0; i < r->in.total_entries; i++) {
1196 if (sid_equal(&member_sids[i],
1197 current_sids.sids[k].sid)) {
1203 status = add_sid_to_array_unique(ctx,
1204 current_sids.sids[k].sid,
1205 &del_sids, &num_del_sids);
1206 if (!NT_STATUS_IS_OK(status)) {
1207 werr = ntstatus_to_werror(status);
1216 for (i=0; i < num_add_sids; i++) {
1217 status = rpccli_samr_AddAliasMember(pipe_cli, ctx,
1220 if (!NT_STATUS_IS_OK(status)) {
1221 werr = ntstatus_to_werror(status);
1228 for (i=0; i < num_del_sids; i++) {
1229 status = rpccli_samr_DeleteAliasMember(pipe_cli, ctx,
1232 if (!NT_STATUS_IS_OK(status)) {
1233 werr = ntstatus_to_werror(status);
1241 if (is_valid_policy_hnd(&alias_handle)) {
1242 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
1245 if (ctx->disable_policy_handle_cache) {
1246 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1247 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1248 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1254 /****************************************************************
1255 ****************************************************************/
1257 WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1258 struct NetLocalGroupAddMembers *r)
1260 return NetLocalGroupModifyMembers_r(ctx, r, NULL, NULL);
1263 /****************************************************************
1264 ****************************************************************/
1266 WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1267 struct NetLocalGroupAddMembers *r)
1269 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAddMembers);
1272 /****************************************************************
1273 ****************************************************************/
1275 WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1276 struct NetLocalGroupDelMembers *r)
1278 return NetLocalGroupModifyMembers_r(ctx, NULL, r, NULL);
1281 /****************************************************************
1282 ****************************************************************/
1284 WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1285 struct NetLocalGroupDelMembers *r)
1287 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDelMembers);
1290 /****************************************************************
1291 ****************************************************************/
1293 WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1294 struct NetLocalGroupGetMembers *r)
1296 return WERR_NOT_SUPPORTED;
1299 /****************************************************************
1300 ****************************************************************/
1302 WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1303 struct NetLocalGroupGetMembers *r)
1305 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetMembers);
1308 /****************************************************************
1309 ****************************************************************/
1311 WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1312 struct NetLocalGroupSetMembers *r)
1314 return NetLocalGroupModifyMembers_r(ctx, NULL, NULL, r);
1317 /****************************************************************
1318 ****************************************************************/
1320 WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1321 struct NetLocalGroupSetMembers *r)
1323 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);