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_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
);
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_LOOKUP_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_LOOKUP_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_LOOKUP_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_LOOKUP_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_LOOKUP_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_LOOKUP_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_LOOKUP_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_LOOKUP_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_LOOKUP_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_LOOKUP_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
);