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"
30 static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
31 struct rpc_pipe_client *pipe_cli,
32 struct policy_handle *domain_handle,
33 const char *group_name,
34 uint32_t access_rights,
35 struct policy_handle *alias_handle)
39 struct lsa_String lsa_account_name;
40 struct samr_Ids user_rids, name_types;
42 init_lsa_String(&lsa_account_name, group_name);
44 status = rpccli_samr_LookupNames(pipe_cli, mem_ctx,
50 if (!NT_STATUS_IS_OK(status)) {
54 switch (name_types.ids[0]) {
56 case SID_NAME_WKN_GRP:
59 return NT_STATUS_INVALID_SID;
62 return rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
69 /****************************************************************
70 ****************************************************************/
72 static NTSTATUS libnetapi_samr_open_alias_queryinfo(TALLOC_CTX *mem_ctx,
73 struct rpc_pipe_client *pipe_cli,
74 struct policy_handle *handle,
76 uint32_t access_rights,
77 enum samr_AliasInfoEnum level,
78 union samr_AliasInfo **alias_info)
81 struct policy_handle alias_handle;
82 union samr_AliasInfo *_alias_info = NULL;
84 ZERO_STRUCT(alias_handle);
86 status = rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
91 if (!NT_STATUS_IS_OK(status)) {
95 status = rpccli_samr_QueryAliasInfo(pipe_cli, mem_ctx,
99 if (!NT_STATUS_IS_OK(status)) {
103 *alias_info = _alias_info;
106 if (is_valid_policy_hnd(&alias_handle)) {
107 rpccli_samr_Close(pipe_cli, mem_ctx, &alias_handle);
113 /****************************************************************
114 ****************************************************************/
116 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
117 struct NetLocalGroupAdd *r)
119 struct rpc_pipe_client *pipe_cli = NULL;
122 struct lsa_String lsa_account_name;
123 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
124 struct dom_sid2 *domain_sid = NULL;
127 struct LOCALGROUP_INFO_0 *info0 = NULL;
128 struct LOCALGROUP_INFO_1 *info1 = NULL;
130 const char *alias_name = NULL;
133 return WERR_INVALID_PARAM;
136 switch (r->in.level) {
138 info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
139 alias_name = info0->lgrpi0_name;
142 info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
143 alias_name = info1->lgrpi1_name;
146 werr = WERR_UNKNOWN_LEVEL;
150 ZERO_STRUCT(connect_handle);
151 ZERO_STRUCT(builtin_handle);
152 ZERO_STRUCT(domain_handle);
153 ZERO_STRUCT(alias_handle);
155 werr = libnetapi_open_pipe(ctx, r->in.server_name,
156 &ndr_table_samr.syntax_id,
158 if (!W_ERROR_IS_OK(werr)) {
162 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
163 SAMR_ACCESS_LOOKUP_DOMAIN |
164 SAMR_ACCESS_ENUM_DOMAINS,
165 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
168 if (!W_ERROR_IS_OK(werr)) {
172 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
175 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
177 if (ctx->disable_policy_handle_cache) {
178 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
181 if (NT_STATUS_IS_OK(status)) {
182 werr = WERR_ALIAS_EXISTS;
186 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
187 SAMR_ACCESS_ENUM_DOMAINS |
188 SAMR_ACCESS_LOOKUP_DOMAIN,
189 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
190 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
194 if (!W_ERROR_IS_OK(werr)) {
198 init_lsa_String(&lsa_account_name, alias_name);
200 status = rpccli_samr_CreateDomAlias(pipe_cli, ctx,
204 SAMR_ALIAS_ACCESS_SET_INFO,
207 if (!NT_STATUS_IS_OK(status)) {
208 werr = ntstatus_to_werror(status);
212 if (r->in.level == 1 && info1->lgrpi1_comment) {
214 union samr_AliasInfo alias_info;
216 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
218 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
220 ALIASINFODESCRIPTION,
222 if (!NT_STATUS_IS_OK(status)) {
223 werr = ntstatus_to_werror(status);
231 if (is_valid_policy_hnd(&alias_handle)) {
232 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
235 if (ctx->disable_policy_handle_cache) {
236 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
237 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
238 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
244 /****************************************************************
245 ****************************************************************/
247 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
248 struct NetLocalGroupAdd *r)
250 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAdd);
253 /****************************************************************
254 ****************************************************************/
257 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
258 struct NetLocalGroupDel *r)
260 struct rpc_pipe_client *pipe_cli = NULL;
263 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
264 struct dom_sid2 *domain_sid = NULL;
266 if (!r->in.group_name) {
267 return WERR_INVALID_PARAM;
270 ZERO_STRUCT(connect_handle);
271 ZERO_STRUCT(builtin_handle);
272 ZERO_STRUCT(domain_handle);
273 ZERO_STRUCT(alias_handle);
275 werr = libnetapi_open_pipe(ctx, r->in.server_name,
276 &ndr_table_samr.syntax_id,
278 if (!W_ERROR_IS_OK(werr)) {
282 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
283 SAMR_ACCESS_LOOKUP_DOMAIN |
284 SAMR_ACCESS_ENUM_DOMAINS,
285 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
288 if (!W_ERROR_IS_OK(werr)) {
292 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
298 if (ctx->disable_policy_handle_cache) {
299 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
302 if (NT_STATUS_IS_OK(status)) {
306 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
307 SAMR_ACCESS_ENUM_DOMAINS |
308 SAMR_ACCESS_LOOKUP_DOMAIN,
309 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
310 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
314 if (!W_ERROR_IS_OK(werr)) {
318 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
324 if (ctx->disable_policy_handle_cache) {
325 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
328 if (!NT_STATUS_IS_OK(status)) {
329 werr = ntstatus_to_werror(status);
335 status = rpccli_samr_DeleteDomAlias(pipe_cli, ctx,
337 if (!NT_STATUS_IS_OK(status)) {
338 werr = ntstatus_to_werror(status);
342 ZERO_STRUCT(alias_handle);
347 if (is_valid_policy_hnd(&alias_handle)) {
348 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
351 if (ctx->disable_policy_handle_cache) {
352 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
353 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
354 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
360 /****************************************************************
361 ****************************************************************/
363 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
364 struct NetLocalGroupDel *r)
366 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDel);
369 /****************************************************************
370 ****************************************************************/
372 static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
373 const char *alias_name,
374 struct samr_AliasInfoAll *info,
376 uint32_t *entries_read,
379 struct LOCALGROUP_INFO_0 g0;
380 struct LOCALGROUP_INFO_1 g1;
381 struct LOCALGROUP_INFO_1002 g1002;
385 g0.lgrpi0_name = talloc_strdup(mem_ctx, alias_name);
386 W_ERROR_HAVE_NO_MEMORY(g0.lgrpi0_name);
388 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_0, g0,
389 (struct LOCALGROUP_INFO_0 **)buffer, entries_read);
393 g1.lgrpi1_name = talloc_strdup(mem_ctx, alias_name);
394 g1.lgrpi1_comment = talloc_strdup(mem_ctx, info->description.string);
395 W_ERROR_HAVE_NO_MEMORY(g1.lgrpi1_name);
397 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1, g1,
398 (struct LOCALGROUP_INFO_1 **)buffer, entries_read);
402 g1002.lgrpi1002_comment = talloc_strdup(mem_ctx, info->description.string);
404 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1002, g1002,
405 (struct LOCALGROUP_INFO_1002 **)buffer, entries_read);
409 return WERR_UNKNOWN_LEVEL;
415 /****************************************************************
416 ****************************************************************/
418 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
419 struct NetLocalGroupGetInfo *r)
421 struct rpc_pipe_client *pipe_cli = NULL;
424 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
425 struct dom_sid2 *domain_sid = NULL;
426 union samr_AliasInfo *alias_info = NULL;
427 uint32_t entries_read = 0;
429 if (!r->in.group_name) {
430 return WERR_INVALID_PARAM;
433 switch (r->in.level) {
439 return WERR_UNKNOWN_LEVEL;
442 ZERO_STRUCT(connect_handle);
443 ZERO_STRUCT(builtin_handle);
444 ZERO_STRUCT(domain_handle);
445 ZERO_STRUCT(alias_handle);
447 werr = libnetapi_open_pipe(ctx, r->in.server_name,
448 &ndr_table_samr.syntax_id,
450 if (!W_ERROR_IS_OK(werr)) {
454 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
455 SAMR_ACCESS_LOOKUP_DOMAIN |
456 SAMR_ACCESS_ENUM_DOMAINS,
457 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
460 if (!W_ERROR_IS_OK(werr)) {
464 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
467 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
470 if (ctx->disable_policy_handle_cache) {
471 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
474 if (NT_STATUS_IS_OK(status)) {
478 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
479 SAMR_ACCESS_ENUM_DOMAINS |
480 SAMR_ACCESS_LOOKUP_DOMAIN,
481 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
482 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
486 if (!W_ERROR_IS_OK(werr)) {
490 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
493 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
496 if (ctx->disable_policy_handle_cache) {
497 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
500 if (!NT_STATUS_IS_OK(status)) {
501 werr = ntstatus_to_werror(status);
506 status = rpccli_samr_QueryAliasInfo(pipe_cli, ctx,
510 if (!NT_STATUS_IS_OK(status)) {
511 werr = ntstatus_to_werror(status);
515 werr = map_alias_info_to_buffer(ctx,
518 r->in.level, &entries_read,
522 if (is_valid_policy_hnd(&alias_handle)) {
523 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
526 if (ctx->disable_policy_handle_cache) {
527 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
528 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
529 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
535 /****************************************************************
536 ****************************************************************/
538 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
539 struct NetLocalGroupGetInfo *r)
541 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetInfo);
544 /****************************************************************
545 ****************************************************************/
547 static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
550 enum samr_AliasInfoEnum *alias_level,
551 union samr_AliasInfo **alias_info)
553 struct LOCALGROUP_INFO_0 *info0;
554 struct LOCALGROUP_INFO_1 *info1;
555 struct LOCALGROUP_INFO_1002 *info1002;
556 union samr_AliasInfo *info = NULL;
558 info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
559 W_ERROR_HAVE_NO_MEMORY(info);
563 info0 = (struct LOCALGROUP_INFO_0 *)buffer;
564 init_lsa_String(&info->name, info0->lgrpi0_name);
565 *alias_level = ALIASINFONAME;
568 info1 = (struct LOCALGROUP_INFO_1 *)buffer;
569 /* group name will be ignored */
570 init_lsa_String(&info->description, info1->lgrpi1_comment);
571 *alias_level = ALIASINFODESCRIPTION;
574 info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
575 init_lsa_String(&info->description, info1002->lgrpi1002_comment);
576 *alias_level = ALIASINFODESCRIPTION;
585 /****************************************************************
586 ****************************************************************/
588 WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
589 struct NetLocalGroupSetInfo *r)
591 struct rpc_pipe_client *pipe_cli = NULL;
594 struct lsa_String lsa_account_name;
595 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
596 struct dom_sid2 *domain_sid = NULL;
597 enum samr_AliasInfoEnum alias_level = 0;
598 union samr_AliasInfo *alias_info = NULL;
600 if (!r->in.group_name) {
601 return WERR_INVALID_PARAM;
604 switch (r->in.level) {
610 return WERR_UNKNOWN_LEVEL;
613 ZERO_STRUCT(connect_handle);
614 ZERO_STRUCT(builtin_handle);
615 ZERO_STRUCT(domain_handle);
616 ZERO_STRUCT(alias_handle);
618 werr = libnetapi_open_pipe(ctx, r->in.server_name,
619 &ndr_table_samr.syntax_id,
621 if (!W_ERROR_IS_OK(werr)) {
625 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
626 SAMR_ACCESS_LOOKUP_DOMAIN |
627 SAMR_ACCESS_ENUM_DOMAINS,
628 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
631 if (!W_ERROR_IS_OK(werr)) {
635 init_lsa_String(&lsa_account_name, r->in.group_name);
637 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
640 SAMR_ALIAS_ACCESS_SET_INFO,
643 if (ctx->disable_policy_handle_cache) {
644 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
647 if (NT_STATUS_IS_OK(status)) {
651 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
652 SAMR_ACCESS_ENUM_DOMAINS |
653 SAMR_ACCESS_LOOKUP_DOMAIN,
654 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
658 if (!W_ERROR_IS_OK(werr)) {
662 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
665 SAMR_ALIAS_ACCESS_SET_INFO,
667 if (!NT_STATUS_IS_OK(status)) {
668 werr = ntstatus_to_werror(status);
672 if (ctx->disable_policy_handle_cache) {
673 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
678 werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer,
679 &alias_level, &alias_info);
680 if (!W_ERROR_IS_OK(werr)) {
684 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
688 if (!NT_STATUS_IS_OK(status)) {
689 werr = ntstatus_to_werror(status);
696 if (is_valid_policy_hnd(&alias_handle)) {
697 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
700 if (ctx->disable_policy_handle_cache) {
701 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
702 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
703 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
709 /****************************************************************
710 ****************************************************************/
712 WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
713 struct NetLocalGroupSetInfo *r)
715 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetInfo);
718 /****************************************************************
719 ****************************************************************/
721 WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
722 struct NetLocalGroupEnum *r)
724 struct rpc_pipe_client *pipe_cli = NULL;
727 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
728 struct dom_sid2 *domain_sid = NULL;
729 uint32_t entries_read = 0;
730 union samr_DomainInfo *domain_info = NULL;
731 union samr_DomainInfo *builtin_info = NULL;
732 struct samr_SamArray *domain_sam_array = NULL;
733 struct samr_SamArray *builtin_sam_array = NULL;
736 if (!r->out.buffer) {
737 return WERR_INVALID_PARAM;
740 switch (r->in.level) {
745 return WERR_UNKNOWN_LEVEL;
748 if (r->out.total_entries) {
749 *r->out.total_entries = 0;
751 if (r->out.entries_read) {
752 *r->out.entries_read = 0;
755 ZERO_STRUCT(connect_handle);
756 ZERO_STRUCT(builtin_handle);
757 ZERO_STRUCT(domain_handle);
758 ZERO_STRUCT(alias_handle);
760 werr = libnetapi_open_pipe(ctx, r->in.server_name,
761 &ndr_table_samr.syntax_id,
763 if (!W_ERROR_IS_OK(werr)) {
767 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
768 SAMR_ACCESS_LOOKUP_DOMAIN |
769 SAMR_ACCESS_ENUM_DOMAINS,
770 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
771 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
772 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
775 if (!W_ERROR_IS_OK(werr)) {
779 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
780 SAMR_ACCESS_LOOKUP_DOMAIN |
781 SAMR_ACCESS_ENUM_DOMAINS,
782 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
783 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
784 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
788 if (!W_ERROR_IS_OK(werr)) {
792 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
796 if (!NT_STATUS_IS_OK(status)) {
797 werr = ntstatus_to_werror(status);
801 if (r->out.total_entries) {
802 *r->out.total_entries += builtin_info->general.num_aliases;
805 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
809 if (!NT_STATUS_IS_OK(status)) {
810 werr = ntstatus_to_werror(status);
814 if (r->out.total_entries) {
815 *r->out.total_entries += domain_info->general.num_aliases;
818 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
824 if (!NT_STATUS_IS_OK(status)) {
825 werr = ntstatus_to_werror(status);
829 for (i=0; i<builtin_sam_array->count; i++) {
830 union samr_AliasInfo *alias_info = NULL;
832 if (r->in.level == 1) {
834 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
836 builtin_sam_array->entries[i].idx,
837 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
840 if (!NT_STATUS_IS_OK(status)) {
841 werr = ntstatus_to_werror(status);
846 werr = map_alias_info_to_buffer(ctx,
847 builtin_sam_array->entries[i].name.string,
848 alias_info ? &alias_info->all : NULL,
854 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
860 if (!NT_STATUS_IS_OK(status)) {
861 werr = ntstatus_to_werror(status);
865 for (i=0; i<domain_sam_array->count; i++) {
867 union samr_AliasInfo *alias_info = NULL;
869 if (r->in.level == 1) {
870 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
872 domain_sam_array->entries[i].idx,
873 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
876 if (!NT_STATUS_IS_OK(status)) {
877 werr = ntstatus_to_werror(status);
882 werr = map_alias_info_to_buffer(ctx,
883 domain_sam_array->entries[i].name.string,
884 alias_info ? &alias_info->all : NULL,
891 if (ctx->disable_policy_handle_cache) {
892 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
893 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
894 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
900 /****************************************************************
901 ****************************************************************/
903 WERROR NetLocalGroupEnum_l(struct libnetapi_ctx *ctx,
904 struct NetLocalGroupEnum *r)
906 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupEnum);
909 /****************************************************************
910 ****************************************************************/
912 static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
913 struct rpc_pipe_client *lsa_pipe,
918 struct policy_handle lsa_handle;
920 struct lsa_RefDomainList *domains = NULL;
921 struct lsa_TransSidArray3 sids;
924 struct lsa_String names;
925 uint32_t num_names = 1;
928 return NT_STATUS_INVALID_PARAMETER;
933 init_lsa_String(&names, name);
935 status = rpccli_lsa_open_policy2(lsa_pipe, mem_ctx,
937 STD_RIGHT_READ_CONTROL_ACCESS |
938 LSA_POLICY_VIEW_LOCAL_INFORMATION |
939 LSA_POLICY_LOOKUP_NAMES,
941 NT_STATUS_NOT_OK_RETURN(status);
943 status = rpccli_lsa_LookupNames3(lsa_pipe, mem_ctx,
949 LSA_LOOKUP_NAMES_ALL, /* sure ? */
952 NT_STATUS_NOT_OK_RETURN(status);
954 if (count != 1 || sids.count != 1) {
955 return NT_STATUS_NONE_MAPPED;
958 sid_copy(sid, sids.sids[0].sid);
963 /****************************************************************
964 ****************************************************************/
966 static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
967 struct NetLocalGroupAddMembers *add,
968 struct NetLocalGroupDelMembers *del,
969 struct NetLocalGroupSetMembers *set)
971 struct NetLocalGroupAddMembers *r = NULL;
973 struct rpc_pipe_client *pipe_cli = NULL;
974 struct rpc_pipe_client *lsa_pipe = NULL;
977 struct lsa_String lsa_account_name;
978 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
979 struct dom_sid2 *domain_sid = NULL;
980 struct dom_sid *member_sids = NULL;
983 struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
984 struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
986 struct dom_sid *add_sids = NULL;
987 struct dom_sid *del_sids = NULL;
988 size_t num_add_sids = 0;
989 size_t num_del_sids = 0;
991 if ((!add && !del && !set) || (add && del && set)) {
992 return WERR_INVALID_PARAM;
1000 r = (struct NetLocalGroupAddMembers *)del;
1004 r = (struct NetLocalGroupAddMembers *)set;
1007 if (!r->in.group_name) {
1008 return WERR_INVALID_PARAM;
1011 switch (r->in.level) {
1016 return WERR_UNKNOWN_LEVEL;
1019 if (r->in.total_entries == 0 || !r->in.buffer) {
1020 return WERR_INVALID_PARAM;
1023 ZERO_STRUCT(connect_handle);
1024 ZERO_STRUCT(builtin_handle);
1025 ZERO_STRUCT(domain_handle);
1026 ZERO_STRUCT(alias_handle);
1028 member_sids = TALLOC_ZERO_ARRAY(ctx, struct dom_sid,
1029 r->in.total_entries);
1030 W_ERROR_HAVE_NO_MEMORY(member_sids);
1032 switch (r->in.level) {
1034 info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
1035 for (i=0; i < r->in.total_entries; i++) {
1036 sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
1040 info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1046 if (r->in.level == 3) {
1047 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1048 &ndr_table_lsarpc.syntax_id,
1050 if (!W_ERROR_IS_OK(werr)) {
1054 for (i=0; i < r->in.total_entries; i++) {
1055 status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1056 info3[i].lgrmi3_domainandname,
1058 if (!NT_STATUS_IS_OK(status)) {
1059 werr = ntstatus_to_werror(status);
1063 TALLOC_FREE(lsa_pipe);
1066 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1067 &ndr_table_samr.syntax_id,
1069 if (!W_ERROR_IS_OK(werr)) {
1073 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1074 SAMR_ACCESS_LOOKUP_DOMAIN |
1075 SAMR_ACCESS_ENUM_DOMAINS,
1076 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1079 if (!W_ERROR_IS_OK(werr)) {
1083 init_lsa_String(&lsa_account_name, r->in.group_name);
1085 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1088 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1089 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1090 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1091 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1094 if (ctx->disable_policy_handle_cache) {
1095 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1098 if (NT_STATUS_IS_OK(status)) {
1099 goto modify_membership;
1102 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1103 SAMR_ACCESS_ENUM_DOMAINS |
1104 SAMR_ACCESS_LOOKUP_DOMAIN,
1105 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1109 if (!W_ERROR_IS_OK(werr)) {
1113 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1116 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1117 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1118 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1119 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1121 if (!NT_STATUS_IS_OK(status)) {
1122 werr = ntstatus_to_werror(status);
1126 if (ctx->disable_policy_handle_cache) {
1127 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1133 for (i=0; i < r->in.total_entries; i++) {
1134 status = add_sid_to_array_unique(ctx, &member_sids[i],
1137 if (!NT_STATUS_IS_OK(status)) {
1138 werr = ntstatus_to_werror(status);
1145 for (i=0; i < r->in.total_entries; i++) {
1146 status = add_sid_to_array_unique(ctx, &member_sids[i],
1149 if (!NT_STATUS_IS_OK(status)) {
1150 werr = ntstatus_to_werror(status);
1158 struct lsa_SidArray current_sids;
1160 status = rpccli_samr_GetMembersInAlias(pipe_cli, ctx,
1163 if (!NT_STATUS_IS_OK(status)) {
1164 werr = ntstatus_to_werror(status);
1170 for (i=0; i < r->in.total_entries; i++) {
1171 bool already_member = false;
1172 for (k=0; k < current_sids.num_sids; k++) {
1173 if (sid_equal(&member_sids[i],
1174 current_sids.sids[k].sid)) {
1175 already_member = true;
1179 if (!already_member) {
1180 status = add_sid_to_array_unique(ctx,
1182 &add_sids, &num_add_sids);
1183 if (!NT_STATUS_IS_OK(status)) {
1184 werr = ntstatus_to_werror(status);
1192 for (k=0; k < current_sids.num_sids; k++) {
1193 bool keep_member = false;
1194 for (i=0; i < r->in.total_entries; i++) {
1195 if (sid_equal(&member_sids[i],
1196 current_sids.sids[k].sid)) {
1202 status = add_sid_to_array_unique(ctx,
1203 current_sids.sids[k].sid,
1204 &del_sids, &num_del_sids);
1205 if (!NT_STATUS_IS_OK(status)) {
1206 werr = ntstatus_to_werror(status);
1215 for (i=0; i < num_add_sids; i++) {
1216 status = rpccli_samr_AddAliasMember(pipe_cli, ctx,
1219 if (!NT_STATUS_IS_OK(status)) {
1220 werr = ntstatus_to_werror(status);
1227 for (i=0; i < num_del_sids; i++) {
1228 status = rpccli_samr_DeleteAliasMember(pipe_cli, ctx,
1231 if (!NT_STATUS_IS_OK(status)) {
1232 werr = ntstatus_to_werror(status);
1240 if (is_valid_policy_hnd(&alias_handle)) {
1241 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
1244 if (ctx->disable_policy_handle_cache) {
1245 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1246 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1247 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1253 /****************************************************************
1254 ****************************************************************/
1256 WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1257 struct NetLocalGroupAddMembers *r)
1259 return NetLocalGroupModifyMembers_r(ctx, r, NULL, NULL);
1262 /****************************************************************
1263 ****************************************************************/
1265 WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1266 struct NetLocalGroupAddMembers *r)
1268 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAddMembers);
1271 /****************************************************************
1272 ****************************************************************/
1274 WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1275 struct NetLocalGroupDelMembers *r)
1277 return NetLocalGroupModifyMembers_r(ctx, NULL, r, NULL);
1280 /****************************************************************
1281 ****************************************************************/
1283 WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1284 struct NetLocalGroupDelMembers *r)
1286 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDelMembers);
1289 /****************************************************************
1290 ****************************************************************/
1292 WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1293 struct NetLocalGroupGetMembers *r)
1295 return WERR_NOT_SUPPORTED;
1298 /****************************************************************
1299 ****************************************************************/
1301 WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1302 struct NetLocalGroupGetMembers *r)
1304 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetMembers);
1307 /****************************************************************
1308 ****************************************************************/
1310 WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1311 struct NetLocalGroupSetMembers *r)
1313 return NetLocalGroupModifyMembers_r(ctx, NULL, NULL, r);
1316 /****************************************************************
1317 ****************************************************************/
1319 WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1320 struct NetLocalGroupSetMembers *r)
1322 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);