2 * Unix SMB/CIFS implementation.
3 * NetApi LocalGroup Support
4 * Copyright (C) Guenther Deschner 2008
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "librpc/gen_ndr/libnetapi.h"
23 #include "lib/netapi/netapi.h"
24 #include "lib/netapi/netapi_private.h"
25 #include "lib/netapi/libnetapi.h"
26 #include "rpc_client/rpc_client.h"
27 #include "../librpc/gen_ndr/ndr_samr_c.h"
28 #include "../librpc/gen_ndr/ndr_lsa_c.h"
29 #include "rpc_client/cli_lsarpc.h"
30 #include "rpc_client/init_lsa.h"
31 #include "../libcli/security/security.h"
33 static NTSTATUS
libnetapi_samr_lookup_and_open_alias(TALLOC_CTX
*mem_ctx
,
34 struct rpc_pipe_client
*pipe_cli
,
35 struct policy_handle
*domain_handle
,
36 const char *group_name
,
37 uint32_t access_rights
,
38 struct policy_handle
*alias_handle
)
40 NTSTATUS status
, result
;
42 struct lsa_String lsa_account_name
;
43 struct samr_Ids user_rids
, name_types
;
44 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
46 init_lsa_String(&lsa_account_name
, group_name
);
48 status
= dcerpc_samr_LookupNames(b
, mem_ctx
,
55 if (!NT_STATUS_IS_OK(status
)) {
58 if (!NT_STATUS_IS_OK(result
)) {
62 switch (name_types
.ids
[0]) {
64 case SID_NAME_WKN_GRP
:
67 return NT_STATUS_INVALID_SID
;
70 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
76 if (!NT_STATUS_IS_OK(status
)) {
83 /****************************************************************
84 ****************************************************************/
86 static NTSTATUS
libnetapi_samr_open_alias_queryinfo(TALLOC_CTX
*mem_ctx
,
87 struct rpc_pipe_client
*pipe_cli
,
88 struct policy_handle
*handle
,
90 uint32_t access_rights
,
91 enum samr_AliasInfoEnum level
,
92 union samr_AliasInfo
**alias_info
)
94 NTSTATUS status
, result
;
95 struct policy_handle alias_handle
;
96 union samr_AliasInfo
*_alias_info
= NULL
;
97 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
99 ZERO_STRUCT(alias_handle
);
101 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
107 if (!NT_STATUS_IS_OK(status
)) {
110 if (!NT_STATUS_IS_OK(result
)) {
115 status
= dcerpc_samr_QueryAliasInfo(b
, mem_ctx
,
120 if (!NT_STATUS_IS_OK(status
)) {
123 if (!NT_STATUS_IS_OK(result
)) {
128 *alias_info
= _alias_info
;
131 if (is_valid_policy_hnd(&alias_handle
)) {
132 dcerpc_samr_Close(b
, mem_ctx
, &alias_handle
, &result
);
138 /****************************************************************
139 ****************************************************************/
141 WERROR
NetLocalGroupAdd_r(struct libnetapi_ctx
*ctx
,
142 struct NetLocalGroupAdd
*r
)
144 struct rpc_pipe_client
*pipe_cli
= NULL
;
145 NTSTATUS status
, result
;
147 struct lsa_String lsa_account_name
;
148 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
149 struct dom_sid2
*domain_sid
= NULL
;
151 struct dcerpc_binding_handle
*b
= NULL
;
153 struct LOCALGROUP_INFO_0
*info0
= NULL
;
154 struct LOCALGROUP_INFO_1
*info1
= NULL
;
156 const char *alias_name
= NULL
;
159 return WERR_INVALID_PARAM
;
162 switch (r
->in
.level
) {
164 info0
= (struct LOCALGROUP_INFO_0
*)r
->in
.buffer
;
165 alias_name
= info0
->lgrpi0_name
;
168 info1
= (struct LOCALGROUP_INFO_1
*)r
->in
.buffer
;
169 alias_name
= info1
->lgrpi1_name
;
172 werr
= WERR_UNKNOWN_LEVEL
;
176 ZERO_STRUCT(connect_handle
);
177 ZERO_STRUCT(builtin_handle
);
178 ZERO_STRUCT(domain_handle
);
179 ZERO_STRUCT(alias_handle
);
181 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
182 &ndr_table_samr
.syntax_id
,
184 if (!W_ERROR_IS_OK(werr
)) {
188 b
= pipe_cli
->binding_handle
;
190 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
191 SAMR_ACCESS_LOOKUP_DOMAIN
|
192 SAMR_ACCESS_ENUM_DOMAINS
,
193 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
196 if (!W_ERROR_IS_OK(werr
)) {
200 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
203 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
205 if (ctx
->disable_policy_handle_cache
) {
206 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
209 if (NT_STATUS_IS_OK(status
)) {
210 werr
= WERR_ALIAS_EXISTS
;
214 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
215 SAMR_ACCESS_ENUM_DOMAINS
|
216 SAMR_ACCESS_LOOKUP_DOMAIN
,
217 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
218 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
222 if (!W_ERROR_IS_OK(werr
)) {
226 init_lsa_String(&lsa_account_name
, alias_name
);
228 status
= dcerpc_samr_CreateDomAlias(b
, talloc_tos(),
232 SAMR_ALIAS_ACCESS_SET_INFO
,
236 if (!NT_STATUS_IS_OK(status
)) {
237 werr
= ntstatus_to_werror(status
);
240 if (!NT_STATUS_IS_OK(result
)) {
241 werr
= ntstatus_to_werror(result
);
246 if (r
->in
.level
== 1 && info1
->lgrpi1_comment
) {
248 union samr_AliasInfo alias_info
;
250 init_lsa_String(&alias_info
.description
, info1
->lgrpi1_comment
);
252 status
= dcerpc_samr_SetAliasInfo(b
, talloc_tos(),
254 ALIASINFODESCRIPTION
,
257 if (!NT_STATUS_IS_OK(status
)) {
258 werr
= ntstatus_to_werror(status
);
261 if (!NT_STATUS_IS_OK(result
)) {
262 werr
= ntstatus_to_werror(result
);
270 if (is_valid_policy_hnd(&alias_handle
)) {
271 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
274 if (ctx
->disable_policy_handle_cache
) {
275 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
276 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
277 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
283 /****************************************************************
284 ****************************************************************/
286 WERROR
NetLocalGroupAdd_l(struct libnetapi_ctx
*ctx
,
287 struct NetLocalGroupAdd
*r
)
289 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupAdd
);
292 /****************************************************************
293 ****************************************************************/
296 WERROR
NetLocalGroupDel_r(struct libnetapi_ctx
*ctx
,
297 struct NetLocalGroupDel
*r
)
299 struct rpc_pipe_client
*pipe_cli
= NULL
;
300 NTSTATUS status
, result
;
302 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
303 struct dom_sid2
*domain_sid
= NULL
;
304 struct dcerpc_binding_handle
*b
= NULL
;
306 if (!r
->in
.group_name
) {
307 return WERR_INVALID_PARAM
;
310 ZERO_STRUCT(connect_handle
);
311 ZERO_STRUCT(builtin_handle
);
312 ZERO_STRUCT(domain_handle
);
313 ZERO_STRUCT(alias_handle
);
315 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
316 &ndr_table_samr
.syntax_id
,
318 if (!W_ERROR_IS_OK(werr
)) {
322 b
= pipe_cli
->binding_handle
;
324 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
325 SAMR_ACCESS_LOOKUP_DOMAIN
|
326 SAMR_ACCESS_ENUM_DOMAINS
,
327 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
330 if (!W_ERROR_IS_OK(werr
)) {
334 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
340 if (ctx
->disable_policy_handle_cache
) {
341 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
344 if (NT_STATUS_IS_OK(status
)) {
348 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
349 SAMR_ACCESS_ENUM_DOMAINS
|
350 SAMR_ACCESS_LOOKUP_DOMAIN
,
351 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
352 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
356 if (!W_ERROR_IS_OK(werr
)) {
360 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
366 if (ctx
->disable_policy_handle_cache
) {
367 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
370 if (!NT_STATUS_IS_OK(status
)) {
371 werr
= ntstatus_to_werror(status
);
377 status
= dcerpc_samr_DeleteDomAlias(b
, talloc_tos(),
380 if (!NT_STATUS_IS_OK(status
)) {
381 werr
= ntstatus_to_werror(status
);
384 if (!NT_STATUS_IS_OK(result
)) {
385 werr
= ntstatus_to_werror(result
);
389 ZERO_STRUCT(alias_handle
);
394 if (is_valid_policy_hnd(&alias_handle
)) {
395 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
398 if (ctx
->disable_policy_handle_cache
) {
399 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
400 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
401 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
407 /****************************************************************
408 ****************************************************************/
410 WERROR
NetLocalGroupDel_l(struct libnetapi_ctx
*ctx
,
411 struct NetLocalGroupDel
*r
)
413 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupDel
);
416 /****************************************************************
417 ****************************************************************/
419 static WERROR
map_alias_info_to_buffer(TALLOC_CTX
*mem_ctx
,
420 const char *alias_name
,
421 struct samr_AliasInfoAll
*info
,
423 uint32_t *entries_read
,
426 struct LOCALGROUP_INFO_0 g0
;
427 struct LOCALGROUP_INFO_1 g1
;
428 struct LOCALGROUP_INFO_1002 g1002
;
432 g0
.lgrpi0_name
= talloc_strdup(mem_ctx
, alias_name
);
433 W_ERROR_HAVE_NO_MEMORY(g0
.lgrpi0_name
);
435 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_0
, g0
,
436 (struct LOCALGROUP_INFO_0
**)buffer
, entries_read
);
440 g1
.lgrpi1_name
= talloc_strdup(mem_ctx
, alias_name
);
441 g1
.lgrpi1_comment
= talloc_strdup(mem_ctx
, info
->description
.string
);
442 W_ERROR_HAVE_NO_MEMORY(g1
.lgrpi1_name
);
444 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_1
, g1
,
445 (struct LOCALGROUP_INFO_1
**)buffer
, entries_read
);
449 g1002
.lgrpi1002_comment
= talloc_strdup(mem_ctx
, info
->description
.string
);
451 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_1002
, g1002
,
452 (struct LOCALGROUP_INFO_1002
**)buffer
, entries_read
);
456 return WERR_UNKNOWN_LEVEL
;
462 /****************************************************************
463 ****************************************************************/
465 WERROR
NetLocalGroupGetInfo_r(struct libnetapi_ctx
*ctx
,
466 struct NetLocalGroupGetInfo
*r
)
468 struct rpc_pipe_client
*pipe_cli
= NULL
;
469 NTSTATUS status
, result
;
471 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
472 struct dom_sid2
*domain_sid
= NULL
;
473 union samr_AliasInfo
*alias_info
= NULL
;
474 uint32_t entries_read
= 0;
475 struct dcerpc_binding_handle
*b
= NULL
;
477 if (!r
->in
.group_name
) {
478 return WERR_INVALID_PARAM
;
481 switch (r
->in
.level
) {
487 return WERR_UNKNOWN_LEVEL
;
490 ZERO_STRUCT(connect_handle
);
491 ZERO_STRUCT(builtin_handle
);
492 ZERO_STRUCT(domain_handle
);
493 ZERO_STRUCT(alias_handle
);
495 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
496 &ndr_table_samr
.syntax_id
,
498 if (!W_ERROR_IS_OK(werr
)) {
502 b
= pipe_cli
->binding_handle
;
504 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
505 SAMR_ACCESS_LOOKUP_DOMAIN
|
506 SAMR_ACCESS_ENUM_DOMAINS
,
507 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
510 if (!W_ERROR_IS_OK(werr
)) {
514 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
517 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
520 if (ctx
->disable_policy_handle_cache
) {
521 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
524 if (NT_STATUS_IS_OK(status
)) {
528 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
529 SAMR_ACCESS_ENUM_DOMAINS
|
530 SAMR_ACCESS_LOOKUP_DOMAIN
,
531 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
532 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
536 if (!W_ERROR_IS_OK(werr
)) {
540 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
543 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
546 if (ctx
->disable_policy_handle_cache
) {
547 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
550 if (!NT_STATUS_IS_OK(status
)) {
551 werr
= ntstatus_to_werror(status
);
556 status
= dcerpc_samr_QueryAliasInfo(b
, talloc_tos(),
561 if (!NT_STATUS_IS_OK(status
)) {
562 werr
= ntstatus_to_werror(status
);
565 if (!NT_STATUS_IS_OK(result
)) {
566 werr
= ntstatus_to_werror(result
);
570 werr
= map_alias_info_to_buffer(ctx
,
573 r
->in
.level
, &entries_read
,
577 if (is_valid_policy_hnd(&alias_handle
)) {
578 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
581 if (ctx
->disable_policy_handle_cache
) {
582 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
583 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
584 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
590 /****************************************************************
591 ****************************************************************/
593 WERROR
NetLocalGroupGetInfo_l(struct libnetapi_ctx
*ctx
,
594 struct NetLocalGroupGetInfo
*r
)
596 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupGetInfo
);
599 /****************************************************************
600 ****************************************************************/
602 static WERROR
map_buffer_to_alias_info(TALLOC_CTX
*mem_ctx
,
605 enum samr_AliasInfoEnum
*alias_level
,
606 union samr_AliasInfo
**alias_info
)
608 struct LOCALGROUP_INFO_0
*info0
;
609 struct LOCALGROUP_INFO_1
*info1
;
610 struct LOCALGROUP_INFO_1002
*info1002
;
611 union samr_AliasInfo
*info
= NULL
;
613 info
= talloc_zero(mem_ctx
, union samr_AliasInfo
);
614 W_ERROR_HAVE_NO_MEMORY(info
);
618 info0
= (struct LOCALGROUP_INFO_0
*)buffer
;
619 init_lsa_String(&info
->name
, info0
->lgrpi0_name
);
620 *alias_level
= ALIASINFONAME
;
623 info1
= (struct LOCALGROUP_INFO_1
*)buffer
;
624 /* group name will be ignored */
625 init_lsa_String(&info
->description
, info1
->lgrpi1_comment
);
626 *alias_level
= ALIASINFODESCRIPTION
;
629 info1002
= (struct LOCALGROUP_INFO_1002
*)buffer
;
630 init_lsa_String(&info
->description
, info1002
->lgrpi1002_comment
);
631 *alias_level
= ALIASINFODESCRIPTION
;
640 /****************************************************************
641 ****************************************************************/
643 WERROR
NetLocalGroupSetInfo_r(struct libnetapi_ctx
*ctx
,
644 struct NetLocalGroupSetInfo
*r
)
646 struct rpc_pipe_client
*pipe_cli
= NULL
;
647 NTSTATUS status
, result
;
649 struct lsa_String lsa_account_name
;
650 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
651 struct dom_sid2
*domain_sid
= NULL
;
652 enum samr_AliasInfoEnum alias_level
= 0;
653 union samr_AliasInfo
*alias_info
= NULL
;
654 struct dcerpc_binding_handle
*b
= NULL
;
656 if (!r
->in
.group_name
) {
657 return WERR_INVALID_PARAM
;
660 switch (r
->in
.level
) {
666 return WERR_UNKNOWN_LEVEL
;
669 ZERO_STRUCT(connect_handle
);
670 ZERO_STRUCT(builtin_handle
);
671 ZERO_STRUCT(domain_handle
);
672 ZERO_STRUCT(alias_handle
);
674 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
675 &ndr_table_samr
.syntax_id
,
677 if (!W_ERROR_IS_OK(werr
)) {
681 b
= pipe_cli
->binding_handle
;
683 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
684 SAMR_ACCESS_LOOKUP_DOMAIN
|
685 SAMR_ACCESS_ENUM_DOMAINS
,
686 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
689 if (!W_ERROR_IS_OK(werr
)) {
693 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
695 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
698 SAMR_ALIAS_ACCESS_SET_INFO
,
701 if (ctx
->disable_policy_handle_cache
) {
702 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
705 if (NT_STATUS_IS_OK(status
)) {
709 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
710 SAMR_ACCESS_ENUM_DOMAINS
|
711 SAMR_ACCESS_LOOKUP_DOMAIN
,
712 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
716 if (!W_ERROR_IS_OK(werr
)) {
720 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
723 SAMR_ALIAS_ACCESS_SET_INFO
,
725 if (!NT_STATUS_IS_OK(status
)) {
726 werr
= ntstatus_to_werror(status
);
730 if (ctx
->disable_policy_handle_cache
) {
731 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
736 werr
= map_buffer_to_alias_info(ctx
, r
->in
.level
, r
->in
.buffer
,
737 &alias_level
, &alias_info
);
738 if (!W_ERROR_IS_OK(werr
)) {
742 status
= dcerpc_samr_SetAliasInfo(b
, talloc_tos(),
747 if (!NT_STATUS_IS_OK(status
)) {
748 werr
= ntstatus_to_werror(status
);
751 if (!NT_STATUS_IS_OK(result
)) {
752 werr
= ntstatus_to_werror(result
);
759 if (is_valid_policy_hnd(&alias_handle
)) {
760 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
763 if (ctx
->disable_policy_handle_cache
) {
764 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
765 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
766 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
772 /****************************************************************
773 ****************************************************************/
775 WERROR
NetLocalGroupSetInfo_l(struct libnetapi_ctx
*ctx
,
776 struct NetLocalGroupSetInfo
*r
)
778 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupSetInfo
);
781 /****************************************************************
782 ****************************************************************/
784 WERROR
NetLocalGroupEnum_r(struct libnetapi_ctx
*ctx
,
785 struct NetLocalGroupEnum
*r
)
787 struct rpc_pipe_client
*pipe_cli
= NULL
;
788 NTSTATUS status
, result
;
790 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
791 struct dom_sid2
*domain_sid
= NULL
;
792 uint32_t entries_read
= 0;
793 union samr_DomainInfo
*domain_info
= NULL
;
794 union samr_DomainInfo
*builtin_info
= NULL
;
795 struct samr_SamArray
*domain_sam_array
= NULL
;
796 struct samr_SamArray
*builtin_sam_array
= NULL
;
798 struct dcerpc_binding_handle
*b
= NULL
;
800 if (!r
->out
.buffer
) {
801 return WERR_INVALID_PARAM
;
804 switch (r
->in
.level
) {
809 return WERR_UNKNOWN_LEVEL
;
812 if (r
->out
.total_entries
) {
813 *r
->out
.total_entries
= 0;
815 if (r
->out
.entries_read
) {
816 *r
->out
.entries_read
= 0;
819 ZERO_STRUCT(connect_handle
);
820 ZERO_STRUCT(builtin_handle
);
821 ZERO_STRUCT(domain_handle
);
822 ZERO_STRUCT(alias_handle
);
824 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
825 &ndr_table_samr
.syntax_id
,
827 if (!W_ERROR_IS_OK(werr
)) {
831 b
= pipe_cli
->binding_handle
;
833 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
834 SAMR_ACCESS_LOOKUP_DOMAIN
|
835 SAMR_ACCESS_ENUM_DOMAINS
,
836 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
837 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
838 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
841 if (!W_ERROR_IS_OK(werr
)) {
845 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
846 SAMR_ACCESS_LOOKUP_DOMAIN
|
847 SAMR_ACCESS_ENUM_DOMAINS
,
848 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
849 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
850 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
854 if (!W_ERROR_IS_OK(werr
)) {
858 status
= dcerpc_samr_QueryDomainInfo(b
, talloc_tos(),
863 if (!NT_STATUS_IS_OK(status
)) {
864 werr
= ntstatus_to_werror(status
);
867 if (!NT_STATUS_IS_OK(result
)) {
868 werr
= ntstatus_to_werror(result
);
872 if (r
->out
.total_entries
) {
873 *r
->out
.total_entries
+= builtin_info
->general
.num_aliases
;
876 status
= dcerpc_samr_QueryDomainInfo(b
, talloc_tos(),
881 if (!NT_STATUS_IS_OK(status
)) {
882 werr
= ntstatus_to_werror(status
);
885 if (!NT_STATUS_IS_OK(result
)) {
886 werr
= ntstatus_to_werror(result
);
890 if (r
->out
.total_entries
) {
891 *r
->out
.total_entries
+= domain_info
->general
.num_aliases
;
894 status
= dcerpc_samr_EnumDomainAliases(b
, talloc_tos(),
901 if (!NT_STATUS_IS_OK(status
)) {
902 werr
= ntstatus_to_werror(status
);
905 if (!NT_STATUS_IS_OK(result
)) {
906 werr
= ntstatus_to_werror(result
);
910 for (i
=0; i
<builtin_sam_array
->count
; i
++) {
911 union samr_AliasInfo
*alias_info
= NULL
;
913 if (r
->in
.level
== 1) {
915 status
= libnetapi_samr_open_alias_queryinfo(ctx
, pipe_cli
,
917 builtin_sam_array
->entries
[i
].idx
,
918 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
921 if (!NT_STATUS_IS_OK(status
)) {
922 werr
= ntstatus_to_werror(status
);
927 werr
= map_alias_info_to_buffer(ctx
,
928 builtin_sam_array
->entries
[i
].name
.string
,
929 alias_info
? &alias_info
->all
: NULL
,
935 status
= dcerpc_samr_EnumDomainAliases(b
, talloc_tos(),
942 if (!NT_STATUS_IS_OK(status
)) {
943 werr
= ntstatus_to_werror(status
);
946 if (!NT_STATUS_IS_OK(result
)) {
947 werr
= ntstatus_to_werror(result
);
951 for (i
=0; i
<domain_sam_array
->count
; i
++) {
953 union samr_AliasInfo
*alias_info
= NULL
;
955 if (r
->in
.level
== 1) {
956 status
= libnetapi_samr_open_alias_queryinfo(ctx
, pipe_cli
,
958 domain_sam_array
->entries
[i
].idx
,
959 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
962 if (!NT_STATUS_IS_OK(status
)) {
963 werr
= ntstatus_to_werror(status
);
968 werr
= map_alias_info_to_buffer(ctx
,
969 domain_sam_array
->entries
[i
].name
.string
,
970 alias_info
? &alias_info
->all
: NULL
,
977 if (ctx
->disable_policy_handle_cache
) {
978 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
979 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
980 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
986 /****************************************************************
987 ****************************************************************/
989 WERROR
NetLocalGroupEnum_l(struct libnetapi_ctx
*ctx
,
990 struct NetLocalGroupEnum
*r
)
992 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupEnum
);
995 /****************************************************************
996 ****************************************************************/
998 static NTSTATUS
libnetapi_lsa_lookup_names3(TALLOC_CTX
*mem_ctx
,
999 struct rpc_pipe_client
*lsa_pipe
,
1001 struct dom_sid
*sid
)
1003 NTSTATUS status
, result
;
1004 struct policy_handle lsa_handle
;
1005 struct dcerpc_binding_handle
*b
= lsa_pipe
->binding_handle
;
1007 struct lsa_RefDomainList
*domains
= NULL
;
1008 struct lsa_TransSidArray3 sids
;
1011 struct lsa_String names
;
1012 uint32_t num_names
= 1;
1014 if (!sid
|| !name
) {
1015 return NT_STATUS_INVALID_PARAMETER
;
1020 init_lsa_String(&names
, name
);
1022 status
= rpccli_lsa_open_policy2(lsa_pipe
, mem_ctx
,
1024 SEC_STD_READ_CONTROL
|
1025 LSA_POLICY_VIEW_LOCAL_INFORMATION
|
1026 LSA_POLICY_LOOKUP_NAMES
,
1028 NT_STATUS_NOT_OK_RETURN(status
);
1030 status
= dcerpc_lsa_LookupNames3(b
, mem_ctx
,
1036 LSA_LOOKUP_NAMES_ALL
, /* sure ? */
1040 NT_STATUS_NOT_OK_RETURN(status
);
1041 NT_STATUS_NOT_OK_RETURN(result
);
1043 if (count
!= 1 || sids
.count
!= 1) {
1044 return NT_STATUS_NONE_MAPPED
;
1047 sid_copy(sid
, sids
.sids
[0].sid
);
1049 return NT_STATUS_OK
;
1052 /****************************************************************
1053 ****************************************************************/
1055 static WERROR
NetLocalGroupModifyMembers_r(struct libnetapi_ctx
*ctx
,
1056 struct NetLocalGroupAddMembers
*add
,
1057 struct NetLocalGroupDelMembers
*del
,
1058 struct NetLocalGroupSetMembers
*set
)
1060 struct NetLocalGroupAddMembers
*r
= NULL
;
1062 struct rpc_pipe_client
*pipe_cli
= NULL
;
1063 struct rpc_pipe_client
*lsa_pipe
= NULL
;
1064 NTSTATUS status
, result
;
1066 struct lsa_String lsa_account_name
;
1067 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
1068 struct dom_sid2
*domain_sid
= NULL
;
1069 struct dom_sid
*member_sids
= NULL
;
1072 struct LOCALGROUP_MEMBERS_INFO_0
*info0
= NULL
;
1073 struct LOCALGROUP_MEMBERS_INFO_3
*info3
= NULL
;
1075 struct dom_sid
*add_sids
= NULL
;
1076 struct dom_sid
*del_sids
= NULL
;
1077 uint32_t num_add_sids
= 0;
1078 uint32_t num_del_sids
= 0;
1079 struct dcerpc_binding_handle
*b
= NULL
;
1081 if ((!add
&& !del
&& !set
) || (add
&& del
&& set
)) {
1082 return WERR_INVALID_PARAM
;
1090 r
= (struct NetLocalGroupAddMembers
*)del
;
1094 r
= (struct NetLocalGroupAddMembers
*)set
;
1097 if (!r
->in
.group_name
) {
1098 return WERR_INVALID_PARAM
;
1101 switch (r
->in
.level
) {
1106 return WERR_UNKNOWN_LEVEL
;
1109 if (r
->in
.total_entries
== 0 || !r
->in
.buffer
) {
1110 return WERR_INVALID_PARAM
;
1113 ZERO_STRUCT(connect_handle
);
1114 ZERO_STRUCT(builtin_handle
);
1115 ZERO_STRUCT(domain_handle
);
1116 ZERO_STRUCT(alias_handle
);
1118 member_sids
= talloc_zero_array(ctx
, struct dom_sid
,
1119 r
->in
.total_entries
);
1120 W_ERROR_HAVE_NO_MEMORY(member_sids
);
1122 switch (r
->in
.level
) {
1124 info0
= (struct LOCALGROUP_MEMBERS_INFO_0
*)r
->in
.buffer
;
1125 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1126 sid_copy(&member_sids
[i
], (struct dom_sid
*)info0
[i
].lgrmi0_sid
);
1130 info3
= (struct LOCALGROUP_MEMBERS_INFO_3
*)r
->in
.buffer
;
1136 if (r
->in
.level
== 3) {
1137 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1138 &ndr_table_lsarpc
.syntax_id
,
1140 if (!W_ERROR_IS_OK(werr
)) {
1144 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1145 status
= libnetapi_lsa_lookup_names3(ctx
, lsa_pipe
,
1146 info3
[i
].lgrmi3_domainandname
,
1148 if (!NT_STATUS_IS_OK(status
)) {
1149 werr
= ntstatus_to_werror(status
);
1153 TALLOC_FREE(lsa_pipe
);
1156 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1157 &ndr_table_samr
.syntax_id
,
1159 if (!W_ERROR_IS_OK(werr
)) {
1163 b
= pipe_cli
->binding_handle
;
1165 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1166 SAMR_ACCESS_LOOKUP_DOMAIN
|
1167 SAMR_ACCESS_ENUM_DOMAINS
,
1168 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1171 if (!W_ERROR_IS_OK(werr
)) {
1175 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
1177 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
1180 SAMR_ALIAS_ACCESS_ADD_MEMBER
|
1181 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
|
1182 SAMR_ALIAS_ACCESS_GET_MEMBERS
|
1183 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
1186 if (ctx
->disable_policy_handle_cache
) {
1187 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1190 if (NT_STATUS_IS_OK(status
)) {
1191 goto modify_membership
;
1194 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1195 SAMR_ACCESS_ENUM_DOMAINS
|
1196 SAMR_ACCESS_LOOKUP_DOMAIN
,
1197 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1201 if (!W_ERROR_IS_OK(werr
)) {
1205 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
1208 SAMR_ALIAS_ACCESS_ADD_MEMBER
|
1209 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
|
1210 SAMR_ALIAS_ACCESS_GET_MEMBERS
|
1211 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
1213 if (!NT_STATUS_IS_OK(status
)) {
1214 werr
= ntstatus_to_werror(status
);
1218 if (ctx
->disable_policy_handle_cache
) {
1219 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1225 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1226 status
= add_sid_to_array_unique(ctx
, &member_sids
[i
],
1229 if (!NT_STATUS_IS_OK(status
)) {
1230 werr
= ntstatus_to_werror(status
);
1237 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1238 status
= add_sid_to_array_unique(ctx
, &member_sids
[i
],
1241 if (!NT_STATUS_IS_OK(status
)) {
1242 werr
= ntstatus_to_werror(status
);
1250 struct lsa_SidArray current_sids
;
1252 status
= dcerpc_samr_GetMembersInAlias(b
, talloc_tos(),
1256 if (!NT_STATUS_IS_OK(status
)) {
1257 werr
= ntstatus_to_werror(status
);
1260 if (!NT_STATUS_IS_OK(result
)) {
1261 werr
= ntstatus_to_werror(result
);
1267 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1268 bool already_member
= false;
1269 for (k
=0; k
< current_sids
.num_sids
; k
++) {
1270 if (dom_sid_equal(&member_sids
[i
],
1271 current_sids
.sids
[k
].sid
)) {
1272 already_member
= true;
1276 if (!already_member
) {
1277 status
= add_sid_to_array_unique(ctx
,
1279 &add_sids
, &num_add_sids
);
1280 if (!NT_STATUS_IS_OK(status
)) {
1281 werr
= ntstatus_to_werror(status
);
1289 for (k
=0; k
< current_sids
.num_sids
; k
++) {
1290 bool keep_member
= false;
1291 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1292 if (dom_sid_equal(&member_sids
[i
],
1293 current_sids
.sids
[k
].sid
)) {
1299 status
= add_sid_to_array_unique(ctx
,
1300 current_sids
.sids
[k
].sid
,
1301 &del_sids
, &num_del_sids
);
1302 if (!NT_STATUS_IS_OK(status
)) {
1303 werr
= ntstatus_to_werror(status
);
1312 for (i
=0; i
< num_add_sids
; i
++) {
1313 status
= dcerpc_samr_AddAliasMember(b
, talloc_tos(),
1317 if (!NT_STATUS_IS_OK(status
)) {
1318 werr
= ntstatus_to_werror(status
);
1321 if (!NT_STATUS_IS_OK(result
)) {
1322 werr
= ntstatus_to_werror(result
);
1329 for (i
=0; i
< num_del_sids
; i
++) {
1330 status
= dcerpc_samr_DeleteAliasMember(b
, talloc_tos(),
1334 if (!NT_STATUS_IS_OK(status
)) {
1335 werr
= ntstatus_to_werror(status
);
1338 if (!NT_STATUS_IS_OK(result
)) {
1339 werr
= ntstatus_to_werror(result
);
1347 if (b
&& is_valid_policy_hnd(&alias_handle
)) {
1348 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
1351 if (ctx
->disable_policy_handle_cache
) {
1352 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1353 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1354 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1360 /****************************************************************
1361 ****************************************************************/
1363 WERROR
NetLocalGroupAddMembers_r(struct libnetapi_ctx
*ctx
,
1364 struct NetLocalGroupAddMembers
*r
)
1366 return NetLocalGroupModifyMembers_r(ctx
, r
, NULL
, NULL
);
1369 /****************************************************************
1370 ****************************************************************/
1372 WERROR
NetLocalGroupAddMembers_l(struct libnetapi_ctx
*ctx
,
1373 struct NetLocalGroupAddMembers
*r
)
1375 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupAddMembers
);
1378 /****************************************************************
1379 ****************************************************************/
1381 WERROR
NetLocalGroupDelMembers_r(struct libnetapi_ctx
*ctx
,
1382 struct NetLocalGroupDelMembers
*r
)
1384 return NetLocalGroupModifyMembers_r(ctx
, NULL
, r
, NULL
);
1387 /****************************************************************
1388 ****************************************************************/
1390 WERROR
NetLocalGroupDelMembers_l(struct libnetapi_ctx
*ctx
,
1391 struct NetLocalGroupDelMembers
*r
)
1393 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupDelMembers
);
1396 /****************************************************************
1397 ****************************************************************/
1399 WERROR
NetLocalGroupGetMembers_r(struct libnetapi_ctx
*ctx
,
1400 struct NetLocalGroupGetMembers
*r
)
1402 return WERR_NOT_SUPPORTED
;
1405 /****************************************************************
1406 ****************************************************************/
1408 WERROR
NetLocalGroupGetMembers_l(struct libnetapi_ctx
*ctx
,
1409 struct NetLocalGroupGetMembers
*r
)
1411 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupGetMembers
);
1414 /****************************************************************
1415 ****************************************************************/
1417 WERROR
NetLocalGroupSetMembers_r(struct libnetapi_ctx
*ctx
,
1418 struct NetLocalGroupSetMembers
*r
)
1420 return NetLocalGroupModifyMembers_r(ctx
, NULL
, NULL
, r
);
1423 /****************************************************************
1424 ****************************************************************/
1426 WERROR
NetLocalGroupSetMembers_l(struct libnetapi_ctx
*ctx
,
1427 struct NetLocalGroupSetMembers
*r
)
1429 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupSetMembers
);