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"
29 static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
30 struct rpc_pipe_client *pipe_cli,
31 struct policy_handle *domain_handle,
32 const char *group_name,
33 uint32_t access_rights,
34 struct policy_handle *alias_handle)
38 struct lsa_String lsa_account_name;
39 struct samr_Ids user_rids, name_types;
41 init_lsa_String(&lsa_account_name, group_name);
43 status = rpccli_samr_LookupNames(pipe_cli, mem_ctx,
49 if (!NT_STATUS_IS_OK(status)) {
53 switch (name_types.ids[0]) {
55 case SID_NAME_WKN_GRP:
58 return NT_STATUS_INVALID_SID;
61 return rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
68 /****************************************************************
69 ****************************************************************/
71 static NTSTATUS libnetapi_samr_open_alias_queryinfo(TALLOC_CTX *mem_ctx,
72 struct rpc_pipe_client *pipe_cli,
73 struct policy_handle *handle,
75 uint32_t access_rights,
76 enum samr_AliasInfoEnum level,
77 union samr_AliasInfo **alias_info)
80 struct policy_handle alias_handle;
81 union samr_AliasInfo *_alias_info = NULL;
83 ZERO_STRUCT(alias_handle);
85 status = rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
90 if (!NT_STATUS_IS_OK(status)) {
94 status = rpccli_samr_QueryAliasInfo(pipe_cli, mem_ctx,
98 if (!NT_STATUS_IS_OK(status)) {
102 *alias_info = _alias_info;
105 if (is_valid_policy_hnd(&alias_handle)) {
106 rpccli_samr_Close(pipe_cli, mem_ctx, &alias_handle);
112 /****************************************************************
113 ****************************************************************/
115 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
116 struct NetLocalGroupAdd *r)
118 struct rpc_pipe_client *pipe_cli = NULL;
121 struct lsa_String lsa_account_name;
122 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
123 struct dom_sid2 *domain_sid = NULL;
126 struct LOCALGROUP_INFO_0 *info0 = NULL;
127 struct LOCALGROUP_INFO_1 *info1 = NULL;
129 const char *alias_name = NULL;
132 return WERR_INVALID_PARAM;
135 switch (r->in.level) {
137 info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
138 alias_name = info0->lgrpi0_name;
141 info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
142 alias_name = info1->lgrpi1_name;
145 werr = WERR_UNKNOWN_LEVEL;
149 ZERO_STRUCT(connect_handle);
150 ZERO_STRUCT(builtin_handle);
151 ZERO_STRUCT(domain_handle);
152 ZERO_STRUCT(alias_handle);
154 werr = libnetapi_open_pipe(ctx, r->in.server_name,
155 &ndr_table_samr.syntax_id,
157 if (!W_ERROR_IS_OK(werr)) {
161 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
162 SAMR_ACCESS_LOOKUP_DOMAIN |
163 SAMR_ACCESS_ENUM_DOMAINS,
164 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
167 if (!W_ERROR_IS_OK(werr)) {
171 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
174 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
176 if (ctx->disable_policy_handle_cache) {
177 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
180 if (NT_STATUS_IS_OK(status)) {
181 werr = WERR_ALIAS_EXISTS;
185 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
186 SAMR_ACCESS_ENUM_DOMAINS |
187 SAMR_ACCESS_LOOKUP_DOMAIN,
188 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
189 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
193 if (!W_ERROR_IS_OK(werr)) {
197 init_lsa_String(&lsa_account_name, alias_name);
199 status = rpccli_samr_CreateDomAlias(pipe_cli, talloc_tos(),
203 SAMR_ALIAS_ACCESS_SET_INFO,
206 if (!NT_STATUS_IS_OK(status)) {
207 werr = ntstatus_to_werror(status);
211 if (r->in.level == 1 && info1->lgrpi1_comment) {
213 union samr_AliasInfo alias_info;
215 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
217 status = rpccli_samr_SetAliasInfo(pipe_cli, talloc_tos(),
219 ALIASINFODESCRIPTION,
221 if (!NT_STATUS_IS_OK(status)) {
222 werr = ntstatus_to_werror(status);
230 if (is_valid_policy_hnd(&alias_handle)) {
231 rpccli_samr_Close(pipe_cli, talloc_tos(), &alias_handle);
234 if (ctx->disable_policy_handle_cache) {
235 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
236 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
237 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
243 /****************************************************************
244 ****************************************************************/
246 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
247 struct NetLocalGroupAdd *r)
249 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAdd);
252 /****************************************************************
253 ****************************************************************/
256 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
257 struct NetLocalGroupDel *r)
259 struct rpc_pipe_client *pipe_cli = NULL;
262 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
263 struct dom_sid2 *domain_sid = NULL;
265 if (!r->in.group_name) {
266 return WERR_INVALID_PARAM;
269 ZERO_STRUCT(connect_handle);
270 ZERO_STRUCT(builtin_handle);
271 ZERO_STRUCT(domain_handle);
272 ZERO_STRUCT(alias_handle);
274 werr = libnetapi_open_pipe(ctx, r->in.server_name,
275 &ndr_table_samr.syntax_id,
277 if (!W_ERROR_IS_OK(werr)) {
281 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
282 SAMR_ACCESS_LOOKUP_DOMAIN |
283 SAMR_ACCESS_ENUM_DOMAINS,
284 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
287 if (!W_ERROR_IS_OK(werr)) {
291 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
297 if (ctx->disable_policy_handle_cache) {
298 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
301 if (NT_STATUS_IS_OK(status)) {
305 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
306 SAMR_ACCESS_ENUM_DOMAINS |
307 SAMR_ACCESS_LOOKUP_DOMAIN,
308 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
309 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
313 if (!W_ERROR_IS_OK(werr)) {
317 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
323 if (ctx->disable_policy_handle_cache) {
324 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
327 if (!NT_STATUS_IS_OK(status)) {
328 werr = ntstatus_to_werror(status);
334 status = rpccli_samr_DeleteDomAlias(pipe_cli, talloc_tos(),
336 if (!NT_STATUS_IS_OK(status)) {
337 werr = ntstatus_to_werror(status);
341 ZERO_STRUCT(alias_handle);
346 if (is_valid_policy_hnd(&alias_handle)) {
347 rpccli_samr_Close(pipe_cli, talloc_tos(), &alias_handle);
350 if (ctx->disable_policy_handle_cache) {
351 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
352 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
353 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
359 /****************************************************************
360 ****************************************************************/
362 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
363 struct NetLocalGroupDel *r)
365 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDel);
368 /****************************************************************
369 ****************************************************************/
371 static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
372 const char *alias_name,
373 struct samr_AliasInfoAll *info,
375 uint32_t *entries_read,
378 struct LOCALGROUP_INFO_0 g0;
379 struct LOCALGROUP_INFO_1 g1;
380 struct LOCALGROUP_INFO_1002 g1002;
384 g0.lgrpi0_name = talloc_strdup(mem_ctx, alias_name);
385 W_ERROR_HAVE_NO_MEMORY(g0.lgrpi0_name);
387 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_0, g0,
388 (struct LOCALGROUP_INFO_0 **)buffer, entries_read);
392 g1.lgrpi1_name = talloc_strdup(mem_ctx, alias_name);
393 g1.lgrpi1_comment = talloc_strdup(mem_ctx, info->description.string);
394 W_ERROR_HAVE_NO_MEMORY(g1.lgrpi1_name);
396 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1, g1,
397 (struct LOCALGROUP_INFO_1 **)buffer, entries_read);
401 g1002.lgrpi1002_comment = talloc_strdup(mem_ctx, info->description.string);
403 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1002, g1002,
404 (struct LOCALGROUP_INFO_1002 **)buffer, entries_read);
408 return WERR_UNKNOWN_LEVEL;
414 /****************************************************************
415 ****************************************************************/
417 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
418 struct NetLocalGroupGetInfo *r)
420 struct rpc_pipe_client *pipe_cli = NULL;
423 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
424 struct dom_sid2 *domain_sid = NULL;
425 union samr_AliasInfo *alias_info = NULL;
426 uint32_t entries_read = 0;
428 if (!r->in.group_name) {
429 return WERR_INVALID_PARAM;
432 switch (r->in.level) {
438 return WERR_UNKNOWN_LEVEL;
441 ZERO_STRUCT(connect_handle);
442 ZERO_STRUCT(builtin_handle);
443 ZERO_STRUCT(domain_handle);
444 ZERO_STRUCT(alias_handle);
446 werr = libnetapi_open_pipe(ctx, r->in.server_name,
447 &ndr_table_samr.syntax_id,
449 if (!W_ERROR_IS_OK(werr)) {
453 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
454 SAMR_ACCESS_LOOKUP_DOMAIN |
455 SAMR_ACCESS_ENUM_DOMAINS,
456 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
459 if (!W_ERROR_IS_OK(werr)) {
463 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
466 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
469 if (ctx->disable_policy_handle_cache) {
470 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
473 if (NT_STATUS_IS_OK(status)) {
477 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
478 SAMR_ACCESS_ENUM_DOMAINS |
479 SAMR_ACCESS_LOOKUP_DOMAIN,
480 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
481 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
485 if (!W_ERROR_IS_OK(werr)) {
489 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
492 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
495 if (ctx->disable_policy_handle_cache) {
496 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
499 if (!NT_STATUS_IS_OK(status)) {
500 werr = ntstatus_to_werror(status);
505 status = rpccli_samr_QueryAliasInfo(pipe_cli, talloc_tos(),
509 if (!NT_STATUS_IS_OK(status)) {
510 werr = ntstatus_to_werror(status);
514 werr = map_alias_info_to_buffer(ctx,
517 r->in.level, &entries_read,
521 if (is_valid_policy_hnd(&alias_handle)) {
522 rpccli_samr_Close(pipe_cli, talloc_tos(), &alias_handle);
525 if (ctx->disable_policy_handle_cache) {
526 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
527 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
528 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
534 /****************************************************************
535 ****************************************************************/
537 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
538 struct NetLocalGroupGetInfo *r)
540 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetInfo);
543 /****************************************************************
544 ****************************************************************/
546 static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
549 enum samr_AliasInfoEnum *alias_level,
550 union samr_AliasInfo **alias_info)
552 struct LOCALGROUP_INFO_0 *info0;
553 struct LOCALGROUP_INFO_1 *info1;
554 struct LOCALGROUP_INFO_1002 *info1002;
555 union samr_AliasInfo *info = NULL;
557 info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
558 W_ERROR_HAVE_NO_MEMORY(info);
562 info0 = (struct LOCALGROUP_INFO_0 *)buffer;
563 init_lsa_String(&info->name, info0->lgrpi0_name);
564 *alias_level = ALIASINFONAME;
567 info1 = (struct LOCALGROUP_INFO_1 *)buffer;
568 /* group name will be ignored */
569 init_lsa_String(&info->description, info1->lgrpi1_comment);
570 *alias_level = ALIASINFODESCRIPTION;
573 info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
574 init_lsa_String(&info->description, info1002->lgrpi1002_comment);
575 *alias_level = ALIASINFODESCRIPTION;
584 /****************************************************************
585 ****************************************************************/
587 WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
588 struct NetLocalGroupSetInfo *r)
590 struct rpc_pipe_client *pipe_cli = NULL;
593 struct lsa_String lsa_account_name;
594 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
595 struct dom_sid2 *domain_sid = NULL;
596 enum samr_AliasInfoEnum alias_level = 0;
597 union samr_AliasInfo *alias_info = NULL;
599 if (!r->in.group_name) {
600 return WERR_INVALID_PARAM;
603 switch (r->in.level) {
609 return WERR_UNKNOWN_LEVEL;
612 ZERO_STRUCT(connect_handle);
613 ZERO_STRUCT(builtin_handle);
614 ZERO_STRUCT(domain_handle);
615 ZERO_STRUCT(alias_handle);
617 werr = libnetapi_open_pipe(ctx, r->in.server_name,
618 &ndr_table_samr.syntax_id,
620 if (!W_ERROR_IS_OK(werr)) {
624 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
625 SAMR_ACCESS_LOOKUP_DOMAIN |
626 SAMR_ACCESS_ENUM_DOMAINS,
627 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
630 if (!W_ERROR_IS_OK(werr)) {
634 init_lsa_String(&lsa_account_name, r->in.group_name);
636 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
639 SAMR_ALIAS_ACCESS_SET_INFO,
642 if (ctx->disable_policy_handle_cache) {
643 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
646 if (NT_STATUS_IS_OK(status)) {
650 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
651 SAMR_ACCESS_ENUM_DOMAINS |
652 SAMR_ACCESS_LOOKUP_DOMAIN,
653 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
657 if (!W_ERROR_IS_OK(werr)) {
661 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
664 SAMR_ALIAS_ACCESS_SET_INFO,
666 if (!NT_STATUS_IS_OK(status)) {
667 werr = ntstatus_to_werror(status);
671 if (ctx->disable_policy_handle_cache) {
672 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
677 werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer,
678 &alias_level, &alias_info);
679 if (!W_ERROR_IS_OK(werr)) {
683 status = rpccli_samr_SetAliasInfo(pipe_cli, talloc_tos(),
687 if (!NT_STATUS_IS_OK(status)) {
688 werr = ntstatus_to_werror(status);
695 if (is_valid_policy_hnd(&alias_handle)) {
696 rpccli_samr_Close(pipe_cli, talloc_tos(), &alias_handle);
699 if (ctx->disable_policy_handle_cache) {
700 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
701 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
702 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
708 /****************************************************************
709 ****************************************************************/
711 WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
712 struct NetLocalGroupSetInfo *r)
714 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetInfo);
717 /****************************************************************
718 ****************************************************************/
720 WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
721 struct NetLocalGroupEnum *r)
723 struct rpc_pipe_client *pipe_cli = NULL;
726 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
727 struct dom_sid2 *domain_sid = NULL;
728 uint32_t entries_read = 0;
729 union samr_DomainInfo *domain_info = NULL;
730 union samr_DomainInfo *builtin_info = NULL;
731 struct samr_SamArray *domain_sam_array = NULL;
732 struct samr_SamArray *builtin_sam_array = NULL;
735 if (!r->out.buffer) {
736 return WERR_INVALID_PARAM;
739 switch (r->in.level) {
744 return WERR_UNKNOWN_LEVEL;
747 if (r->out.total_entries) {
748 *r->out.total_entries = 0;
750 if (r->out.entries_read) {
751 *r->out.entries_read = 0;
754 ZERO_STRUCT(connect_handle);
755 ZERO_STRUCT(builtin_handle);
756 ZERO_STRUCT(domain_handle);
757 ZERO_STRUCT(alias_handle);
759 werr = libnetapi_open_pipe(ctx, r->in.server_name,
760 &ndr_table_samr.syntax_id,
762 if (!W_ERROR_IS_OK(werr)) {
766 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
767 SAMR_ACCESS_LOOKUP_DOMAIN |
768 SAMR_ACCESS_ENUM_DOMAINS,
769 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
770 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
771 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
774 if (!W_ERROR_IS_OK(werr)) {
778 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
779 SAMR_ACCESS_LOOKUP_DOMAIN |
780 SAMR_ACCESS_ENUM_DOMAINS,
781 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
782 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
783 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
787 if (!W_ERROR_IS_OK(werr)) {
791 status = rpccli_samr_QueryDomainInfo(pipe_cli, talloc_tos(),
795 if (!NT_STATUS_IS_OK(status)) {
796 werr = ntstatus_to_werror(status);
800 if (r->out.total_entries) {
801 *r->out.total_entries += builtin_info->general.num_aliases;
804 status = rpccli_samr_QueryDomainInfo(pipe_cli, talloc_tos(),
808 if (!NT_STATUS_IS_OK(status)) {
809 werr = ntstatus_to_werror(status);
813 if (r->out.total_entries) {
814 *r->out.total_entries += domain_info->general.num_aliases;
817 status = rpccli_samr_EnumDomainAliases(pipe_cli, talloc_tos(),
823 if (!NT_STATUS_IS_OK(status)) {
824 werr = ntstatus_to_werror(status);
828 for (i=0; i<builtin_sam_array->count; i++) {
829 union samr_AliasInfo *alias_info = NULL;
831 if (r->in.level == 1) {
833 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
835 builtin_sam_array->entries[i].idx,
836 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
839 if (!NT_STATUS_IS_OK(status)) {
840 werr = ntstatus_to_werror(status);
845 werr = map_alias_info_to_buffer(ctx,
846 builtin_sam_array->entries[i].name.string,
847 alias_info ? &alias_info->all : NULL,
853 status = rpccli_samr_EnumDomainAliases(pipe_cli, talloc_tos(),
859 if (!NT_STATUS_IS_OK(status)) {
860 werr = ntstatus_to_werror(status);
864 for (i=0; i<domain_sam_array->count; i++) {
866 union samr_AliasInfo *alias_info = NULL;
868 if (r->in.level == 1) {
869 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
871 domain_sam_array->entries[i].idx,
872 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
875 if (!NT_STATUS_IS_OK(status)) {
876 werr = ntstatus_to_werror(status);
881 werr = map_alias_info_to_buffer(ctx,
882 domain_sam_array->entries[i].name.string,
883 alias_info ? &alias_info->all : NULL,
890 if (ctx->disable_policy_handle_cache) {
891 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
892 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
893 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
899 /****************************************************************
900 ****************************************************************/
902 WERROR NetLocalGroupEnum_l(struct libnetapi_ctx *ctx,
903 struct NetLocalGroupEnum *r)
905 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupEnum);
908 /****************************************************************
909 ****************************************************************/
911 static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
912 struct rpc_pipe_client *lsa_pipe,
917 struct policy_handle lsa_handle;
919 struct lsa_RefDomainList *domains = NULL;
920 struct lsa_TransSidArray3 sids;
923 struct lsa_String names;
924 uint32_t num_names = 1;
927 return NT_STATUS_INVALID_PARAMETER;
932 init_lsa_String(&names, name);
934 status = rpccli_lsa_open_policy2(lsa_pipe, mem_ctx,
936 STD_RIGHT_READ_CONTROL_ACCESS |
937 LSA_POLICY_VIEW_LOCAL_INFORMATION |
938 LSA_POLICY_LOOKUP_NAMES,
940 NT_STATUS_NOT_OK_RETURN(status);
942 status = rpccli_lsa_LookupNames3(lsa_pipe, mem_ctx,
948 LSA_LOOKUP_NAMES_ALL, /* sure ? */
951 NT_STATUS_NOT_OK_RETURN(status);
953 if (count != 1 || sids.count != 1) {
954 return NT_STATUS_NONE_MAPPED;
957 sid_copy(sid, sids.sids[0].sid);
962 /****************************************************************
963 ****************************************************************/
965 static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
966 struct NetLocalGroupAddMembers *add,
967 struct NetLocalGroupDelMembers *del,
968 struct NetLocalGroupSetMembers *set)
970 struct NetLocalGroupAddMembers *r = NULL;
972 struct rpc_pipe_client *pipe_cli = NULL;
973 struct rpc_pipe_client *lsa_pipe = NULL;
976 struct lsa_String lsa_account_name;
977 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
978 struct dom_sid2 *domain_sid = NULL;
979 struct dom_sid *member_sids = NULL;
982 struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
983 struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
985 struct dom_sid *add_sids = NULL;
986 struct dom_sid *del_sids = NULL;
987 size_t num_add_sids = 0;
988 size_t num_del_sids = 0;
990 if ((!add && !del && !set) || (add && del && set)) {
991 return WERR_INVALID_PARAM;
999 r = (struct NetLocalGroupAddMembers *)del;
1003 r = (struct NetLocalGroupAddMembers *)set;
1006 if (!r->in.group_name) {
1007 return WERR_INVALID_PARAM;
1010 switch (r->in.level) {
1015 return WERR_UNKNOWN_LEVEL;
1018 if (r->in.total_entries == 0 || !r->in.buffer) {
1019 return WERR_INVALID_PARAM;
1022 ZERO_STRUCT(connect_handle);
1023 ZERO_STRUCT(builtin_handle);
1024 ZERO_STRUCT(domain_handle);
1025 ZERO_STRUCT(alias_handle);
1027 member_sids = TALLOC_ZERO_ARRAY(ctx, struct dom_sid,
1028 r->in.total_entries);
1029 W_ERROR_HAVE_NO_MEMORY(member_sids);
1031 switch (r->in.level) {
1033 info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
1034 for (i=0; i < r->in.total_entries; i++) {
1035 sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
1039 info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1045 if (r->in.level == 3) {
1046 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1047 &ndr_table_lsarpc.syntax_id,
1049 if (!W_ERROR_IS_OK(werr)) {
1053 for (i=0; i < r->in.total_entries; i++) {
1054 status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1055 info3[i].lgrmi3_domainandname,
1057 if (!NT_STATUS_IS_OK(status)) {
1058 werr = ntstatus_to_werror(status);
1062 TALLOC_FREE(lsa_pipe);
1065 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1066 &ndr_table_samr.syntax_id,
1068 if (!W_ERROR_IS_OK(werr)) {
1072 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1073 SAMR_ACCESS_LOOKUP_DOMAIN |
1074 SAMR_ACCESS_ENUM_DOMAINS,
1075 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1078 if (!W_ERROR_IS_OK(werr)) {
1082 init_lsa_String(&lsa_account_name, r->in.group_name);
1084 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1087 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1088 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1089 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1090 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1093 if (ctx->disable_policy_handle_cache) {
1094 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1097 if (NT_STATUS_IS_OK(status)) {
1098 goto modify_membership;
1101 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1102 SAMR_ACCESS_ENUM_DOMAINS |
1103 SAMR_ACCESS_LOOKUP_DOMAIN,
1104 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1108 if (!W_ERROR_IS_OK(werr)) {
1112 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1115 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1116 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1117 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1118 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1120 if (!NT_STATUS_IS_OK(status)) {
1121 werr = ntstatus_to_werror(status);
1125 if (ctx->disable_policy_handle_cache) {
1126 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1132 for (i=0; i < r->in.total_entries; i++) {
1133 status = add_sid_to_array_unique(ctx, &member_sids[i],
1136 if (!NT_STATUS_IS_OK(status)) {
1137 werr = ntstatus_to_werror(status);
1144 for (i=0; i < r->in.total_entries; i++) {
1145 status = add_sid_to_array_unique(ctx, &member_sids[i],
1148 if (!NT_STATUS_IS_OK(status)) {
1149 werr = ntstatus_to_werror(status);
1157 struct lsa_SidArray current_sids;
1159 status = rpccli_samr_GetMembersInAlias(pipe_cli, talloc_tos(),
1162 if (!NT_STATUS_IS_OK(status)) {
1163 werr = ntstatus_to_werror(status);
1169 for (i=0; i < r->in.total_entries; i++) {
1170 bool already_member = false;
1171 for (k=0; k < current_sids.num_sids; k++) {
1172 if (sid_equal(&member_sids[i],
1173 current_sids.sids[k].sid)) {
1174 already_member = true;
1178 if (!already_member) {
1179 status = add_sid_to_array_unique(ctx,
1181 &add_sids, &num_add_sids);
1182 if (!NT_STATUS_IS_OK(status)) {
1183 werr = ntstatus_to_werror(status);
1191 for (k=0; k < current_sids.num_sids; k++) {
1192 bool keep_member = false;
1193 for (i=0; i < r->in.total_entries; i++) {
1194 if (sid_equal(&member_sids[i],
1195 current_sids.sids[k].sid)) {
1201 status = add_sid_to_array_unique(ctx,
1202 current_sids.sids[k].sid,
1203 &del_sids, &num_del_sids);
1204 if (!NT_STATUS_IS_OK(status)) {
1205 werr = ntstatus_to_werror(status);
1214 for (i=0; i < num_add_sids; i++) {
1215 status = rpccli_samr_AddAliasMember(pipe_cli, talloc_tos(),
1218 if (!NT_STATUS_IS_OK(status)) {
1219 werr = ntstatus_to_werror(status);
1226 for (i=0; i < num_del_sids; i++) {
1227 status = rpccli_samr_DeleteAliasMember(pipe_cli, talloc_tos(),
1230 if (!NT_STATUS_IS_OK(status)) {
1231 werr = ntstatus_to_werror(status);
1239 if (is_valid_policy_hnd(&alias_handle)) {
1240 rpccli_samr_Close(pipe_cli, talloc_tos(), &alias_handle);
1243 if (ctx->disable_policy_handle_cache) {
1244 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1245 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1246 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1252 /****************************************************************
1253 ****************************************************************/
1255 WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1256 struct NetLocalGroupAddMembers *r)
1258 return NetLocalGroupModifyMembers_r(ctx, r, NULL, NULL);
1261 /****************************************************************
1262 ****************************************************************/
1264 WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1265 struct NetLocalGroupAddMembers *r)
1267 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAddMembers);
1270 /****************************************************************
1271 ****************************************************************/
1273 WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1274 struct NetLocalGroupDelMembers *r)
1276 return NetLocalGroupModifyMembers_r(ctx, NULL, r, NULL);
1279 /****************************************************************
1280 ****************************************************************/
1282 WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1283 struct NetLocalGroupDelMembers *r)
1285 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDelMembers);
1288 /****************************************************************
1289 ****************************************************************/
1291 WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1292 struct NetLocalGroupGetMembers *r)
1294 return WERR_NOT_SUPPORTED;
1297 /****************************************************************
1298 ****************************************************************/
1300 WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1301 struct NetLocalGroupGetMembers *r)
1303 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetMembers);
1306 /****************************************************************
1307 ****************************************************************/
1309 WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1310 struct NetLocalGroupSetMembers *r)
1312 return NetLocalGroupModifyMembers_r(ctx, NULL, NULL, r);
1315 /****************************************************************
1316 ****************************************************************/
1318 WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1319 struct NetLocalGroupSetMembers *r)
1321 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);