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