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
)) {
61 if (user_rids
.count
!= 1) {
62 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
64 if (name_types
.count
!= 1) {
65 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
68 switch (name_types
.ids
[0]) {
70 case SID_NAME_WKN_GRP
:
73 return NT_STATUS_INVALID_SID
;
76 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
82 if (!NT_STATUS_IS_OK(status
)) {
89 /****************************************************************
90 ****************************************************************/
92 static NTSTATUS
libnetapi_samr_open_alias_queryinfo(TALLOC_CTX
*mem_ctx
,
93 struct rpc_pipe_client
*pipe_cli
,
94 struct policy_handle
*handle
,
96 uint32_t access_rights
,
97 enum samr_AliasInfoEnum level
,
98 union samr_AliasInfo
**alias_info
)
100 NTSTATUS status
, result
;
101 struct policy_handle alias_handle
;
102 union samr_AliasInfo
*_alias_info
= NULL
;
103 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
105 ZERO_STRUCT(alias_handle
);
107 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
113 if (!NT_STATUS_IS_OK(status
)) {
116 if (!NT_STATUS_IS_OK(result
)) {
121 status
= dcerpc_samr_QueryAliasInfo(b
, mem_ctx
,
126 if (!NT_STATUS_IS_OK(status
)) {
129 if (!NT_STATUS_IS_OK(result
)) {
134 *alias_info
= _alias_info
;
137 if (is_valid_policy_hnd(&alias_handle
)) {
138 dcerpc_samr_Close(b
, mem_ctx
, &alias_handle
, &result
);
144 /****************************************************************
145 ****************************************************************/
147 WERROR
NetLocalGroupAdd_r(struct libnetapi_ctx
*ctx
,
148 struct NetLocalGroupAdd
*r
)
150 struct rpc_pipe_client
*pipe_cli
= NULL
;
151 NTSTATUS status
, result
;
153 struct lsa_String lsa_account_name
;
154 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
155 struct dom_sid2
*domain_sid
= NULL
;
157 struct dcerpc_binding_handle
*b
= NULL
;
159 struct LOCALGROUP_INFO_0
*info0
= NULL
;
160 struct LOCALGROUP_INFO_1
*info1
= NULL
;
162 const char *alias_name
= NULL
;
165 return WERR_INVALID_PARAM
;
168 ZERO_STRUCT(connect_handle
);
169 ZERO_STRUCT(builtin_handle
);
170 ZERO_STRUCT(domain_handle
);
171 ZERO_STRUCT(alias_handle
);
173 switch (r
->in
.level
) {
175 info0
= (struct LOCALGROUP_INFO_0
*)r
->in
.buffer
;
176 alias_name
= info0
->lgrpi0_name
;
179 info1
= (struct LOCALGROUP_INFO_1
*)r
->in
.buffer
;
180 alias_name
= info1
->lgrpi1_name
;
183 werr
= WERR_UNKNOWN_LEVEL
;
187 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
190 if (!W_ERROR_IS_OK(werr
)) {
194 b
= pipe_cli
->binding_handle
;
196 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
197 SAMR_ACCESS_LOOKUP_DOMAIN
|
198 SAMR_ACCESS_ENUM_DOMAINS
,
199 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
202 if (!W_ERROR_IS_OK(werr
)) {
206 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
209 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
211 if (ctx
->disable_policy_handle_cache
) {
212 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
215 if (NT_STATUS_IS_OK(status
)) {
216 werr
= WERR_ALIAS_EXISTS
;
220 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
221 SAMR_ACCESS_ENUM_DOMAINS
|
222 SAMR_ACCESS_LOOKUP_DOMAIN
,
223 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
224 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
228 if (!W_ERROR_IS_OK(werr
)) {
232 init_lsa_String(&lsa_account_name
, alias_name
);
234 status
= dcerpc_samr_CreateDomAlias(b
, talloc_tos(),
238 SAMR_ALIAS_ACCESS_SET_INFO
,
242 if (!NT_STATUS_IS_OK(status
)) {
243 werr
= ntstatus_to_werror(status
);
246 if (!NT_STATUS_IS_OK(result
)) {
247 werr
= ntstatus_to_werror(result
);
252 if (r
->in
.level
== 1 && info1
->lgrpi1_comment
) {
254 union samr_AliasInfo alias_info
;
256 init_lsa_String(&alias_info
.description
, info1
->lgrpi1_comment
);
258 status
= dcerpc_samr_SetAliasInfo(b
, talloc_tos(),
260 ALIASINFODESCRIPTION
,
263 if (!NT_STATUS_IS_OK(status
)) {
264 werr
= ntstatus_to_werror(status
);
267 if (!NT_STATUS_IS_OK(result
)) {
268 werr
= ntstatus_to_werror(result
);
276 if (is_valid_policy_hnd(&alias_handle
)) {
277 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
280 if (ctx
->disable_policy_handle_cache
) {
281 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
282 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
283 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
289 /****************************************************************
290 ****************************************************************/
292 WERROR
NetLocalGroupAdd_l(struct libnetapi_ctx
*ctx
,
293 struct NetLocalGroupAdd
*r
)
295 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupAdd
);
298 /****************************************************************
299 ****************************************************************/
302 WERROR
NetLocalGroupDel_r(struct libnetapi_ctx
*ctx
,
303 struct NetLocalGroupDel
*r
)
305 struct rpc_pipe_client
*pipe_cli
= NULL
;
306 NTSTATUS status
, result
;
308 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
309 struct dom_sid2
*domain_sid
= NULL
;
310 struct dcerpc_binding_handle
*b
= NULL
;
312 if (!r
->in
.group_name
) {
313 return WERR_INVALID_PARAM
;
316 ZERO_STRUCT(connect_handle
);
317 ZERO_STRUCT(builtin_handle
);
318 ZERO_STRUCT(domain_handle
);
319 ZERO_STRUCT(alias_handle
);
321 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
324 if (!W_ERROR_IS_OK(werr
)) {
328 b
= pipe_cli
->binding_handle
;
330 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
331 SAMR_ACCESS_LOOKUP_DOMAIN
|
332 SAMR_ACCESS_ENUM_DOMAINS
,
333 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
336 if (!W_ERROR_IS_OK(werr
)) {
340 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
346 if (ctx
->disable_policy_handle_cache
) {
347 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
350 if (NT_STATUS_IS_OK(status
)) {
354 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
355 SAMR_ACCESS_ENUM_DOMAINS
|
356 SAMR_ACCESS_LOOKUP_DOMAIN
,
357 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
358 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
362 if (!W_ERROR_IS_OK(werr
)) {
366 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
372 if (ctx
->disable_policy_handle_cache
) {
373 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
376 if (!NT_STATUS_IS_OK(status
)) {
377 werr
= ntstatus_to_werror(status
);
383 status
= dcerpc_samr_DeleteDomAlias(b
, talloc_tos(),
386 if (!NT_STATUS_IS_OK(status
)) {
387 werr
= ntstatus_to_werror(status
);
390 if (!NT_STATUS_IS_OK(result
)) {
391 werr
= ntstatus_to_werror(result
);
395 ZERO_STRUCT(alias_handle
);
400 if (is_valid_policy_hnd(&alias_handle
)) {
401 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
404 if (ctx
->disable_policy_handle_cache
) {
405 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
406 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
407 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
413 /****************************************************************
414 ****************************************************************/
416 WERROR
NetLocalGroupDel_l(struct libnetapi_ctx
*ctx
,
417 struct NetLocalGroupDel
*r
)
419 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupDel
);
422 /****************************************************************
423 ****************************************************************/
425 static WERROR
map_alias_info_to_buffer(TALLOC_CTX
*mem_ctx
,
426 const char *alias_name
,
427 struct samr_AliasInfoAll
*info
,
429 uint32_t *entries_read
,
432 struct LOCALGROUP_INFO_0 g0
;
433 struct LOCALGROUP_INFO_1 g1
;
434 struct LOCALGROUP_INFO_1002 g1002
;
438 g0
.lgrpi0_name
= talloc_strdup(mem_ctx
, alias_name
);
439 W_ERROR_HAVE_NO_MEMORY(g0
.lgrpi0_name
);
441 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_0
, g0
,
442 (struct LOCALGROUP_INFO_0
**)buffer
, entries_read
);
446 g1
.lgrpi1_name
= talloc_strdup(mem_ctx
, alias_name
);
447 g1
.lgrpi1_comment
= talloc_strdup(mem_ctx
, info
->description
.string
);
448 W_ERROR_HAVE_NO_MEMORY(g1
.lgrpi1_name
);
450 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_1
, g1
,
451 (struct LOCALGROUP_INFO_1
**)buffer
, entries_read
);
455 g1002
.lgrpi1002_comment
= talloc_strdup(mem_ctx
, info
->description
.string
);
457 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_1002
, g1002
,
458 (struct LOCALGROUP_INFO_1002
**)buffer
, entries_read
);
462 return WERR_UNKNOWN_LEVEL
;
468 /****************************************************************
469 ****************************************************************/
471 WERROR
NetLocalGroupGetInfo_r(struct libnetapi_ctx
*ctx
,
472 struct NetLocalGroupGetInfo
*r
)
474 struct rpc_pipe_client
*pipe_cli
= NULL
;
475 NTSTATUS status
, result
;
477 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
478 struct dom_sid2
*domain_sid
= NULL
;
479 union samr_AliasInfo
*alias_info
= NULL
;
480 uint32_t entries_read
= 0;
481 struct dcerpc_binding_handle
*b
= NULL
;
483 if (!r
->in
.group_name
) {
484 return WERR_INVALID_PARAM
;
487 switch (r
->in
.level
) {
493 return WERR_UNKNOWN_LEVEL
;
496 ZERO_STRUCT(connect_handle
);
497 ZERO_STRUCT(builtin_handle
);
498 ZERO_STRUCT(domain_handle
);
499 ZERO_STRUCT(alias_handle
);
501 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
504 if (!W_ERROR_IS_OK(werr
)) {
508 b
= pipe_cli
->binding_handle
;
510 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
511 SAMR_ACCESS_LOOKUP_DOMAIN
|
512 SAMR_ACCESS_ENUM_DOMAINS
,
513 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
516 if (!W_ERROR_IS_OK(werr
)) {
520 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
523 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
526 if (ctx
->disable_policy_handle_cache
) {
527 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
530 if (NT_STATUS_IS_OK(status
)) {
534 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
535 SAMR_ACCESS_ENUM_DOMAINS
|
536 SAMR_ACCESS_LOOKUP_DOMAIN
,
537 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
538 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
542 if (!W_ERROR_IS_OK(werr
)) {
546 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
549 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
552 if (ctx
->disable_policy_handle_cache
) {
553 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
556 if (!NT_STATUS_IS_OK(status
)) {
557 werr
= ntstatus_to_werror(status
);
562 status
= dcerpc_samr_QueryAliasInfo(b
, talloc_tos(),
567 if (!NT_STATUS_IS_OK(status
)) {
568 werr
= ntstatus_to_werror(status
);
571 if (!NT_STATUS_IS_OK(result
)) {
572 werr
= ntstatus_to_werror(result
);
576 werr
= map_alias_info_to_buffer(ctx
,
579 r
->in
.level
, &entries_read
,
583 if (is_valid_policy_hnd(&alias_handle
)) {
584 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
587 if (ctx
->disable_policy_handle_cache
) {
588 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
589 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
590 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
596 /****************************************************************
597 ****************************************************************/
599 WERROR
NetLocalGroupGetInfo_l(struct libnetapi_ctx
*ctx
,
600 struct NetLocalGroupGetInfo
*r
)
602 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupGetInfo
);
605 /****************************************************************
606 ****************************************************************/
608 static WERROR
map_buffer_to_alias_info(TALLOC_CTX
*mem_ctx
,
611 enum samr_AliasInfoEnum
*alias_level
,
612 union samr_AliasInfo
**alias_info
)
614 struct LOCALGROUP_INFO_0
*info0
;
615 struct LOCALGROUP_INFO_1
*info1
;
616 struct LOCALGROUP_INFO_1002
*info1002
;
617 union samr_AliasInfo
*info
= NULL
;
619 info
= talloc_zero(mem_ctx
, union samr_AliasInfo
);
620 W_ERROR_HAVE_NO_MEMORY(info
);
624 info0
= (struct LOCALGROUP_INFO_0
*)buffer
;
625 init_lsa_String(&info
->name
, info0
->lgrpi0_name
);
626 *alias_level
= ALIASINFONAME
;
629 info1
= (struct LOCALGROUP_INFO_1
*)buffer
;
630 /* group name will be ignored */
631 init_lsa_String(&info
->description
, info1
->lgrpi1_comment
);
632 *alias_level
= ALIASINFODESCRIPTION
;
635 info1002
= (struct LOCALGROUP_INFO_1002
*)buffer
;
636 init_lsa_String(&info
->description
, info1002
->lgrpi1002_comment
);
637 *alias_level
= ALIASINFODESCRIPTION
;
646 /****************************************************************
647 ****************************************************************/
649 WERROR
NetLocalGroupSetInfo_r(struct libnetapi_ctx
*ctx
,
650 struct NetLocalGroupSetInfo
*r
)
652 struct rpc_pipe_client
*pipe_cli
= NULL
;
653 NTSTATUS status
, result
;
655 struct lsa_String lsa_account_name
;
656 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
657 struct dom_sid2
*domain_sid
= NULL
;
658 enum samr_AliasInfoEnum alias_level
= 0;
659 union samr_AliasInfo
*alias_info
= NULL
;
660 struct dcerpc_binding_handle
*b
= NULL
;
662 if (!r
->in
.group_name
) {
663 return WERR_INVALID_PARAM
;
666 switch (r
->in
.level
) {
672 return WERR_UNKNOWN_LEVEL
;
675 ZERO_STRUCT(connect_handle
);
676 ZERO_STRUCT(builtin_handle
);
677 ZERO_STRUCT(domain_handle
);
678 ZERO_STRUCT(alias_handle
);
680 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
683 if (!W_ERROR_IS_OK(werr
)) {
687 b
= pipe_cli
->binding_handle
;
689 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
690 SAMR_ACCESS_LOOKUP_DOMAIN
|
691 SAMR_ACCESS_ENUM_DOMAINS
,
692 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
695 if (!W_ERROR_IS_OK(werr
)) {
699 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
701 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
704 SAMR_ALIAS_ACCESS_SET_INFO
,
707 if (ctx
->disable_policy_handle_cache
) {
708 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
711 if (NT_STATUS_IS_OK(status
)) {
715 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
716 SAMR_ACCESS_ENUM_DOMAINS
|
717 SAMR_ACCESS_LOOKUP_DOMAIN
,
718 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
722 if (!W_ERROR_IS_OK(werr
)) {
726 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
729 SAMR_ALIAS_ACCESS_SET_INFO
,
731 if (!NT_STATUS_IS_OK(status
)) {
732 werr
= ntstatus_to_werror(status
);
736 if (ctx
->disable_policy_handle_cache
) {
737 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
742 werr
= map_buffer_to_alias_info(ctx
, r
->in
.level
, r
->in
.buffer
,
743 &alias_level
, &alias_info
);
744 if (!W_ERROR_IS_OK(werr
)) {
748 status
= dcerpc_samr_SetAliasInfo(b
, talloc_tos(),
753 if (!NT_STATUS_IS_OK(status
)) {
754 werr
= ntstatus_to_werror(status
);
757 if (!NT_STATUS_IS_OK(result
)) {
758 werr
= ntstatus_to_werror(result
);
765 if (is_valid_policy_hnd(&alias_handle
)) {
766 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
769 if (ctx
->disable_policy_handle_cache
) {
770 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
771 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
772 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
778 /****************************************************************
779 ****************************************************************/
781 WERROR
NetLocalGroupSetInfo_l(struct libnetapi_ctx
*ctx
,
782 struct NetLocalGroupSetInfo
*r
)
784 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupSetInfo
);
787 /****************************************************************
788 ****************************************************************/
790 WERROR
NetLocalGroupEnum_r(struct libnetapi_ctx
*ctx
,
791 struct NetLocalGroupEnum
*r
)
793 struct rpc_pipe_client
*pipe_cli
= NULL
;
794 NTSTATUS status
, result
;
796 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
797 struct dom_sid2
*domain_sid
= NULL
;
798 uint32_t entries_read
= 0;
799 union samr_DomainInfo
*domain_info
= NULL
;
800 union samr_DomainInfo
*builtin_info
= NULL
;
801 struct samr_SamArray
*domain_sam_array
= NULL
;
802 struct samr_SamArray
*builtin_sam_array
= NULL
;
804 struct dcerpc_binding_handle
*b
= NULL
;
806 if (!r
->out
.buffer
) {
807 return WERR_INVALID_PARAM
;
810 switch (r
->in
.level
) {
815 return WERR_UNKNOWN_LEVEL
;
818 if (r
->out
.total_entries
) {
819 *r
->out
.total_entries
= 0;
821 if (r
->out
.entries_read
) {
822 *r
->out
.entries_read
= 0;
825 ZERO_STRUCT(connect_handle
);
826 ZERO_STRUCT(builtin_handle
);
827 ZERO_STRUCT(domain_handle
);
828 ZERO_STRUCT(alias_handle
);
830 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
833 if (!W_ERROR_IS_OK(werr
)) {
837 b
= pipe_cli
->binding_handle
;
839 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
840 SAMR_ACCESS_LOOKUP_DOMAIN
|
841 SAMR_ACCESS_ENUM_DOMAINS
,
842 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
843 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
844 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
847 if (!W_ERROR_IS_OK(werr
)) {
851 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
852 SAMR_ACCESS_LOOKUP_DOMAIN
|
853 SAMR_ACCESS_ENUM_DOMAINS
,
854 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
855 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
856 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
860 if (!W_ERROR_IS_OK(werr
)) {
864 status
= dcerpc_samr_QueryDomainInfo(b
, talloc_tos(),
869 if (!NT_STATUS_IS_OK(status
)) {
870 werr
= ntstatus_to_werror(status
);
873 if (!NT_STATUS_IS_OK(result
)) {
874 werr
= ntstatus_to_werror(result
);
878 if (r
->out
.total_entries
) {
879 *r
->out
.total_entries
+= builtin_info
->general
.num_aliases
;
882 status
= dcerpc_samr_QueryDomainInfo(b
, talloc_tos(),
887 if (!NT_STATUS_IS_OK(status
)) {
888 werr
= ntstatus_to_werror(status
);
891 if (!NT_STATUS_IS_OK(result
)) {
892 werr
= ntstatus_to_werror(result
);
896 if (r
->out
.total_entries
) {
897 *r
->out
.total_entries
+= domain_info
->general
.num_aliases
;
900 status
= dcerpc_samr_EnumDomainAliases(b
, talloc_tos(),
907 if (!NT_STATUS_IS_OK(status
)) {
908 werr
= ntstatus_to_werror(status
);
911 if (!NT_STATUS_IS_OK(result
)) {
912 werr
= ntstatus_to_werror(result
);
916 for (i
=0; i
<builtin_sam_array
->count
; i
++) {
917 union samr_AliasInfo
*alias_info
= NULL
;
919 if (r
->in
.level
== 1) {
921 status
= libnetapi_samr_open_alias_queryinfo(ctx
, pipe_cli
,
923 builtin_sam_array
->entries
[i
].idx
,
924 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
927 if (!NT_STATUS_IS_OK(status
)) {
928 werr
= ntstatus_to_werror(status
);
933 werr
= map_alias_info_to_buffer(ctx
,
934 builtin_sam_array
->entries
[i
].name
.string
,
935 alias_info
? &alias_info
->all
: NULL
,
941 status
= dcerpc_samr_EnumDomainAliases(b
, talloc_tos(),
948 if (!NT_STATUS_IS_OK(status
)) {
949 werr
= ntstatus_to_werror(status
);
952 if (!NT_STATUS_IS_OK(result
)) {
953 werr
= ntstatus_to_werror(result
);
957 for (i
=0; i
<domain_sam_array
->count
; i
++) {
959 union samr_AliasInfo
*alias_info
= NULL
;
961 if (r
->in
.level
== 1) {
962 status
= libnetapi_samr_open_alias_queryinfo(ctx
, pipe_cli
,
964 domain_sam_array
->entries
[i
].idx
,
965 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
968 if (!NT_STATUS_IS_OK(status
)) {
969 werr
= ntstatus_to_werror(status
);
974 werr
= map_alias_info_to_buffer(ctx
,
975 domain_sam_array
->entries
[i
].name
.string
,
976 alias_info
? &alias_info
->all
: NULL
,
983 if (ctx
->disable_policy_handle_cache
) {
984 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
985 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
986 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
992 /****************************************************************
993 ****************************************************************/
995 WERROR
NetLocalGroupEnum_l(struct libnetapi_ctx
*ctx
,
996 struct NetLocalGroupEnum
*r
)
998 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupEnum
);
1001 /****************************************************************
1002 ****************************************************************/
1004 static NTSTATUS
libnetapi_lsa_lookup_names3(TALLOC_CTX
*mem_ctx
,
1005 struct rpc_pipe_client
*lsa_pipe
,
1007 struct dom_sid
*sid
)
1009 NTSTATUS status
, result
;
1010 struct policy_handle lsa_handle
;
1011 struct dcerpc_binding_handle
*b
= lsa_pipe
->binding_handle
;
1013 struct lsa_RefDomainList
*domains
= NULL
;
1014 struct lsa_TransSidArray3 sids
;
1017 struct lsa_String names
;
1018 uint32_t num_names
= 1;
1020 if (!sid
|| !name
) {
1021 return NT_STATUS_INVALID_PARAMETER
;
1026 init_lsa_String(&names
, name
);
1028 status
= rpccli_lsa_open_policy2(lsa_pipe
, mem_ctx
,
1030 SEC_STD_READ_CONTROL
|
1031 LSA_POLICY_VIEW_LOCAL_INFORMATION
|
1032 LSA_POLICY_LOOKUP_NAMES
,
1034 NT_STATUS_NOT_OK_RETURN(status
);
1036 status
= dcerpc_lsa_LookupNames3(b
, mem_ctx
,
1042 LSA_LOOKUP_NAMES_ALL
, /* sure ? */
1046 NT_STATUS_NOT_OK_RETURN(status
);
1047 NT_STATUS_NOT_OK_RETURN(result
);
1049 if (count
!= 1 || sids
.count
!= 1) {
1050 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1053 sid_copy(sid
, sids
.sids
[0].sid
);
1055 return NT_STATUS_OK
;
1058 /****************************************************************
1059 ****************************************************************/
1061 static WERROR
NetLocalGroupModifyMembers_r(struct libnetapi_ctx
*ctx
,
1062 struct NetLocalGroupAddMembers
*add
,
1063 struct NetLocalGroupDelMembers
*del
,
1064 struct NetLocalGroupSetMembers
*set
)
1066 struct NetLocalGroupAddMembers
*r
= NULL
;
1068 struct rpc_pipe_client
*pipe_cli
= NULL
;
1069 struct rpc_pipe_client
*lsa_pipe
= NULL
;
1070 NTSTATUS status
, result
;
1072 struct lsa_String lsa_account_name
;
1073 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
1074 struct dom_sid2
*domain_sid
= NULL
;
1075 struct dom_sid
*member_sids
= NULL
;
1078 struct LOCALGROUP_MEMBERS_INFO_0
*info0
= NULL
;
1079 struct LOCALGROUP_MEMBERS_INFO_3
*info3
= NULL
;
1081 struct dom_sid
*add_sids
= NULL
;
1082 struct dom_sid
*del_sids
= NULL
;
1083 uint32_t num_add_sids
= 0;
1084 uint32_t num_del_sids
= 0;
1085 struct dcerpc_binding_handle
*b
= NULL
;
1087 if ((!add
&& !del
&& !set
) || (add
&& del
&& set
)) {
1088 return WERR_INVALID_PARAM
;
1096 r
= (struct NetLocalGroupAddMembers
*)del
;
1100 r
= (struct NetLocalGroupAddMembers
*)set
;
1103 if (!r
->in
.group_name
) {
1104 return WERR_INVALID_PARAM
;
1107 switch (r
->in
.level
) {
1112 return WERR_UNKNOWN_LEVEL
;
1115 if (r
->in
.total_entries
== 0 || !r
->in
.buffer
) {
1116 return WERR_INVALID_PARAM
;
1119 ZERO_STRUCT(connect_handle
);
1120 ZERO_STRUCT(builtin_handle
);
1121 ZERO_STRUCT(domain_handle
);
1122 ZERO_STRUCT(alias_handle
);
1124 member_sids
= talloc_zero_array(ctx
, struct dom_sid
,
1125 r
->in
.total_entries
);
1126 W_ERROR_HAVE_NO_MEMORY(member_sids
);
1128 switch (r
->in
.level
) {
1130 info0
= (struct LOCALGROUP_MEMBERS_INFO_0
*)r
->in
.buffer
;
1131 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1132 sid_copy(&member_sids
[i
], (struct dom_sid
*)info0
[i
].lgrmi0_sid
);
1136 info3
= (struct LOCALGROUP_MEMBERS_INFO_3
*)r
->in
.buffer
;
1142 if (r
->in
.level
== 3) {
1143 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1146 if (!W_ERROR_IS_OK(werr
)) {
1150 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1151 status
= libnetapi_lsa_lookup_names3(ctx
, lsa_pipe
,
1152 info3
[i
].lgrmi3_domainandname
,
1154 if (!NT_STATUS_IS_OK(status
)) {
1155 werr
= ntstatus_to_werror(status
);
1159 TALLOC_FREE(lsa_pipe
);
1162 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1165 if (!W_ERROR_IS_OK(werr
)) {
1169 b
= pipe_cli
->binding_handle
;
1171 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1172 SAMR_ACCESS_LOOKUP_DOMAIN
|
1173 SAMR_ACCESS_ENUM_DOMAINS
,
1174 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1177 if (!W_ERROR_IS_OK(werr
)) {
1181 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
1183 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
1186 SAMR_ALIAS_ACCESS_ADD_MEMBER
|
1187 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
|
1188 SAMR_ALIAS_ACCESS_GET_MEMBERS
|
1189 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
1192 if (ctx
->disable_policy_handle_cache
) {
1193 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1196 if (NT_STATUS_IS_OK(status
)) {
1197 goto modify_membership
;
1200 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1201 SAMR_ACCESS_ENUM_DOMAINS
|
1202 SAMR_ACCESS_LOOKUP_DOMAIN
,
1203 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1207 if (!W_ERROR_IS_OK(werr
)) {
1211 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
1214 SAMR_ALIAS_ACCESS_ADD_MEMBER
|
1215 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
|
1216 SAMR_ALIAS_ACCESS_GET_MEMBERS
|
1217 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
1219 if (!NT_STATUS_IS_OK(status
)) {
1220 werr
= ntstatus_to_werror(status
);
1224 if (ctx
->disable_policy_handle_cache
) {
1225 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1231 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1232 status
= add_sid_to_array_unique(ctx
, &member_sids
[i
],
1235 if (!NT_STATUS_IS_OK(status
)) {
1236 werr
= ntstatus_to_werror(status
);
1243 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1244 status
= add_sid_to_array_unique(ctx
, &member_sids
[i
],
1247 if (!NT_STATUS_IS_OK(status
)) {
1248 werr
= ntstatus_to_werror(status
);
1256 struct lsa_SidArray current_sids
;
1258 status
= dcerpc_samr_GetMembersInAlias(b
, talloc_tos(),
1262 if (!NT_STATUS_IS_OK(status
)) {
1263 werr
= ntstatus_to_werror(status
);
1266 if (!NT_STATUS_IS_OK(result
)) {
1267 werr
= ntstatus_to_werror(result
);
1273 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1274 bool already_member
= false;
1275 for (k
=0; k
< current_sids
.num_sids
; k
++) {
1276 if (dom_sid_equal(&member_sids
[i
],
1277 current_sids
.sids
[k
].sid
)) {
1278 already_member
= true;
1282 if (!already_member
) {
1283 status
= add_sid_to_array_unique(ctx
,
1285 &add_sids
, &num_add_sids
);
1286 if (!NT_STATUS_IS_OK(status
)) {
1287 werr
= ntstatus_to_werror(status
);
1295 for (k
=0; k
< current_sids
.num_sids
; k
++) {
1296 bool keep_member
= false;
1297 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1298 if (dom_sid_equal(&member_sids
[i
],
1299 current_sids
.sids
[k
].sid
)) {
1305 status
= add_sid_to_array_unique(ctx
,
1306 current_sids
.sids
[k
].sid
,
1307 &del_sids
, &num_del_sids
);
1308 if (!NT_STATUS_IS_OK(status
)) {
1309 werr
= ntstatus_to_werror(status
);
1318 for (i
=0; i
< num_add_sids
; i
++) {
1319 status
= dcerpc_samr_AddAliasMember(b
, talloc_tos(),
1323 if (!NT_STATUS_IS_OK(status
)) {
1324 werr
= ntstatus_to_werror(status
);
1327 if (!NT_STATUS_IS_OK(result
)) {
1328 werr
= ntstatus_to_werror(result
);
1335 for (i
=0; i
< num_del_sids
; i
++) {
1336 status
= dcerpc_samr_DeleteAliasMember(b
, talloc_tos(),
1340 if (!NT_STATUS_IS_OK(status
)) {
1341 werr
= ntstatus_to_werror(status
);
1344 if (!NT_STATUS_IS_OK(result
)) {
1345 werr
= ntstatus_to_werror(result
);
1353 if (b
&& is_valid_policy_hnd(&alias_handle
)) {
1354 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
1357 if (ctx
->disable_policy_handle_cache
) {
1358 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1359 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1360 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1366 /****************************************************************
1367 ****************************************************************/
1369 WERROR
NetLocalGroupAddMembers_r(struct libnetapi_ctx
*ctx
,
1370 struct NetLocalGroupAddMembers
*r
)
1372 return NetLocalGroupModifyMembers_r(ctx
, r
, NULL
, NULL
);
1375 /****************************************************************
1376 ****************************************************************/
1378 WERROR
NetLocalGroupAddMembers_l(struct libnetapi_ctx
*ctx
,
1379 struct NetLocalGroupAddMembers
*r
)
1381 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupAddMembers
);
1384 /****************************************************************
1385 ****************************************************************/
1387 WERROR
NetLocalGroupDelMembers_r(struct libnetapi_ctx
*ctx
,
1388 struct NetLocalGroupDelMembers
*r
)
1390 return NetLocalGroupModifyMembers_r(ctx
, NULL
, r
, NULL
);
1393 /****************************************************************
1394 ****************************************************************/
1396 WERROR
NetLocalGroupDelMembers_l(struct libnetapi_ctx
*ctx
,
1397 struct NetLocalGroupDelMembers
*r
)
1399 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupDelMembers
);
1402 /****************************************************************
1403 ****************************************************************/
1405 WERROR
NetLocalGroupGetMembers_r(struct libnetapi_ctx
*ctx
,
1406 struct NetLocalGroupGetMembers
*r
)
1408 return WERR_NOT_SUPPORTED
;
1411 /****************************************************************
1412 ****************************************************************/
1414 WERROR
NetLocalGroupGetMembers_l(struct libnetapi_ctx
*ctx
,
1415 struct NetLocalGroupGetMembers
*r
)
1417 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupGetMembers
);
1420 /****************************************************************
1421 ****************************************************************/
1423 WERROR
NetLocalGroupSetMembers_r(struct libnetapi_ctx
*ctx
,
1424 struct NetLocalGroupSetMembers
*r
)
1426 return NetLocalGroupModifyMembers_r(ctx
, NULL
, NULL
, r
);
1429 /****************************************************************
1430 ****************************************************************/
1432 WERROR
NetLocalGroupSetMembers_l(struct libnetapi_ctx
*ctx
,
1433 struct NetLocalGroupSetMembers
*r
)
1435 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupSetMembers
);