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"
27 static WERROR libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
28 struct rpc_pipe_client *pipe_cli,
29 struct policy_handle *domain_handle,
30 const char *group_name,
31 uint32_t access_rights,
32 struct policy_handle *alias_handle)
37 struct lsa_String lsa_account_name;
38 struct samr_Ids user_rids, name_types;
40 init_lsa_String(&lsa_account_name, group_name);
42 status = rpccli_samr_LookupNames(pipe_cli, mem_ctx,
48 if (!NT_STATUS_IS_OK(status)) {
49 werr = ntstatus_to_werror(status);
53 switch (name_types.ids[0]) {
55 case SID_NAME_WKN_GRP:
58 return WERR_INVALID_DATATYPE;
61 status = rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
66 if (NT_STATUS_IS_OK(status)) {
67 werr = ntstatus_to_werror(status);
77 /****************************************************************
78 ****************************************************************/
80 static NTSTATUS libnetapi_samr_open_alias_queryinfo(TALLOC_CTX *mem_ctx,
81 struct rpc_pipe_client *pipe_cli,
82 struct policy_handle *handle,
84 uint32_t access_rights,
85 enum samr_AliasInfoEnum level,
86 union samr_AliasInfo **alias_info)
89 struct policy_handle alias_handle;
90 union samr_AliasInfo *_alias_info = NULL;
92 ZERO_STRUCT(alias_handle);
94 status = rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
99 if (!NT_STATUS_IS_OK(status)) {
103 status = rpccli_samr_QueryAliasInfo(pipe_cli, mem_ctx,
107 if (!NT_STATUS_IS_OK(status)) {
111 *alias_info = _alias_info;
114 if (is_valid_policy_hnd(&alias_handle)) {
115 rpccli_samr_Close(pipe_cli, mem_ctx, &alias_handle);
121 /****************************************************************
122 ****************************************************************/
124 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
125 struct NetLocalGroupAdd *r)
127 struct cli_state *cli = NULL;
128 struct rpc_pipe_client *pipe_cli = NULL;
131 struct lsa_String lsa_account_name;
132 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
133 struct dom_sid2 *domain_sid = NULL;
136 struct LOCALGROUP_INFO_0 *info0 = NULL;
137 struct LOCALGROUP_INFO_1 *info1 = NULL;
139 const char *alias_name = NULL;
142 return WERR_INVALID_PARAM;
145 switch (r->in.level) {
147 info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
148 alias_name = info0->lgrpi0_name;
151 info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
152 alias_name = info1->lgrpi1_name;
155 werr = WERR_UNKNOWN_LEVEL;
159 ZERO_STRUCT(connect_handle);
160 ZERO_STRUCT(builtin_handle);
161 ZERO_STRUCT(domain_handle);
162 ZERO_STRUCT(alias_handle);
164 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
165 if (!W_ERROR_IS_OK(werr)) {
169 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
171 if (!W_ERROR_IS_OK(werr)) {
175 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
176 SAMR_ACCESS_OPEN_DOMAIN |
177 SAMR_ACCESS_ENUM_DOMAINS,
178 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
181 if (!W_ERROR_IS_OK(werr)) {
185 werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
188 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
191 if (ctx->disable_policy_handle_cache) {
192 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
195 if (W_ERROR_IS_OK(werr)) {
196 werr = WERR_ALIAS_EXISTS;
200 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
201 SAMR_ACCESS_ENUM_DOMAINS |
202 SAMR_ACCESS_OPEN_DOMAIN,
203 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
204 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
208 if (!W_ERROR_IS_OK(werr)) {
212 init_lsa_String(&lsa_account_name, alias_name);
214 status = rpccli_samr_CreateDomAlias(pipe_cli, ctx,
218 SAMR_ALIAS_ACCESS_SET_INFO,
221 if (!NT_STATUS_IS_OK(status)) {
222 werr = ntstatus_to_werror(status);
226 if (r->in.level == 1 && info1->lgrpi1_comment) {
228 union samr_AliasInfo alias_info;
230 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
232 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
234 ALIASINFODESCRIPTION,
236 if (!NT_STATUS_IS_OK(status)) {
237 werr = ntstatus_to_werror(status);
249 if (is_valid_policy_hnd(&alias_handle)) {
250 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
253 if (ctx->disable_policy_handle_cache) {
254 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
255 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
256 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
262 /****************************************************************
263 ****************************************************************/
265 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
266 struct NetLocalGroupAdd *r)
268 return NetLocalGroupAdd_r(ctx, r);
271 /****************************************************************
272 ****************************************************************/
275 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
276 struct NetLocalGroupDel *r)
278 struct cli_state *cli = NULL;
279 struct rpc_pipe_client *pipe_cli = NULL;
282 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
283 struct dom_sid2 *domain_sid = NULL;
285 if (!r->in.group_name) {
286 return WERR_INVALID_PARAM;
289 ZERO_STRUCT(connect_handle);
290 ZERO_STRUCT(builtin_handle);
291 ZERO_STRUCT(domain_handle);
292 ZERO_STRUCT(alias_handle);
294 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
295 if (!W_ERROR_IS_OK(werr)) {
299 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
301 if (!W_ERROR_IS_OK(werr)) {
305 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
306 SAMR_ACCESS_OPEN_DOMAIN |
307 SAMR_ACCESS_ENUM_DOMAINS,
308 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
311 if (!W_ERROR_IS_OK(werr)) {
315 werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
321 if (ctx->disable_policy_handle_cache) {
322 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
325 if (W_ERROR_IS_OK(werr)) {
329 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
330 SAMR_ACCESS_ENUM_DOMAINS |
331 SAMR_ACCESS_OPEN_DOMAIN,
332 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
333 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
337 if (!W_ERROR_IS_OK(werr)) {
341 werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
347 if (ctx->disable_policy_handle_cache) {
348 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
351 if (!W_ERROR_IS_OK(werr)) {
357 status = rpccli_samr_DeleteDomAlias(pipe_cli, ctx,
359 if (!NT_STATUS_IS_OK(status)) {
360 werr = ntstatus_to_werror(status);
364 ZERO_STRUCT(alias_handle);
373 if (is_valid_policy_hnd(&alias_handle)) {
374 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
377 if (ctx->disable_policy_handle_cache) {
378 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
379 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
380 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
386 /****************************************************************
387 ****************************************************************/
389 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
390 struct NetLocalGroupDel *r)
392 return NetLocalGroupDel_r(ctx, r);
395 /****************************************************************
396 ****************************************************************/
398 static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
399 const char *alias_name,
400 struct samr_AliasInfoAll *info,
402 uint32_t *entries_read,
405 struct LOCALGROUP_INFO_0 g0;
406 struct LOCALGROUP_INFO_1 g1;
407 struct LOCALGROUP_INFO_1002 g1002;
411 g0.lgrpi0_name = talloc_strdup(mem_ctx, alias_name);
412 W_ERROR_HAVE_NO_MEMORY(g0.lgrpi0_name);
414 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_0, g0,
415 (struct LOCALGROUP_INFO_0 **)buffer, entries_read);
419 g1.lgrpi1_name = talloc_strdup(mem_ctx, alias_name);
420 g1.lgrpi1_comment = talloc_strdup(mem_ctx, info->description.string);
421 W_ERROR_HAVE_NO_MEMORY(g1.lgrpi1_name);
423 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1, g1,
424 (struct LOCALGROUP_INFO_1 **)buffer, entries_read);
428 g1002.lgrpi1002_comment = talloc_strdup(mem_ctx, info->description.string);
430 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1002, g1002,
431 (struct LOCALGROUP_INFO_1002 **)buffer, entries_read);
435 return WERR_UNKNOWN_LEVEL;
441 /****************************************************************
442 ****************************************************************/
444 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
445 struct NetLocalGroupGetInfo *r)
447 struct cli_state *cli = NULL;
448 struct rpc_pipe_client *pipe_cli = NULL;
451 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
452 struct dom_sid2 *domain_sid = NULL;
453 union samr_AliasInfo *alias_info = NULL;
454 uint32_t entries_read = 0;
456 if (!r->in.group_name) {
457 return WERR_INVALID_PARAM;
460 switch (r->in.level) {
466 return WERR_UNKNOWN_LEVEL;
469 ZERO_STRUCT(connect_handle);
470 ZERO_STRUCT(builtin_handle);
471 ZERO_STRUCT(domain_handle);
472 ZERO_STRUCT(alias_handle);
474 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
475 if (!W_ERROR_IS_OK(werr)) {
479 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
481 if (!W_ERROR_IS_OK(werr)) {
485 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
486 SAMR_ACCESS_OPEN_DOMAIN |
487 SAMR_ACCESS_ENUM_DOMAINS,
488 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
491 if (!W_ERROR_IS_OK(werr)) {
495 werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
498 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
501 if (ctx->disable_policy_handle_cache) {
502 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
505 if (W_ERROR_IS_OK(werr)) {
509 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
510 SAMR_ACCESS_ENUM_DOMAINS |
511 SAMR_ACCESS_OPEN_DOMAIN,
512 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
513 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
517 if (!W_ERROR_IS_OK(werr)) {
521 werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
524 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
527 if (ctx->disable_policy_handle_cache) {
528 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
531 if (!W_ERROR_IS_OK(werr)) {
536 status = rpccli_samr_QueryAliasInfo(pipe_cli, ctx,
540 if (!NT_STATUS_IS_OK(status)) {
541 werr = ntstatus_to_werror(status);
545 werr = map_alias_info_to_buffer(ctx,
548 r->in.level, &entries_read,
556 if (is_valid_policy_hnd(&alias_handle)) {
557 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
560 if (ctx->disable_policy_handle_cache) {
561 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
562 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
563 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
569 /****************************************************************
570 ****************************************************************/
572 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
573 struct NetLocalGroupGetInfo *r)
575 return NetLocalGroupGetInfo_r(ctx, r);
578 /****************************************************************
579 ****************************************************************/
581 static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
584 enum samr_AliasInfoEnum *alias_level,
585 union samr_AliasInfo **alias_info)
587 struct LOCALGROUP_INFO_0 *info0;
588 struct LOCALGROUP_INFO_1 *info1;
589 struct LOCALGROUP_INFO_1002 *info1002;
590 union samr_AliasInfo *info = NULL;
592 info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
593 W_ERROR_HAVE_NO_MEMORY(info);
597 info0 = (struct LOCALGROUP_INFO_0 *)buffer;
598 init_lsa_String(&info->name, info0->lgrpi0_name);
599 *alias_level = ALIASINFONAME;
602 info1 = (struct LOCALGROUP_INFO_1 *)buffer;
603 /* group name will be ignored */
604 init_lsa_String(&info->description, info1->lgrpi1_comment);
605 *alias_level = ALIASINFODESCRIPTION;
608 info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
609 init_lsa_String(&info->description, info1002->lgrpi1002_comment);
610 *alias_level = ALIASINFODESCRIPTION;
619 /****************************************************************
620 ****************************************************************/
622 WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
623 struct NetLocalGroupSetInfo *r)
625 struct cli_state *cli = NULL;
626 struct rpc_pipe_client *pipe_cli = NULL;
629 struct lsa_String lsa_account_name;
630 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
631 struct dom_sid2 *domain_sid = NULL;
632 enum samr_AliasInfoEnum alias_level = 0;
633 union samr_AliasInfo *alias_info = NULL;
635 if (!r->in.group_name) {
636 return WERR_INVALID_PARAM;
639 switch (r->in.level) {
645 return WERR_UNKNOWN_LEVEL;
648 ZERO_STRUCT(connect_handle);
649 ZERO_STRUCT(builtin_handle);
650 ZERO_STRUCT(domain_handle);
651 ZERO_STRUCT(alias_handle);
653 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
654 if (!W_ERROR_IS_OK(werr)) {
658 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
660 if (!W_ERROR_IS_OK(werr)) {
664 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
665 SAMR_ACCESS_OPEN_DOMAIN |
666 SAMR_ACCESS_ENUM_DOMAINS,
667 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
670 if (!W_ERROR_IS_OK(werr)) {
674 init_lsa_String(&lsa_account_name, r->in.group_name);
676 werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
679 SAMR_ALIAS_ACCESS_SET_INFO,
682 if (ctx->disable_policy_handle_cache) {
683 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
686 if (W_ERROR_IS_OK(werr)) {
690 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
691 SAMR_ACCESS_ENUM_DOMAINS |
692 SAMR_ACCESS_OPEN_DOMAIN,
693 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
697 if (!W_ERROR_IS_OK(werr)) {
701 werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
704 SAMR_ALIAS_ACCESS_SET_INFO,
706 if (!W_ERROR_IS_OK(werr)) {
710 if (ctx->disable_policy_handle_cache) {
711 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
716 werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer,
717 &alias_level, &alias_info);
718 if (!W_ERROR_IS_OK(werr)) {
722 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
726 if (!NT_STATUS_IS_OK(status)) {
727 werr = ntstatus_to_werror(status);
738 if (is_valid_policy_hnd(&alias_handle)) {
739 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
742 if (ctx->disable_policy_handle_cache) {
743 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
744 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
745 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
751 /****************************************************************
752 ****************************************************************/
754 WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
755 struct NetLocalGroupSetInfo *r)
757 return NetLocalGroupSetInfo_r(ctx, r);
760 /****************************************************************
761 ****************************************************************/
763 WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
764 struct NetLocalGroupEnum *r)
766 struct cli_state *cli = NULL;
767 struct rpc_pipe_client *pipe_cli = NULL;
770 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
771 struct dom_sid2 *domain_sid = NULL;
772 uint32_t entries_read = 0;
773 union samr_DomainInfo *domain_info = NULL;
774 union samr_DomainInfo *builtin_info = NULL;
775 struct samr_SamArray *domain_sam_array = NULL;
776 struct samr_SamArray *builtin_sam_array = NULL;
779 if (!r->out.buffer) {
780 return WERR_INVALID_PARAM;
783 switch (r->in.level) {
788 return WERR_UNKNOWN_LEVEL;
791 if (r->out.total_entries) {
792 *r->out.total_entries = 0;
794 if (r->out.entries_read) {
795 *r->out.entries_read = 0;
798 ZERO_STRUCT(connect_handle);
799 ZERO_STRUCT(builtin_handle);
800 ZERO_STRUCT(domain_handle);
801 ZERO_STRUCT(alias_handle);
803 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
804 if (!W_ERROR_IS_OK(werr)) {
808 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
810 if (!W_ERROR_IS_OK(werr)) {
814 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
815 SAMR_ACCESS_OPEN_DOMAIN |
816 SAMR_ACCESS_ENUM_DOMAINS,
817 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
818 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
819 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
822 if (!W_ERROR_IS_OK(werr)) {
826 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
827 SAMR_ACCESS_OPEN_DOMAIN |
828 SAMR_ACCESS_ENUM_DOMAINS,
829 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
830 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
831 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
835 if (!W_ERROR_IS_OK(werr)) {
839 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
843 if (!NT_STATUS_IS_OK(status)) {
844 werr = ntstatus_to_werror(status);
848 if (r->out.total_entries) {
849 *r->out.total_entries += builtin_info->info2.num_aliases;
852 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
856 if (!NT_STATUS_IS_OK(status)) {
857 werr = ntstatus_to_werror(status);
861 if (r->out.total_entries) {
862 *r->out.total_entries += domain_info->info2.num_aliases;
865 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
871 if (!NT_STATUS_IS_OK(status)) {
872 werr = ntstatus_to_werror(status);
876 for (i=0; i<builtin_sam_array->count; i++) {
877 union samr_AliasInfo *alias_info = NULL;
879 if (r->in.level == 1) {
881 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
883 builtin_sam_array->entries[i].idx,
884 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
887 if (!NT_STATUS_IS_OK(status)) {
888 werr = ntstatus_to_werror(status);
893 werr = map_alias_info_to_buffer(ctx,
894 builtin_sam_array->entries[i].name.string,
895 alias_info ? &alias_info->all : NULL,
901 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
907 if (!NT_STATUS_IS_OK(status)) {
908 werr = ntstatus_to_werror(status);
912 for (i=0; i<domain_sam_array->count; i++) {
914 union samr_AliasInfo *alias_info = NULL;
916 if (r->in.level == 1) {
917 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
919 domain_sam_array->entries[i].idx,
920 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
923 if (!NT_STATUS_IS_OK(status)) {
924 werr = ntstatus_to_werror(status);
929 werr = map_alias_info_to_buffer(ctx,
930 domain_sam_array->entries[i].name.string,
931 alias_info ? &alias_info->all : NULL,
942 if (ctx->disable_policy_handle_cache) {
943 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
944 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
945 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
951 /****************************************************************
952 ****************************************************************/
954 WERROR NetLocalGroupEnum_l(struct libnetapi_ctx *ctx,
955 struct NetLocalGroupEnum *r)
957 return WERR_NOT_SUPPORTED;
960 /****************************************************************
961 ****************************************************************/
963 static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
964 struct rpc_pipe_client *lsa_pipe,
969 struct policy_handle lsa_handle;
971 struct lsa_RefDomainList *domains = NULL;
972 struct lsa_TransSidArray3 sids;
975 struct lsa_String names;
976 uint32_t num_names = 1;
979 return NT_STATUS_INVALID_PARAMETER;
984 init_lsa_String(&names, name);
986 status = rpccli_lsa_open_policy2(lsa_pipe, mem_ctx,
988 STD_RIGHT_READ_CONTROL_ACCESS |
989 LSA_POLICY_VIEW_LOCAL_INFORMATION |
990 LSA_POLICY_LOOKUP_NAMES,
992 NT_STATUS_NOT_OK_RETURN(status);
994 status = rpccli_lsa_LookupNames3(lsa_pipe, mem_ctx,
1000 LSA_LOOKUP_NAMES_ALL, /* sure ? */
1003 NT_STATUS_NOT_OK_RETURN(status);
1005 if (count != 1 || sids.count != 1) {
1006 return NT_STATUS_NONE_MAPPED;
1009 sid_copy(sid, sids.sids[0].sid);
1011 return NT_STATUS_OK;
1014 /****************************************************************
1015 ****************************************************************/
1017 static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
1018 struct NetLocalGroupAddMembers *add,
1019 struct NetLocalGroupDelMembers *del,
1020 struct NetLocalGroupSetMembers *set)
1022 struct NetLocalGroupAddMembers *r = NULL;
1024 struct cli_state *cli = NULL;
1025 struct rpc_pipe_client *pipe_cli = NULL;
1026 struct rpc_pipe_client *lsa_pipe = NULL;
1029 struct lsa_String lsa_account_name;
1030 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
1031 struct dom_sid2 *domain_sid = NULL;
1032 struct dom_sid *member_sids = NULL;
1035 struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
1036 struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
1038 struct dom_sid *add_sids = NULL;
1039 struct dom_sid *del_sids = NULL;
1040 size_t num_add_sids = 0;
1041 size_t num_del_sids = 0;
1043 if ((!add && !del && !set) || (add && del && set)) {
1044 return WERR_INVALID_PARAM;
1052 r = (struct NetLocalGroupAddMembers *)del;
1056 r = (struct NetLocalGroupAddMembers *)set;
1059 if (!r->in.group_name) {
1060 return WERR_INVALID_PARAM;
1063 switch (r->in.level) {
1068 return WERR_UNKNOWN_LEVEL;
1071 if (r->in.total_entries == 0 || !r->in.buffer) {
1072 return WERR_INVALID_PARAM;
1075 ZERO_STRUCT(connect_handle);
1076 ZERO_STRUCT(builtin_handle);
1077 ZERO_STRUCT(domain_handle);
1078 ZERO_STRUCT(alias_handle);
1080 member_sids = TALLOC_ZERO_ARRAY(ctx, struct dom_sid,
1081 r->in.total_entries);
1082 W_ERROR_HAVE_NO_MEMORY(member_sids);
1084 switch (r->in.level) {
1086 info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
1087 for (i=0; i < r->in.total_entries; i++) {
1088 sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
1092 info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1098 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1099 if (!W_ERROR_IS_OK(werr)) {
1103 if (r->in.level == 3) {
1104 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_lsarpc.syntax_id,
1106 if (!W_ERROR_IS_OK(werr)) {
1110 for (i=0; i < r->in.total_entries; i++) {
1111 status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1112 info3[i].lgrmi3_domainandname,
1114 if (!NT_STATUS_IS_OK(status)) {
1115 werr = ntstatus_to_werror(status);
1119 TALLOC_FREE(lsa_pipe);
1122 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1124 if (!W_ERROR_IS_OK(werr)) {
1128 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1129 SAMR_ACCESS_OPEN_DOMAIN |
1130 SAMR_ACCESS_ENUM_DOMAINS,
1131 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1134 if (!W_ERROR_IS_OK(werr)) {
1138 init_lsa_String(&lsa_account_name, r->in.group_name);
1140 werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1143 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1144 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1145 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1146 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1149 if (ctx->disable_policy_handle_cache) {
1150 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1153 if (W_ERROR_IS_OK(werr)) {
1154 goto modify_membership;
1157 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1158 SAMR_ACCESS_ENUM_DOMAINS |
1159 SAMR_ACCESS_OPEN_DOMAIN,
1160 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1164 if (!W_ERROR_IS_OK(werr)) {
1168 werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1171 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1172 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1173 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1174 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1176 if (!W_ERROR_IS_OK(werr)) {
1180 if (ctx->disable_policy_handle_cache) {
1181 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1187 for (i=0; i < r->in.total_entries; i++) {
1188 status = add_sid_to_array_unique(ctx, &member_sids[i],
1191 if (!NT_STATUS_IS_OK(status)) {
1192 werr = ntstatus_to_werror(status);
1199 for (i=0; i < r->in.total_entries; i++) {
1200 status = add_sid_to_array_unique(ctx, &member_sids[i],
1203 if (!NT_STATUS_IS_OK(status)) {
1204 werr = ntstatus_to_werror(status);
1212 struct lsa_SidArray current_sids;
1214 status = rpccli_samr_GetMembersInAlias(pipe_cli, ctx,
1217 if (!NT_STATUS_IS_OK(status)) {
1218 werr = ntstatus_to_werror(status);
1224 for (i=0; i < r->in.total_entries; i++) {
1225 bool already_member = false;
1226 for (k=0; k < current_sids.num_sids; k++) {
1227 if (sid_equal(&member_sids[i],
1228 current_sids.sids[k].sid)) {
1229 already_member = true;
1233 if (!already_member) {
1234 status = add_sid_to_array_unique(ctx,
1236 &add_sids, &num_add_sids);
1237 if (!NT_STATUS_IS_OK(status)) {
1238 werr = ntstatus_to_werror(status);
1246 for (k=0; k < current_sids.num_sids; k++) {
1247 bool keep_member = false;
1248 for (i=0; i < r->in.total_entries; i++) {
1249 if (sid_equal(&member_sids[i],
1250 current_sids.sids[k].sid)) {
1256 status = add_sid_to_array_unique(ctx,
1257 current_sids.sids[k].sid,
1258 &del_sids, &num_del_sids);
1259 if (!NT_STATUS_IS_OK(status)) {
1260 werr = ntstatus_to_werror(status);
1269 for (i=0; i < num_add_sids; i++) {
1270 status = rpccli_samr_AddAliasMember(pipe_cli, ctx,
1273 if (!NT_STATUS_IS_OK(status)) {
1274 werr = ntstatus_to_werror(status);
1281 for (i=0; i < num_del_sids; i++) {
1282 status = rpccli_samr_DeleteAliasMember(pipe_cli, ctx,
1285 if (!NT_STATUS_IS_OK(status)) {
1286 werr = ntstatus_to_werror(status);
1298 if (is_valid_policy_hnd(&alias_handle)) {
1299 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
1302 if (ctx->disable_policy_handle_cache) {
1303 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1304 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1305 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1311 /****************************************************************
1312 ****************************************************************/
1314 WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1315 struct NetLocalGroupAddMembers *r)
1317 return NetLocalGroupModifyMembers_r(ctx, r, NULL, NULL);
1320 /****************************************************************
1321 ****************************************************************/
1323 WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1324 struct NetLocalGroupAddMembers *r)
1326 return NetLocalGroupAddMembers_r(ctx, r);
1329 /****************************************************************
1330 ****************************************************************/
1332 WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1333 struct NetLocalGroupDelMembers *r)
1335 return NetLocalGroupModifyMembers_r(ctx, NULL, r, NULL);
1338 /****************************************************************
1339 ****************************************************************/
1341 WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1342 struct NetLocalGroupDelMembers *r)
1344 return NetLocalGroupDelMembers_r(ctx, r);
1347 /****************************************************************
1348 ****************************************************************/
1350 WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1351 struct NetLocalGroupGetMembers *r)
1353 return WERR_NOT_SUPPORTED;
1356 /****************************************************************
1357 ****************************************************************/
1359 WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1360 struct NetLocalGroupGetMembers *r)
1362 return WERR_NOT_SUPPORTED;
1365 /****************************************************************
1366 ****************************************************************/
1368 WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1369 struct NetLocalGroupSetMembers *r)
1371 return NetLocalGroupModifyMembers_r(ctx, NULL, NULL, r);
1374 /****************************************************************
1375 ****************************************************************/
1377 WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1378 struct NetLocalGroupSetMembers *r)
1380 return NetLocalGroupSetMembers_r(ctx, r);