2 * Unix SMB/CIFS implementation.
3 * NetApi LocalGroup Support
4 * Copyright (C) Guenther Deschner 2008
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "librpc/gen_ndr/libnetapi.h"
23 #include "lib/netapi/netapi.h"
24 #include "lib/netapi/netapi_private.h"
25 #include "lib/netapi/libnetapi.h"
27 static NTSTATUS
libnetapi_samr_lookup_and_open_alias(TALLOC_CTX
*mem_ctx
,
28 struct rpc_pipe_client
*pipe_cli
,
29 struct policy_handle
*domain_handle
,
30 const char *group_name
,
31 uint32_t access_rights
,
32 struct policy_handle
*alias_handle
)
36 struct lsa_String lsa_account_name
;
37 struct samr_Ids user_rids
, name_types
;
39 init_lsa_String(&lsa_account_name
, group_name
);
41 status
= rpccli_samr_LookupNames(pipe_cli
, mem_ctx
,
47 if (!NT_STATUS_IS_OK(status
)) {
51 switch (name_types
.ids
[0]) {
53 case SID_NAME_WKN_GRP
:
56 return NT_STATUS_INVALID_SID
;
59 return rpccli_samr_OpenAlias(pipe_cli
, mem_ctx
,
66 /****************************************************************
67 ****************************************************************/
69 static NTSTATUS
libnetapi_samr_open_alias_queryinfo(TALLOC_CTX
*mem_ctx
,
70 struct rpc_pipe_client
*pipe_cli
,
71 struct policy_handle
*handle
,
73 uint32_t access_rights
,
74 enum samr_AliasInfoEnum level
,
75 union samr_AliasInfo
**alias_info
)
78 struct policy_handle alias_handle
;
79 union samr_AliasInfo
*_alias_info
= NULL
;
81 ZERO_STRUCT(alias_handle
);
83 status
= rpccli_samr_OpenAlias(pipe_cli
, mem_ctx
,
88 if (!NT_STATUS_IS_OK(status
)) {
92 status
= rpccli_samr_QueryAliasInfo(pipe_cli
, mem_ctx
,
96 if (!NT_STATUS_IS_OK(status
)) {
100 *alias_info
= _alias_info
;
103 if (is_valid_policy_hnd(&alias_handle
)) {
104 rpccli_samr_Close(pipe_cli
, mem_ctx
, &alias_handle
);
110 /****************************************************************
111 ****************************************************************/
113 WERROR
NetLocalGroupAdd_r(struct libnetapi_ctx
*ctx
,
114 struct NetLocalGroupAdd
*r
)
116 struct rpc_pipe_client
*pipe_cli
= NULL
;
119 struct lsa_String lsa_account_name
;
120 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
121 struct dom_sid2
*domain_sid
= NULL
;
124 struct LOCALGROUP_INFO_0
*info0
= NULL
;
125 struct LOCALGROUP_INFO_1
*info1
= NULL
;
127 const char *alias_name
= NULL
;
130 return WERR_INVALID_PARAM
;
133 switch (r
->in
.level
) {
135 info0
= (struct LOCALGROUP_INFO_0
*)r
->in
.buffer
;
136 alias_name
= info0
->lgrpi0_name
;
139 info1
= (struct LOCALGROUP_INFO_1
*)r
->in
.buffer
;
140 alias_name
= info1
->lgrpi1_name
;
143 werr
= WERR_UNKNOWN_LEVEL
;
147 ZERO_STRUCT(connect_handle
);
148 ZERO_STRUCT(builtin_handle
);
149 ZERO_STRUCT(domain_handle
);
150 ZERO_STRUCT(alias_handle
);
152 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
153 &ndr_table_samr
.syntax_id
,
155 if (!W_ERROR_IS_OK(werr
)) {
159 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
160 SAMR_ACCESS_LOOKUP_DOMAIN
|
161 SAMR_ACCESS_ENUM_DOMAINS
,
162 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
165 if (!W_ERROR_IS_OK(werr
)) {
169 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
172 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
174 if (ctx
->disable_policy_handle_cache
) {
175 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
178 if (NT_STATUS_IS_OK(status
)) {
179 werr
= WERR_ALIAS_EXISTS
;
183 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
184 SAMR_ACCESS_ENUM_DOMAINS
|
185 SAMR_ACCESS_LOOKUP_DOMAIN
,
186 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
187 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
191 if (!W_ERROR_IS_OK(werr
)) {
195 init_lsa_String(&lsa_account_name
, alias_name
);
197 status
= rpccli_samr_CreateDomAlias(pipe_cli
, ctx
,
201 SAMR_ALIAS_ACCESS_SET_INFO
,
204 if (!NT_STATUS_IS_OK(status
)) {
205 werr
= ntstatus_to_werror(status
);
209 if (r
->in
.level
== 1 && info1
->lgrpi1_comment
) {
211 union samr_AliasInfo alias_info
;
213 init_lsa_String(&alias_info
.description
, info1
->lgrpi1_comment
);
215 status
= rpccli_samr_SetAliasInfo(pipe_cli
, ctx
,
217 ALIASINFODESCRIPTION
,
219 if (!NT_STATUS_IS_OK(status
)) {
220 werr
= ntstatus_to_werror(status
);
228 if (is_valid_policy_hnd(&alias_handle
)) {
229 rpccli_samr_Close(pipe_cli
, ctx
, &alias_handle
);
232 if (ctx
->disable_policy_handle_cache
) {
233 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
234 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
235 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
241 /****************************************************************
242 ****************************************************************/
244 WERROR
NetLocalGroupAdd_l(struct libnetapi_ctx
*ctx
,
245 struct NetLocalGroupAdd
*r
)
247 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupAdd
);
250 /****************************************************************
251 ****************************************************************/
254 WERROR
NetLocalGroupDel_r(struct libnetapi_ctx
*ctx
,
255 struct NetLocalGroupDel
*r
)
257 struct rpc_pipe_client
*pipe_cli
= NULL
;
260 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
261 struct dom_sid2
*domain_sid
= NULL
;
263 if (!r
->in
.group_name
) {
264 return WERR_INVALID_PARAM
;
267 ZERO_STRUCT(connect_handle
);
268 ZERO_STRUCT(builtin_handle
);
269 ZERO_STRUCT(domain_handle
);
270 ZERO_STRUCT(alias_handle
);
272 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
273 &ndr_table_samr
.syntax_id
,
275 if (!W_ERROR_IS_OK(werr
)) {
279 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
280 SAMR_ACCESS_LOOKUP_DOMAIN
|
281 SAMR_ACCESS_ENUM_DOMAINS
,
282 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
285 if (!W_ERROR_IS_OK(werr
)) {
289 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
295 if (ctx
->disable_policy_handle_cache
) {
296 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
299 if (NT_STATUS_IS_OK(status
)) {
303 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
304 SAMR_ACCESS_ENUM_DOMAINS
|
305 SAMR_ACCESS_LOOKUP_DOMAIN
,
306 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
307 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
311 if (!W_ERROR_IS_OK(werr
)) {
315 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
321 if (ctx
->disable_policy_handle_cache
) {
322 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
325 if (!NT_STATUS_IS_OK(status
)) {
326 werr
= ntstatus_to_werror(status
);
332 status
= rpccli_samr_DeleteDomAlias(pipe_cli
, ctx
,
334 if (!NT_STATUS_IS_OK(status
)) {
335 werr
= ntstatus_to_werror(status
);
339 ZERO_STRUCT(alias_handle
);
344 if (is_valid_policy_hnd(&alias_handle
)) {
345 rpccli_samr_Close(pipe_cli
, ctx
, &alias_handle
);
348 if (ctx
->disable_policy_handle_cache
) {
349 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
350 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
351 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
357 /****************************************************************
358 ****************************************************************/
360 WERROR
NetLocalGroupDel_l(struct libnetapi_ctx
*ctx
,
361 struct NetLocalGroupDel
*r
)
363 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupDel
);
366 /****************************************************************
367 ****************************************************************/
369 static WERROR
map_alias_info_to_buffer(TALLOC_CTX
*mem_ctx
,
370 const char *alias_name
,
371 struct samr_AliasInfoAll
*info
,
373 uint32_t *entries_read
,
376 struct LOCALGROUP_INFO_0 g0
;
377 struct LOCALGROUP_INFO_1 g1
;
378 struct LOCALGROUP_INFO_1002 g1002
;
382 g0
.lgrpi0_name
= talloc_strdup(mem_ctx
, alias_name
);
383 W_ERROR_HAVE_NO_MEMORY(g0
.lgrpi0_name
);
385 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_0
, g0
,
386 (struct LOCALGROUP_INFO_0
**)buffer
, entries_read
);
390 g1
.lgrpi1_name
= talloc_strdup(mem_ctx
, alias_name
);
391 g1
.lgrpi1_comment
= talloc_strdup(mem_ctx
, info
->description
.string
);
392 W_ERROR_HAVE_NO_MEMORY(g1
.lgrpi1_name
);
394 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_1
, g1
,
395 (struct LOCALGROUP_INFO_1
**)buffer
, entries_read
);
399 g1002
.lgrpi1002_comment
= talloc_strdup(mem_ctx
, info
->description
.string
);
401 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_INFO_1002
, g1002
,
402 (struct LOCALGROUP_INFO_1002
**)buffer
, entries_read
);
406 return WERR_UNKNOWN_LEVEL
;
412 /****************************************************************
413 ****************************************************************/
415 WERROR
NetLocalGroupGetInfo_r(struct libnetapi_ctx
*ctx
,
416 struct NetLocalGroupGetInfo
*r
)
418 struct rpc_pipe_client
*pipe_cli
= NULL
;
421 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
422 struct dom_sid2
*domain_sid
= NULL
;
423 union samr_AliasInfo
*alias_info
= NULL
;
424 uint32_t entries_read
= 0;
426 if (!r
->in
.group_name
) {
427 return WERR_INVALID_PARAM
;
430 switch (r
->in
.level
) {
436 return WERR_UNKNOWN_LEVEL
;
439 ZERO_STRUCT(connect_handle
);
440 ZERO_STRUCT(builtin_handle
);
441 ZERO_STRUCT(domain_handle
);
442 ZERO_STRUCT(alias_handle
);
444 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
445 &ndr_table_samr
.syntax_id
,
447 if (!W_ERROR_IS_OK(werr
)) {
451 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
452 SAMR_ACCESS_LOOKUP_DOMAIN
|
453 SAMR_ACCESS_ENUM_DOMAINS
,
454 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
457 if (!W_ERROR_IS_OK(werr
)) {
461 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
464 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
467 if (ctx
->disable_policy_handle_cache
) {
468 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
471 if (NT_STATUS_IS_OK(status
)) {
475 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
476 SAMR_ACCESS_ENUM_DOMAINS
|
477 SAMR_ACCESS_LOOKUP_DOMAIN
,
478 SAMR_DOMAIN_ACCESS_CREATE_ALIAS
|
479 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
483 if (!W_ERROR_IS_OK(werr
)) {
487 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
490 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
493 if (ctx
->disable_policy_handle_cache
) {
494 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
497 if (!NT_STATUS_IS_OK(status
)) {
498 werr
= ntstatus_to_werror(status
);
503 status
= rpccli_samr_QueryAliasInfo(pipe_cli
, ctx
,
507 if (!NT_STATUS_IS_OK(status
)) {
508 werr
= ntstatus_to_werror(status
);
512 werr
= map_alias_info_to_buffer(ctx
,
515 r
->in
.level
, &entries_read
,
519 if (is_valid_policy_hnd(&alias_handle
)) {
520 rpccli_samr_Close(pipe_cli
, ctx
, &alias_handle
);
523 if (ctx
->disable_policy_handle_cache
) {
524 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
525 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
526 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
532 /****************************************************************
533 ****************************************************************/
535 WERROR
NetLocalGroupGetInfo_l(struct libnetapi_ctx
*ctx
,
536 struct NetLocalGroupGetInfo
*r
)
538 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupGetInfo
);
541 /****************************************************************
542 ****************************************************************/
544 static WERROR
map_buffer_to_alias_info(TALLOC_CTX
*mem_ctx
,
547 enum samr_AliasInfoEnum
*alias_level
,
548 union samr_AliasInfo
**alias_info
)
550 struct LOCALGROUP_INFO_0
*info0
;
551 struct LOCALGROUP_INFO_1
*info1
;
552 struct LOCALGROUP_INFO_1002
*info1002
;
553 union samr_AliasInfo
*info
= NULL
;
555 info
= TALLOC_ZERO_P(mem_ctx
, union samr_AliasInfo
);
556 W_ERROR_HAVE_NO_MEMORY(info
);
560 info0
= (struct LOCALGROUP_INFO_0
*)buffer
;
561 init_lsa_String(&info
->name
, info0
->lgrpi0_name
);
562 *alias_level
= ALIASINFONAME
;
565 info1
= (struct LOCALGROUP_INFO_1
*)buffer
;
566 /* group name will be ignored */
567 init_lsa_String(&info
->description
, info1
->lgrpi1_comment
);
568 *alias_level
= ALIASINFODESCRIPTION
;
571 info1002
= (struct LOCALGROUP_INFO_1002
*)buffer
;
572 init_lsa_String(&info
->description
, info1002
->lgrpi1002_comment
);
573 *alias_level
= ALIASINFODESCRIPTION
;
582 /****************************************************************
583 ****************************************************************/
585 WERROR
NetLocalGroupSetInfo_r(struct libnetapi_ctx
*ctx
,
586 struct NetLocalGroupSetInfo
*r
)
588 struct rpc_pipe_client
*pipe_cli
= NULL
;
591 struct lsa_String lsa_account_name
;
592 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
593 struct dom_sid2
*domain_sid
= NULL
;
594 enum samr_AliasInfoEnum alias_level
= 0;
595 union samr_AliasInfo
*alias_info
= NULL
;
597 if (!r
->in
.group_name
) {
598 return WERR_INVALID_PARAM
;
601 switch (r
->in
.level
) {
607 return WERR_UNKNOWN_LEVEL
;
610 ZERO_STRUCT(connect_handle
);
611 ZERO_STRUCT(builtin_handle
);
612 ZERO_STRUCT(domain_handle
);
613 ZERO_STRUCT(alias_handle
);
615 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
616 &ndr_table_samr
.syntax_id
,
618 if (!W_ERROR_IS_OK(werr
)) {
622 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
623 SAMR_ACCESS_LOOKUP_DOMAIN
|
624 SAMR_ACCESS_ENUM_DOMAINS
,
625 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
628 if (!W_ERROR_IS_OK(werr
)) {
632 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
634 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
637 SAMR_ALIAS_ACCESS_SET_INFO
,
640 if (ctx
->disable_policy_handle_cache
) {
641 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
644 if (NT_STATUS_IS_OK(status
)) {
648 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
649 SAMR_ACCESS_ENUM_DOMAINS
|
650 SAMR_ACCESS_LOOKUP_DOMAIN
,
651 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
655 if (!W_ERROR_IS_OK(werr
)) {
659 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
662 SAMR_ALIAS_ACCESS_SET_INFO
,
664 if (!NT_STATUS_IS_OK(status
)) {
665 werr
= ntstatus_to_werror(status
);
669 if (ctx
->disable_policy_handle_cache
) {
670 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
675 werr
= map_buffer_to_alias_info(ctx
, r
->in
.level
, r
->in
.buffer
,
676 &alias_level
, &alias_info
);
677 if (!W_ERROR_IS_OK(werr
)) {
681 status
= rpccli_samr_SetAliasInfo(pipe_cli
, ctx
,
685 if (!NT_STATUS_IS_OK(status
)) {
686 werr
= ntstatus_to_werror(status
);
693 if (is_valid_policy_hnd(&alias_handle
)) {
694 rpccli_samr_Close(pipe_cli
, ctx
, &alias_handle
);
697 if (ctx
->disable_policy_handle_cache
) {
698 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
699 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
700 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
706 /****************************************************************
707 ****************************************************************/
709 WERROR
NetLocalGroupSetInfo_l(struct libnetapi_ctx
*ctx
,
710 struct NetLocalGroupSetInfo
*r
)
712 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupSetInfo
);
715 /****************************************************************
716 ****************************************************************/
718 WERROR
NetLocalGroupEnum_r(struct libnetapi_ctx
*ctx
,
719 struct NetLocalGroupEnum
*r
)
721 struct rpc_pipe_client
*pipe_cli
= NULL
;
724 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
725 struct dom_sid2
*domain_sid
= NULL
;
726 uint32_t entries_read
= 0;
727 union samr_DomainInfo
*domain_info
= NULL
;
728 union samr_DomainInfo
*builtin_info
= NULL
;
729 struct samr_SamArray
*domain_sam_array
= NULL
;
730 struct samr_SamArray
*builtin_sam_array
= NULL
;
733 if (!r
->out
.buffer
) {
734 return WERR_INVALID_PARAM
;
737 switch (r
->in
.level
) {
742 return WERR_UNKNOWN_LEVEL
;
745 if (r
->out
.total_entries
) {
746 *r
->out
.total_entries
= 0;
748 if (r
->out
.entries_read
) {
749 *r
->out
.entries_read
= 0;
752 ZERO_STRUCT(connect_handle
);
753 ZERO_STRUCT(builtin_handle
);
754 ZERO_STRUCT(domain_handle
);
755 ZERO_STRUCT(alias_handle
);
757 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
758 &ndr_table_samr
.syntax_id
,
760 if (!W_ERROR_IS_OK(werr
)) {
764 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
765 SAMR_ACCESS_LOOKUP_DOMAIN
|
766 SAMR_ACCESS_ENUM_DOMAINS
,
767 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
768 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
769 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
772 if (!W_ERROR_IS_OK(werr
)) {
776 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
777 SAMR_ACCESS_LOOKUP_DOMAIN
|
778 SAMR_ACCESS_ENUM_DOMAINS
,
779 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
780 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
781 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
785 if (!W_ERROR_IS_OK(werr
)) {
789 status
= rpccli_samr_QueryDomainInfo(pipe_cli
, ctx
,
793 if (!NT_STATUS_IS_OK(status
)) {
794 werr
= ntstatus_to_werror(status
);
798 if (r
->out
.total_entries
) {
799 *r
->out
.total_entries
+= builtin_info
->general
.num_aliases
;
802 status
= rpccli_samr_QueryDomainInfo(pipe_cli
, ctx
,
806 if (!NT_STATUS_IS_OK(status
)) {
807 werr
= ntstatus_to_werror(status
);
811 if (r
->out
.total_entries
) {
812 *r
->out
.total_entries
+= domain_info
->general
.num_aliases
;
815 status
= rpccli_samr_EnumDomainAliases(pipe_cli
, ctx
,
821 if (!NT_STATUS_IS_OK(status
)) {
822 werr
= ntstatus_to_werror(status
);
826 for (i
=0; i
<builtin_sam_array
->count
; i
++) {
827 union samr_AliasInfo
*alias_info
= NULL
;
829 if (r
->in
.level
== 1) {
831 status
= libnetapi_samr_open_alias_queryinfo(ctx
, pipe_cli
,
833 builtin_sam_array
->entries
[i
].idx
,
834 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
837 if (!NT_STATUS_IS_OK(status
)) {
838 werr
= ntstatus_to_werror(status
);
843 werr
= map_alias_info_to_buffer(ctx
,
844 builtin_sam_array
->entries
[i
].name
.string
,
845 alias_info
? &alias_info
->all
: NULL
,
851 status
= rpccli_samr_EnumDomainAliases(pipe_cli
, ctx
,
857 if (!NT_STATUS_IS_OK(status
)) {
858 werr
= ntstatus_to_werror(status
);
862 for (i
=0; i
<domain_sam_array
->count
; i
++) {
864 union samr_AliasInfo
*alias_info
= NULL
;
866 if (r
->in
.level
== 1) {
867 status
= libnetapi_samr_open_alias_queryinfo(ctx
, pipe_cli
,
869 domain_sam_array
->entries
[i
].idx
,
870 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
873 if (!NT_STATUS_IS_OK(status
)) {
874 werr
= ntstatus_to_werror(status
);
879 werr
= map_alias_info_to_buffer(ctx
,
880 domain_sam_array
->entries
[i
].name
.string
,
881 alias_info
? &alias_info
->all
: NULL
,
888 if (ctx
->disable_policy_handle_cache
) {
889 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
890 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
891 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
897 /****************************************************************
898 ****************************************************************/
900 WERROR
NetLocalGroupEnum_l(struct libnetapi_ctx
*ctx
,
901 struct NetLocalGroupEnum
*r
)
903 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupEnum
);
906 /****************************************************************
907 ****************************************************************/
909 static NTSTATUS
libnetapi_lsa_lookup_names3(TALLOC_CTX
*mem_ctx
,
910 struct rpc_pipe_client
*lsa_pipe
,
915 struct policy_handle lsa_handle
;
917 struct lsa_RefDomainList
*domains
= NULL
;
918 struct lsa_TransSidArray3 sids
;
921 struct lsa_String names
;
922 uint32_t num_names
= 1;
925 return NT_STATUS_INVALID_PARAMETER
;
930 init_lsa_String(&names
, name
);
932 status
= rpccli_lsa_open_policy2(lsa_pipe
, mem_ctx
,
934 STD_RIGHT_READ_CONTROL_ACCESS
|
935 LSA_POLICY_VIEW_LOCAL_INFORMATION
|
936 LSA_POLICY_LOOKUP_NAMES
,
938 NT_STATUS_NOT_OK_RETURN(status
);
940 status
= rpccli_lsa_LookupNames3(lsa_pipe
, mem_ctx
,
946 LSA_LOOKUP_NAMES_ALL
, /* sure ? */
949 NT_STATUS_NOT_OK_RETURN(status
);
951 if (count
!= 1 || sids
.count
!= 1) {
952 return NT_STATUS_NONE_MAPPED
;
955 sid_copy(sid
, sids
.sids
[0].sid
);
960 /****************************************************************
961 ****************************************************************/
963 static WERROR
NetLocalGroupModifyMembers_r(struct libnetapi_ctx
*ctx
,
964 struct NetLocalGroupAddMembers
*add
,
965 struct NetLocalGroupDelMembers
*del
,
966 struct NetLocalGroupSetMembers
*set
)
968 struct NetLocalGroupAddMembers
*r
= NULL
;
970 struct rpc_pipe_client
*pipe_cli
= NULL
;
971 struct rpc_pipe_client
*lsa_pipe
= NULL
;
974 struct lsa_String lsa_account_name
;
975 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, alias_handle
;
976 struct dom_sid2
*domain_sid
= NULL
;
977 struct dom_sid
*member_sids
= NULL
;
980 struct LOCALGROUP_MEMBERS_INFO_0
*info0
= NULL
;
981 struct LOCALGROUP_MEMBERS_INFO_3
*info3
= NULL
;
983 struct dom_sid
*add_sids
= NULL
;
984 struct dom_sid
*del_sids
= NULL
;
985 size_t num_add_sids
= 0;
986 size_t num_del_sids
= 0;
988 if ((!add
&& !del
&& !set
) || (add
&& del
&& set
)) {
989 return WERR_INVALID_PARAM
;
997 r
= (struct NetLocalGroupAddMembers
*)del
;
1001 r
= (struct NetLocalGroupAddMembers
*)set
;
1004 if (!r
->in
.group_name
) {
1005 return WERR_INVALID_PARAM
;
1008 switch (r
->in
.level
) {
1013 return WERR_UNKNOWN_LEVEL
;
1016 if (r
->in
.total_entries
== 0 || !r
->in
.buffer
) {
1017 return WERR_INVALID_PARAM
;
1020 ZERO_STRUCT(connect_handle
);
1021 ZERO_STRUCT(builtin_handle
);
1022 ZERO_STRUCT(domain_handle
);
1023 ZERO_STRUCT(alias_handle
);
1025 member_sids
= TALLOC_ZERO_ARRAY(ctx
, struct dom_sid
,
1026 r
->in
.total_entries
);
1027 W_ERROR_HAVE_NO_MEMORY(member_sids
);
1029 switch (r
->in
.level
) {
1031 info0
= (struct LOCALGROUP_MEMBERS_INFO_0
*)r
->in
.buffer
;
1032 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1033 sid_copy(&member_sids
[i
], (struct dom_sid
*)info0
[i
].lgrmi0_sid
);
1037 info3
= (struct LOCALGROUP_MEMBERS_INFO_3
*)r
->in
.buffer
;
1043 if (r
->in
.level
== 3) {
1044 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1045 &ndr_table_lsarpc
.syntax_id
,
1047 if (!W_ERROR_IS_OK(werr
)) {
1051 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1052 status
= libnetapi_lsa_lookup_names3(ctx
, lsa_pipe
,
1053 info3
[i
].lgrmi3_domainandname
,
1055 if (!NT_STATUS_IS_OK(status
)) {
1056 werr
= ntstatus_to_werror(status
);
1060 TALLOC_FREE(lsa_pipe
);
1063 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1064 &ndr_table_samr
.syntax_id
,
1066 if (!W_ERROR_IS_OK(werr
)) {
1070 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1071 SAMR_ACCESS_LOOKUP_DOMAIN
|
1072 SAMR_ACCESS_ENUM_DOMAINS
,
1073 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1076 if (!W_ERROR_IS_OK(werr
)) {
1080 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
1082 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
1085 SAMR_ALIAS_ACCESS_ADD_MEMBER
|
1086 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
|
1087 SAMR_ALIAS_ACCESS_GET_MEMBERS
|
1088 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
1091 if (ctx
->disable_policy_handle_cache
) {
1092 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1095 if (NT_STATUS_IS_OK(status
)) {
1096 goto modify_membership
;
1099 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1100 SAMR_ACCESS_ENUM_DOMAINS
|
1101 SAMR_ACCESS_LOOKUP_DOMAIN
,
1102 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1106 if (!W_ERROR_IS_OK(werr
)) {
1110 status
= libnetapi_samr_lookup_and_open_alias(ctx
, pipe_cli
,
1113 SAMR_ALIAS_ACCESS_ADD_MEMBER
|
1114 SAMR_ALIAS_ACCESS_REMOVE_MEMBER
|
1115 SAMR_ALIAS_ACCESS_GET_MEMBERS
|
1116 SAMR_ALIAS_ACCESS_LOOKUP_INFO
,
1118 if (!NT_STATUS_IS_OK(status
)) {
1119 werr
= ntstatus_to_werror(status
);
1123 if (ctx
->disable_policy_handle_cache
) {
1124 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1130 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1131 status
= add_sid_to_array_unique(ctx
, &member_sids
[i
],
1134 if (!NT_STATUS_IS_OK(status
)) {
1135 werr
= ntstatus_to_werror(status
);
1142 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1143 status
= add_sid_to_array_unique(ctx
, &member_sids
[i
],
1146 if (!NT_STATUS_IS_OK(status
)) {
1147 werr
= ntstatus_to_werror(status
);
1155 struct lsa_SidArray current_sids
;
1157 status
= rpccli_samr_GetMembersInAlias(pipe_cli
, ctx
,
1160 if (!NT_STATUS_IS_OK(status
)) {
1161 werr
= ntstatus_to_werror(status
);
1167 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1168 bool already_member
= false;
1169 for (k
=0; k
< current_sids
.num_sids
; k
++) {
1170 if (sid_equal(&member_sids
[i
],
1171 current_sids
.sids
[k
].sid
)) {
1172 already_member
= true;
1176 if (!already_member
) {
1177 status
= add_sid_to_array_unique(ctx
,
1179 &add_sids
, &num_add_sids
);
1180 if (!NT_STATUS_IS_OK(status
)) {
1181 werr
= ntstatus_to_werror(status
);
1189 for (k
=0; k
< current_sids
.num_sids
; k
++) {
1190 bool keep_member
= false;
1191 for (i
=0; i
< r
->in
.total_entries
; i
++) {
1192 if (sid_equal(&member_sids
[i
],
1193 current_sids
.sids
[k
].sid
)) {
1199 status
= add_sid_to_array_unique(ctx
,
1200 current_sids
.sids
[k
].sid
,
1201 &del_sids
, &num_del_sids
);
1202 if (!NT_STATUS_IS_OK(status
)) {
1203 werr
= ntstatus_to_werror(status
);
1212 for (i
=0; i
< num_add_sids
; i
++) {
1213 status
= rpccli_samr_AddAliasMember(pipe_cli
, ctx
,
1216 if (!NT_STATUS_IS_OK(status
)) {
1217 werr
= ntstatus_to_werror(status
);
1224 for (i
=0; i
< num_del_sids
; i
++) {
1225 status
= rpccli_samr_DeleteAliasMember(pipe_cli
, ctx
,
1228 if (!NT_STATUS_IS_OK(status
)) {
1229 werr
= ntstatus_to_werror(status
);
1237 if (is_valid_policy_hnd(&alias_handle
)) {
1238 rpccli_samr_Close(pipe_cli
, ctx
, &alias_handle
);
1241 if (ctx
->disable_policy_handle_cache
) {
1242 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1243 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1244 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1250 /****************************************************************
1251 ****************************************************************/
1253 WERROR
NetLocalGroupAddMembers_r(struct libnetapi_ctx
*ctx
,
1254 struct NetLocalGroupAddMembers
*r
)
1256 return NetLocalGroupModifyMembers_r(ctx
, r
, NULL
, NULL
);
1259 /****************************************************************
1260 ****************************************************************/
1262 WERROR
NetLocalGroupAddMembers_l(struct libnetapi_ctx
*ctx
,
1263 struct NetLocalGroupAddMembers
*r
)
1265 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupAddMembers
);
1268 /****************************************************************
1269 ****************************************************************/
1271 WERROR
NetLocalGroupDelMembers_r(struct libnetapi_ctx
*ctx
,
1272 struct NetLocalGroupDelMembers
*r
)
1274 return NetLocalGroupModifyMembers_r(ctx
, NULL
, r
, NULL
);
1277 /****************************************************************
1278 ****************************************************************/
1280 WERROR
NetLocalGroupDelMembers_l(struct libnetapi_ctx
*ctx
,
1281 struct NetLocalGroupDelMembers
*r
)
1283 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupDelMembers
);
1286 /****************************************************************
1287 ****************************************************************/
1289 WERROR
NetLocalGroupGetMembers_r(struct libnetapi_ctx
*ctx
,
1290 struct NetLocalGroupGetMembers
*r
)
1292 return WERR_NOT_SUPPORTED
;
1295 /****************************************************************
1296 ****************************************************************/
1298 WERROR
NetLocalGroupGetMembers_l(struct libnetapi_ctx
*ctx
,
1299 struct NetLocalGroupGetMembers
*r
)
1301 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupGetMembers
);
1304 /****************************************************************
1305 ****************************************************************/
1307 WERROR
NetLocalGroupSetMembers_r(struct libnetapi_ctx
*ctx
,
1308 struct NetLocalGroupSetMembers
*r
)
1310 return NetLocalGroupModifyMembers_r(ctx
, NULL
, NULL
, r
);
1313 /****************************************************************
1314 ****************************************************************/
1316 WERROR
NetLocalGroupSetMembers_l(struct libnetapi_ctx
*ctx
,
1317 struct NetLocalGroupSetMembers
*r
)
1319 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetLocalGroupSetMembers
);