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"
28 #include "rpc_client/cli_lsarpc.h"
29 #include "rpc_client/init_lsa.h"
30 #include "../libcli/security/dom_sid.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
)
41 struct lsa_String lsa_account_name
;
42 struct samr_Ids user_rids
, name_types
;
44 init_lsa_String(&lsa_account_name
, group_name
);
46 status
= rpccli_samr_LookupNames(pipe_cli
, mem_ctx
,
52 if (!NT_STATUS_IS_OK(status
)) {
56 switch (name_types
.ids
[0]) {
58 case SID_NAME_WKN_GRP
:
61 return NT_STATUS_INVALID_SID
;
64 return rpccli_samr_OpenAlias(pipe_cli
, mem_ctx
,
71 /****************************************************************
72 ****************************************************************/
74 static NTSTATUS
libnetapi_samr_open_alias_queryinfo(TALLOC_CTX
*mem_ctx
,
75 struct rpc_pipe_client
*pipe_cli
,
76 struct policy_handle
*handle
,
78 uint32_t access_rights
,
79 enum samr_AliasInfoEnum level
,
80 union samr_AliasInfo
**alias_info
)
83 struct policy_handle alias_handle
;
84 union samr_AliasInfo
*_alias_info
= NULL
;
86 ZERO_STRUCT(alias_handle
);
88 status
= rpccli_samr_OpenAlias(pipe_cli
, mem_ctx
,
93 if (!NT_STATUS_IS_OK(status
)) {
97 status
= rpccli_samr_QueryAliasInfo(pipe_cli
, mem_ctx
,
101 if (!NT_STATUS_IS_OK(status
)) {
105 *alias_info
= _alias_info
;
108 if (is_valid_policy_hnd(&alias_handle
)) {
109 rpccli_samr_Close(pipe_cli
, mem_ctx
, &alias_handle
);
115 /****************************************************************
116 ****************************************************************/
118 WERROR
NetLocalGroupAdd_r(struct libnetapi_ctx
*ctx
,
119 struct NetLocalGroupAdd
*r
)
121 struct rpc_pipe_client
*pipe_cli
= NULL
;
124 struct lsa_String lsa_account_name
;
125 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
126 struct dom_sid2
*domain_sid
= NULL
;
129 struct LOCALGROUP_INFO_0
*info0
= NULL
;
130 struct LOCALGROUP_INFO_1
*info1
= NULL
;
132 const char *alias_name
= NULL
;
135 return WERR_INVALID_PARAM
;
138 switch (r
->in
.level
) {
140 info0
= (struct LOCALGROUP_INFO_0
*)r
->in
.buffer
;
141 alias_name
= info0
->lgrpi0_name
;
144 info1
= (struct LOCALGROUP_INFO_1
*)r
->in
.buffer
;
145 alias_name
= info1
->lgrpi1_name
;
148 werr
= WERR_UNKNOWN_LEVEL
;
152 ZERO_STRUCT(connect_handle
);
153 ZERO_STRUCT(builtin_handle
);
154 ZERO_STRUCT(domain_handle
);
155 ZERO_STRUCT(alias_handle
);
157 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
158 &ndr_table_samr
.syntax_id
,
160 if (!W_ERROR_IS_OK(werr
)) {
164 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
165 SAMR_ACCESS_LOOKUP_DOMAIN
|
166 SAMR_ACCESS_ENUM_DOMAINS
,
167 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
170 if (!W_ERROR_IS_OK(werr
)) {
174 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
177 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
179 if (ctx
->disable_policy_handle_cache
) {
180 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
183 if (NT_STATUS_IS_OK(status
)) {
184 werr
= WERR_ALIAS_EXISTS
;
188 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
189 SAMR_ACCESS_ENUM_DOMAINS
|
190 SAMR_ACCESS_LOOKUP_DOMAIN
,
191 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
192 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
196 if (!W_ERROR_IS_OK(werr
)) {
200 init_lsa_String(&lsa_account_name
, alias_name
);
202 status
= rpccli_samr_CreateDomAlias(pipe_cli
, ctx
,
206 SAMR_ALIAS_ACCESS_SET_INFO
,
209 if (!NT_STATUS_IS_OK(status
)) {
210 werr
= ntstatus_to_werror(status
);
214 if (r
->in
.level
== 1 && info1
->lgrpi1_comment
) {
216 union samr_AliasInfo alias_info
;
218 init_lsa_String(&alias_info
.description
, info1
->lgrpi1_comment
);
220 status
= rpccli_samr_SetAliasInfo(pipe_cli
, ctx
,
222 ALIASINFODESCRIPTION
,
224 if (!NT_STATUS_IS_OK(status
)) {
225 werr
= ntstatus_to_werror(status
);
233 if (is_valid_policy_hnd(&alias_handle
)) {
234 rpccli_samr_Close(pipe_cli
, ctx
, &alias_handle
);
237 if (ctx
->disable_policy_handle_cache
) {
238 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
239 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
240 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
246 /****************************************************************
247 ****************************************************************/
249 WERROR
NetLocalGroupAdd_l(struct libnetapi_ctx
*ctx
,
250 struct NetLocalGroupAdd
*r
)
252 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupAdd
);
255 /****************************************************************
256 ****************************************************************/
259 WERROR
NetLocalGroupDel_r(struct libnetapi_ctx
*ctx
,
260 struct NetLocalGroupDel
*r
)
262 struct rpc_pipe_client
*pipe_cli
= NULL
;
265 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
266 struct dom_sid2
*domain_sid
= NULL
;
268 if (!r
->in
.group_name
) {
269 return WERR_INVALID_PARAM
;
272 ZERO_STRUCT(connect_handle
);
273 ZERO_STRUCT(builtin_handle
);
274 ZERO_STRUCT(domain_handle
);
275 ZERO_STRUCT(alias_handle
);
277 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
278 &ndr_table_samr
.syntax_id
,
280 if (!W_ERROR_IS_OK(werr
)) {
284 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
285 SAMR_ACCESS_LOOKUP_DOMAIN
|
286 SAMR_ACCESS_ENUM_DOMAINS
,
287 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
290 if (!W_ERROR_IS_OK(werr
)) {
294 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
300 if (ctx
->disable_policy_handle_cache
) {
301 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
304 if (NT_STATUS_IS_OK(status
)) {
308 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
309 SAMR_ACCESS_ENUM_DOMAINS
|
310 SAMR_ACCESS_LOOKUP_DOMAIN
,
311 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
312 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
316 if (!W_ERROR_IS_OK(werr
)) {
320 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
326 if (ctx
->disable_policy_handle_cache
) {
327 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
330 if (!NT_STATUS_IS_OK(status
)) {
331 werr
= ntstatus_to_werror(status
);
337 status
= rpccli_samr_DeleteDomAlias(pipe_cli
, ctx
,
339 if (!NT_STATUS_IS_OK(status
)) {
340 werr
= ntstatus_to_werror(status
);
344 ZERO_STRUCT(alias_handle
);
349 if (is_valid_policy_hnd(&alias_handle
)) {
350 rpccli_samr_Close(pipe_cli
, ctx
, &alias_handle
);
353 if (ctx
->disable_policy_handle_cache
) {
354 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
355 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
356 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
362 /****************************************************************
363 ****************************************************************/
365 WERROR
NetLocalGroupDel_l(struct libnetapi_ctx
*ctx
,
366 struct NetLocalGroupDel
*r
)
368 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupDel
);
371 /****************************************************************
372 ****************************************************************/
374 static WERROR
map_alias_info_to_buffer(TALLOC_CTX
*mem_ctx
,
375 const char *alias_name
,
376 struct samr_AliasInfoAll
*info
,
378 uint32_t *entries_read
,
381 struct LOCALGROUP_INFO_0 g0
;
382 struct LOCALGROUP_INFO_1 g1
;
383 struct LOCALGROUP_INFO_1002 g1002
;
387 g0
.lgrpi0_name
= talloc_strdup(mem_ctx
, alias_name
);
388 W_ERROR_HAVE_NO_MEMORY(g0
.lgrpi0_name
);
390 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_0
, g0
,
391 (struct LOCALGROUP_INFO_0
**)buffer
, entries_read
);
395 g1
.lgrpi1_name
= talloc_strdup(mem_ctx
, alias_name
);
396 g1
.lgrpi1_comment
= talloc_strdup(mem_ctx
, info
->description
.string
);
397 W_ERROR_HAVE_NO_MEMORY(g1
.lgrpi1_name
);
399 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_1
, g1
,
400 (struct LOCALGROUP_INFO_1
**)buffer
, entries_read
);
404 g1002
.lgrpi1002_comment
= talloc_strdup(mem_ctx
, info
->description
.string
);
406 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_1002
, g1002
,
407 (struct LOCALGROUP_INFO_1002
**)buffer
, entries_read
);
411 return WERR_UNKNOWN_LEVEL
;
417 /****************************************************************
418 ****************************************************************/
420 WERROR
NetLocalGroupGetInfo_r(struct libnetapi_ctx
*ctx
,
421 struct NetLocalGroupGetInfo
*r
)
423 struct rpc_pipe_client
*pipe_cli
= NULL
;
426 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
427 struct dom_sid2
*domain_sid
= NULL
;
428 union samr_AliasInfo
*alias_info
= NULL
;
429 uint32_t entries_read
= 0;
431 if (!r
->in
.group_name
) {
432 return WERR_INVALID_PARAM
;
435 switch (r
->in
.level
) {
441 return WERR_UNKNOWN_LEVEL
;
444 ZERO_STRUCT(connect_handle
);
445 ZERO_STRUCT(builtin_handle
);
446 ZERO_STRUCT(domain_handle
);
447 ZERO_STRUCT(alias_handle
);
449 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
450 &ndr_table_samr
.syntax_id
,
452 if (!W_ERROR_IS_OK(werr
)) {
456 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
457 SAMR_ACCESS_LOOKUP_DOMAIN
|
458 SAMR_ACCESS_ENUM_DOMAINS
,
459 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
462 if (!W_ERROR_IS_OK(werr
)) {
466 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
469 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
472 if (ctx
->disable_policy_handle_cache
) {
473 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
476 if (NT_STATUS_IS_OK(status
)) {
480 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
481 SAMR_ACCESS_ENUM_DOMAINS
|
482 SAMR_ACCESS_LOOKUP_DOMAIN
,
483 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
484 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
488 if (!W_ERROR_IS_OK(werr
)) {
492 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
495 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
498 if (ctx
->disable_policy_handle_cache
) {
499 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
502 if (!NT_STATUS_IS_OK(status
)) {
503 werr
= ntstatus_to_werror(status
);
508 status
= rpccli_samr_QueryAliasInfo(pipe_cli
, ctx
,
512 if (!NT_STATUS_IS_OK(status
)) {
513 werr
= ntstatus_to_werror(status
);
517 werr
= map_alias_info_to_buffer(ctx
,
520 r
->in
.level
, &entries_read
,
524 if (is_valid_policy_hnd(&alias_handle
)) {
525 rpccli_samr_Close(pipe_cli
, ctx
, &alias_handle
);
528 if (ctx
->disable_policy_handle_cache
) {
529 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
530 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
531 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
537 /****************************************************************
538 ****************************************************************/
540 WERROR
NetLocalGroupGetInfo_l(struct libnetapi_ctx
*ctx
,
541 struct NetLocalGroupGetInfo
*r
)
543 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupGetInfo
);
546 /****************************************************************
547 ****************************************************************/
549 static WERROR
map_buffer_to_alias_info(TALLOC_CTX
*mem_ctx
,
552 enum samr_AliasInfoEnum
*alias_level
,
553 union samr_AliasInfo
**alias_info
)
555 struct LOCALGROUP_INFO_0
*info0
;
556 struct LOCALGROUP_INFO_1
*info1
;
557 struct LOCALGROUP_INFO_1002
*info1002
;
558 union samr_AliasInfo
*info
= NULL
;
560 info
= TALLOC_ZERO_P(mem_ctx
, union samr_AliasInfo
);
561 W_ERROR_HAVE_NO_MEMORY(info
);
565 info0
= (struct LOCALGROUP_INFO_0
*)buffer
;
566 init_lsa_String(&info
->name
, info0
->lgrpi0_name
);
567 *alias_level
= ALIASINFONAME
;
570 info1
= (struct LOCALGROUP_INFO_1
*)buffer
;
571 /* group name will be ignored */
572 init_lsa_String(&info
->description
, info1
->lgrpi1_comment
);
573 *alias_level
= ALIASINFODESCRIPTION
;
576 info1002
= (struct LOCALGROUP_INFO_1002
*)buffer
;
577 init_lsa_String(&info
->description
, info1002
->lgrpi1002_comment
);
578 *alias_level
= ALIASINFODESCRIPTION
;
587 /****************************************************************
588 ****************************************************************/
590 WERROR
NetLocalGroupSetInfo_r(struct libnetapi_ctx
*ctx
,
591 struct NetLocalGroupSetInfo
*r
)
593 struct rpc_pipe_client
*pipe_cli
= NULL
;
596 struct lsa_String lsa_account_name
;
597 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
598 struct dom_sid2
*domain_sid
= NULL
;
599 enum samr_AliasInfoEnum alias_level
= 0;
600 union samr_AliasInfo
*alias_info
= NULL
;
602 if (!r
->in
.group_name
) {
603 return WERR_INVALID_PARAM
;
606 switch (r
->in
.level
) {
612 return WERR_UNKNOWN_LEVEL
;
615 ZERO_STRUCT(connect_handle
);
616 ZERO_STRUCT(builtin_handle
);
617 ZERO_STRUCT(domain_handle
);
618 ZERO_STRUCT(alias_handle
);
620 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
621 &ndr_table_samr
.syntax_id
,
623 if (!W_ERROR_IS_OK(werr
)) {
627 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
628 SAMR_ACCESS_LOOKUP_DOMAIN
|
629 SAMR_ACCESS_ENUM_DOMAINS
,
630 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
633 if (!W_ERROR_IS_OK(werr
)) {
637 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
639 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
642 SAMR_ALIAS_ACCESS_SET_INFO
,
645 if (ctx
->disable_policy_handle_cache
) {
646 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
649 if (NT_STATUS_IS_OK(status
)) {
653 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
654 SAMR_ACCESS_ENUM_DOMAINS
|
655 SAMR_ACCESS_LOOKUP_DOMAIN
,
656 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
660 if (!W_ERROR_IS_OK(werr
)) {
664 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
667 SAMR_ALIAS_ACCESS_SET_INFO
,
669 if (!NT_STATUS_IS_OK(status
)) {
670 werr
= ntstatus_to_werror(status
);
674 if (ctx
->disable_policy_handle_cache
) {
675 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
680 werr
= map_buffer_to_alias_info(ctx
, r
->in
.level
, r
->in
.buffer
,
681 &alias_level
, &alias_info
);
682 if (!W_ERROR_IS_OK(werr
)) {
686 status
= rpccli_samr_SetAliasInfo(pipe_cli
, ctx
,
690 if (!NT_STATUS_IS_OK(status
)) {
691 werr
= ntstatus_to_werror(status
);
698 if (is_valid_policy_hnd(&alias_handle
)) {
699 rpccli_samr_Close(pipe_cli
, ctx
, &alias_handle
);
702 if (ctx
->disable_policy_handle_cache
) {
703 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
704 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
705 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
711 /****************************************************************
712 ****************************************************************/
714 WERROR
NetLocalGroupSetInfo_l(struct libnetapi_ctx
*ctx
,
715 struct NetLocalGroupSetInfo
*r
)
717 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupSetInfo
);
720 /****************************************************************
721 ****************************************************************/
723 WERROR
NetLocalGroupEnum_r(struct libnetapi_ctx
*ctx
,
724 struct NetLocalGroupEnum
*r
)
726 struct rpc_pipe_client
*pipe_cli
= NULL
;
729 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
730 struct dom_sid2
*domain_sid
= NULL
;
731 uint32_t entries_read
= 0;
732 union samr_DomainInfo
*domain_info
= NULL
;
733 union samr_DomainInfo
*builtin_info
= NULL
;
734 struct samr_SamArray
*domain_sam_array
= NULL
;
735 struct samr_SamArray
*builtin_sam_array
= NULL
;
738 if (!r
->out
.buffer
) {
739 return WERR_INVALID_PARAM
;
742 switch (r
->in
.level
) {
747 return WERR_UNKNOWN_LEVEL
;
750 if (r
->out
.total_entries
) {
751 *r
->out
.total_entries
= 0;
753 if (r
->out
.entries_read
) {
754 *r
->out
.entries_read
= 0;
757 ZERO_STRUCT(connect_handle
);
758 ZERO_STRUCT(builtin_handle
);
759 ZERO_STRUCT(domain_handle
);
760 ZERO_STRUCT(alias_handle
);
762 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
763 &ndr_table_samr
.syntax_id
,
765 if (!W_ERROR_IS_OK(werr
)) {
769 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
770 SAMR_ACCESS_LOOKUP_DOMAIN
|
771 SAMR_ACCESS_ENUM_DOMAINS
,
772 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
773 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
774 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
777 if (!W_ERROR_IS_OK(werr
)) {
781 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
782 SAMR_ACCESS_LOOKUP_DOMAIN
|
783 SAMR_ACCESS_ENUM_DOMAINS
,
784 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
785 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
786 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
790 if (!W_ERROR_IS_OK(werr
)) {
794 status
= rpccli_samr_QueryDomainInfo(pipe_cli
, ctx
,
798 if (!NT_STATUS_IS_OK(status
)) {
799 werr
= ntstatus_to_werror(status
);
803 if (r
->out
.total_entries
) {
804 *r
->out
.total_entries
+= builtin_info
->general
.num_aliases
;
807 status
= rpccli_samr_QueryDomainInfo(pipe_cli
, ctx
,
811 if (!NT_STATUS_IS_OK(status
)) {
812 werr
= ntstatus_to_werror(status
);
816 if (r
->out
.total_entries
) {
817 *r
->out
.total_entries
+= domain_info
->general
.num_aliases
;
820 status
= rpccli_samr_EnumDomainAliases(pipe_cli
, ctx
,
826 if (!NT_STATUS_IS_OK(status
)) {
827 werr
= ntstatus_to_werror(status
);
831 for (i
=0; i
<builtin_sam_array
->count
; i
++) {
832 union samr_AliasInfo
*alias_info
= NULL
;
834 if (r
->in
.level
== 1) {
836 status
= libnetapi_samr_open_alias_queryinfo(ctx
, pipe_cli
,
838 builtin_sam_array
->entries
[i
].idx
,
839 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
842 if (!NT_STATUS_IS_OK(status
)) {
843 werr
= ntstatus_to_werror(status
);
848 werr
= map_alias_info_to_buffer(ctx
,
849 builtin_sam_array
->entries
[i
].name
.string
,
850 alias_info
? &alias_info
->all
: NULL
,
856 status
= rpccli_samr_EnumDomainAliases(pipe_cli
, ctx
,
862 if (!NT_STATUS_IS_OK(status
)) {
863 werr
= ntstatus_to_werror(status
);
867 for (i
=0; i
<domain_sam_array
->count
; i
++) {
869 union samr_AliasInfo
*alias_info
= NULL
;
871 if (r
->in
.level
== 1) {
872 status
= libnetapi_samr_open_alias_queryinfo(ctx
, pipe_cli
,
874 domain_sam_array
->entries
[i
].idx
,
875 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
878 if (!NT_STATUS_IS_OK(status
)) {
879 werr
= ntstatus_to_werror(status
);
884 werr
= map_alias_info_to_buffer(ctx
,
885 domain_sam_array
->entries
[i
].name
.string
,
886 alias_info
? &alias_info
->all
: NULL
,
893 if (ctx
->disable_policy_handle_cache
) {
894 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
895 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
896 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
902 /****************************************************************
903 ****************************************************************/
905 WERROR
NetLocalGroupEnum_l(struct libnetapi_ctx
*ctx
,
906 struct NetLocalGroupEnum
*r
)
908 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupEnum
);
911 /****************************************************************
912 ****************************************************************/
914 static NTSTATUS
libnetapi_lsa_lookup_names3(TALLOC_CTX
*mem_ctx
,
915 struct rpc_pipe_client
*lsa_pipe
,
920 struct policy_handle lsa_handle
;
922 struct lsa_RefDomainList
*domains
= NULL
;
923 struct lsa_TransSidArray3 sids
;
926 struct lsa_String names
;
927 uint32_t num_names
= 1;
930 return NT_STATUS_INVALID_PARAMETER
;
935 init_lsa_String(&names
, name
);
937 status
= rpccli_lsa_open_policy2(lsa_pipe
, mem_ctx
,
939 SEC_STD_READ_CONTROL
|
940 LSA_POLICY_VIEW_LOCAL_INFORMATION
|
941 LSA_POLICY_LOOKUP_NAMES
,
943 NT_STATUS_NOT_OK_RETURN(status
);
945 status
= rpccli_lsa_LookupNames3(lsa_pipe
, mem_ctx
,
951 LSA_LOOKUP_NAMES_ALL
, /* sure ? */
954 NT_STATUS_NOT_OK_RETURN(status
);
956 if (count
!= 1 || sids
.count
!= 1) {
957 return NT_STATUS_NONE_MAPPED
;
960 sid_copy(sid
, sids
.sids
[0].sid
);
965 /****************************************************************
966 ****************************************************************/
968 static WERROR
NetLocalGroupModifyMembers_r(struct libnetapi_ctx
*ctx
,
969 struct NetLocalGroupAddMembers
*add
,
970 struct NetLocalGroupDelMembers
*del
,
971 struct NetLocalGroupSetMembers
*set
)
973 struct NetLocalGroupAddMembers
*r
= NULL
;
975 struct rpc_pipe_client
*pipe_cli
= NULL
;
976 struct rpc_pipe_client
*lsa_pipe
= NULL
;
979 struct lsa_String lsa_account_name
;
980 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
981 struct dom_sid2
*domain_sid
= NULL
;
982 struct dom_sid
*member_sids
= NULL
;
985 struct LOCALGROUP_MEMBERS_INFO_0
*info0
= NULL
;
986 struct LOCALGROUP_MEMBERS_INFO_3
*info3
= NULL
;
988 struct dom_sid
*add_sids
= NULL
;
989 struct dom_sid
*del_sids
= NULL
;
990 uint32_t num_add_sids
= 0;
991 uint32_t num_del_sids
= 0;
993 if ((!add
&& !del
&& !set
) || (add
&& del
&& set
)) {
994 return WERR_INVALID_PARAM
;
1002 r
= (struct NetLocalGroupAddMembers
*)del
;
1006 r
= (struct NetLocalGroupAddMembers
*)set
;
1009 if (!r
->in
.group_name
) {
1010 return WERR_INVALID_PARAM
;
1013 switch (r
->in
.level
) {
1018 return WERR_UNKNOWN_LEVEL
;
1021 if (r
->in
.total_entries
== 0 || !r
->in
.buffer
) {
1022 return WERR_INVALID_PARAM
;
1025 ZERO_STRUCT(connect_handle
);
1026 ZERO_STRUCT(builtin_handle
);
1027 ZERO_STRUCT(domain_handle
);
1028 ZERO_STRUCT(alias_handle
);
1030 member_sids
= TALLOC_ZERO_ARRAY(ctx
, struct dom_sid
,
1031 r
->in
.total_entries
);
1032 W_ERROR_HAVE_NO_MEMORY(member_sids
);
1034 switch (r
->in
.level
) {
1036 info0
= (struct LOCALGROUP_MEMBERS_INFO_0
*)r
->in
.buffer
;
1037 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1038 sid_copy(&member_sids
[i
], (struct dom_sid
*)info0
[i
].lgrmi0_sid
);
1042 info3
= (struct LOCALGROUP_MEMBERS_INFO_3
*)r
->in
.buffer
;
1048 if (r
->in
.level
== 3) {
1049 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1050 &ndr_table_lsarpc
.syntax_id
,
1052 if (!W_ERROR_IS_OK(werr
)) {
1056 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1057 status
= libnetapi_lsa_lookup_names3(ctx
, lsa_pipe
,
1058 info3
[i
].lgrmi3_domainandname
,
1060 if (!NT_STATUS_IS_OK(status
)) {
1061 werr
= ntstatus_to_werror(status
);
1065 TALLOC_FREE(lsa_pipe
);
1068 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1069 &ndr_table_samr
.syntax_id
,
1071 if (!W_ERROR_IS_OK(werr
)) {
1075 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1076 SAMR_ACCESS_LOOKUP_DOMAIN
|
1077 SAMR_ACCESS_ENUM_DOMAINS
,
1078 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1081 if (!W_ERROR_IS_OK(werr
)) {
1085 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
1087 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
1090 SAMR_ALIAS_ACCESS_ADD_MEMBER
|
1091 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
|
1092 SAMR_ALIAS_ACCESS_GET_MEMBERS
|
1093 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
1096 if (ctx
->disable_policy_handle_cache
) {
1097 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1100 if (NT_STATUS_IS_OK(status
)) {
1101 goto modify_membership
;
1104 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1105 SAMR_ACCESS_ENUM_DOMAINS
|
1106 SAMR_ACCESS_LOOKUP_DOMAIN
,
1107 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1111 if (!W_ERROR_IS_OK(werr
)) {
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
,
1123 if (!NT_STATUS_IS_OK(status
)) {
1124 werr
= ntstatus_to_werror(status
);
1128 if (ctx
->disable_policy_handle_cache
) {
1129 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1135 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1136 status
= add_sid_to_array_unique(ctx
, &member_sids
[i
],
1139 if (!NT_STATUS_IS_OK(status
)) {
1140 werr
= ntstatus_to_werror(status
);
1147 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1148 status
= add_sid_to_array_unique(ctx
, &member_sids
[i
],
1151 if (!NT_STATUS_IS_OK(status
)) {
1152 werr
= ntstatus_to_werror(status
);
1160 struct lsa_SidArray current_sids
;
1162 status
= rpccli_samr_GetMembersInAlias(pipe_cli
, ctx
,
1165 if (!NT_STATUS_IS_OK(status
)) {
1166 werr
= ntstatus_to_werror(status
);
1172 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1173 bool already_member
= false;
1174 for (k
=0; k
< current_sids
.num_sids
; k
++) {
1175 if (dom_sid_equal(&member_sids
[i
],
1176 current_sids
.sids
[k
].sid
)) {
1177 already_member
= true;
1181 if (!already_member
) {
1182 status
= add_sid_to_array_unique(ctx
,
1184 &add_sids
, &num_add_sids
);
1185 if (!NT_STATUS_IS_OK(status
)) {
1186 werr
= ntstatus_to_werror(status
);
1194 for (k
=0; k
< current_sids
.num_sids
; k
++) {
1195 bool keep_member
= false;
1196 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1197 if (dom_sid_equal(&member_sids
[i
],
1198 current_sids
.sids
[k
].sid
)) {
1204 status
= add_sid_to_array_unique(ctx
,
1205 current_sids
.sids
[k
].sid
,
1206 &del_sids
, &num_del_sids
);
1207 if (!NT_STATUS_IS_OK(status
)) {
1208 werr
= ntstatus_to_werror(status
);
1217 for (i
=0; i
< num_add_sids
; i
++) {
1218 status
= rpccli_samr_AddAliasMember(pipe_cli
, ctx
,
1221 if (!NT_STATUS_IS_OK(status
)) {
1222 werr
= ntstatus_to_werror(status
);
1229 for (i
=0; i
< num_del_sids
; i
++) {
1230 status
= rpccli_samr_DeleteAliasMember(pipe_cli
, ctx
,
1233 if (!NT_STATUS_IS_OK(status
)) {
1234 werr
= ntstatus_to_werror(status
);
1242 if (is_valid_policy_hnd(&alias_handle
)) {
1243 rpccli_samr_Close(pipe_cli
, ctx
, &alias_handle
);
1246 if (ctx
->disable_policy_handle_cache
) {
1247 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1248 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1249 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1255 /****************************************************************
1256 ****************************************************************/
1258 WERROR
NetLocalGroupAddMembers_r(struct libnetapi_ctx
*ctx
,
1259 struct NetLocalGroupAddMembers
*r
)
1261 return NetLocalGroupModifyMembers_r(ctx
, r
, NULL
, NULL
);
1264 /****************************************************************
1265 ****************************************************************/
1267 WERROR
NetLocalGroupAddMembers_l(struct libnetapi_ctx
*ctx
,
1268 struct NetLocalGroupAddMembers
*r
)
1270 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupAddMembers
);
1273 /****************************************************************
1274 ****************************************************************/
1276 WERROR
NetLocalGroupDelMembers_r(struct libnetapi_ctx
*ctx
,
1277 struct NetLocalGroupDelMembers
*r
)
1279 return NetLocalGroupModifyMembers_r(ctx
, NULL
, r
, NULL
);
1282 /****************************************************************
1283 ****************************************************************/
1285 WERROR
NetLocalGroupDelMembers_l(struct libnetapi_ctx
*ctx
,
1286 struct NetLocalGroupDelMembers
*r
)
1288 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupDelMembers
);
1291 /****************************************************************
1292 ****************************************************************/
1294 WERROR
NetLocalGroupGetMembers_r(struct libnetapi_ctx
*ctx
,
1295 struct NetLocalGroupGetMembers
*r
)
1297 return WERR_NOT_SUPPORTED
;
1300 /****************************************************************
1301 ****************************************************************/
1303 WERROR
NetLocalGroupGetMembers_l(struct libnetapi_ctx
*ctx
,
1304 struct NetLocalGroupGetMembers
*r
)
1306 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupGetMembers
);
1309 /****************************************************************
1310 ****************************************************************/
1312 WERROR
NetLocalGroupSetMembers_r(struct libnetapi_ctx
*ctx
,
1313 struct NetLocalGroupSetMembers
*r
)
1315 return NetLocalGroupModifyMembers_r(ctx
, NULL
, NULL
, r
);
1318 /****************************************************************
1319 ****************************************************************/
1321 WERROR
NetLocalGroupSetMembers_l(struct libnetapi_ctx
*ctx
,
1322 struct NetLocalGroupSetMembers
*r
)
1324 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupSetMembers
);