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 NTSTATUS 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)
36 struct lsa_String lsa_account_name;
37 struct samr_Ids user_rids, name_types;
39 init_lsa_String(&lsa_account_name, group_name);
41 status = rpccli_samr_LookupNames(pipe_cli, mem_ctx,
47 if (!NT_STATUS_IS_OK(status)) {
51 switch (name_types.ids[0]) {
53 case SID_NAME_WKN_GRP:
56 return NT_STATUS_INVALID_SID;
59 return rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
66 /****************************************************************
67 ****************************************************************/
69 static NTSTATUS libnetapi_samr_open_alias_queryinfo(TALLOC_CTX *mem_ctx,
70 struct rpc_pipe_client *pipe_cli,
71 struct policy_handle *handle,
73 uint32_t access_rights,
74 enum samr_AliasInfoEnum level,
75 union samr_AliasInfo **alias_info)
78 struct policy_handle alias_handle;
79 union samr_AliasInfo *_alias_info = NULL;
81 ZERO_STRUCT(alias_handle);
83 status = rpccli_samr_OpenAlias(pipe_cli, mem_ctx,
88 if (!NT_STATUS_IS_OK(status)) {
92 status = rpccli_samr_QueryAliasInfo(pipe_cli, mem_ctx,
96 if (!NT_STATUS_IS_OK(status)) {
100 *alias_info = _alias_info;
103 if (is_valid_policy_hnd(&alias_handle)) {
104 rpccli_samr_Close(pipe_cli, mem_ctx, &alias_handle);
110 /****************************************************************
111 ****************************************************************/
113 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
114 struct NetLocalGroupAdd *r)
116 struct cli_state *cli = NULL;
117 struct rpc_pipe_client *pipe_cli = NULL;
120 struct lsa_String lsa_account_name;
121 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
122 struct dom_sid2 *domain_sid = NULL;
125 struct LOCALGROUP_INFO_0 *info0 = NULL;
126 struct LOCALGROUP_INFO_1 *info1 = NULL;
128 const char *alias_name = NULL;
131 return WERR_INVALID_PARAM;
134 switch (r->in.level) {
136 info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
137 alias_name = info0->lgrpi0_name;
140 info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
141 alias_name = info1->lgrpi1_name;
144 werr = WERR_UNKNOWN_LEVEL;
148 ZERO_STRUCT(connect_handle);
149 ZERO_STRUCT(builtin_handle);
150 ZERO_STRUCT(domain_handle);
151 ZERO_STRUCT(alias_handle);
153 werr = libnetapi_open_pipe(ctx, r->in.server_name,
154 &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_OPEN_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_OPEN_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, ctx,
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, ctx,
219 ALIASINFODESCRIPTION,
221 if (!NT_STATUS_IS_OK(status)) {
222 werr = ntstatus_to_werror(status);
234 if (is_valid_policy_hnd(&alias_handle)) {
235 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
238 if (ctx->disable_policy_handle_cache) {
239 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
240 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
241 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
247 /****************************************************************
248 ****************************************************************/
250 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
251 struct NetLocalGroupAdd *r)
253 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAdd);
256 /****************************************************************
257 ****************************************************************/
260 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
261 struct NetLocalGroupDel *r)
263 struct cli_state *cli = NULL;
264 struct rpc_pipe_client *pipe_cli = NULL;
267 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
268 struct dom_sid2 *domain_sid = NULL;
270 if (!r->in.group_name) {
271 return WERR_INVALID_PARAM;
274 ZERO_STRUCT(connect_handle);
275 ZERO_STRUCT(builtin_handle);
276 ZERO_STRUCT(domain_handle);
277 ZERO_STRUCT(alias_handle);
279 werr = libnetapi_open_pipe(ctx, r->in.server_name,
280 &ndr_table_samr.syntax_id,
283 if (!W_ERROR_IS_OK(werr)) {
287 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
288 SAMR_ACCESS_OPEN_DOMAIN |
289 SAMR_ACCESS_ENUM_DOMAINS,
290 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
293 if (!W_ERROR_IS_OK(werr)) {
297 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
303 if (ctx->disable_policy_handle_cache) {
304 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
307 if (NT_STATUS_IS_OK(status)) {
311 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
312 SAMR_ACCESS_ENUM_DOMAINS |
313 SAMR_ACCESS_OPEN_DOMAIN,
314 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
315 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
319 if (!W_ERROR_IS_OK(werr)) {
323 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
329 if (ctx->disable_policy_handle_cache) {
330 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
333 if (!NT_STATUS_IS_OK(status)) {
334 werr = ntstatus_to_werror(status);
340 status = rpccli_samr_DeleteDomAlias(pipe_cli, ctx,
342 if (!NT_STATUS_IS_OK(status)) {
343 werr = ntstatus_to_werror(status);
347 ZERO_STRUCT(alias_handle);
356 if (is_valid_policy_hnd(&alias_handle)) {
357 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
360 if (ctx->disable_policy_handle_cache) {
361 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
362 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
363 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
369 /****************************************************************
370 ****************************************************************/
372 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
373 struct NetLocalGroupDel *r)
375 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDel);
378 /****************************************************************
379 ****************************************************************/
381 static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
382 const char *alias_name,
383 struct samr_AliasInfoAll *info,
385 uint32_t *entries_read,
388 struct LOCALGROUP_INFO_0 g0;
389 struct LOCALGROUP_INFO_1 g1;
390 struct LOCALGROUP_INFO_1002 g1002;
394 g0.lgrpi0_name = talloc_strdup(mem_ctx, alias_name);
395 W_ERROR_HAVE_NO_MEMORY(g0.lgrpi0_name);
397 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_0, g0,
398 (struct LOCALGROUP_INFO_0 **)buffer, entries_read);
402 g1.lgrpi1_name = talloc_strdup(mem_ctx, alias_name);
403 g1.lgrpi1_comment = talloc_strdup(mem_ctx, info->description.string);
404 W_ERROR_HAVE_NO_MEMORY(g1.lgrpi1_name);
406 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1, g1,
407 (struct LOCALGROUP_INFO_1 **)buffer, entries_read);
411 g1002.lgrpi1002_comment = talloc_strdup(mem_ctx, info->description.string);
413 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1002, g1002,
414 (struct LOCALGROUP_INFO_1002 **)buffer, entries_read);
418 return WERR_UNKNOWN_LEVEL;
424 /****************************************************************
425 ****************************************************************/
427 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
428 struct NetLocalGroupGetInfo *r)
430 struct cli_state *cli = NULL;
431 struct rpc_pipe_client *pipe_cli = NULL;
434 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
435 struct dom_sid2 *domain_sid = NULL;
436 union samr_AliasInfo *alias_info = NULL;
437 uint32_t entries_read = 0;
439 if (!r->in.group_name) {
440 return WERR_INVALID_PARAM;
443 switch (r->in.level) {
449 return WERR_UNKNOWN_LEVEL;
452 ZERO_STRUCT(connect_handle);
453 ZERO_STRUCT(builtin_handle);
454 ZERO_STRUCT(domain_handle);
455 ZERO_STRUCT(alias_handle);
457 werr = libnetapi_open_pipe(ctx, r->in.server_name,
458 &ndr_table_samr.syntax_id,
461 if (!W_ERROR_IS_OK(werr)) {
465 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
466 SAMR_ACCESS_OPEN_DOMAIN |
467 SAMR_ACCESS_ENUM_DOMAINS,
468 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
471 if (!W_ERROR_IS_OK(werr)) {
475 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
478 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
481 if (ctx->disable_policy_handle_cache) {
482 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
485 if (NT_STATUS_IS_OK(status)) {
489 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
490 SAMR_ACCESS_ENUM_DOMAINS |
491 SAMR_ACCESS_OPEN_DOMAIN,
492 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
493 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
497 if (!W_ERROR_IS_OK(werr)) {
501 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
504 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
507 if (ctx->disable_policy_handle_cache) {
508 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
511 if (!NT_STATUS_IS_OK(status)) {
512 werr = ntstatus_to_werror(status);
517 status = rpccli_samr_QueryAliasInfo(pipe_cli, ctx,
521 if (!NT_STATUS_IS_OK(status)) {
522 werr = ntstatus_to_werror(status);
526 werr = map_alias_info_to_buffer(ctx,
529 r->in.level, &entries_read,
537 if (is_valid_policy_hnd(&alias_handle)) {
538 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
541 if (ctx->disable_policy_handle_cache) {
542 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
543 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
544 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
550 /****************************************************************
551 ****************************************************************/
553 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
554 struct NetLocalGroupGetInfo *r)
556 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetInfo);
559 /****************************************************************
560 ****************************************************************/
562 static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
565 enum samr_AliasInfoEnum *alias_level,
566 union samr_AliasInfo **alias_info)
568 struct LOCALGROUP_INFO_0 *info0;
569 struct LOCALGROUP_INFO_1 *info1;
570 struct LOCALGROUP_INFO_1002 *info1002;
571 union samr_AliasInfo *info = NULL;
573 info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
574 W_ERROR_HAVE_NO_MEMORY(info);
578 info0 = (struct LOCALGROUP_INFO_0 *)buffer;
579 init_lsa_String(&info->name, info0->lgrpi0_name);
580 *alias_level = ALIASINFONAME;
583 info1 = (struct LOCALGROUP_INFO_1 *)buffer;
584 /* group name will be ignored */
585 init_lsa_String(&info->description, info1->lgrpi1_comment);
586 *alias_level = ALIASINFODESCRIPTION;
589 info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
590 init_lsa_String(&info->description, info1002->lgrpi1002_comment);
591 *alias_level = ALIASINFODESCRIPTION;
600 /****************************************************************
601 ****************************************************************/
603 WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
604 struct NetLocalGroupSetInfo *r)
606 struct cli_state *cli = NULL;
607 struct rpc_pipe_client *pipe_cli = NULL;
610 struct lsa_String lsa_account_name;
611 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
612 struct dom_sid2 *domain_sid = NULL;
613 enum samr_AliasInfoEnum alias_level = 0;
614 union samr_AliasInfo *alias_info = NULL;
616 if (!r->in.group_name) {
617 return WERR_INVALID_PARAM;
620 switch (r->in.level) {
626 return WERR_UNKNOWN_LEVEL;
629 ZERO_STRUCT(connect_handle);
630 ZERO_STRUCT(builtin_handle);
631 ZERO_STRUCT(domain_handle);
632 ZERO_STRUCT(alias_handle);
634 werr = libnetapi_open_pipe(ctx, r->in.server_name,
635 &ndr_table_samr.syntax_id,
638 if (!W_ERROR_IS_OK(werr)) {
642 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
643 SAMR_ACCESS_OPEN_DOMAIN |
644 SAMR_ACCESS_ENUM_DOMAINS,
645 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
648 if (!W_ERROR_IS_OK(werr)) {
652 init_lsa_String(&lsa_account_name, r->in.group_name);
654 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
657 SAMR_ALIAS_ACCESS_SET_INFO,
660 if (ctx->disable_policy_handle_cache) {
661 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
664 if (NT_STATUS_IS_OK(status)) {
668 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
669 SAMR_ACCESS_ENUM_DOMAINS |
670 SAMR_ACCESS_OPEN_DOMAIN,
671 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
675 if (!W_ERROR_IS_OK(werr)) {
679 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
682 SAMR_ALIAS_ACCESS_SET_INFO,
684 if (!NT_STATUS_IS_OK(status)) {
685 werr = ntstatus_to_werror(status);
689 if (ctx->disable_policy_handle_cache) {
690 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
695 werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer,
696 &alias_level, &alias_info);
697 if (!W_ERROR_IS_OK(werr)) {
701 status = rpccli_samr_SetAliasInfo(pipe_cli, ctx,
705 if (!NT_STATUS_IS_OK(status)) {
706 werr = ntstatus_to_werror(status);
717 if (is_valid_policy_hnd(&alias_handle)) {
718 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
721 if (ctx->disable_policy_handle_cache) {
722 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
723 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
724 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
730 /****************************************************************
731 ****************************************************************/
733 WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
734 struct NetLocalGroupSetInfo *r)
736 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetInfo);
739 /****************************************************************
740 ****************************************************************/
742 WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
743 struct NetLocalGroupEnum *r)
745 struct cli_state *cli = NULL;
746 struct rpc_pipe_client *pipe_cli = NULL;
749 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
750 struct dom_sid2 *domain_sid = NULL;
751 uint32_t entries_read = 0;
752 union samr_DomainInfo *domain_info = NULL;
753 union samr_DomainInfo *builtin_info = NULL;
754 struct samr_SamArray *domain_sam_array = NULL;
755 struct samr_SamArray *builtin_sam_array = NULL;
758 if (!r->out.buffer) {
759 return WERR_INVALID_PARAM;
762 switch (r->in.level) {
767 return WERR_UNKNOWN_LEVEL;
770 if (r->out.total_entries) {
771 *r->out.total_entries = 0;
773 if (r->out.entries_read) {
774 *r->out.entries_read = 0;
777 ZERO_STRUCT(connect_handle);
778 ZERO_STRUCT(builtin_handle);
779 ZERO_STRUCT(domain_handle);
780 ZERO_STRUCT(alias_handle);
782 werr = libnetapi_open_pipe(ctx, r->in.server_name,
783 &ndr_table_samr.syntax_id,
786 if (!W_ERROR_IS_OK(werr)) {
790 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
791 SAMR_ACCESS_OPEN_DOMAIN |
792 SAMR_ACCESS_ENUM_DOMAINS,
793 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
794 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
795 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
798 if (!W_ERROR_IS_OK(werr)) {
802 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
803 SAMR_ACCESS_OPEN_DOMAIN |
804 SAMR_ACCESS_ENUM_DOMAINS,
805 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
806 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
807 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
811 if (!W_ERROR_IS_OK(werr)) {
815 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
819 if (!NT_STATUS_IS_OK(status)) {
820 werr = ntstatus_to_werror(status);
824 if (r->out.total_entries) {
825 *r->out.total_entries += builtin_info->info2.num_aliases;
828 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
832 if (!NT_STATUS_IS_OK(status)) {
833 werr = ntstatus_to_werror(status);
837 if (r->out.total_entries) {
838 *r->out.total_entries += domain_info->info2.num_aliases;
841 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
847 if (!NT_STATUS_IS_OK(status)) {
848 werr = ntstatus_to_werror(status);
852 for (i=0; i<builtin_sam_array->count; i++) {
853 union samr_AliasInfo *alias_info = NULL;
855 if (r->in.level == 1) {
857 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
859 builtin_sam_array->entries[i].idx,
860 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
863 if (!NT_STATUS_IS_OK(status)) {
864 werr = ntstatus_to_werror(status);
869 werr = map_alias_info_to_buffer(ctx,
870 builtin_sam_array->entries[i].name.string,
871 alias_info ? &alias_info->all : NULL,
877 status = rpccli_samr_EnumDomainAliases(pipe_cli, ctx,
883 if (!NT_STATUS_IS_OK(status)) {
884 werr = ntstatus_to_werror(status);
888 for (i=0; i<domain_sam_array->count; i++) {
890 union samr_AliasInfo *alias_info = NULL;
892 if (r->in.level == 1) {
893 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
895 domain_sam_array->entries[i].idx,
896 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
899 if (!NT_STATUS_IS_OK(status)) {
900 werr = ntstatus_to_werror(status);
905 werr = map_alias_info_to_buffer(ctx,
906 domain_sam_array->entries[i].name.string,
907 alias_info ? &alias_info->all : NULL,
918 if (ctx->disable_policy_handle_cache) {
919 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
920 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
921 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
927 /****************************************************************
928 ****************************************************************/
930 WERROR NetLocalGroupEnum_l(struct libnetapi_ctx *ctx,
931 struct NetLocalGroupEnum *r)
933 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupEnum);
936 /****************************************************************
937 ****************************************************************/
939 static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
940 struct rpc_pipe_client *lsa_pipe,
945 struct policy_handle lsa_handle;
947 struct lsa_RefDomainList *domains = NULL;
948 struct lsa_TransSidArray3 sids;
951 struct lsa_String names;
952 uint32_t num_names = 1;
955 return NT_STATUS_INVALID_PARAMETER;
960 init_lsa_String(&names, name);
962 status = rpccli_lsa_open_policy2(lsa_pipe, mem_ctx,
964 STD_RIGHT_READ_CONTROL_ACCESS |
965 LSA_POLICY_VIEW_LOCAL_INFORMATION |
966 LSA_POLICY_LOOKUP_NAMES,
968 NT_STATUS_NOT_OK_RETURN(status);
970 status = rpccli_lsa_LookupNames3(lsa_pipe, mem_ctx,
976 LSA_LOOKUP_NAMES_ALL, /* sure ? */
979 NT_STATUS_NOT_OK_RETURN(status);
981 if (count != 1 || sids.count != 1) {
982 return NT_STATUS_NONE_MAPPED;
985 sid_copy(sid, sids.sids[0].sid);
990 /****************************************************************
991 ****************************************************************/
993 static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
994 struct NetLocalGroupAddMembers *add,
995 struct NetLocalGroupDelMembers *del,
996 struct NetLocalGroupSetMembers *set)
998 struct NetLocalGroupAddMembers *r = NULL;
1000 struct cli_state *cli = NULL;
1001 struct rpc_pipe_client *pipe_cli = NULL;
1002 struct rpc_pipe_client *lsa_pipe = NULL;
1005 struct lsa_String lsa_account_name;
1006 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
1007 struct dom_sid2 *domain_sid = NULL;
1008 struct dom_sid *member_sids = NULL;
1011 struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
1012 struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
1014 struct dom_sid *add_sids = NULL;
1015 struct dom_sid *del_sids = NULL;
1016 size_t num_add_sids = 0;
1017 size_t num_del_sids = 0;
1019 if ((!add && !del && !set) || (add && del && set)) {
1020 return WERR_INVALID_PARAM;
1028 r = (struct NetLocalGroupAddMembers *)del;
1032 r = (struct NetLocalGroupAddMembers *)set;
1035 if (!r->in.group_name) {
1036 return WERR_INVALID_PARAM;
1039 switch (r->in.level) {
1044 return WERR_UNKNOWN_LEVEL;
1047 if (r->in.total_entries == 0 || !r->in.buffer) {
1048 return WERR_INVALID_PARAM;
1051 ZERO_STRUCT(connect_handle);
1052 ZERO_STRUCT(builtin_handle);
1053 ZERO_STRUCT(domain_handle);
1054 ZERO_STRUCT(alias_handle);
1056 member_sids = TALLOC_ZERO_ARRAY(ctx, struct dom_sid,
1057 r->in.total_entries);
1058 W_ERROR_HAVE_NO_MEMORY(member_sids);
1060 switch (r->in.level) {
1062 info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
1063 for (i=0; i < r->in.total_entries; i++) {
1064 sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
1068 info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1074 if (r->in.level == 3) {
1075 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1076 &ndr_table_lsarpc.syntax_id,
1079 if (!W_ERROR_IS_OK(werr)) {
1083 for (i=0; i < r->in.total_entries; i++) {
1084 status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1085 info3[i].lgrmi3_domainandname,
1087 if (!NT_STATUS_IS_OK(status)) {
1088 werr = ntstatus_to_werror(status);
1092 TALLOC_FREE(lsa_pipe);
1095 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1096 &ndr_table_samr.syntax_id,
1099 if (!W_ERROR_IS_OK(werr)) {
1103 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1104 SAMR_ACCESS_OPEN_DOMAIN |
1105 SAMR_ACCESS_ENUM_DOMAINS,
1106 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1109 if (!W_ERROR_IS_OK(werr)) {
1113 init_lsa_String(&lsa_account_name, r->in.group_name);
1115 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1118 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1119 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1120 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1121 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1124 if (ctx->disable_policy_handle_cache) {
1125 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1128 if (NT_STATUS_IS_OK(status)) {
1129 goto modify_membership;
1132 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1133 SAMR_ACCESS_ENUM_DOMAINS |
1134 SAMR_ACCESS_OPEN_DOMAIN,
1135 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1139 if (!W_ERROR_IS_OK(werr)) {
1143 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1146 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1147 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1148 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1149 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1151 if (!NT_STATUS_IS_OK(status)) {
1152 werr = ntstatus_to_werror(status);
1156 if (ctx->disable_policy_handle_cache) {
1157 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1163 for (i=0; i < r->in.total_entries; i++) {
1164 status = add_sid_to_array_unique(ctx, &member_sids[i],
1167 if (!NT_STATUS_IS_OK(status)) {
1168 werr = ntstatus_to_werror(status);
1175 for (i=0; i < r->in.total_entries; i++) {
1176 status = add_sid_to_array_unique(ctx, &member_sids[i],
1179 if (!NT_STATUS_IS_OK(status)) {
1180 werr = ntstatus_to_werror(status);
1188 struct lsa_SidArray current_sids;
1190 status = rpccli_samr_GetMembersInAlias(pipe_cli, ctx,
1193 if (!NT_STATUS_IS_OK(status)) {
1194 werr = ntstatus_to_werror(status);
1200 for (i=0; i < r->in.total_entries; i++) {
1201 bool already_member = false;
1202 for (k=0; k < current_sids.num_sids; k++) {
1203 if (sid_equal(&member_sids[i],
1204 current_sids.sids[k].sid)) {
1205 already_member = true;
1209 if (!already_member) {
1210 status = add_sid_to_array_unique(ctx,
1212 &add_sids, &num_add_sids);
1213 if (!NT_STATUS_IS_OK(status)) {
1214 werr = ntstatus_to_werror(status);
1222 for (k=0; k < current_sids.num_sids; k++) {
1223 bool keep_member = false;
1224 for (i=0; i < r->in.total_entries; i++) {
1225 if (sid_equal(&member_sids[i],
1226 current_sids.sids[k].sid)) {
1232 status = add_sid_to_array_unique(ctx,
1233 current_sids.sids[k].sid,
1234 &del_sids, &num_del_sids);
1235 if (!NT_STATUS_IS_OK(status)) {
1236 werr = ntstatus_to_werror(status);
1245 for (i=0; i < num_add_sids; i++) {
1246 status = rpccli_samr_AddAliasMember(pipe_cli, ctx,
1249 if (!NT_STATUS_IS_OK(status)) {
1250 werr = ntstatus_to_werror(status);
1257 for (i=0; i < num_del_sids; i++) {
1258 status = rpccli_samr_DeleteAliasMember(pipe_cli, ctx,
1261 if (!NT_STATUS_IS_OK(status)) {
1262 werr = ntstatus_to_werror(status);
1274 if (is_valid_policy_hnd(&alias_handle)) {
1275 rpccli_samr_Close(pipe_cli, ctx, &alias_handle);
1278 if (ctx->disable_policy_handle_cache) {
1279 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1280 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1281 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1287 /****************************************************************
1288 ****************************************************************/
1290 WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1291 struct NetLocalGroupAddMembers *r)
1293 return NetLocalGroupModifyMembers_r(ctx, r, NULL, NULL);
1296 /****************************************************************
1297 ****************************************************************/
1299 WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1300 struct NetLocalGroupAddMembers *r)
1302 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAddMembers);
1305 /****************************************************************
1306 ****************************************************************/
1308 WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1309 struct NetLocalGroupDelMembers *r)
1311 return NetLocalGroupModifyMembers_r(ctx, NULL, r, NULL);
1314 /****************************************************************
1315 ****************************************************************/
1317 WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1318 struct NetLocalGroupDelMembers *r)
1320 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDelMembers);
1323 /****************************************************************
1324 ****************************************************************/
1326 WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1327 struct NetLocalGroupGetMembers *r)
1329 return WERR_NOT_SUPPORTED;
1332 /****************************************************************
1333 ****************************************************************/
1335 WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1336 struct NetLocalGroupGetMembers *r)
1338 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetMembers);
1341 /****************************************************************
1342 ****************************************************************/
1344 WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1345 struct NetLocalGroupSetMembers *r)
1347 return NetLocalGroupModifyMembers_r(ctx, NULL, NULL, r);
1350 /****************************************************************
1351 ****************************************************************/
1353 WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1354 struct NetLocalGroupSetMembers *r)
1356 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);