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 "rpc_client/rpc_client.h"
27 #include "../librpc/gen_ndr/ndr_samr_c.h"
28 #include "../librpc/gen_ndr/ndr_lsa_c.h"
29 #include "rpc_client/cli_lsarpc.h"
30 #include "rpc_client/init_lsa.h"
31 #include "../libcli/security/security.h"
33 static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
34 struct rpc_pipe_client *pipe_cli,
35 struct policy_handle *domain_handle,
36 const char *group_name,
37 uint32_t access_rights,
38 struct policy_handle *alias_handle)
40 NTSTATUS status, result;
42 struct lsa_String lsa_account_name;
43 struct samr_Ids user_rids, name_types;
44 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
46 init_lsa_String(&lsa_account_name, group_name);
48 status = dcerpc_samr_LookupNames(b, mem_ctx,
55 if (!NT_STATUS_IS_OK(status)) {
58 if (!NT_STATUS_IS_OK(result)) {
61 if (user_rids.count != 1) {
62 return NT_STATUS_INVALID_NETWORK_RESPONSE;
64 if (name_types.count != 1) {
65 return NT_STATUS_INVALID_NETWORK_RESPONSE;
68 switch (name_types.ids[0]) {
70 case SID_NAME_WKN_GRP:
73 return NT_STATUS_INVALID_SID;
76 status = dcerpc_samr_OpenAlias(b, mem_ctx,
82 if (!NT_STATUS_IS_OK(status)) {
89 /****************************************************************
90 ****************************************************************/
92 static NTSTATUS libnetapi_samr_open_alias_queryinfo(TALLOC_CTX *mem_ctx,
93 struct rpc_pipe_client *pipe_cli,
94 struct policy_handle *handle,
96 uint32_t access_rights,
97 enum samr_AliasInfoEnum level,
98 union samr_AliasInfo **alias_info)
100 NTSTATUS status, result;
101 struct policy_handle alias_handle;
102 union samr_AliasInfo *_alias_info = NULL;
103 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
105 ZERO_STRUCT(alias_handle);
107 status = dcerpc_samr_OpenAlias(b, mem_ctx,
113 if (!NT_STATUS_IS_OK(status)) {
116 if (!NT_STATUS_IS_OK(result)) {
121 status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
126 if (!NT_STATUS_IS_OK(status)) {
129 if (!NT_STATUS_IS_OK(result)) {
134 *alias_info = _alias_info;
137 if (is_valid_policy_hnd(&alias_handle)) {
138 dcerpc_samr_Close(b, mem_ctx, &alias_handle, &result);
144 /****************************************************************
145 ****************************************************************/
147 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
148 struct NetLocalGroupAdd *r)
150 struct rpc_pipe_client *pipe_cli = NULL;
151 NTSTATUS status, result;
153 struct lsa_String lsa_account_name;
154 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
155 struct dom_sid2 *domain_sid = NULL;
157 struct dcerpc_binding_handle *b = NULL;
159 struct LOCALGROUP_INFO_0 *info0 = NULL;
160 struct LOCALGROUP_INFO_1 *info1 = NULL;
162 const char *alias_name = NULL;
165 return WERR_INVALID_PARAMETER;
168 ZERO_STRUCT(connect_handle);
169 ZERO_STRUCT(builtin_handle);
170 ZERO_STRUCT(domain_handle);
171 ZERO_STRUCT(alias_handle);
173 switch (r->in.level) {
175 info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
176 alias_name = info0->lgrpi0_name;
179 info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
180 alias_name = info1->lgrpi1_name;
183 werr = WERR_INVALID_LEVEL;
187 werr = libnetapi_open_pipe(ctx, r->in.server_name,
190 if (!W_ERROR_IS_OK(werr)) {
194 b = pipe_cli->binding_handle;
196 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
197 SAMR_ACCESS_LOOKUP_DOMAIN |
198 SAMR_ACCESS_ENUM_DOMAINS,
199 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
202 if (!W_ERROR_IS_OK(werr)) {
206 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
209 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
211 if (ctx->disable_policy_handle_cache) {
212 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
215 if (NT_STATUS_IS_OK(status)) {
216 werr = WERR_ALIAS_EXISTS;
220 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
221 SAMR_ACCESS_ENUM_DOMAINS |
222 SAMR_ACCESS_LOOKUP_DOMAIN,
223 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
224 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
228 if (!W_ERROR_IS_OK(werr)) {
232 init_lsa_String(&lsa_account_name, alias_name);
234 status = dcerpc_samr_CreateDomAlias(b, talloc_tos(),
238 SAMR_ALIAS_ACCESS_SET_INFO,
242 if (!NT_STATUS_IS_OK(status)) {
243 werr = ntstatus_to_werror(status);
246 if (!NT_STATUS_IS_OK(result)) {
247 werr = ntstatus_to_werror(result);
252 if (r->in.level == 1 && info1->lgrpi1_comment) {
254 union samr_AliasInfo alias_info;
256 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
258 status = dcerpc_samr_SetAliasInfo(b, talloc_tos(),
260 ALIASINFODESCRIPTION,
263 if (!NT_STATUS_IS_OK(status)) {
264 werr = ntstatus_to_werror(status);
267 if (!NT_STATUS_IS_OK(result)) {
268 werr = ntstatus_to_werror(result);
276 if (is_valid_policy_hnd(&alias_handle)) {
277 dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
280 if (ctx->disable_policy_handle_cache) {
281 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
282 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
283 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
289 /****************************************************************
290 ****************************************************************/
292 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
293 struct NetLocalGroupAdd *r)
295 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAdd);
298 /****************************************************************
299 ****************************************************************/
302 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
303 struct NetLocalGroupDel *r)
305 struct rpc_pipe_client *pipe_cli = NULL;
306 NTSTATUS status, result;
308 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
309 struct dom_sid2 *domain_sid = NULL;
310 struct dcerpc_binding_handle *b = NULL;
312 if (!r->in.group_name) {
313 return WERR_INVALID_PARAMETER;
316 ZERO_STRUCT(connect_handle);
317 ZERO_STRUCT(builtin_handle);
318 ZERO_STRUCT(domain_handle);
319 ZERO_STRUCT(alias_handle);
321 werr = libnetapi_open_pipe(ctx, r->in.server_name,
324 if (!W_ERROR_IS_OK(werr)) {
328 b = pipe_cli->binding_handle;
330 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
331 SAMR_ACCESS_LOOKUP_DOMAIN |
332 SAMR_ACCESS_ENUM_DOMAINS,
333 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
336 if (!W_ERROR_IS_OK(werr)) {
340 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
346 if (ctx->disable_policy_handle_cache) {
347 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
350 if (NT_STATUS_IS_OK(status)) {
354 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
355 SAMR_ACCESS_ENUM_DOMAINS |
356 SAMR_ACCESS_LOOKUP_DOMAIN,
357 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
358 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
362 if (!W_ERROR_IS_OK(werr)) {
366 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
372 if (ctx->disable_policy_handle_cache) {
373 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
376 if (!NT_STATUS_IS_OK(status)) {
377 werr = ntstatus_to_werror(status);
383 status = dcerpc_samr_DeleteDomAlias(b, talloc_tos(),
386 if (!NT_STATUS_IS_OK(status)) {
387 werr = ntstatus_to_werror(status);
390 if (!NT_STATUS_IS_OK(result)) {
391 werr = ntstatus_to_werror(result);
395 ZERO_STRUCT(alias_handle);
400 if (is_valid_policy_hnd(&alias_handle)) {
401 dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
404 if (ctx->disable_policy_handle_cache) {
405 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
406 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
407 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
413 /****************************************************************
414 ****************************************************************/
416 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
417 struct NetLocalGroupDel *r)
419 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDel);
422 /****************************************************************
423 ****************************************************************/
425 static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
426 const char *alias_name,
427 struct samr_AliasInfoAll *info,
429 uint32_t *entries_read,
432 struct LOCALGROUP_INFO_0 g0;
433 struct LOCALGROUP_INFO_1 g1;
434 struct LOCALGROUP_INFO_1002 g1002;
438 g0.lgrpi0_name = talloc_strdup(mem_ctx, alias_name);
439 W_ERROR_HAVE_NO_MEMORY(g0.lgrpi0_name);
441 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_0, g0,
442 (struct LOCALGROUP_INFO_0 **)buffer, entries_read);
446 g1.lgrpi1_name = talloc_strdup(mem_ctx, alias_name);
447 g1.lgrpi1_comment = talloc_strdup(mem_ctx, info->description.string);
448 W_ERROR_HAVE_NO_MEMORY(g1.lgrpi1_name);
450 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1, g1,
451 (struct LOCALGROUP_INFO_1 **)buffer, entries_read);
455 g1002.lgrpi1002_comment = talloc_strdup(mem_ctx, info->description.string);
457 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1002, g1002,
458 (struct LOCALGROUP_INFO_1002 **)buffer, entries_read);
462 return WERR_INVALID_LEVEL;
468 /****************************************************************
469 ****************************************************************/
471 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
472 struct NetLocalGroupGetInfo *r)
474 struct rpc_pipe_client *pipe_cli = NULL;
475 NTSTATUS status, result;
477 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
478 struct dom_sid2 *domain_sid = NULL;
479 union samr_AliasInfo *alias_info = NULL;
480 uint32_t entries_read = 0;
481 struct dcerpc_binding_handle *b = NULL;
483 if (!r->in.group_name) {
484 return WERR_INVALID_PARAMETER;
487 switch (r->in.level) {
493 return WERR_INVALID_LEVEL;
496 ZERO_STRUCT(connect_handle);
497 ZERO_STRUCT(builtin_handle);
498 ZERO_STRUCT(domain_handle);
499 ZERO_STRUCT(alias_handle);
501 werr = libnetapi_open_pipe(ctx, r->in.server_name,
504 if (!W_ERROR_IS_OK(werr)) {
508 b = pipe_cli->binding_handle;
510 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
511 SAMR_ACCESS_LOOKUP_DOMAIN |
512 SAMR_ACCESS_ENUM_DOMAINS,
513 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
516 if (!W_ERROR_IS_OK(werr)) {
520 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
523 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
526 if (ctx->disable_policy_handle_cache) {
527 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
530 if (NT_STATUS_IS_OK(status)) {
534 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
535 SAMR_ACCESS_ENUM_DOMAINS |
536 SAMR_ACCESS_LOOKUP_DOMAIN,
537 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
538 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
542 if (!W_ERROR_IS_OK(werr)) {
546 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
549 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
552 if (ctx->disable_policy_handle_cache) {
553 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
556 if (!NT_STATUS_IS_OK(status)) {
557 werr = ntstatus_to_werror(status);
562 status = dcerpc_samr_QueryAliasInfo(b, talloc_tos(),
567 if (!NT_STATUS_IS_OK(status)) {
568 werr = ntstatus_to_werror(status);
571 if (!NT_STATUS_IS_OK(result)) {
572 werr = ntstatus_to_werror(result);
576 werr = map_alias_info_to_buffer(ctx,
579 r->in.level, &entries_read,
583 if (is_valid_policy_hnd(&alias_handle)) {
584 dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
587 if (ctx->disable_policy_handle_cache) {
588 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
589 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
590 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
596 /****************************************************************
597 ****************************************************************/
599 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
600 struct NetLocalGroupGetInfo *r)
602 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetInfo);
605 /****************************************************************
606 ****************************************************************/
608 static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
611 enum samr_AliasInfoEnum *alias_level,
612 union samr_AliasInfo **alias_info)
614 struct LOCALGROUP_INFO_0 *info0;
615 struct LOCALGROUP_INFO_1 *info1;
616 struct LOCALGROUP_INFO_1002 *info1002;
617 union samr_AliasInfo *info = NULL;
619 info = talloc_zero(mem_ctx, union samr_AliasInfo);
620 W_ERROR_HAVE_NO_MEMORY(info);
624 info0 = (struct LOCALGROUP_INFO_0 *)buffer;
625 init_lsa_String(&info->name, info0->lgrpi0_name);
626 *alias_level = ALIASINFONAME;
629 info1 = (struct LOCALGROUP_INFO_1 *)buffer;
630 /* group name will be ignored */
631 init_lsa_String(&info->description, info1->lgrpi1_comment);
632 *alias_level = ALIASINFODESCRIPTION;
635 info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
636 init_lsa_String(&info->description, info1002->lgrpi1002_comment);
637 *alias_level = ALIASINFODESCRIPTION;
646 /****************************************************************
647 ****************************************************************/
649 WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
650 struct NetLocalGroupSetInfo *r)
652 struct rpc_pipe_client *pipe_cli = NULL;
653 NTSTATUS status, result;
655 struct lsa_String lsa_account_name;
656 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
657 struct dom_sid2 *domain_sid = NULL;
658 enum samr_AliasInfoEnum alias_level = 0;
659 union samr_AliasInfo *alias_info = NULL;
660 struct dcerpc_binding_handle *b = NULL;
662 if (!r->in.group_name) {
663 return WERR_INVALID_PARAMETER;
666 switch (r->in.level) {
672 return WERR_INVALID_LEVEL;
675 ZERO_STRUCT(connect_handle);
676 ZERO_STRUCT(builtin_handle);
677 ZERO_STRUCT(domain_handle);
678 ZERO_STRUCT(alias_handle);
680 werr = libnetapi_open_pipe(ctx, r->in.server_name,
683 if (!W_ERROR_IS_OK(werr)) {
687 b = pipe_cli->binding_handle;
689 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
690 SAMR_ACCESS_LOOKUP_DOMAIN |
691 SAMR_ACCESS_ENUM_DOMAINS,
692 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
695 if (!W_ERROR_IS_OK(werr)) {
699 init_lsa_String(&lsa_account_name, r->in.group_name);
701 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
704 SAMR_ALIAS_ACCESS_SET_INFO,
707 if (ctx->disable_policy_handle_cache) {
708 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
711 if (NT_STATUS_IS_OK(status)) {
715 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
716 SAMR_ACCESS_ENUM_DOMAINS |
717 SAMR_ACCESS_LOOKUP_DOMAIN,
718 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
722 if (!W_ERROR_IS_OK(werr)) {
726 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
729 SAMR_ALIAS_ACCESS_SET_INFO,
731 if (!NT_STATUS_IS_OK(status)) {
732 werr = ntstatus_to_werror(status);
736 if (ctx->disable_policy_handle_cache) {
737 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
742 werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer,
743 &alias_level, &alias_info);
744 if (!W_ERROR_IS_OK(werr)) {
748 status = dcerpc_samr_SetAliasInfo(b, talloc_tos(),
753 if (!NT_STATUS_IS_OK(status)) {
754 werr = ntstatus_to_werror(status);
757 if (!NT_STATUS_IS_OK(result)) {
758 werr = ntstatus_to_werror(result);
765 if (is_valid_policy_hnd(&alias_handle)) {
766 dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
769 if (ctx->disable_policy_handle_cache) {
770 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
771 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
772 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
778 /****************************************************************
779 ****************************************************************/
781 WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
782 struct NetLocalGroupSetInfo *r)
784 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetInfo);
787 /****************************************************************
788 ****************************************************************/
790 WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
791 struct NetLocalGroupEnum *r)
793 struct rpc_pipe_client *pipe_cli = NULL;
794 NTSTATUS status, result;
796 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
797 struct dom_sid2 *domain_sid = NULL;
798 uint32_t entries_read = 0;
799 union samr_DomainInfo *domain_info = NULL;
800 union samr_DomainInfo *builtin_info = NULL;
801 struct samr_SamArray *domain_sam_array = NULL;
802 struct samr_SamArray *builtin_sam_array = NULL;
804 struct dcerpc_binding_handle *b = NULL;
806 if (!r->out.buffer) {
807 return WERR_INVALID_PARAMETER;
810 switch (r->in.level) {
815 return WERR_INVALID_LEVEL;
818 if (r->out.total_entries) {
819 *r->out.total_entries = 0;
821 if (r->out.entries_read) {
822 *r->out.entries_read = 0;
825 ZERO_STRUCT(connect_handle);
826 ZERO_STRUCT(builtin_handle);
827 ZERO_STRUCT(domain_handle);
828 ZERO_STRUCT(alias_handle);
830 werr = libnetapi_open_pipe(ctx, r->in.server_name,
833 if (!W_ERROR_IS_OK(werr)) {
837 b = pipe_cli->binding_handle;
839 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
840 SAMR_ACCESS_LOOKUP_DOMAIN |
841 SAMR_ACCESS_ENUM_DOMAINS,
842 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
843 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
844 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
847 if (!W_ERROR_IS_OK(werr)) {
851 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
852 SAMR_ACCESS_LOOKUP_DOMAIN |
853 SAMR_ACCESS_ENUM_DOMAINS,
854 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
855 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
856 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
860 if (!W_ERROR_IS_OK(werr)) {
864 status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(),
869 if (!NT_STATUS_IS_OK(status)) {
870 werr = ntstatus_to_werror(status);
873 if (!NT_STATUS_IS_OK(result)) {
874 werr = ntstatus_to_werror(result);
878 if (r->out.total_entries) {
879 *r->out.total_entries += builtin_info->general.num_aliases;
882 status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(),
887 if (!NT_STATUS_IS_OK(status)) {
888 werr = ntstatus_to_werror(status);
891 if (!NT_STATUS_IS_OK(result)) {
892 werr = ntstatus_to_werror(result);
896 if (r->out.total_entries) {
897 *r->out.total_entries += domain_info->general.num_aliases;
900 status = dcerpc_samr_EnumDomainAliases(b, talloc_tos(),
907 if (!NT_STATUS_IS_OK(status)) {
908 werr = ntstatus_to_werror(status);
911 if (!NT_STATUS_IS_OK(result)) {
912 werr = ntstatus_to_werror(result);
916 for (i=0; i<builtin_sam_array->count; i++) {
917 union samr_AliasInfo *alias_info = NULL;
919 if (r->in.level == 1) {
921 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
923 builtin_sam_array->entries[i].idx,
924 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
927 if (!NT_STATUS_IS_OK(status)) {
928 werr = ntstatus_to_werror(status);
933 werr = map_alias_info_to_buffer(ctx,
934 builtin_sam_array->entries[i].name.string,
935 alias_info ? &alias_info->all : NULL,
941 status = dcerpc_samr_EnumDomainAliases(b, talloc_tos(),
948 if (!NT_STATUS_IS_OK(status)) {
949 werr = ntstatus_to_werror(status);
952 if (!NT_STATUS_IS_OK(result)) {
953 werr = ntstatus_to_werror(result);
957 for (i=0; i<domain_sam_array->count; i++) {
959 union samr_AliasInfo *alias_info = NULL;
961 if (r->in.level == 1) {
962 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
964 domain_sam_array->entries[i].idx,
965 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
968 if (!NT_STATUS_IS_OK(status)) {
969 werr = ntstatus_to_werror(status);
974 werr = map_alias_info_to_buffer(ctx,
975 domain_sam_array->entries[i].name.string,
976 alias_info ? &alias_info->all : NULL,
983 if (ctx->disable_policy_handle_cache) {
984 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
985 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
986 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
992 /****************************************************************
993 ****************************************************************/
995 WERROR NetLocalGroupEnum_l(struct libnetapi_ctx *ctx,
996 struct NetLocalGroupEnum *r)
998 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupEnum);
1001 /****************************************************************
1002 ****************************************************************/
1004 static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
1005 struct rpc_pipe_client *lsa_pipe,
1007 struct dom_sid *sid)
1009 NTSTATUS status, result;
1010 struct policy_handle lsa_handle;
1011 struct dcerpc_binding_handle *b = lsa_pipe->binding_handle;
1013 struct lsa_RefDomainList *domains = NULL;
1014 struct lsa_TransSidArray3 sids;
1017 struct lsa_String names;
1018 uint32_t num_names = 1;
1020 if (!sid || !name) {
1021 return NT_STATUS_INVALID_PARAMETER;
1026 init_lsa_String(&names, name);
1028 status = rpccli_lsa_open_policy2(lsa_pipe, mem_ctx,
1030 SEC_STD_READ_CONTROL |
1031 LSA_POLICY_VIEW_LOCAL_INFORMATION |
1032 LSA_POLICY_LOOKUP_NAMES,
1034 NT_STATUS_NOT_OK_RETURN(status);
1036 status = dcerpc_lsa_LookupNames3(b, mem_ctx,
1042 LSA_LOOKUP_NAMES_ALL, /* sure ? */
1046 NT_STATUS_NOT_OK_RETURN(status);
1047 NT_STATUS_NOT_OK_RETURN(result);
1049 if (count != 1 || sids.count != 1) {
1050 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1053 sid_copy(sid, sids.sids[0].sid);
1055 return NT_STATUS_OK;
1058 /****************************************************************
1059 ****************************************************************/
1061 static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
1062 struct NetLocalGroupAddMembers *add,
1063 struct NetLocalGroupDelMembers *del,
1064 struct NetLocalGroupSetMembers *set)
1066 struct NetLocalGroupAddMembers *r = NULL;
1068 struct rpc_pipe_client *pipe_cli = NULL;
1069 struct rpc_pipe_client *lsa_pipe = NULL;
1070 NTSTATUS status, result;
1072 struct lsa_String lsa_account_name;
1073 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
1074 struct dom_sid2 *domain_sid = NULL;
1075 struct dom_sid *member_sids = NULL;
1078 struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
1079 struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
1081 struct dom_sid *add_sids = NULL;
1082 struct dom_sid *del_sids = NULL;
1083 uint32_t num_add_sids = 0;
1084 uint32_t num_del_sids = 0;
1085 struct dcerpc_binding_handle *b = NULL;
1087 if ((!add && !del && !set) || (add && del && set)) {
1088 return WERR_INVALID_PARAMETER;
1096 r = (struct NetLocalGroupAddMembers *)del;
1100 r = (struct NetLocalGroupAddMembers *)set;
1103 if (r==NULL || r->in.group_name == NULL) {
1104 return WERR_INVALID_PARAMETER;
1107 switch (r->in.level) {
1112 return WERR_INVALID_LEVEL;
1115 if (r->in.total_entries == 0 || !r->in.buffer) {
1116 return WERR_INVALID_PARAMETER;
1119 ZERO_STRUCT(connect_handle);
1120 ZERO_STRUCT(builtin_handle);
1121 ZERO_STRUCT(domain_handle);
1122 ZERO_STRUCT(alias_handle);
1124 member_sids = talloc_zero_array(ctx, struct dom_sid,
1125 r->in.total_entries);
1126 W_ERROR_HAVE_NO_MEMORY(member_sids);
1128 switch (r->in.level) {
1130 info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
1131 for (i=0; i < r->in.total_entries; i++) {
1132 sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
1136 info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1142 if (r->in.level == 3) {
1143 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1146 if (!W_ERROR_IS_OK(werr)) {
1150 for (i=0; i < r->in.total_entries; i++) {
1151 status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1152 info3[i].lgrmi3_domainandname,
1154 if (!NT_STATUS_IS_OK(status)) {
1155 werr = ntstatus_to_werror(status);
1159 TALLOC_FREE(lsa_pipe);
1162 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1165 if (!W_ERROR_IS_OK(werr)) {
1169 b = pipe_cli->binding_handle;
1171 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1172 SAMR_ACCESS_LOOKUP_DOMAIN |
1173 SAMR_ACCESS_ENUM_DOMAINS,
1174 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1177 if (!W_ERROR_IS_OK(werr)) {
1181 init_lsa_String(&lsa_account_name, r->in.group_name);
1183 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1186 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1187 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1188 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1189 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1192 if (ctx->disable_policy_handle_cache) {
1193 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1196 if (NT_STATUS_IS_OK(status)) {
1197 goto modify_membership;
1200 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1201 SAMR_ACCESS_ENUM_DOMAINS |
1202 SAMR_ACCESS_LOOKUP_DOMAIN,
1203 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1207 if (!W_ERROR_IS_OK(werr)) {
1211 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1214 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1215 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1216 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1217 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1219 if (!NT_STATUS_IS_OK(status)) {
1220 werr = ntstatus_to_werror(status);
1224 if (ctx->disable_policy_handle_cache) {
1225 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1231 for (i=0; i < r->in.total_entries; i++) {
1232 status = add_sid_to_array_unique(ctx, &member_sids[i],
1235 if (!NT_STATUS_IS_OK(status)) {
1236 werr = ntstatus_to_werror(status);
1243 for (i=0; i < r->in.total_entries; i++) {
1244 status = add_sid_to_array_unique(ctx, &member_sids[i],
1247 if (!NT_STATUS_IS_OK(status)) {
1248 werr = ntstatus_to_werror(status);
1256 struct lsa_SidArray current_sids;
1258 status = dcerpc_samr_GetMembersInAlias(b, talloc_tos(),
1262 if (!NT_STATUS_IS_OK(status)) {
1263 werr = ntstatus_to_werror(status);
1266 if (!NT_STATUS_IS_OK(result)) {
1267 werr = ntstatus_to_werror(result);
1273 for (i=0; i < r->in.total_entries; i++) {
1274 bool already_member = false;
1275 for (k=0; k < current_sids.num_sids; k++) {
1276 if (dom_sid_equal(&member_sids[i],
1277 current_sids.sids[k].sid)) {
1278 already_member = true;
1282 if (!already_member) {
1283 status = add_sid_to_array_unique(ctx,
1285 &add_sids, &num_add_sids);
1286 if (!NT_STATUS_IS_OK(status)) {
1287 werr = ntstatus_to_werror(status);
1295 for (k=0; k < current_sids.num_sids; k++) {
1296 bool keep_member = false;
1297 for (i=0; i < r->in.total_entries; i++) {
1298 if (dom_sid_equal(&member_sids[i],
1299 current_sids.sids[k].sid)) {
1305 status = add_sid_to_array_unique(ctx,
1306 current_sids.sids[k].sid,
1307 &del_sids, &num_del_sids);
1308 if (!NT_STATUS_IS_OK(status)) {
1309 werr = ntstatus_to_werror(status);
1318 for (i=0; i < num_add_sids; i++) {
1319 status = dcerpc_samr_AddAliasMember(b, talloc_tos(),
1323 if (!NT_STATUS_IS_OK(status)) {
1324 werr = ntstatus_to_werror(status);
1327 if (!NT_STATUS_IS_OK(result)) {
1328 werr = ntstatus_to_werror(result);
1335 for (i=0; i < num_del_sids; i++) {
1336 status = dcerpc_samr_DeleteAliasMember(b, talloc_tos(),
1340 if (!NT_STATUS_IS_OK(status)) {
1341 werr = ntstatus_to_werror(status);
1344 if (!NT_STATUS_IS_OK(result)) {
1345 werr = ntstatus_to_werror(result);
1353 if (b && is_valid_policy_hnd(&alias_handle)) {
1354 dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
1357 if (ctx->disable_policy_handle_cache) {
1358 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1359 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1360 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1366 /****************************************************************
1367 ****************************************************************/
1369 WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1370 struct NetLocalGroupAddMembers *r)
1372 return NetLocalGroupModifyMembers_r(ctx, r, NULL, NULL);
1375 /****************************************************************
1376 ****************************************************************/
1378 WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1379 struct NetLocalGroupAddMembers *r)
1381 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAddMembers);
1384 /****************************************************************
1385 ****************************************************************/
1387 WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1388 struct NetLocalGroupDelMembers *r)
1390 return NetLocalGroupModifyMembers_r(ctx, NULL, r, NULL);
1393 /****************************************************************
1394 ****************************************************************/
1396 WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1397 struct NetLocalGroupDelMembers *r)
1399 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDelMembers);
1402 /****************************************************************
1403 ****************************************************************/
1405 WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1406 struct NetLocalGroupGetMembers *r)
1408 return WERR_NOT_SUPPORTED;
1411 /****************************************************************
1412 ****************************************************************/
1414 WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1415 struct NetLocalGroupGetMembers *r)
1417 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetMembers);
1420 /****************************************************************
1421 ****************************************************************/
1423 WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1424 struct NetLocalGroupSetMembers *r)
1426 return NetLocalGroupModifyMembers_r(ctx, NULL, NULL, r);
1429 /****************************************************************
1430 ****************************************************************/
1432 WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1433 struct NetLocalGroupSetMembers *r)
1435 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);