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"
30 #include "../libcli/security/dom_sid.h"
32 static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
33 struct rpc_pipe_client *pipe_cli,
34 struct policy_handle *domain_handle,
35 const char *group_name,
36 uint32_t access_rights,
37 struct policy_handle *alias_handle)
41 struct lsa_String lsa_account_name;
42 struct samr_Ids user_rids, name_types;
44 init_lsa_String(&lsa_account_name, group_name);
46 status = rpccli_samr_LookupNames(pipe_cli, mem_ctx,
52 if (!NT_STATUS_IS_OK(status)) {
56 switch (name_types.ids[0]) {
58 case SID_NAME_WKN_GRP:
61 return NT_STATUS_INVALID_SID;
64 return rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
71 /****************************************************************
72 ****************************************************************/
74 static NTSTATUS libnetapi_samr_open_alias_queryinfo(TALLOC_CTX *mem_ctx,
75 struct rpc_pipe_client *pipe_cli,
76 struct policy_handle *handle,
78 uint32_t access_rights,
79 enum samr_AliasInfoEnum level,
80 union samr_AliasInfo **alias_info)
83 struct policy_handle alias_handle;
84 union samr_AliasInfo *_alias_info = NULL;
86 ZERO_STRUCT(alias_handle);
88 status = rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
93 if (!NT_STATUS_IS_OK(status)) {
97 status = rpccli_samr_QueryAliasInfo(pipe_cli, mem_ctx,
101 if (!NT_STATUS_IS_OK(status)) {
105 *alias_info = _alias_info;
108 if (is_valid_policy_hnd(&alias_handle)) {
109 rpccli_samr_Close(pipe_cli, mem_ctx, &alias_handle);
115 /****************************************************************
116 ****************************************************************/
118 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
119 struct NetLocalGroupAdd *r)
121 struct rpc_pipe_client *pipe_cli = NULL;
124 struct lsa_String lsa_account_name;
125 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
126 struct dom_sid2 *domain_sid = NULL;
129 struct LOCALGROUP_INFO_0 *info0 = NULL;
130 struct LOCALGROUP_INFO_1 *info1 = NULL;
132 const char *alias_name = NULL;
135 return WERR_INVALID_PARAM;
138 switch (r->in.level) {
140 info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
141 alias_name = info0->lgrpi0_name;
144 info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
145 alias_name = info1->lgrpi1_name;
148 werr = WERR_UNKNOWN_LEVEL;
152 ZERO_STRUCT(connect_handle);
153 ZERO_STRUCT(builtin_handle);
154 ZERO_STRUCT(domain_handle);
155 ZERO_STRUCT(alias_handle);
157 werr = libnetapi_open_pipe(ctx, r->in.server_name,
158 &ndr_table_samr.syntax_id,
160 if (!W_ERROR_IS_OK(werr)) {
164 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
165 SAMR_ACCESS_LOOKUP_DOMAIN |
166 SAMR_ACCESS_ENUM_DOMAINS,
167 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
170 if (!W_ERROR_IS_OK(werr)) {
174 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
177 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
179 if (ctx->disable_policy_handle_cache) {
180 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
183 if (NT_STATUS_IS_OK(status)) {
184 werr = WERR_ALIAS_EXISTS;
188 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
189 SAMR_ACCESS_ENUM_DOMAINS |
190 SAMR_ACCESS_LOOKUP_DOMAIN,
191 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
192 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
196 if (!W_ERROR_IS_OK(werr)) {
200 init_lsa_String(&lsa_account_name, alias_name);
202 status = rpccli_samr_CreateDomAlias(pipe_cli, ctx,
206 SAMR_ALIAS_ACCESS_SET_INFO,
209 if (!NT_STATUS_IS_OK(status)) {
210 werr = ntstatus_to_werror(status);
214 if (r->in.level == 1 && info1->lgrpi1_comment) {
216 union samr_AliasInfo alias_info;
218 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
220 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
222 ALIASINFODESCRIPTION,
224 if (!NT_STATUS_IS_OK(status)) {
225 werr = ntstatus_to_werror(status);
233 if (is_valid_policy_hnd(&alias_handle)) {
234 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
237 if (ctx->disable_policy_handle_cache) {
238 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
239 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
240 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
246 /****************************************************************
247 ****************************************************************/
249 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
250 struct NetLocalGroupAdd *r)
252 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAdd);
255 /****************************************************************
256 ****************************************************************/
259 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
260 struct NetLocalGroupDel *r)
262 struct rpc_pipe_client *pipe_cli = NULL;
265 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
266 struct dom_sid2 *domain_sid = NULL;
268 if (!r->in.group_name) {
269 return WERR_INVALID_PARAM;
272 ZERO_STRUCT(connect_handle);
273 ZERO_STRUCT(builtin_handle);
274 ZERO_STRUCT(domain_handle);
275 ZERO_STRUCT(alias_handle);
277 werr = libnetapi_open_pipe(ctx, r->in.server_name,
278 &ndr_table_samr.syntax_id,
280 if (!W_ERROR_IS_OK(werr)) {
284 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
285 SAMR_ACCESS_LOOKUP_DOMAIN |
286 SAMR_ACCESS_ENUM_DOMAINS,
287 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
290 if (!W_ERROR_IS_OK(werr)) {
294 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
300 if (ctx->disable_policy_handle_cache) {
301 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
304 if (NT_STATUS_IS_OK(status)) {
308 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
309 SAMR_ACCESS_ENUM_DOMAINS |
310 SAMR_ACCESS_LOOKUP_DOMAIN,
311 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
312 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
316 if (!W_ERROR_IS_OK(werr)) {
320 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
326 if (ctx->disable_policy_handle_cache) {
327 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
330 if (!NT_STATUS_IS_OK(status)) {
331 werr = ntstatus_to_werror(status);
337 status = rpccli_samr_DeleteDomAlias(pipe_cli, ctx,
339 if (!NT_STATUS_IS_OK(status)) {
340 werr = ntstatus_to_werror(status);
344 ZERO_STRUCT(alias_handle);
349 if (is_valid_policy_hnd(&alias_handle)) {
350 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
353 if (ctx->disable_policy_handle_cache) {
354 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
355 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
356 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
362 /****************************************************************
363 ****************************************************************/
365 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
366 struct NetLocalGroupDel *r)
368 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDel);
371 /****************************************************************
372 ****************************************************************/
374 static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
375 const char *alias_name,
376 struct samr_AliasInfoAll *info,
378 uint32_t *entries_read,
381 struct LOCALGROUP_INFO_0 g0;
382 struct LOCALGROUP_INFO_1 g1;
383 struct LOCALGROUP_INFO_1002 g1002;
387 g0.lgrpi0_name = talloc_strdup(mem_ctx, alias_name);
388 W_ERROR_HAVE_NO_MEMORY(g0.lgrpi0_name);
390 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_0, g0,
391 (struct LOCALGROUP_INFO_0 **)buffer, entries_read);
395 g1.lgrpi1_name = talloc_strdup(mem_ctx, alias_name);
396 g1.lgrpi1_comment = talloc_strdup(mem_ctx, info->description.string);
397 W_ERROR_HAVE_NO_MEMORY(g1.lgrpi1_name);
399 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1, g1,
400 (struct LOCALGROUP_INFO_1 **)buffer, entries_read);
404 g1002.lgrpi1002_comment = talloc_strdup(mem_ctx, info->description.string);
406 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1002, g1002,
407 (struct LOCALGROUP_INFO_1002 **)buffer, entries_read);
411 return WERR_UNKNOWN_LEVEL;
417 /****************************************************************
418 ****************************************************************/
420 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
421 struct NetLocalGroupGetInfo *r)
423 struct rpc_pipe_client *pipe_cli = NULL;
426 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
427 struct dom_sid2 *domain_sid = NULL;
428 union samr_AliasInfo *alias_info = NULL;
429 uint32_t entries_read = 0;
431 if (!r->in.group_name) {
432 return WERR_INVALID_PARAM;
435 switch (r->in.level) {
441 return WERR_UNKNOWN_LEVEL;
444 ZERO_STRUCT(connect_handle);
445 ZERO_STRUCT(builtin_handle);
446 ZERO_STRUCT(domain_handle);
447 ZERO_STRUCT(alias_handle);
449 werr = libnetapi_open_pipe(ctx, r->in.server_name,
450 &ndr_table_samr.syntax_id,
452 if (!W_ERROR_IS_OK(werr)) {
456 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
457 SAMR_ACCESS_LOOKUP_DOMAIN |
458 SAMR_ACCESS_ENUM_DOMAINS,
459 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
462 if (!W_ERROR_IS_OK(werr)) {
466 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
469 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
472 if (ctx->disable_policy_handle_cache) {
473 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
476 if (NT_STATUS_IS_OK(status)) {
480 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
481 SAMR_ACCESS_ENUM_DOMAINS |
482 SAMR_ACCESS_LOOKUP_DOMAIN,
483 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
484 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
488 if (!W_ERROR_IS_OK(werr)) {
492 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
495 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
498 if (ctx->disable_policy_handle_cache) {
499 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
502 if (!NT_STATUS_IS_OK(status)) {
503 werr = ntstatus_to_werror(status);
508 status = rpccli_samr_QueryAliasInfo(pipe_cli, ctx,
512 if (!NT_STATUS_IS_OK(status)) {
513 werr = ntstatus_to_werror(status);
517 werr = map_alias_info_to_buffer(ctx,
520 r->in.level, &entries_read,
524 if (is_valid_policy_hnd(&alias_handle)) {
525 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
528 if (ctx->disable_policy_handle_cache) {
529 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
530 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
531 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
537 /****************************************************************
538 ****************************************************************/
540 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
541 struct NetLocalGroupGetInfo *r)
543 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetInfo);
546 /****************************************************************
547 ****************************************************************/
549 static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
552 enum samr_AliasInfoEnum *alias_level,
553 union samr_AliasInfo **alias_info)
555 struct LOCALGROUP_INFO_0 *info0;
556 struct LOCALGROUP_INFO_1 *info1;
557 struct LOCALGROUP_INFO_1002 *info1002;
558 union samr_AliasInfo *info = NULL;
560 info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
561 W_ERROR_HAVE_NO_MEMORY(info);
565 info0 = (struct LOCALGROUP_INFO_0 *)buffer;
566 init_lsa_String(&info->name, info0->lgrpi0_name);
567 *alias_level = ALIASINFONAME;
570 info1 = (struct LOCALGROUP_INFO_1 *)buffer;
571 /* group name will be ignored */
572 init_lsa_String(&info->description, info1->lgrpi1_comment);
573 *alias_level = ALIASINFODESCRIPTION;
576 info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
577 init_lsa_String(&info->description, info1002->lgrpi1002_comment);
578 *alias_level = ALIASINFODESCRIPTION;
587 /****************************************************************
588 ****************************************************************/
590 WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
591 struct NetLocalGroupSetInfo *r)
593 struct rpc_pipe_client *pipe_cli = NULL;
596 struct lsa_String lsa_account_name;
597 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
598 struct dom_sid2 *domain_sid = NULL;
599 enum samr_AliasInfoEnum alias_level = 0;
600 union samr_AliasInfo *alias_info = NULL;
602 if (!r->in.group_name) {
603 return WERR_INVALID_PARAM;
606 switch (r->in.level) {
612 return WERR_UNKNOWN_LEVEL;
615 ZERO_STRUCT(connect_handle);
616 ZERO_STRUCT(builtin_handle);
617 ZERO_STRUCT(domain_handle);
618 ZERO_STRUCT(alias_handle);
620 werr = libnetapi_open_pipe(ctx, r->in.server_name,
621 &ndr_table_samr.syntax_id,
623 if (!W_ERROR_IS_OK(werr)) {
627 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
628 SAMR_ACCESS_LOOKUP_DOMAIN |
629 SAMR_ACCESS_ENUM_DOMAINS,
630 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
633 if (!W_ERROR_IS_OK(werr)) {
637 init_lsa_String(&lsa_account_name, r->in.group_name);
639 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
642 SAMR_ALIAS_ACCESS_SET_INFO,
645 if (ctx->disable_policy_handle_cache) {
646 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
649 if (NT_STATUS_IS_OK(status)) {
653 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
654 SAMR_ACCESS_ENUM_DOMAINS |
655 SAMR_ACCESS_LOOKUP_DOMAIN,
656 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
660 if (!W_ERROR_IS_OK(werr)) {
664 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
667 SAMR_ALIAS_ACCESS_SET_INFO,
669 if (!NT_STATUS_IS_OK(status)) {
670 werr = ntstatus_to_werror(status);
674 if (ctx->disable_policy_handle_cache) {
675 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
680 werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer,
681 &alias_level, &alias_info);
682 if (!W_ERROR_IS_OK(werr)) {
686 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
690 if (!NT_STATUS_IS_OK(status)) {
691 werr = ntstatus_to_werror(status);
698 if (is_valid_policy_hnd(&alias_handle)) {
699 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
702 if (ctx->disable_policy_handle_cache) {
703 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
704 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
705 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
711 /****************************************************************
712 ****************************************************************/
714 WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
715 struct NetLocalGroupSetInfo *r)
717 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetInfo);
720 /****************************************************************
721 ****************************************************************/
723 WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
724 struct NetLocalGroupEnum *r)
726 struct rpc_pipe_client *pipe_cli = NULL;
729 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
730 struct dom_sid2 *domain_sid = NULL;
731 uint32_t entries_read = 0;
732 union samr_DomainInfo *domain_info = NULL;
733 union samr_DomainInfo *builtin_info = NULL;
734 struct samr_SamArray *domain_sam_array = NULL;
735 struct samr_SamArray *builtin_sam_array = NULL;
738 if (!r->out.buffer) {
739 return WERR_INVALID_PARAM;
742 switch (r->in.level) {
747 return WERR_UNKNOWN_LEVEL;
750 if (r->out.total_entries) {
751 *r->out.total_entries = 0;
753 if (r->out.entries_read) {
754 *r->out.entries_read = 0;
757 ZERO_STRUCT(connect_handle);
758 ZERO_STRUCT(builtin_handle);
759 ZERO_STRUCT(domain_handle);
760 ZERO_STRUCT(alias_handle);
762 werr = libnetapi_open_pipe(ctx, r->in.server_name,
763 &ndr_table_samr.syntax_id,
765 if (!W_ERROR_IS_OK(werr)) {
769 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
770 SAMR_ACCESS_LOOKUP_DOMAIN |
771 SAMR_ACCESS_ENUM_DOMAINS,
772 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
773 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
774 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
777 if (!W_ERROR_IS_OK(werr)) {
781 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
782 SAMR_ACCESS_LOOKUP_DOMAIN |
783 SAMR_ACCESS_ENUM_DOMAINS,
784 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
785 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
786 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
790 if (!W_ERROR_IS_OK(werr)) {
794 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
798 if (!NT_STATUS_IS_OK(status)) {
799 werr = ntstatus_to_werror(status);
803 if (r->out.total_entries) {
804 *r->out.total_entries += builtin_info->general.num_aliases;
807 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
811 if (!NT_STATUS_IS_OK(status)) {
812 werr = ntstatus_to_werror(status);
816 if (r->out.total_entries) {
817 *r->out.total_entries += domain_info->general.num_aliases;
820 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
826 if (!NT_STATUS_IS_OK(status)) {
827 werr = ntstatus_to_werror(status);
831 for (i=0; i<builtin_sam_array->count; i++) {
832 union samr_AliasInfo *alias_info = NULL;
834 if (r->in.level == 1) {
836 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
838 builtin_sam_array->entries[i].idx,
839 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
842 if (!NT_STATUS_IS_OK(status)) {
843 werr = ntstatus_to_werror(status);
848 werr = map_alias_info_to_buffer(ctx,
849 builtin_sam_array->entries[i].name.string,
850 alias_info ? &alias_info->all : NULL,
856 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
862 if (!NT_STATUS_IS_OK(status)) {
863 werr = ntstatus_to_werror(status);
867 for (i=0; i<domain_sam_array->count; i++) {
869 union samr_AliasInfo *alias_info = NULL;
871 if (r->in.level == 1) {
872 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
874 domain_sam_array->entries[i].idx,
875 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
878 if (!NT_STATUS_IS_OK(status)) {
879 werr = ntstatus_to_werror(status);
884 werr = map_alias_info_to_buffer(ctx,
885 domain_sam_array->entries[i].name.string,
886 alias_info ? &alias_info->all : NULL,
893 if (ctx->disable_policy_handle_cache) {
894 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
895 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
896 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
902 /****************************************************************
903 ****************************************************************/
905 WERROR NetLocalGroupEnum_l(struct libnetapi_ctx *ctx,
906 struct NetLocalGroupEnum *r)
908 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupEnum);
911 /****************************************************************
912 ****************************************************************/
914 static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
915 struct rpc_pipe_client *lsa_pipe,
920 struct policy_handle lsa_handle;
922 struct lsa_RefDomainList *domains = NULL;
923 struct lsa_TransSidArray3 sids;
926 struct lsa_String names;
927 uint32_t num_names = 1;
930 return NT_STATUS_INVALID_PARAMETER;
935 init_lsa_String(&names, name);
937 status = rpccli_lsa_open_policy2(lsa_pipe, mem_ctx,
939 SEC_STD_READ_CONTROL |
940 LSA_POLICY_VIEW_LOCAL_INFORMATION |
941 LSA_POLICY_LOOKUP_NAMES,
943 NT_STATUS_NOT_OK_RETURN(status);
945 status = rpccli_lsa_LookupNames3(lsa_pipe, mem_ctx,
951 LSA_LOOKUP_NAMES_ALL, /* sure ? */
954 NT_STATUS_NOT_OK_RETURN(status);
956 if (count != 1 || sids.count != 1) {
957 return NT_STATUS_NONE_MAPPED;
960 sid_copy(sid, sids.sids[0].sid);
965 /****************************************************************
966 ****************************************************************/
968 static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
969 struct NetLocalGroupAddMembers *add,
970 struct NetLocalGroupDelMembers *del,
971 struct NetLocalGroupSetMembers *set)
973 struct NetLocalGroupAddMembers *r = NULL;
975 struct rpc_pipe_client *pipe_cli = NULL;
976 struct rpc_pipe_client *lsa_pipe = NULL;
979 struct lsa_String lsa_account_name;
980 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
981 struct dom_sid2 *domain_sid = NULL;
982 struct dom_sid *member_sids = NULL;
985 struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
986 struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
988 struct dom_sid *add_sids = NULL;
989 struct dom_sid *del_sids = NULL;
990 uint32_t num_add_sids = 0;
991 uint32_t num_del_sids = 0;
993 if ((!add && !del && !set) || (add && del && set)) {
994 return WERR_INVALID_PARAM;
1002 r = (struct NetLocalGroupAddMembers *)del;
1006 r = (struct NetLocalGroupAddMembers *)set;
1009 if (!r->in.group_name) {
1010 return WERR_INVALID_PARAM;
1013 switch (r->in.level) {
1018 return WERR_UNKNOWN_LEVEL;
1021 if (r->in.total_entries == 0 || !r->in.buffer) {
1022 return WERR_INVALID_PARAM;
1025 ZERO_STRUCT(connect_handle);
1026 ZERO_STRUCT(builtin_handle);
1027 ZERO_STRUCT(domain_handle);
1028 ZERO_STRUCT(alias_handle);
1030 member_sids = TALLOC_ZERO_ARRAY(ctx, struct dom_sid,
1031 r->in.total_entries);
1032 W_ERROR_HAVE_NO_MEMORY(member_sids);
1034 switch (r->in.level) {
1036 info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
1037 for (i=0; i < r->in.total_entries; i++) {
1038 sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
1042 info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1048 if (r->in.level == 3) {
1049 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1050 &ndr_table_lsarpc.syntax_id,
1052 if (!W_ERROR_IS_OK(werr)) {
1056 for (i=0; i < r->in.total_entries; i++) {
1057 status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1058 info3[i].lgrmi3_domainandname,
1060 if (!NT_STATUS_IS_OK(status)) {
1061 werr = ntstatus_to_werror(status);
1065 TALLOC_FREE(lsa_pipe);
1068 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1069 &ndr_table_samr.syntax_id,
1071 if (!W_ERROR_IS_OK(werr)) {
1075 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1076 SAMR_ACCESS_LOOKUP_DOMAIN |
1077 SAMR_ACCESS_ENUM_DOMAINS,
1078 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1081 if (!W_ERROR_IS_OK(werr)) {
1085 init_lsa_String(&lsa_account_name, r->in.group_name);
1087 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1090 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1091 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1092 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1093 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1096 if (ctx->disable_policy_handle_cache) {
1097 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1100 if (NT_STATUS_IS_OK(status)) {
1101 goto modify_membership;
1104 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1105 SAMR_ACCESS_ENUM_DOMAINS |
1106 SAMR_ACCESS_LOOKUP_DOMAIN,
1107 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1111 if (!W_ERROR_IS_OK(werr)) {
1115 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1118 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1119 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1120 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1121 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1123 if (!NT_STATUS_IS_OK(status)) {
1124 werr = ntstatus_to_werror(status);
1128 if (ctx->disable_policy_handle_cache) {
1129 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1135 for (i=0; i < r->in.total_entries; i++) {
1136 status = add_sid_to_array_unique(ctx, &member_sids[i],
1139 if (!NT_STATUS_IS_OK(status)) {
1140 werr = ntstatus_to_werror(status);
1147 for (i=0; i < r->in.total_entries; i++) {
1148 status = add_sid_to_array_unique(ctx, &member_sids[i],
1151 if (!NT_STATUS_IS_OK(status)) {
1152 werr = ntstatus_to_werror(status);
1160 struct lsa_SidArray current_sids;
1162 status = rpccli_samr_GetMembersInAlias(pipe_cli, ctx,
1165 if (!NT_STATUS_IS_OK(status)) {
1166 werr = ntstatus_to_werror(status);
1172 for (i=0; i < r->in.total_entries; i++) {
1173 bool already_member = false;
1174 for (k=0; k < current_sids.num_sids; k++) {
1175 if (dom_sid_equal(&member_sids[i],
1176 current_sids.sids[k].sid)) {
1177 already_member = true;
1181 if (!already_member) {
1182 status = add_sid_to_array_unique(ctx,
1184 &add_sids, &num_add_sids);
1185 if (!NT_STATUS_IS_OK(status)) {
1186 werr = ntstatus_to_werror(status);
1194 for (k=0; k < current_sids.num_sids; k++) {
1195 bool keep_member = false;
1196 for (i=0; i < r->in.total_entries; i++) {
1197 if (dom_sid_equal(&member_sids[i],
1198 current_sids.sids[k].sid)) {
1204 status = add_sid_to_array_unique(ctx,
1205 current_sids.sids[k].sid,
1206 &del_sids, &num_del_sids);
1207 if (!NT_STATUS_IS_OK(status)) {
1208 werr = ntstatus_to_werror(status);
1217 for (i=0; i < num_add_sids; i++) {
1218 status = rpccli_samr_AddAliasMember(pipe_cli, ctx,
1221 if (!NT_STATUS_IS_OK(status)) {
1222 werr = ntstatus_to_werror(status);
1229 for (i=0; i < num_del_sids; i++) {
1230 status = rpccli_samr_DeleteAliasMember(pipe_cli, ctx,
1233 if (!NT_STATUS_IS_OK(status)) {
1234 werr = ntstatus_to_werror(status);
1242 if (is_valid_policy_hnd(&alias_handle)) {
1243 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
1246 if (ctx->disable_policy_handle_cache) {
1247 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1248 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1249 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1255 /****************************************************************
1256 ****************************************************************/
1258 WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1259 struct NetLocalGroupAddMembers *r)
1261 return NetLocalGroupModifyMembers_r(ctx, r, NULL, NULL);
1264 /****************************************************************
1265 ****************************************************************/
1267 WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1268 struct NetLocalGroupAddMembers *r)
1270 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAddMembers);
1273 /****************************************************************
1274 ****************************************************************/
1276 WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1277 struct NetLocalGroupDelMembers *r)
1279 return NetLocalGroupModifyMembers_r(ctx, NULL, r, NULL);
1282 /****************************************************************
1283 ****************************************************************/
1285 WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1286 struct NetLocalGroupDelMembers *r)
1288 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDelMembers);
1291 /****************************************************************
1292 ****************************************************************/
1294 WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1295 struct NetLocalGroupGetMembers *r)
1297 return WERR_NOT_SUPPORTED;
1300 /****************************************************************
1301 ****************************************************************/
1303 WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1304 struct NetLocalGroupGetMembers *r)
1306 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetMembers);
1309 /****************************************************************
1310 ****************************************************************/
1312 WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1313 struct NetLocalGroupSetMembers *r)
1315 return NetLocalGroupModifyMembers_r(ctx, NULL, NULL, r);
1318 /****************************************************************
1319 ****************************************************************/
1321 WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1322 struct NetLocalGroupSetMembers *r)
1324 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);