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 (any_nt_status_not_ok(status
, result
, &status
)) {
58 if (user_rids
.count
!= 1) {
59 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
61 if (name_types
.count
!= 1) {
62 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
65 switch (name_types
.ids
[0]) {
67 case SID_NAME_WKN_GRP
:
70 return NT_STATUS_INVALID_SID
;
73 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
79 if (!NT_STATUS_IS_OK(status
)) {
86 /****************************************************************
87 ****************************************************************/
89 static NTSTATUS
libnetapi_samr_open_alias_queryinfo(TALLOC_CTX
*mem_ctx
,
90 struct rpc_pipe_client
*pipe_cli
,
91 struct policy_handle
*handle
,
93 uint32_t access_rights
,
94 enum samr_AliasInfoEnum level
,
95 union samr_AliasInfo
**alias_info
)
97 NTSTATUS status
, result
;
98 struct policy_handle alias_handle
;
99 union samr_AliasInfo
*_alias_info
= NULL
;
100 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
102 ZERO_STRUCT(alias_handle
);
104 status
= dcerpc_samr_OpenAlias(b
, mem_ctx
,
110 if (any_nt_status_not_ok(status
, result
, &status
)) {
114 status
= dcerpc_samr_QueryAliasInfo(b
, mem_ctx
,
119 if (any_nt_status_not_ok(status
, result
, &status
)) {
123 *alias_info
= _alias_info
;
126 if (is_valid_policy_hnd(&alias_handle
)) {
127 dcerpc_samr_Close(b
, mem_ctx
, &alias_handle
, &result
);
133 /****************************************************************
134 ****************************************************************/
136 WERROR
NetLocalGroupAdd_r(struct libnetapi_ctx
*ctx
,
137 struct NetLocalGroupAdd
*r
)
139 struct rpc_pipe_client
*pipe_cli
= NULL
;
140 NTSTATUS status
, result
;
142 struct lsa_String lsa_account_name
;
143 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
144 struct dom_sid2
*domain_sid
= NULL
;
146 struct dcerpc_binding_handle
*b
= NULL
;
148 struct LOCALGROUP_INFO_0
*info0
= NULL
;
149 struct LOCALGROUP_INFO_1
*info1
= NULL
;
151 const char *alias_name
= NULL
;
154 return WERR_INVALID_PARAMETER
;
157 ZERO_STRUCT(connect_handle
);
158 ZERO_STRUCT(builtin_handle
);
159 ZERO_STRUCT(domain_handle
);
160 ZERO_STRUCT(alias_handle
);
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_INVALID_LEVEL
;
176 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
179 if (!W_ERROR_IS_OK(werr
)) {
183 b
= pipe_cli
->binding_handle
;
185 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
186 SAMR_ACCESS_LOOKUP_DOMAIN
|
187 SAMR_ACCESS_ENUM_DOMAINS
,
188 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
191 if (!W_ERROR_IS_OK(werr
)) {
195 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
198 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
200 if (ctx
->disable_policy_handle_cache
) {
201 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
204 if (NT_STATUS_IS_OK(status
)) {
205 werr
= WERR_ALIAS_EXISTS
;
209 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
210 SAMR_ACCESS_ENUM_DOMAINS
|
211 SAMR_ACCESS_LOOKUP_DOMAIN
,
212 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
213 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
217 if (!W_ERROR_IS_OK(werr
)) {
221 init_lsa_String(&lsa_account_name
, alias_name
);
223 status
= dcerpc_samr_CreateDomAlias(b
, talloc_tos(),
227 SAMR_ALIAS_ACCESS_SET_INFO
,
231 if (any_nt_status_not_ok(status
, result
, &status
)) {
232 werr
= ntstatus_to_werror(status
);
236 if (r
->in
.level
== 1 && info1
->lgrpi1_comment
) {
238 union samr_AliasInfo alias_info
;
240 init_lsa_String(&alias_info
.description
, info1
->lgrpi1_comment
);
242 status
= dcerpc_samr_SetAliasInfo(b
, talloc_tos(),
244 ALIASINFODESCRIPTION
,
247 if (any_nt_status_not_ok(status
, result
, &status
)) {
248 werr
= ntstatus_to_werror(status
);
256 if (is_valid_policy_hnd(&alias_handle
)) {
257 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
260 if (ctx
->disable_policy_handle_cache
) {
261 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
262 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
263 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
269 /****************************************************************
270 ****************************************************************/
272 WERROR
NetLocalGroupAdd_l(struct libnetapi_ctx
*ctx
,
273 struct NetLocalGroupAdd
*r
)
275 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupAdd
);
278 /****************************************************************
279 ****************************************************************/
282 WERROR
NetLocalGroupDel_r(struct libnetapi_ctx
*ctx
,
283 struct NetLocalGroupDel
*r
)
285 struct rpc_pipe_client
*pipe_cli
= NULL
;
286 NTSTATUS status
, result
;
288 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
289 struct dom_sid2
*domain_sid
= NULL
;
290 struct dcerpc_binding_handle
*b
= NULL
;
292 if (!r
->in
.group_name
) {
293 return WERR_INVALID_PARAMETER
;
296 ZERO_STRUCT(connect_handle
);
297 ZERO_STRUCT(builtin_handle
);
298 ZERO_STRUCT(domain_handle
);
299 ZERO_STRUCT(alias_handle
);
301 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
304 if (!W_ERROR_IS_OK(werr
)) {
308 b
= pipe_cli
->binding_handle
;
310 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
311 SAMR_ACCESS_LOOKUP_DOMAIN
|
312 SAMR_ACCESS_ENUM_DOMAINS
,
313 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_builtin_handle(ctx
, &builtin_handle
);
330 if (NT_STATUS_IS_OK(status
)) {
334 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
335 SAMR_ACCESS_ENUM_DOMAINS
|
336 SAMR_ACCESS_LOOKUP_DOMAIN
,
337 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
338 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
342 if (!W_ERROR_IS_OK(werr
)) {
346 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
352 if (ctx
->disable_policy_handle_cache
) {
353 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
356 if (!NT_STATUS_IS_OK(status
)) {
357 werr
= ntstatus_to_werror(status
);
363 status
= dcerpc_samr_DeleteDomAlias(b
, talloc_tos(),
366 if (any_nt_status_not_ok(status
, result
, &status
)) {
367 werr
= ntstatus_to_werror(status
);
371 ZERO_STRUCT(alias_handle
);
376 if (is_valid_policy_hnd(&alias_handle
)) {
377 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
380 if (ctx
->disable_policy_handle_cache
) {
381 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
382 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
383 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
389 /****************************************************************
390 ****************************************************************/
392 WERROR
NetLocalGroupDel_l(struct libnetapi_ctx
*ctx
,
393 struct NetLocalGroupDel
*r
)
395 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupDel
);
398 /****************************************************************
399 ****************************************************************/
401 static WERROR
map_alias_info_to_buffer(TALLOC_CTX
*mem_ctx
,
402 const char *alias_name
,
403 struct samr_AliasInfoAll
*info
,
405 uint32_t *entries_read
,
408 struct LOCALGROUP_INFO_0 g0
;
409 struct LOCALGROUP_INFO_1 g1
;
410 struct LOCALGROUP_INFO_1002 g1002
;
414 g0
.lgrpi0_name
= talloc_strdup(mem_ctx
, alias_name
);
415 W_ERROR_HAVE_NO_MEMORY(g0
.lgrpi0_name
);
417 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_0
, g0
,
418 (struct LOCALGROUP_INFO_0
**)buffer
, entries_read
);
422 g1
.lgrpi1_name
= talloc_strdup(mem_ctx
, alias_name
);
423 g1
.lgrpi1_comment
= talloc_strdup(mem_ctx
, info
->description
.string
);
424 W_ERROR_HAVE_NO_MEMORY(g1
.lgrpi1_name
);
426 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_1
, g1
,
427 (struct LOCALGROUP_INFO_1
**)buffer
, entries_read
);
431 g1002
.lgrpi1002_comment
= talloc_strdup(mem_ctx
, info
->description
.string
);
433 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_1002
, g1002
,
434 (struct LOCALGROUP_INFO_1002
**)buffer
, entries_read
);
438 return WERR_INVALID_LEVEL
;
444 /****************************************************************
445 ****************************************************************/
447 WERROR
NetLocalGroupGetInfo_r(struct libnetapi_ctx
*ctx
,
448 struct NetLocalGroupGetInfo
*r
)
450 struct rpc_pipe_client
*pipe_cli
= NULL
;
451 NTSTATUS status
, result
;
453 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
454 struct dom_sid2
*domain_sid
= NULL
;
455 union samr_AliasInfo
*alias_info
= NULL
;
456 uint32_t entries_read
= 0;
457 struct dcerpc_binding_handle
*b
= NULL
;
459 if (!r
->in
.group_name
) {
460 return WERR_INVALID_PARAMETER
;
463 switch (r
->in
.level
) {
469 return WERR_INVALID_LEVEL
;
472 ZERO_STRUCT(connect_handle
);
473 ZERO_STRUCT(builtin_handle
);
474 ZERO_STRUCT(domain_handle
);
475 ZERO_STRUCT(alias_handle
);
477 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
480 if (!W_ERROR_IS_OK(werr
)) {
484 b
= pipe_cli
->binding_handle
;
486 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
487 SAMR_ACCESS_LOOKUP_DOMAIN
|
488 SAMR_ACCESS_ENUM_DOMAINS
,
489 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
492 if (!W_ERROR_IS_OK(werr
)) {
496 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
499 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
502 if (ctx
->disable_policy_handle_cache
) {
503 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
506 if (NT_STATUS_IS_OK(status
)) {
510 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
511 SAMR_ACCESS_ENUM_DOMAINS
|
512 SAMR_ACCESS_LOOKUP_DOMAIN
,
513 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
514 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
518 if (!W_ERROR_IS_OK(werr
)) {
522 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
525 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
528 if (ctx
->disable_policy_handle_cache
) {
529 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
532 if (!NT_STATUS_IS_OK(status
)) {
533 werr
= ntstatus_to_werror(status
);
538 status
= dcerpc_samr_QueryAliasInfo(b
, talloc_tos(),
543 if (any_nt_status_not_ok(status
, result
, &status
)) {
544 werr
= ntstatus_to_werror(status
);
548 werr
= map_alias_info_to_buffer(ctx
,
551 r
->in
.level
, &entries_read
,
555 if (is_valid_policy_hnd(&alias_handle
)) {
556 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
559 if (ctx
->disable_policy_handle_cache
) {
560 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
561 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
562 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
568 /****************************************************************
569 ****************************************************************/
571 WERROR
NetLocalGroupGetInfo_l(struct libnetapi_ctx
*ctx
,
572 struct NetLocalGroupGetInfo
*r
)
574 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupGetInfo
);
577 /****************************************************************
578 ****************************************************************/
580 static WERROR
map_buffer_to_alias_info(TALLOC_CTX
*mem_ctx
,
583 enum samr_AliasInfoEnum
*alias_level
,
584 union samr_AliasInfo
**alias_info
)
586 struct LOCALGROUP_INFO_0
*info0
;
587 struct LOCALGROUP_INFO_1
*info1
;
588 struct LOCALGROUP_INFO_1002
*info1002
;
589 union samr_AliasInfo
*info
= NULL
;
591 info
= talloc_zero(mem_ctx
, union samr_AliasInfo
);
592 W_ERROR_HAVE_NO_MEMORY(info
);
596 info0
= (struct LOCALGROUP_INFO_0
*)buffer
;
597 init_lsa_String(&info
->name
, info0
->lgrpi0_name
);
598 *alias_level
= ALIASINFONAME
;
601 info1
= (struct LOCALGROUP_INFO_1
*)buffer
;
602 /* group name will be ignored */
603 init_lsa_String(&info
->description
, info1
->lgrpi1_comment
);
604 *alias_level
= ALIASINFODESCRIPTION
;
607 info1002
= (struct LOCALGROUP_INFO_1002
*)buffer
;
608 init_lsa_String(&info
->description
, info1002
->lgrpi1002_comment
);
609 *alias_level
= ALIASINFODESCRIPTION
;
618 /****************************************************************
619 ****************************************************************/
621 WERROR
NetLocalGroupSetInfo_r(struct libnetapi_ctx
*ctx
,
622 struct NetLocalGroupSetInfo
*r
)
624 struct rpc_pipe_client
*pipe_cli
= NULL
;
625 NTSTATUS status
, result
;
627 struct lsa_String lsa_account_name
;
628 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
629 struct dom_sid2
*domain_sid
= NULL
;
630 enum samr_AliasInfoEnum alias_level
= 0;
631 union samr_AliasInfo
*alias_info
= NULL
;
632 struct dcerpc_binding_handle
*b
= NULL
;
634 if (!r
->in
.group_name
) {
635 return WERR_INVALID_PARAMETER
;
638 switch (r
->in
.level
) {
644 return WERR_INVALID_LEVEL
;
647 ZERO_STRUCT(connect_handle
);
648 ZERO_STRUCT(builtin_handle
);
649 ZERO_STRUCT(domain_handle
);
650 ZERO_STRUCT(alias_handle
);
652 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
655 if (!W_ERROR_IS_OK(werr
)) {
659 b
= pipe_cli
->binding_handle
;
661 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
662 SAMR_ACCESS_LOOKUP_DOMAIN
|
663 SAMR_ACCESS_ENUM_DOMAINS
,
664 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
667 if (!W_ERROR_IS_OK(werr
)) {
671 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
673 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
676 SAMR_ALIAS_ACCESS_SET_INFO
,
679 if (ctx
->disable_policy_handle_cache
) {
680 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
683 if (NT_STATUS_IS_OK(status
)) {
687 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
688 SAMR_ACCESS_ENUM_DOMAINS
|
689 SAMR_ACCESS_LOOKUP_DOMAIN
,
690 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
694 if (!W_ERROR_IS_OK(werr
)) {
698 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
701 SAMR_ALIAS_ACCESS_SET_INFO
,
703 if (!NT_STATUS_IS_OK(status
)) {
704 werr
= ntstatus_to_werror(status
);
708 if (ctx
->disable_policy_handle_cache
) {
709 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
714 werr
= map_buffer_to_alias_info(ctx
, r
->in
.level
, r
->in
.buffer
,
715 &alias_level
, &alias_info
);
716 if (!W_ERROR_IS_OK(werr
)) {
720 status
= dcerpc_samr_SetAliasInfo(b
, talloc_tos(),
725 if (any_nt_status_not_ok(status
, result
, &status
)) {
726 werr
= ntstatus_to_werror(status
);
733 if (is_valid_policy_hnd(&alias_handle
)) {
734 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
737 if (ctx
->disable_policy_handle_cache
) {
738 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
739 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
740 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
746 /****************************************************************
747 ****************************************************************/
749 WERROR
NetLocalGroupSetInfo_l(struct libnetapi_ctx
*ctx
,
750 struct NetLocalGroupSetInfo
*r
)
752 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupSetInfo
);
755 /****************************************************************
756 ****************************************************************/
758 WERROR
NetLocalGroupEnum_r(struct libnetapi_ctx
*ctx
,
759 struct NetLocalGroupEnum
*r
)
761 struct rpc_pipe_client
*pipe_cli
= NULL
;
762 NTSTATUS status
, result
;
764 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
765 struct dom_sid2
*domain_sid
= NULL
;
766 uint32_t entries_read
= 0;
767 union samr_DomainInfo
*domain_info
= NULL
;
768 union samr_DomainInfo
*builtin_info
= NULL
;
769 struct samr_SamArray
*domain_sam_array
= NULL
;
770 struct samr_SamArray
*builtin_sam_array
= NULL
;
772 struct dcerpc_binding_handle
*b
= NULL
;
774 if (!r
->out
.buffer
) {
775 return WERR_INVALID_PARAMETER
;
778 switch (r
->in
.level
) {
783 return WERR_INVALID_LEVEL
;
786 if (r
->out
.total_entries
) {
787 *r
->out
.total_entries
= 0;
789 if (r
->out
.entries_read
) {
790 *r
->out
.entries_read
= 0;
793 ZERO_STRUCT(connect_handle
);
794 ZERO_STRUCT(builtin_handle
);
795 ZERO_STRUCT(domain_handle
);
796 ZERO_STRUCT(alias_handle
);
798 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
801 if (!W_ERROR_IS_OK(werr
)) {
805 b
= pipe_cli
->binding_handle
;
807 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
808 SAMR_ACCESS_LOOKUP_DOMAIN
|
809 SAMR_ACCESS_ENUM_DOMAINS
,
810 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
811 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
812 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
815 if (!W_ERROR_IS_OK(werr
)) {
819 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
820 SAMR_ACCESS_LOOKUP_DOMAIN
|
821 SAMR_ACCESS_ENUM_DOMAINS
,
822 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
823 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
824 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
828 if (!W_ERROR_IS_OK(werr
)) {
832 status
= dcerpc_samr_QueryDomainInfo(b
, talloc_tos(),
837 if (any_nt_status_not_ok(status
, result
, &status
)) {
838 werr
= ntstatus_to_werror(status
);
842 if (r
->out
.total_entries
) {
843 *r
->out
.total_entries
+= builtin_info
->general
.num_aliases
;
846 status
= dcerpc_samr_QueryDomainInfo(b
, talloc_tos(),
851 if (any_nt_status_not_ok(status
, result
, &status
)) {
852 werr
= ntstatus_to_werror(status
);
856 if (r
->out
.total_entries
) {
857 *r
->out
.total_entries
+= domain_info
->general
.num_aliases
;
860 status
= dcerpc_samr_EnumDomainAliases(b
, talloc_tos(),
867 if (any_nt_status_not_ok(status
, result
, &status
)) {
868 werr
= ntstatus_to_werror(status
);
872 for (i
=0; i
<builtin_sam_array
->count
; i
++) {
873 union samr_AliasInfo
*alias_info
= NULL
;
875 if (r
->in
.level
== 1) {
877 status
= libnetapi_samr_open_alias_queryinfo(ctx
, pipe_cli
,
879 builtin_sam_array
->entries
[i
].idx
,
880 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
883 if (!NT_STATUS_IS_OK(status
)) {
884 werr
= ntstatus_to_werror(status
);
889 werr
= map_alias_info_to_buffer(ctx
,
890 builtin_sam_array
->entries
[i
].name
.string
,
891 alias_info
? &alias_info
->all
: NULL
,
897 status
= dcerpc_samr_EnumDomainAliases(b
, talloc_tos(),
904 if (any_nt_status_not_ok(status
, result
, &status
)) {
905 werr
= ntstatus_to_werror(status
);
909 for (i
=0; i
<domain_sam_array
->count
; i
++) {
911 union samr_AliasInfo
*alias_info
= NULL
;
913 if (r
->in
.level
== 1) {
914 status
= libnetapi_samr_open_alias_queryinfo(ctx
, pipe_cli
,
916 domain_sam_array
->entries
[i
].idx
,
917 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
920 if (!NT_STATUS_IS_OK(status
)) {
921 werr
= ntstatus_to_werror(status
);
926 werr
= map_alias_info_to_buffer(ctx
,
927 domain_sam_array
->entries
[i
].name
.string
,
928 alias_info
? &alias_info
->all
: NULL
,
935 if (ctx
->disable_policy_handle_cache
) {
936 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
937 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
938 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
944 /****************************************************************
945 ****************************************************************/
947 WERROR
NetLocalGroupEnum_l(struct libnetapi_ctx
*ctx
,
948 struct NetLocalGroupEnum
*r
)
950 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupEnum
);
953 /****************************************************************
954 ****************************************************************/
956 static NTSTATUS
libnetapi_lsa_lookup_names3(TALLOC_CTX
*mem_ctx
,
957 struct rpc_pipe_client
*lsa_pipe
,
961 NTSTATUS status
, result
;
962 struct policy_handle lsa_handle
;
963 struct dcerpc_binding_handle
*b
= lsa_pipe
->binding_handle
;
965 struct lsa_RefDomainList
*domains
= NULL
;
966 struct lsa_TransSidArray3 sids
;
969 struct lsa_String names
;
970 uint32_t num_names
= 1;
971 union lsa_revision_info out_revision_info
= {
976 uint32_t out_version
= 0;
979 return NT_STATUS_INVALID_PARAMETER
;
984 init_lsa_String(&names
, name
);
986 status
= dcerpc_lsa_open_policy_fallback(
989 lsa_pipe
->srv_name_slash
,
991 SEC_STD_READ_CONTROL
|
992 LSA_POLICY_VIEW_LOCAL_INFORMATION
|
993 LSA_POLICY_LOOKUP_NAMES
,
998 if (any_nt_status_not_ok(status
, result
, &status
)) {
1002 status
= dcerpc_lsa_LookupNames3(b
, mem_ctx
,
1008 LSA_LOOKUP_NAMES_ALL
, /* sure ? */
1012 NT_STATUS_NOT_OK_RETURN(status
);
1013 NT_STATUS_NOT_OK_RETURN(result
);
1015 if (count
!= 1 || sids
.count
!= 1) {
1016 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1019 sid_copy(sid
, sids
.sids
[0].sid
);
1021 return NT_STATUS_OK
;
1024 /****************************************************************
1025 ****************************************************************/
1027 static WERROR
NetLocalGroupModifyMembers_r(struct libnetapi_ctx
*ctx
,
1028 struct NetLocalGroupAddMembers
*add
,
1029 struct NetLocalGroupDelMembers
*del
,
1030 struct NetLocalGroupSetMembers
*set
)
1032 struct NetLocalGroupAddMembers
*r
= NULL
;
1034 struct rpc_pipe_client
*pipe_cli
= NULL
;
1035 struct rpc_pipe_client
*lsa_pipe
= NULL
;
1036 NTSTATUS status
, result
;
1038 struct lsa_String lsa_account_name
;
1039 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
1040 struct dom_sid2
*domain_sid
= NULL
;
1041 struct dom_sid
*member_sids
= NULL
;
1044 struct LOCALGROUP_MEMBERS_INFO_0
*info0
= NULL
;
1045 struct LOCALGROUP_MEMBERS_INFO_3
*info3
= NULL
;
1047 struct dom_sid
*add_sids
= NULL
;
1048 struct dom_sid
*del_sids
= NULL
;
1049 uint32_t num_add_sids
= 0;
1050 uint32_t num_del_sids
= 0;
1051 struct dcerpc_binding_handle
*b
= NULL
;
1053 if ((!add
&& !del
&& !set
) || (add
&& del
&& set
)) {
1054 return WERR_INVALID_PARAMETER
;
1062 r
= (struct NetLocalGroupAddMembers
*)del
;
1066 r
= (struct NetLocalGroupAddMembers
*)set
;
1069 if (r
==NULL
|| r
->in
.group_name
== NULL
) {
1070 return WERR_INVALID_PARAMETER
;
1073 switch (r
->in
.level
) {
1078 return WERR_INVALID_LEVEL
;
1081 if (r
->in
.total_entries
== 0 || !r
->in
.buffer
) {
1082 return WERR_INVALID_PARAMETER
;
1085 ZERO_STRUCT(connect_handle
);
1086 ZERO_STRUCT(builtin_handle
);
1087 ZERO_STRUCT(domain_handle
);
1088 ZERO_STRUCT(alias_handle
);
1090 member_sids
= talloc_zero_array(ctx
, struct dom_sid
,
1091 r
->in
.total_entries
);
1092 W_ERROR_HAVE_NO_MEMORY(member_sids
);
1094 switch (r
->in
.level
) {
1096 info0
= (struct LOCALGROUP_MEMBERS_INFO_0
*)r
->in
.buffer
;
1097 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1098 sid_copy(&member_sids
[i
], (struct dom_sid
*)info0
[i
].lgrmi0_sid
);
1102 info3
= (struct LOCALGROUP_MEMBERS_INFO_3
*)r
->in
.buffer
;
1108 if (r
->in
.level
== 3) {
1109 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1112 if (!W_ERROR_IS_OK(werr
)) {
1116 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1117 status
= libnetapi_lsa_lookup_names3(ctx
, lsa_pipe
,
1118 info3
[i
].lgrmi3_domainandname
,
1120 if (!NT_STATUS_IS_OK(status
)) {
1121 werr
= ntstatus_to_werror(status
);
1125 TALLOC_FREE(lsa_pipe
);
1128 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1131 if (!W_ERROR_IS_OK(werr
)) {
1135 b
= pipe_cli
->binding_handle
;
1137 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1138 SAMR_ACCESS_LOOKUP_DOMAIN
|
1139 SAMR_ACCESS_ENUM_DOMAINS
,
1140 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1143 if (!W_ERROR_IS_OK(werr
)) {
1147 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
1149 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
1152 SAMR_ALIAS_ACCESS_ADD_MEMBER
|
1153 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
|
1154 SAMR_ALIAS_ACCESS_GET_MEMBERS
|
1155 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
1158 if (ctx
->disable_policy_handle_cache
) {
1159 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1162 if (NT_STATUS_IS_OK(status
)) {
1163 goto modify_membership
;
1166 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1167 SAMR_ACCESS_ENUM_DOMAINS
|
1168 SAMR_ACCESS_LOOKUP_DOMAIN
,
1169 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1173 if (!W_ERROR_IS_OK(werr
)) {
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
,
1185 if (!NT_STATUS_IS_OK(status
)) {
1186 werr
= ntstatus_to_werror(status
);
1190 if (ctx
->disable_policy_handle_cache
) {
1191 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1197 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1198 status
= add_sid_to_array_unique(ctx
, &member_sids
[i
],
1201 if (!NT_STATUS_IS_OK(status
)) {
1202 werr
= ntstatus_to_werror(status
);
1209 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1210 status
= add_sid_to_array_unique(ctx
, &member_sids
[i
],
1213 if (!NT_STATUS_IS_OK(status
)) {
1214 werr
= ntstatus_to_werror(status
);
1222 struct lsa_SidArray current_sids
;
1224 status
= dcerpc_samr_GetMembersInAlias(b
, talloc_tos(),
1228 if (any_nt_status_not_ok(status
, result
, &status
)) {
1229 werr
= ntstatus_to_werror(status
);
1235 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1236 bool already_member
= false;
1237 for (k
=0; k
< current_sids
.num_sids
; k
++) {
1238 if (dom_sid_equal(&member_sids
[i
],
1239 current_sids
.sids
[k
].sid
)) {
1240 already_member
= true;
1244 if (!already_member
) {
1245 status
= add_sid_to_array_unique(ctx
,
1247 &add_sids
, &num_add_sids
);
1248 if (!NT_STATUS_IS_OK(status
)) {
1249 werr
= ntstatus_to_werror(status
);
1257 for (k
=0; k
< current_sids
.num_sids
; k
++) {
1258 bool keep_member
= false;
1259 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1260 if (dom_sid_equal(&member_sids
[i
],
1261 current_sids
.sids
[k
].sid
)) {
1267 status
= add_sid_to_array_unique(ctx
,
1268 current_sids
.sids
[k
].sid
,
1269 &del_sids
, &num_del_sids
);
1270 if (!NT_STATUS_IS_OK(status
)) {
1271 werr
= ntstatus_to_werror(status
);
1280 for (i
=0; i
< num_add_sids
; i
++) {
1281 status
= dcerpc_samr_AddAliasMember(b
, talloc_tos(),
1285 if (any_nt_status_not_ok(status
, result
, &status
)) {
1286 werr
= ntstatus_to_werror(status
);
1293 for (i
=0; i
< num_del_sids
; i
++) {
1294 status
= dcerpc_samr_DeleteAliasMember(b
, talloc_tos(),
1298 if (any_nt_status_not_ok(status
, result
, &status
)) {
1299 werr
= ntstatus_to_werror(status
);
1307 if (b
&& is_valid_policy_hnd(&alias_handle
)) {
1308 dcerpc_samr_Close(b
, talloc_tos(), &alias_handle
, &result
);
1311 if (ctx
->disable_policy_handle_cache
) {
1312 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1313 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1314 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1320 /****************************************************************
1321 ****************************************************************/
1323 WERROR
NetLocalGroupAddMembers_r(struct libnetapi_ctx
*ctx
,
1324 struct NetLocalGroupAddMembers
*r
)
1326 return NetLocalGroupModifyMembers_r(ctx
, r
, NULL
, NULL
);
1329 /****************************************************************
1330 ****************************************************************/
1332 WERROR
NetLocalGroupAddMembers_l(struct libnetapi_ctx
*ctx
,
1333 struct NetLocalGroupAddMembers
*r
)
1335 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupAddMembers
);
1338 /****************************************************************
1339 ****************************************************************/
1341 WERROR
NetLocalGroupDelMembers_r(struct libnetapi_ctx
*ctx
,
1342 struct NetLocalGroupDelMembers
*r
)
1344 return NetLocalGroupModifyMembers_r(ctx
, NULL
, r
, NULL
);
1347 /****************************************************************
1348 ****************************************************************/
1350 WERROR
NetLocalGroupDelMembers_l(struct libnetapi_ctx
*ctx
,
1351 struct NetLocalGroupDelMembers
*r
)
1353 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupDelMembers
);
1356 /****************************************************************
1357 ****************************************************************/
1359 WERROR
NetLocalGroupGetMembers_r(struct libnetapi_ctx
*ctx
,
1360 struct NetLocalGroupGetMembers
*r
)
1362 return WERR_NOT_SUPPORTED
;
1365 /****************************************************************
1366 ****************************************************************/
1368 WERROR
NetLocalGroupGetMembers_l(struct libnetapi_ctx
*ctx
,
1369 struct NetLocalGroupGetMembers
*r
)
1371 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupGetMembers
);
1374 /****************************************************************
1375 ****************************************************************/
1377 WERROR
NetLocalGroupSetMembers_r(struct libnetapi_ctx
*ctx
,
1378 struct NetLocalGroupSetMembers
*r
)
1380 return NetLocalGroupModifyMembers_r(ctx
, NULL
, NULL
, r
);
1383 /****************************************************************
1384 ****************************************************************/
1386 WERROR
NetLocalGroupSetMembers_l(struct libnetapi_ctx
*ctx
,
1387 struct NetLocalGroupSetMembers
*r
)
1389 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupSetMembers
);