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)
1021 struct NetLocalGroupAddMembers *r = NULL;
1023 struct cli_state *cli = NULL;
1024 struct rpc_pipe_client *pipe_cli = NULL;
1025 struct rpc_pipe_client *lsa_pipe = NULL;
1028 struct lsa_String lsa_account_name;
1029 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
1030 struct dom_sid2 *domain_sid = NULL;
1031 struct dom_sid *member_sids = NULL;
1034 struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
1035 struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
1037 struct dom_sid *add_sids = NULL;
1038 struct dom_sid *del_sids = NULL;
1039 size_t num_add_sids = 0;
1040 size_t num_del_sids = 0;
1042 if ((!add && !del) || (add && del)) {
1043 return WERR_INVALID_PARAM;
1051 r = (struct NetLocalGroupAddMembers *)del;
1054 if (!r->in.group_name) {
1055 return WERR_INVALID_PARAM;
1058 switch (r->in.level) {
1063 return WERR_UNKNOWN_LEVEL;
1066 if (r->in.total_entries == 0 || !r->in.buffer) {
1067 return WERR_INVALID_PARAM;
1070 ZERO_STRUCT(connect_handle);
1071 ZERO_STRUCT(builtin_handle);
1072 ZERO_STRUCT(domain_handle);
1073 ZERO_STRUCT(alias_handle);
1075 member_sids = TALLOC_ZERO_ARRAY(ctx, struct dom_sid,
1076 r->in.total_entries);
1077 W_ERROR_HAVE_NO_MEMORY(member_sids);
1079 switch (r->in.level) {
1081 info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
1082 for (i=0; i < r->in.total_entries; i++) {
1083 sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
1087 info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1093 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1094 if (!W_ERROR_IS_OK(werr)) {
1098 if (r->in.level == 3) {
1099 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_lsarpc.syntax_id,
1101 if (!W_ERROR_IS_OK(werr)) {
1105 for (i=0; i < r->in.total_entries; i++) {
1106 status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1107 info3[i].lgrmi3_domainandname,
1109 if (!NT_STATUS_IS_OK(status)) {
1110 werr = ntstatus_to_werror(status);
1114 TALLOC_FREE(lsa_pipe);
1117 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1119 if (!W_ERROR_IS_OK(werr)) {
1123 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1124 SAMR_ACCESS_OPEN_DOMAIN |
1125 SAMR_ACCESS_ENUM_DOMAINS,
1126 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1129 if (!W_ERROR_IS_OK(werr)) {
1133 init_lsa_String(&lsa_account_name, r->in.group_name);
1135 werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1138 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1139 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1140 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1141 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1144 if (ctx->disable_policy_handle_cache) {
1145 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1148 if (W_ERROR_IS_OK(werr)) {
1149 goto modify_membership;
1152 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1153 SAMR_ACCESS_ENUM_DOMAINS |
1154 SAMR_ACCESS_OPEN_DOMAIN,
1155 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1159 if (!W_ERROR_IS_OK(werr)) {
1163 werr = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1166 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1167 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1168 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1169 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1171 if (!W_ERROR_IS_OK(werr)) {
1175 if (ctx->disable_policy_handle_cache) {
1176 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1182 for (i=0; i < r->in.total_entries; i++) {
1183 status = add_sid_to_array_unique(ctx, &member_sids[i],
1186 if (!NT_STATUS_IS_OK(status)) {
1187 werr = ntstatus_to_werror(status);
1194 for (i=0; i < r->in.total_entries; i++) {
1195 status = add_sid_to_array_unique(ctx, &member_sids[i],
1198 if (!NT_STATUS_IS_OK(status)) {
1199 werr = ntstatus_to_werror(status);
1207 for (i=0; i < num_add_sids; i++) {
1208 status = rpccli_samr_AddAliasMember(pipe_cli, ctx,
1211 if (!NT_STATUS_IS_OK(status)) {
1212 werr = ntstatus_to_werror(status);
1219 for (i=0; i < num_del_sids; i++) {
1220 status = rpccli_samr_DeleteAliasMember(pipe_cli, ctx,
1223 if (!NT_STATUS_IS_OK(status)) {
1224 werr = ntstatus_to_werror(status);
1236 if (is_valid_policy_hnd(&alias_handle)) {
1237 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
1240 if (ctx->disable_policy_handle_cache) {
1241 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1242 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1243 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1249 /****************************************************************
1250 ****************************************************************/
1252 WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1253 struct NetLocalGroupAddMembers *r)
1255 return NetLocalGroupModifyMembers_r(ctx, r, NULL);
1258 /****************************************************************
1259 ****************************************************************/
1261 WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1262 struct NetLocalGroupAddMembers *r)
1264 return NetLocalGroupAddMembers_r(ctx, r);
1267 /****************************************************************
1268 ****************************************************************/
1270 WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1271 struct NetLocalGroupDelMembers *r)
1273 return NetLocalGroupModifyMembers_r(ctx, NULL, r);
1276 /****************************************************************
1277 ****************************************************************/
1279 WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1280 struct NetLocalGroupDelMembers *r)
1282 return NetLocalGroupDelMembers_r(ctx, r);
1285 /****************************************************************
1286 ****************************************************************/
1288 WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1289 struct NetLocalGroupGetMembers *r)
1291 return WERR_NOT_SUPPORTED;
1294 /****************************************************************
1295 ****************************************************************/
1297 WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1298 struct NetLocalGroupGetMembers *r)
1300 return WERR_NOT_SUPPORTED;
1303 /****************************************************************
1304 ****************************************************************/
1306 WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1307 struct NetLocalGroupSetMembers *r)
1309 return WERR_NOT_SUPPORTED;
1312 /****************************************************************
1313 ****************************************************************/
1315 WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1316 struct NetLocalGroupSetMembers *r)
1318 return WERR_NOT_SUPPORTED;