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/ndr_samr_c.h"
27 #include "../librpc/gen_ndr/ndr_lsa_c.h"
28 #include "rpc_client/cli_lsarpc.h"
29 #include "rpc_client/init_lsa.h"
30 #include "../libcli/security/security.h"
32 static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
33 struct rpc_pipe_client *pipe_cli,
34 struct policy_handle *domain_handle,
35 const char *group_name,
36 uint32_t access_rights,
37 struct policy_handle *alias_handle)
39 NTSTATUS status, result;
41 struct lsa_String lsa_account_name;
42 struct samr_Ids user_rids, name_types;
43 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
45 init_lsa_String(&lsa_account_name, group_name);
47 status = dcerpc_samr_LookupNames(b, mem_ctx,
54 if (!NT_STATUS_IS_OK(status)) {
57 if (!NT_STATUS_IS_OK(result)) {
61 switch (name_types.ids[0]) {
63 case SID_NAME_WKN_GRP:
66 return NT_STATUS_INVALID_SID;
69 status = dcerpc_samr_OpenAlias(b, mem_ctx,
75 if (!NT_STATUS_IS_OK(status)) {
82 /****************************************************************
83 ****************************************************************/
85 static NTSTATUS libnetapi_samr_open_alias_queryinfo(TALLOC_CTX *mem_ctx,
86 struct rpc_pipe_client *pipe_cli,
87 struct policy_handle *handle,
89 uint32_t access_rights,
90 enum samr_AliasInfoEnum level,
91 union samr_AliasInfo **alias_info)
93 NTSTATUS status, result;
94 struct policy_handle alias_handle;
95 union samr_AliasInfo *_alias_info = NULL;
96 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
98 ZERO_STRUCT(alias_handle);
100 status = dcerpc_samr_OpenAlias(b, mem_ctx,
106 if (!NT_STATUS_IS_OK(status)) {
109 if (!NT_STATUS_IS_OK(result)) {
114 status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
119 if (!NT_STATUS_IS_OK(status)) {
122 if (!NT_STATUS_IS_OK(result)) {
127 *alias_info = _alias_info;
130 if (is_valid_policy_hnd(&alias_handle)) {
131 dcerpc_samr_Close(b, mem_ctx, &alias_handle, &result);
137 /****************************************************************
138 ****************************************************************/
140 WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
141 struct NetLocalGroupAdd *r)
143 struct rpc_pipe_client *pipe_cli = NULL;
144 NTSTATUS status, result;
146 struct lsa_String lsa_account_name;
147 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
148 struct dom_sid2 *domain_sid = NULL;
150 struct dcerpc_binding_handle *b = NULL;
152 struct LOCALGROUP_INFO_0 *info0 = NULL;
153 struct LOCALGROUP_INFO_1 *info1 = NULL;
155 const char *alias_name = NULL;
158 return WERR_INVALID_PARAM;
161 switch (r->in.level) {
163 info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer;
164 alias_name = info0->lgrpi0_name;
167 info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer;
168 alias_name = info1->lgrpi1_name;
171 werr = WERR_UNKNOWN_LEVEL;
175 ZERO_STRUCT(connect_handle);
176 ZERO_STRUCT(builtin_handle);
177 ZERO_STRUCT(domain_handle);
178 ZERO_STRUCT(alias_handle);
180 werr = libnetapi_open_pipe(ctx, r->in.server_name,
181 &ndr_table_samr.syntax_id,
183 if (!W_ERROR_IS_OK(werr)) {
187 b = pipe_cli->binding_handle;
189 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
190 SAMR_ACCESS_LOOKUP_DOMAIN |
191 SAMR_ACCESS_ENUM_DOMAINS,
192 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
195 if (!W_ERROR_IS_OK(werr)) {
199 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
202 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
204 if (ctx->disable_policy_handle_cache) {
205 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
208 if (NT_STATUS_IS_OK(status)) {
209 werr = WERR_ALIAS_EXISTS;
213 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
214 SAMR_ACCESS_ENUM_DOMAINS |
215 SAMR_ACCESS_LOOKUP_DOMAIN,
216 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
217 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
221 if (!W_ERROR_IS_OK(werr)) {
225 init_lsa_String(&lsa_account_name, alias_name);
227 status = dcerpc_samr_CreateDomAlias(b, talloc_tos(),
231 SAMR_ALIAS_ACCESS_SET_INFO,
235 if (!NT_STATUS_IS_OK(status)) {
236 werr = ntstatus_to_werror(status);
239 if (!NT_STATUS_IS_OK(result)) {
240 werr = ntstatus_to_werror(result);
245 if (r->in.level == 1 && info1->lgrpi1_comment) {
247 union samr_AliasInfo alias_info;
249 init_lsa_String(&alias_info.description, info1->lgrpi1_comment);
251 status = dcerpc_samr_SetAliasInfo(b, talloc_tos(),
253 ALIASINFODESCRIPTION,
256 if (!NT_STATUS_IS_OK(status)) {
257 werr = ntstatus_to_werror(status);
260 if (!NT_STATUS_IS_OK(result)) {
261 werr = ntstatus_to_werror(result);
269 if (is_valid_policy_hnd(&alias_handle)) {
270 dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
273 if (ctx->disable_policy_handle_cache) {
274 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
275 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
276 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
282 /****************************************************************
283 ****************************************************************/
285 WERROR NetLocalGroupAdd_l(struct libnetapi_ctx *ctx,
286 struct NetLocalGroupAdd *r)
288 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAdd);
291 /****************************************************************
292 ****************************************************************/
295 WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
296 struct NetLocalGroupDel *r)
298 struct rpc_pipe_client *pipe_cli = NULL;
299 NTSTATUS status, result;
301 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
302 struct dom_sid2 *domain_sid = NULL;
303 struct dcerpc_binding_handle *b = NULL;
305 if (!r->in.group_name) {
306 return WERR_INVALID_PARAM;
309 ZERO_STRUCT(connect_handle);
310 ZERO_STRUCT(builtin_handle);
311 ZERO_STRUCT(domain_handle);
312 ZERO_STRUCT(alias_handle);
314 werr = libnetapi_open_pipe(ctx, r->in.server_name,
315 &ndr_table_samr.syntax_id,
317 if (!W_ERROR_IS_OK(werr)) {
321 b = pipe_cli->binding_handle;
323 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
324 SAMR_ACCESS_LOOKUP_DOMAIN |
325 SAMR_ACCESS_ENUM_DOMAINS,
326 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
329 if (!W_ERROR_IS_OK(werr)) {
333 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
339 if (ctx->disable_policy_handle_cache) {
340 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
343 if (NT_STATUS_IS_OK(status)) {
347 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
348 SAMR_ACCESS_ENUM_DOMAINS |
349 SAMR_ACCESS_LOOKUP_DOMAIN,
350 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
351 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
355 if (!W_ERROR_IS_OK(werr)) {
359 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
365 if (ctx->disable_policy_handle_cache) {
366 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
369 if (!NT_STATUS_IS_OK(status)) {
370 werr = ntstatus_to_werror(status);
376 status = dcerpc_samr_DeleteDomAlias(b, talloc_tos(),
379 if (!NT_STATUS_IS_OK(status)) {
380 werr = ntstatus_to_werror(status);
383 if (!NT_STATUS_IS_OK(result)) {
384 werr = ntstatus_to_werror(result);
388 ZERO_STRUCT(alias_handle);
393 if (is_valid_policy_hnd(&alias_handle)) {
394 dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
397 if (ctx->disable_policy_handle_cache) {
398 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
399 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
400 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
406 /****************************************************************
407 ****************************************************************/
409 WERROR NetLocalGroupDel_l(struct libnetapi_ctx *ctx,
410 struct NetLocalGroupDel *r)
412 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDel);
415 /****************************************************************
416 ****************************************************************/
418 static WERROR map_alias_info_to_buffer(TALLOC_CTX *mem_ctx,
419 const char *alias_name,
420 struct samr_AliasInfoAll *info,
422 uint32_t *entries_read,
425 struct LOCALGROUP_INFO_0 g0;
426 struct LOCALGROUP_INFO_1 g1;
427 struct LOCALGROUP_INFO_1002 g1002;
431 g0.lgrpi0_name = talloc_strdup(mem_ctx, alias_name);
432 W_ERROR_HAVE_NO_MEMORY(g0.lgrpi0_name);
434 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_0, g0,
435 (struct LOCALGROUP_INFO_0 **)buffer, entries_read);
439 g1.lgrpi1_name = talloc_strdup(mem_ctx, alias_name);
440 g1.lgrpi1_comment = talloc_strdup(mem_ctx, info->description.string);
441 W_ERROR_HAVE_NO_MEMORY(g1.lgrpi1_name);
443 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1, g1,
444 (struct LOCALGROUP_INFO_1 **)buffer, entries_read);
448 g1002.lgrpi1002_comment = talloc_strdup(mem_ctx, info->description.string);
450 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_INFO_1002, g1002,
451 (struct LOCALGROUP_INFO_1002 **)buffer, entries_read);
455 return WERR_UNKNOWN_LEVEL;
461 /****************************************************************
462 ****************************************************************/
464 WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
465 struct NetLocalGroupGetInfo *r)
467 struct rpc_pipe_client *pipe_cli = NULL;
468 NTSTATUS status, result;
470 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
471 struct dom_sid2 *domain_sid = NULL;
472 union samr_AliasInfo *alias_info = NULL;
473 uint32_t entries_read = 0;
474 struct dcerpc_binding_handle *b = NULL;
476 if (!r->in.group_name) {
477 return WERR_INVALID_PARAM;
480 switch (r->in.level) {
486 return WERR_UNKNOWN_LEVEL;
489 ZERO_STRUCT(connect_handle);
490 ZERO_STRUCT(builtin_handle);
491 ZERO_STRUCT(domain_handle);
492 ZERO_STRUCT(alias_handle);
494 werr = libnetapi_open_pipe(ctx, r->in.server_name,
495 &ndr_table_samr.syntax_id,
497 if (!W_ERROR_IS_OK(werr)) {
501 b = pipe_cli->binding_handle;
503 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
504 SAMR_ACCESS_LOOKUP_DOMAIN |
505 SAMR_ACCESS_ENUM_DOMAINS,
506 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
509 if (!W_ERROR_IS_OK(werr)) {
513 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
516 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
519 if (ctx->disable_policy_handle_cache) {
520 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
523 if (NT_STATUS_IS_OK(status)) {
527 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
528 SAMR_ACCESS_ENUM_DOMAINS |
529 SAMR_ACCESS_LOOKUP_DOMAIN,
530 SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
531 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
535 if (!W_ERROR_IS_OK(werr)) {
539 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
542 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
545 if (ctx->disable_policy_handle_cache) {
546 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
549 if (!NT_STATUS_IS_OK(status)) {
550 werr = ntstatus_to_werror(status);
555 status = dcerpc_samr_QueryAliasInfo(b, talloc_tos(),
560 if (!NT_STATUS_IS_OK(status)) {
561 werr = ntstatus_to_werror(status);
564 if (!NT_STATUS_IS_OK(result)) {
565 werr = ntstatus_to_werror(result);
569 werr = map_alias_info_to_buffer(ctx,
572 r->in.level, &entries_read,
576 if (is_valid_policy_hnd(&alias_handle)) {
577 dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
580 if (ctx->disable_policy_handle_cache) {
581 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
582 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
583 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
589 /****************************************************************
590 ****************************************************************/
592 WERROR NetLocalGroupGetInfo_l(struct libnetapi_ctx *ctx,
593 struct NetLocalGroupGetInfo *r)
595 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetInfo);
598 /****************************************************************
599 ****************************************************************/
601 static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
604 enum samr_AliasInfoEnum *alias_level,
605 union samr_AliasInfo **alias_info)
607 struct LOCALGROUP_INFO_0 *info0;
608 struct LOCALGROUP_INFO_1 *info1;
609 struct LOCALGROUP_INFO_1002 *info1002;
610 union samr_AliasInfo *info = NULL;
612 info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
613 W_ERROR_HAVE_NO_MEMORY(info);
617 info0 = (struct LOCALGROUP_INFO_0 *)buffer;
618 init_lsa_String(&info->name, info0->lgrpi0_name);
619 *alias_level = ALIASINFONAME;
622 info1 = (struct LOCALGROUP_INFO_1 *)buffer;
623 /* group name will be ignored */
624 init_lsa_String(&info->description, info1->lgrpi1_comment);
625 *alias_level = ALIASINFODESCRIPTION;
628 info1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
629 init_lsa_String(&info->description, info1002->lgrpi1002_comment);
630 *alias_level = ALIASINFODESCRIPTION;
639 /****************************************************************
640 ****************************************************************/
642 WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
643 struct NetLocalGroupSetInfo *r)
645 struct rpc_pipe_client *pipe_cli = NULL;
646 NTSTATUS status, result;
648 struct lsa_String lsa_account_name;
649 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
650 struct dom_sid2 *domain_sid = NULL;
651 enum samr_AliasInfoEnum alias_level = 0;
652 union samr_AliasInfo *alias_info = NULL;
653 struct dcerpc_binding_handle *b = NULL;
655 if (!r->in.group_name) {
656 return WERR_INVALID_PARAM;
659 switch (r->in.level) {
665 return WERR_UNKNOWN_LEVEL;
668 ZERO_STRUCT(connect_handle);
669 ZERO_STRUCT(builtin_handle);
670 ZERO_STRUCT(domain_handle);
671 ZERO_STRUCT(alias_handle);
673 werr = libnetapi_open_pipe(ctx, r->in.server_name,
674 &ndr_table_samr.syntax_id,
676 if (!W_ERROR_IS_OK(werr)) {
680 b = pipe_cli->binding_handle;
682 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
683 SAMR_ACCESS_LOOKUP_DOMAIN |
684 SAMR_ACCESS_ENUM_DOMAINS,
685 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
688 if (!W_ERROR_IS_OK(werr)) {
692 init_lsa_String(&lsa_account_name, r->in.group_name);
694 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
697 SAMR_ALIAS_ACCESS_SET_INFO,
700 if (ctx->disable_policy_handle_cache) {
701 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
704 if (NT_STATUS_IS_OK(status)) {
708 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
709 SAMR_ACCESS_ENUM_DOMAINS |
710 SAMR_ACCESS_LOOKUP_DOMAIN,
711 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
715 if (!W_ERROR_IS_OK(werr)) {
719 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
722 SAMR_ALIAS_ACCESS_SET_INFO,
724 if (!NT_STATUS_IS_OK(status)) {
725 werr = ntstatus_to_werror(status);
729 if (ctx->disable_policy_handle_cache) {
730 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
735 werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer,
736 &alias_level, &alias_info);
737 if (!W_ERROR_IS_OK(werr)) {
741 status = dcerpc_samr_SetAliasInfo(b, talloc_tos(),
746 if (!NT_STATUS_IS_OK(status)) {
747 werr = ntstatus_to_werror(status);
750 if (!NT_STATUS_IS_OK(result)) {
751 werr = ntstatus_to_werror(result);
758 if (is_valid_policy_hnd(&alias_handle)) {
759 dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
762 if (ctx->disable_policy_handle_cache) {
763 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
764 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
765 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
771 /****************************************************************
772 ****************************************************************/
774 WERROR NetLocalGroupSetInfo_l(struct libnetapi_ctx *ctx,
775 struct NetLocalGroupSetInfo *r)
777 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetInfo);
780 /****************************************************************
781 ****************************************************************/
783 WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
784 struct NetLocalGroupEnum *r)
786 struct rpc_pipe_client *pipe_cli = NULL;
787 NTSTATUS status, result;
789 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
790 struct dom_sid2 *domain_sid = NULL;
791 uint32_t entries_read = 0;
792 union samr_DomainInfo *domain_info = NULL;
793 union samr_DomainInfo *builtin_info = NULL;
794 struct samr_SamArray *domain_sam_array = NULL;
795 struct samr_SamArray *builtin_sam_array = NULL;
797 struct dcerpc_binding_handle *b = NULL;
799 if (!r->out.buffer) {
800 return WERR_INVALID_PARAM;
803 switch (r->in.level) {
808 return WERR_UNKNOWN_LEVEL;
811 if (r->out.total_entries) {
812 *r->out.total_entries = 0;
814 if (r->out.entries_read) {
815 *r->out.entries_read = 0;
818 ZERO_STRUCT(connect_handle);
819 ZERO_STRUCT(builtin_handle);
820 ZERO_STRUCT(domain_handle);
821 ZERO_STRUCT(alias_handle);
823 werr = libnetapi_open_pipe(ctx, r->in.server_name,
824 &ndr_table_samr.syntax_id,
826 if (!W_ERROR_IS_OK(werr)) {
830 b = pipe_cli->binding_handle;
832 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
833 SAMR_ACCESS_LOOKUP_DOMAIN |
834 SAMR_ACCESS_ENUM_DOMAINS,
835 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
836 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
837 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
840 if (!W_ERROR_IS_OK(werr)) {
844 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
845 SAMR_ACCESS_LOOKUP_DOMAIN |
846 SAMR_ACCESS_ENUM_DOMAINS,
847 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
848 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
849 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
853 if (!W_ERROR_IS_OK(werr)) {
857 status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(),
862 if (!NT_STATUS_IS_OK(status)) {
863 werr = ntstatus_to_werror(status);
866 if (!NT_STATUS_IS_OK(result)) {
867 werr = ntstatus_to_werror(result);
871 if (r->out.total_entries) {
872 *r->out.total_entries += builtin_info->general.num_aliases;
875 status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(),
880 if (!NT_STATUS_IS_OK(status)) {
881 werr = ntstatus_to_werror(status);
884 if (!NT_STATUS_IS_OK(result)) {
885 werr = ntstatus_to_werror(result);
889 if (r->out.total_entries) {
890 *r->out.total_entries += domain_info->general.num_aliases;
893 status = dcerpc_samr_EnumDomainAliases(b, talloc_tos(),
900 if (!NT_STATUS_IS_OK(status)) {
901 werr = ntstatus_to_werror(status);
904 if (!NT_STATUS_IS_OK(result)) {
905 werr = ntstatus_to_werror(result);
909 for (i=0; i<builtin_sam_array->count; i++) {
910 union samr_AliasInfo *alias_info = NULL;
912 if (r->in.level == 1) {
914 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
916 builtin_sam_array->entries[i].idx,
917 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
920 if (!NT_STATUS_IS_OK(status)) {
921 werr = ntstatus_to_werror(status);
926 werr = map_alias_info_to_buffer(ctx,
927 builtin_sam_array->entries[i].name.string,
928 alias_info ? &alias_info->all : NULL,
934 status = dcerpc_samr_EnumDomainAliases(b, talloc_tos(),
941 if (!NT_STATUS_IS_OK(status)) {
942 werr = ntstatus_to_werror(status);
945 if (!NT_STATUS_IS_OK(result)) {
946 werr = ntstatus_to_werror(result);
950 for (i=0; i<domain_sam_array->count; i++) {
952 union samr_AliasInfo *alias_info = NULL;
954 if (r->in.level == 1) {
955 status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli,
957 domain_sam_array->entries[i].idx,
958 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
961 if (!NT_STATUS_IS_OK(status)) {
962 werr = ntstatus_to_werror(status);
967 werr = map_alias_info_to_buffer(ctx,
968 domain_sam_array->entries[i].name.string,
969 alias_info ? &alias_info->all : NULL,
976 if (ctx->disable_policy_handle_cache) {
977 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
978 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
979 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
985 /****************************************************************
986 ****************************************************************/
988 WERROR NetLocalGroupEnum_l(struct libnetapi_ctx *ctx,
989 struct NetLocalGroupEnum *r)
991 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupEnum);
994 /****************************************************************
995 ****************************************************************/
997 static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
998 struct rpc_pipe_client *lsa_pipe,
1000 struct dom_sid *sid)
1002 NTSTATUS status, result;
1003 struct policy_handle lsa_handle;
1004 struct dcerpc_binding_handle *b = lsa_pipe->binding_handle;
1006 struct lsa_RefDomainList *domains = NULL;
1007 struct lsa_TransSidArray3 sids;
1010 struct lsa_String names;
1011 uint32_t num_names = 1;
1013 if (!sid || !name) {
1014 return NT_STATUS_INVALID_PARAMETER;
1019 init_lsa_String(&names, name);
1021 status = rpccli_lsa_open_policy2(lsa_pipe, mem_ctx,
1023 SEC_STD_READ_CONTROL |
1024 LSA_POLICY_VIEW_LOCAL_INFORMATION |
1025 LSA_POLICY_LOOKUP_NAMES,
1027 NT_STATUS_NOT_OK_RETURN(status);
1029 status = dcerpc_lsa_LookupNames3(b, mem_ctx,
1035 LSA_LOOKUP_NAMES_ALL, /* sure ? */
1039 NT_STATUS_NOT_OK_RETURN(status);
1040 NT_STATUS_NOT_OK_RETURN(result);
1042 if (count != 1 || sids.count != 1) {
1043 return NT_STATUS_NONE_MAPPED;
1046 sid_copy(sid, sids.sids[0].sid);
1048 return NT_STATUS_OK;
1051 /****************************************************************
1052 ****************************************************************/
1054 static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
1055 struct NetLocalGroupAddMembers *add,
1056 struct NetLocalGroupDelMembers *del,
1057 struct NetLocalGroupSetMembers *set)
1059 struct NetLocalGroupAddMembers *r = NULL;
1061 struct rpc_pipe_client *pipe_cli = NULL;
1062 struct rpc_pipe_client *lsa_pipe = NULL;
1063 NTSTATUS status, result;
1065 struct lsa_String lsa_account_name;
1066 struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle;
1067 struct dom_sid2 *domain_sid = NULL;
1068 struct dom_sid *member_sids = NULL;
1071 struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
1072 struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
1074 struct dom_sid *add_sids = NULL;
1075 struct dom_sid *del_sids = NULL;
1076 uint32_t num_add_sids = 0;
1077 uint32_t num_del_sids = 0;
1078 struct dcerpc_binding_handle *b = NULL;
1080 if ((!add && !del && !set) || (add && del && set)) {
1081 return WERR_INVALID_PARAM;
1089 r = (struct NetLocalGroupAddMembers *)del;
1093 r = (struct NetLocalGroupAddMembers *)set;
1096 if (!r->in.group_name) {
1097 return WERR_INVALID_PARAM;
1100 switch (r->in.level) {
1105 return WERR_UNKNOWN_LEVEL;
1108 if (r->in.total_entries == 0 || !r->in.buffer) {
1109 return WERR_INVALID_PARAM;
1112 ZERO_STRUCT(connect_handle);
1113 ZERO_STRUCT(builtin_handle);
1114 ZERO_STRUCT(domain_handle);
1115 ZERO_STRUCT(alias_handle);
1117 member_sids = TALLOC_ZERO_ARRAY(ctx, struct dom_sid,
1118 r->in.total_entries);
1119 W_ERROR_HAVE_NO_MEMORY(member_sids);
1121 switch (r->in.level) {
1123 info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer;
1124 for (i=0; i < r->in.total_entries; i++) {
1125 sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid);
1129 info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer;
1135 if (r->in.level == 3) {
1136 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1137 &ndr_table_lsarpc.syntax_id,
1139 if (!W_ERROR_IS_OK(werr)) {
1143 for (i=0; i < r->in.total_entries; i++) {
1144 status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe,
1145 info3[i].lgrmi3_domainandname,
1147 if (!NT_STATUS_IS_OK(status)) {
1148 werr = ntstatus_to_werror(status);
1152 TALLOC_FREE(lsa_pipe);
1155 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1156 &ndr_table_samr.syntax_id,
1158 if (!W_ERROR_IS_OK(werr)) {
1162 b = pipe_cli->binding_handle;
1164 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1165 SAMR_ACCESS_LOOKUP_DOMAIN |
1166 SAMR_ACCESS_ENUM_DOMAINS,
1167 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1170 if (!W_ERROR_IS_OK(werr)) {
1174 init_lsa_String(&lsa_account_name, r->in.group_name);
1176 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1179 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1180 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1181 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1182 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1185 if (ctx->disable_policy_handle_cache) {
1186 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1189 if (NT_STATUS_IS_OK(status)) {
1190 goto modify_membership;
1193 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1194 SAMR_ACCESS_ENUM_DOMAINS |
1195 SAMR_ACCESS_LOOKUP_DOMAIN,
1196 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1200 if (!W_ERROR_IS_OK(werr)) {
1204 status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli,
1207 SAMR_ALIAS_ACCESS_ADD_MEMBER |
1208 SAMR_ALIAS_ACCESS_REMOVE_MEMBER |
1209 SAMR_ALIAS_ACCESS_GET_MEMBERS |
1210 SAMR_ALIAS_ACCESS_LOOKUP_INFO,
1212 if (!NT_STATUS_IS_OK(status)) {
1213 werr = ntstatus_to_werror(status);
1217 if (ctx->disable_policy_handle_cache) {
1218 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1224 for (i=0; i < r->in.total_entries; i++) {
1225 status = add_sid_to_array_unique(ctx, &member_sids[i],
1228 if (!NT_STATUS_IS_OK(status)) {
1229 werr = ntstatus_to_werror(status);
1236 for (i=0; i < r->in.total_entries; i++) {
1237 status = add_sid_to_array_unique(ctx, &member_sids[i],
1240 if (!NT_STATUS_IS_OK(status)) {
1241 werr = ntstatus_to_werror(status);
1249 struct lsa_SidArray current_sids;
1251 status = dcerpc_samr_GetMembersInAlias(b, talloc_tos(),
1255 if (!NT_STATUS_IS_OK(status)) {
1256 werr = ntstatus_to_werror(status);
1259 if (!NT_STATUS_IS_OK(result)) {
1260 werr = ntstatus_to_werror(result);
1266 for (i=0; i < r->in.total_entries; i++) {
1267 bool already_member = false;
1268 for (k=0; k < current_sids.num_sids; k++) {
1269 if (dom_sid_equal(&member_sids[i],
1270 current_sids.sids[k].sid)) {
1271 already_member = true;
1275 if (!already_member) {
1276 status = add_sid_to_array_unique(ctx,
1278 &add_sids, &num_add_sids);
1279 if (!NT_STATUS_IS_OK(status)) {
1280 werr = ntstatus_to_werror(status);
1288 for (k=0; k < current_sids.num_sids; k++) {
1289 bool keep_member = false;
1290 for (i=0; i < r->in.total_entries; i++) {
1291 if (dom_sid_equal(&member_sids[i],
1292 current_sids.sids[k].sid)) {
1298 status = add_sid_to_array_unique(ctx,
1299 current_sids.sids[k].sid,
1300 &del_sids, &num_del_sids);
1301 if (!NT_STATUS_IS_OK(status)) {
1302 werr = ntstatus_to_werror(status);
1311 for (i=0; i < num_add_sids; i++) {
1312 status = dcerpc_samr_AddAliasMember(b, talloc_tos(),
1316 if (!NT_STATUS_IS_OK(status)) {
1317 werr = ntstatus_to_werror(status);
1320 if (!NT_STATUS_IS_OK(result)) {
1321 werr = ntstatus_to_werror(result);
1328 for (i=0; i < num_del_sids; i++) {
1329 status = dcerpc_samr_DeleteAliasMember(b, talloc_tos(),
1333 if (!NT_STATUS_IS_OK(status)) {
1334 werr = ntstatus_to_werror(status);
1337 if (!NT_STATUS_IS_OK(result)) {
1338 werr = ntstatus_to_werror(result);
1346 if (is_valid_policy_hnd(&alias_handle)) {
1347 dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
1350 if (ctx->disable_policy_handle_cache) {
1351 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1352 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1353 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1359 /****************************************************************
1360 ****************************************************************/
1362 WERROR NetLocalGroupAddMembers_r(struct libnetapi_ctx *ctx,
1363 struct NetLocalGroupAddMembers *r)
1365 return NetLocalGroupModifyMembers_r(ctx, r, NULL, NULL);
1368 /****************************************************************
1369 ****************************************************************/
1371 WERROR NetLocalGroupAddMembers_l(struct libnetapi_ctx *ctx,
1372 struct NetLocalGroupAddMembers *r)
1374 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupAddMembers);
1377 /****************************************************************
1378 ****************************************************************/
1380 WERROR NetLocalGroupDelMembers_r(struct libnetapi_ctx *ctx,
1381 struct NetLocalGroupDelMembers *r)
1383 return NetLocalGroupModifyMembers_r(ctx, NULL, r, NULL);
1386 /****************************************************************
1387 ****************************************************************/
1389 WERROR NetLocalGroupDelMembers_l(struct libnetapi_ctx *ctx,
1390 struct NetLocalGroupDelMembers *r)
1392 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupDelMembers);
1395 /****************************************************************
1396 ****************************************************************/
1398 WERROR NetLocalGroupGetMembers_r(struct libnetapi_ctx *ctx,
1399 struct NetLocalGroupGetMembers *r)
1401 return WERR_NOT_SUPPORTED;
1404 /****************************************************************
1405 ****************************************************************/
1407 WERROR NetLocalGroupGetMembers_l(struct libnetapi_ctx *ctx,
1408 struct NetLocalGroupGetMembers *r)
1410 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupGetMembers);
1413 /****************************************************************
1414 ****************************************************************/
1416 WERROR NetLocalGroupSetMembers_r(struct libnetapi_ctx *ctx,
1417 struct NetLocalGroupSetMembers *r)
1419 return NetLocalGroupModifyMembers_r(ctx, NULL, NULL, r);
1422 /****************************************************************
1423 ****************************************************************/
1425 WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
1426 struct NetLocalGroupSetMembers *r)
1428 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);