2 * Unix SMB/CIFS implementation.
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 "rpc_client/init_lsa.h"
29 #include "../libcli/security/security.h"
31 /****************************************************************
32 ****************************************************************/
34 WERROR
NetGroupAdd_r(struct libnetapi_ctx
*ctx
,
35 struct NetGroupAdd
*r
)
37 struct rpc_pipe_client
*pipe_cli
= NULL
;
38 NTSTATUS status
, result
;
40 struct policy_handle connect_handle
, domain_handle
, group_handle
;
41 struct lsa_String lsa_group_name
;
42 struct dom_sid2
*domain_sid
= NULL
;
44 struct dcerpc_binding_handle
*b
= NULL
;
46 struct GROUP_INFO_0
*info0
= NULL
;
47 struct GROUP_INFO_1
*info1
= NULL
;
48 struct GROUP_INFO_2
*info2
= NULL
;
49 struct GROUP_INFO_3
*info3
= NULL
;
50 union samr_GroupInfo info
;
52 ZERO_STRUCT(connect_handle
);
53 ZERO_STRUCT(domain_handle
);
54 ZERO_STRUCT(group_handle
);
57 return WERR_INVALID_PARAM
;
60 switch (r
->in
.level
) {
62 info0
= (struct GROUP_INFO_0
*)r
->in
.buffer
;
65 info1
= (struct GROUP_INFO_1
*)r
->in
.buffer
;
68 info2
= (struct GROUP_INFO_2
*)r
->in
.buffer
;
71 info3
= (struct GROUP_INFO_3
*)r
->in
.buffer
;
74 werr
= WERR_UNKNOWN_LEVEL
;
78 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
81 if (!W_ERROR_IS_OK(werr
)) {
85 b
= pipe_cli
->binding_handle
;
87 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
88 SAMR_ACCESS_ENUM_DOMAINS
|
89 SAMR_ACCESS_LOOKUP_DOMAIN
,
90 SAMR_DOMAIN_ACCESS_CREATE_GROUP
|
91 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
95 if (!W_ERROR_IS_OK(werr
)) {
99 switch (r
->in
.level
) {
101 init_lsa_String(&lsa_group_name
, info0
->grpi0_name
);
104 init_lsa_String(&lsa_group_name
, info1
->grpi1_name
);
107 init_lsa_String(&lsa_group_name
, info2
->grpi2_name
);
110 init_lsa_String(&lsa_group_name
, info3
->grpi3_name
);
114 status
= dcerpc_samr_CreateDomainGroup(b
, talloc_tos(),
118 SAMR_GROUP_ACCESS_SET_INFO
,
123 if (!NT_STATUS_IS_OK(status
)) {
124 werr
= ntstatus_to_werror(status
);
127 if (!NT_STATUS_IS_OK(result
)) {
128 werr
= ntstatus_to_werror(result
);
132 switch (r
->in
.level
) {
134 if (info1
->grpi1_comment
) {
135 init_lsa_String(&info
.description
,
136 info1
->grpi1_comment
);
138 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
140 GROUPINFODESCRIPTION
,
146 if (info2
->grpi2_comment
) {
147 init_lsa_String(&info
.description
,
148 info2
->grpi2_comment
);
150 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
152 GROUPINFODESCRIPTION
,
155 if (!NT_STATUS_IS_OK(status
)) {
156 werr
= ntstatus_to_werror(status
);
159 if (!NT_STATUS_IS_OK(result
)) {
160 werr
= ntstatus_to_werror(result
);
165 if (info2
->grpi2_attributes
!= 0) {
166 info
.attributes
.attributes
= info2
->grpi2_attributes
;
167 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
176 if (info3
->grpi3_comment
) {
177 init_lsa_String(&info
.description
,
178 info3
->grpi3_comment
);
180 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
182 GROUPINFODESCRIPTION
,
185 if (!NT_STATUS_IS_OK(status
)) {
186 werr
= ntstatus_to_werror(status
);
189 if (!NT_STATUS_IS_OK(result
)) {
190 werr
= ntstatus_to_werror(result
);
195 if (info3
->grpi3_attributes
!= 0) {
196 info
.attributes
.attributes
= info3
->grpi3_attributes
;
197 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
208 if (!NT_STATUS_IS_OK(status
)) {
209 werr
= ntstatus_to_werror(status
);
212 if (!NT_STATUS_IS_OK(result
)) {
213 werr
= ntstatus_to_werror(result
);
221 dcerpc_samr_DeleteDomainGroup(b
, talloc_tos(),
222 &group_handle
, &result
);
225 if (is_valid_policy_hnd(&group_handle
)) {
226 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
229 if (ctx
->disable_policy_handle_cache
) {
230 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
231 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
237 /****************************************************************
238 ****************************************************************/
240 WERROR
NetGroupAdd_l(struct libnetapi_ctx
*ctx
,
241 struct NetGroupAdd
*r
)
243 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupAdd
);
246 /****************************************************************
247 ****************************************************************/
249 WERROR
NetGroupDel_r(struct libnetapi_ctx
*ctx
,
250 struct NetGroupDel
*r
)
252 struct rpc_pipe_client
*pipe_cli
= NULL
;
253 NTSTATUS status
, result
;
255 struct policy_handle connect_handle
, domain_handle
, group_handle
;
256 struct lsa_String lsa_group_name
;
257 struct dom_sid2
*domain_sid
= NULL
;
259 struct dcerpc_binding_handle
*b
= NULL
;
261 struct samr_Ids rids
;
262 struct samr_Ids types
;
263 union samr_GroupInfo
*info
= NULL
;
264 struct samr_RidAttrArray
*rid_array
= NULL
;
266 ZERO_STRUCT(connect_handle
);
267 ZERO_STRUCT(domain_handle
);
268 ZERO_STRUCT(group_handle
);
270 if (!r
->in
.group_name
) {
271 return WERR_INVALID_PARAM
;
274 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
277 if (!W_ERROR_IS_OK(werr
)) {
281 b
= pipe_cli
->binding_handle
;
283 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
284 SAMR_ACCESS_ENUM_DOMAINS
|
285 SAMR_ACCESS_LOOKUP_DOMAIN
,
286 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
290 if (!W_ERROR_IS_OK(werr
)) {
294 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
296 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
303 if (!NT_STATUS_IS_OK(status
)) {
304 werr
= ntstatus_to_werror(status
);
307 if (!NT_STATUS_IS_OK(result
)) {
308 werr
= ntstatus_to_werror(result
);
312 if (rids
.count
!= 1) {
313 werr
= WERR_BAD_NET_RESP
;
316 if (types
.count
!= 1) {
317 werr
= WERR_BAD_NET_RESP
;
321 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
322 werr
= WERR_INVALID_DATATYPE
;
326 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
329 SAMR_GROUP_ACCESS_GET_MEMBERS
|
330 SAMR_GROUP_ACCESS_REMOVE_MEMBER
|
331 SAMR_GROUP_ACCESS_ADD_MEMBER
|
332 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
336 if (!NT_STATUS_IS_OK(status
)) {
337 werr
= ntstatus_to_werror(status
);
340 if (!NT_STATUS_IS_OK(result
)) {
341 werr
= ntstatus_to_werror(result
);
345 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
350 if (!NT_STATUS_IS_OK(status
)) {
351 werr
= ntstatus_to_werror(status
);
354 if (!NT_STATUS_IS_OK(result
)) {
355 werr
= ntstatus_to_werror(result
);
360 /* breaks against NT4 */
361 if (!(info
->attributes
.attributes
& SE_GROUP_ENABLED
)) {
362 werr
= WERR_ACCESS_DENIED
;
366 status
= dcerpc_samr_QueryGroupMember(b
, talloc_tos(),
370 if (!NT_STATUS_IS_OK(status
)) {
371 werr
= ntstatus_to_werror(status
);
374 if (!NT_STATUS_IS_OK(result
)) {
375 werr
= ntstatus_to_werror(result
);
380 struct lsa_Strings names
;
381 struct samr_Ids member_types
;
383 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
390 if (!NT_STATUS_IS_OK(status
)) {
391 werr
= ntstatus_to_werror(status
);
394 if (!NT_STATUS_IS_OK(result
)) {
395 werr
= ntstatus_to_werror(result
);
398 if (names
.count
!= rid_array
->count
) {
399 werr
= WERR_BAD_NET_RESP
;
402 if (member_types
.count
!= rid_array
->count
) {
403 werr
= WERR_BAD_NET_RESP
;
408 for (i
=0; i
< rid_array
->count
; i
++) {
410 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
414 if (!NT_STATUS_IS_OK(status
)) {
415 werr
= ntstatus_to_werror(status
);
418 if (!NT_STATUS_IS_OK(result
)) {
419 werr
= ntstatus_to_werror(result
);
424 status
= dcerpc_samr_DeleteDomainGroup(b
, talloc_tos(),
427 if (!NT_STATUS_IS_OK(status
)) {
428 werr
= ntstatus_to_werror(status
);
431 if (!NT_STATUS_IS_OK(result
)) {
432 werr
= ntstatus_to_werror(result
);
436 ZERO_STRUCT(group_handle
);
441 if (is_valid_policy_hnd(&group_handle
)) {
442 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
445 if (ctx
->disable_policy_handle_cache
) {
446 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
447 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
453 /****************************************************************
454 ****************************************************************/
456 WERROR
NetGroupDel_l(struct libnetapi_ctx
*ctx
,
457 struct NetGroupDel
*r
)
459 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupDel
);
462 /****************************************************************
463 ****************************************************************/
465 WERROR
NetGroupSetInfo_r(struct libnetapi_ctx
*ctx
,
466 struct NetGroupSetInfo
*r
)
468 struct rpc_pipe_client
*pipe_cli
= NULL
;
469 NTSTATUS status
, result
;
471 struct policy_handle connect_handle
, domain_handle
, group_handle
;
472 struct lsa_String lsa_group_name
;
473 struct dom_sid2
*domain_sid
= NULL
;
474 struct dcerpc_binding_handle
*b
= NULL
;
476 struct samr_Ids rids
;
477 struct samr_Ids types
;
478 union samr_GroupInfo info
;
479 struct GROUP_INFO_0
*g0
;
480 struct GROUP_INFO_1
*g1
;
481 struct GROUP_INFO_2
*g2
;
482 struct GROUP_INFO_3
*g3
;
483 struct GROUP_INFO_1002
*g1002
;
484 struct GROUP_INFO_1005
*g1005
;
486 ZERO_STRUCT(connect_handle
);
487 ZERO_STRUCT(domain_handle
);
488 ZERO_STRUCT(group_handle
);
490 if (!r
->in
.group_name
) {
491 return WERR_INVALID_PARAM
;
494 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
497 if (!W_ERROR_IS_OK(werr
)) {
501 b
= pipe_cli
->binding_handle
;
503 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
504 SAMR_ACCESS_ENUM_DOMAINS
|
505 SAMR_ACCESS_LOOKUP_DOMAIN
,
506 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
510 if (!W_ERROR_IS_OK(werr
)) {
514 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
516 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
523 if (!NT_STATUS_IS_OK(status
)) {
524 werr
= ntstatus_to_werror(status
);
527 if (!NT_STATUS_IS_OK(result
)) {
528 werr
= ntstatus_to_werror(result
);
531 if (rids
.count
!= 1) {
532 werr
= WERR_BAD_NET_RESP
;
535 if (types
.count
!= 1) {
536 werr
= WERR_BAD_NET_RESP
;
540 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
541 werr
= WERR_INVALID_DATATYPE
;
545 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
547 SAMR_GROUP_ACCESS_SET_INFO
|
548 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
552 if (!NT_STATUS_IS_OK(status
)) {
553 werr
= ntstatus_to_werror(status
);
556 if (!NT_STATUS_IS_OK(result
)) {
557 werr
= ntstatus_to_werror(result
);
561 switch (r
->in
.level
) {
563 g0
= (struct GROUP_INFO_0
*)r
->in
.buffer
;
564 init_lsa_String(&info
.name
, g0
->grpi0_name
);
565 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
572 g1
= (struct GROUP_INFO_1
*)r
->in
.buffer
;
573 init_lsa_String(&info
.description
, g1
->grpi1_comment
);
574 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
576 GROUPINFODESCRIPTION
,
581 g2
= (struct GROUP_INFO_2
*)r
->in
.buffer
;
582 init_lsa_String(&info
.description
, g2
->grpi2_comment
);
583 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
585 GROUPINFODESCRIPTION
,
588 if (!NT_STATUS_IS_OK(status
)) {
589 werr
= ntstatus_to_werror(status
);
592 if (!NT_STATUS_IS_OK(result
)) {
593 werr
= ntstatus_to_werror(result
);
597 info
.attributes
.attributes
= g2
->grpi2_attributes
;
598 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
605 g3
= (struct GROUP_INFO_3
*)r
->in
.buffer
;
606 init_lsa_String(&info
.description
, g3
->grpi3_comment
);
607 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
609 GROUPINFODESCRIPTION
,
612 if (!NT_STATUS_IS_OK(status
)) {
613 werr
= ntstatus_to_werror(status
);
616 if (!NT_STATUS_IS_OK(result
)) {
617 werr
= ntstatus_to_werror(result
);
621 info
.attributes
.attributes
= g3
->grpi3_attributes
;
622 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
629 g1002
= (struct GROUP_INFO_1002
*)r
->in
.buffer
;
630 init_lsa_String(&info
.description
, g1002
->grpi1002_comment
);
631 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
633 GROUPINFODESCRIPTION
,
638 g1005
= (struct GROUP_INFO_1005
*)r
->in
.buffer
;
639 info
.attributes
.attributes
= g1005
->grpi1005_attributes
;
640 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
647 status
= NT_STATUS_INVALID_LEVEL
;
651 if (!NT_STATUS_IS_OK(status
)) {
652 werr
= ntstatus_to_werror(status
);
655 if (!NT_STATUS_IS_OK(result
)) {
656 werr
= ntstatus_to_werror(result
);
663 if (is_valid_policy_hnd(&group_handle
)) {
664 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
667 if (ctx
->disable_policy_handle_cache
) {
668 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
669 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
675 /****************************************************************
676 ****************************************************************/
678 WERROR
NetGroupSetInfo_l(struct libnetapi_ctx
*ctx
,
679 struct NetGroupSetInfo
*r
)
681 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupSetInfo
);
684 /****************************************************************
685 ****************************************************************/
687 static WERROR
map_group_info_to_buffer(TALLOC_CTX
*mem_ctx
,
689 struct samr_GroupInfoAll
*info
,
690 struct dom_sid2
*domain_sid
,
694 struct GROUP_INFO_0 info0
;
695 struct GROUP_INFO_1 info1
;
696 struct GROUP_INFO_2 info2
;
697 struct GROUP_INFO_3 info3
;
702 info0
.grpi0_name
= info
->name
.string
;
704 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info0
, sizeof(info0
));
708 info1
.grpi1_name
= info
->name
.string
;
709 info1
.grpi1_comment
= info
->description
.string
;
711 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info1
, sizeof(info1
));
715 info2
.grpi2_name
= info
->name
.string
;
716 info2
.grpi2_comment
= info
->description
.string
;
717 info2
.grpi2_group_id
= rid
;
718 info2
.grpi2_attributes
= info
->attributes
;
720 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info2
, sizeof(info2
));
724 if (!sid_compose(&sid
, domain_sid
, rid
)) {
728 info3
.grpi3_name
= info
->name
.string
;
729 info3
.grpi3_comment
= info
->description
.string
;
730 info3
.grpi3_attributes
= info
->attributes
;
731 info3
.grpi3_group_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
733 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info3
, sizeof(info3
));
737 return WERR_UNKNOWN_LEVEL
;
740 W_ERROR_HAVE_NO_MEMORY(*buffer
);
745 /****************************************************************
746 ****************************************************************/
748 WERROR
NetGroupGetInfo_r(struct libnetapi_ctx
*ctx
,
749 struct NetGroupGetInfo
*r
)
751 struct rpc_pipe_client
*pipe_cli
= NULL
;
752 NTSTATUS status
, result
;
754 struct policy_handle connect_handle
, domain_handle
, group_handle
;
755 struct lsa_String lsa_group_name
;
756 struct dom_sid2
*domain_sid
= NULL
;
757 struct dcerpc_binding_handle
*b
= NULL
;
759 struct samr_Ids rids
;
760 struct samr_Ids types
;
761 union samr_GroupInfo
*info
= NULL
;
762 bool group_info_all
= false;
764 ZERO_STRUCT(connect_handle
);
765 ZERO_STRUCT(domain_handle
);
766 ZERO_STRUCT(group_handle
);
768 if (!r
->in
.group_name
) {
769 return WERR_INVALID_PARAM
;
772 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
775 if (!W_ERROR_IS_OK(werr
)) {
779 b
= pipe_cli
->binding_handle
;
781 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
782 SAMR_ACCESS_ENUM_DOMAINS
|
783 SAMR_ACCESS_LOOKUP_DOMAIN
,
784 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
788 if (!W_ERROR_IS_OK(werr
)) {
792 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
794 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
801 if (!NT_STATUS_IS_OK(status
)) {
802 werr
= ntstatus_to_werror(status
);
805 if (!NT_STATUS_IS_OK(result
)) {
806 werr
= ntstatus_to_werror(result
);
809 if (rids
.count
!= 1) {
810 werr
= WERR_BAD_NET_RESP
;
813 if (types
.count
!= 1) {
814 werr
= WERR_BAD_NET_RESP
;
818 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
819 werr
= WERR_INVALID_DATATYPE
;
823 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
825 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
829 if (!NT_STATUS_IS_OK(status
)) {
830 werr
= ntstatus_to_werror(status
);
833 if (!NT_STATUS_IS_OK(result
)) {
834 werr
= ntstatus_to_werror(result
);
838 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
843 if (!NT_STATUS_IS_OK(status
)) {
844 werr
= ntstatus_to_werror(status
);
848 if (NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_INFO_CLASS
)) {
849 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
854 group_info_all
= true;
855 if (!NT_STATUS_IS_OK(status
)) {
856 werr
= ntstatus_to_werror(status
);
861 if (!NT_STATUS_IS_OK(result
)) {
862 werr
= ntstatus_to_werror(result
);
866 werr
= map_group_info_to_buffer(ctx
, r
->in
.level
,
867 group_info_all
? &info
->all
: &info
->all2
,
868 domain_sid
, rids
.ids
[0],
870 if (!W_ERROR_IS_OK(werr
)) {
874 if (is_valid_policy_hnd(&group_handle
)) {
875 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
878 if (ctx
->disable_policy_handle_cache
) {
879 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
880 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
886 /****************************************************************
887 ****************************************************************/
889 WERROR
NetGroupGetInfo_l(struct libnetapi_ctx
*ctx
,
890 struct NetGroupGetInfo
*r
)
892 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupGetInfo
);
895 /****************************************************************
896 ****************************************************************/
898 WERROR
NetGroupAddUser_r(struct libnetapi_ctx
*ctx
,
899 struct NetGroupAddUser
*r
)
901 struct rpc_pipe_client
*pipe_cli
= NULL
;
902 NTSTATUS status
, result
;
904 struct policy_handle connect_handle
, domain_handle
, group_handle
;
905 struct lsa_String lsa_group_name
, lsa_user_name
;
906 struct dom_sid2
*domain_sid
= NULL
;
907 struct dcerpc_binding_handle
*b
= NULL
;
909 struct samr_Ids rids
;
910 struct samr_Ids types
;
912 ZERO_STRUCT(connect_handle
);
913 ZERO_STRUCT(domain_handle
);
914 ZERO_STRUCT(group_handle
);
916 if (!r
->in
.group_name
) {
917 return WERR_INVALID_PARAM
;
920 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
923 if (!W_ERROR_IS_OK(werr
)) {
927 b
= pipe_cli
->binding_handle
;
929 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
930 SAMR_ACCESS_ENUM_DOMAINS
|
931 SAMR_ACCESS_LOOKUP_DOMAIN
,
932 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
936 if (!W_ERROR_IS_OK(werr
)) {
940 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
942 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
949 if (!NT_STATUS_IS_OK(status
)) {
950 werr
= ntstatus_to_werror(status
);
953 if (!NT_STATUS_IS_OK(result
)) {
954 werr
= WERR_GROUPNOTFOUND
;
957 if (rids
.count
!= 1) {
958 werr
= WERR_BAD_NET_RESP
;
961 if (types
.count
!= 1) {
962 werr
= WERR_BAD_NET_RESP
;
966 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
967 werr
= WERR_GROUPNOTFOUND
;
971 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
973 SAMR_GROUP_ACCESS_ADD_MEMBER
,
977 if (!NT_STATUS_IS_OK(status
)) {
978 werr
= ntstatus_to_werror(status
);
981 if (!NT_STATUS_IS_OK(result
)) {
982 werr
= ntstatus_to_werror(result
);
986 init_lsa_String(&lsa_user_name
, r
->in
.user_name
);
988 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
995 if (!NT_STATUS_IS_OK(status
)) {
996 werr
= ntstatus_to_werror(status
);
999 if (!NT_STATUS_IS_OK(result
)) {
1000 werr
= WERR_USER_NOT_FOUND
;
1003 if (rids
.count
!= 1) {
1004 werr
= WERR_BAD_NET_RESP
;
1007 if (types
.count
!= 1) {
1008 werr
= WERR_BAD_NET_RESP
;
1012 if (types
.ids
[0] != SID_NAME_USER
) {
1013 werr
= WERR_USER_NOT_FOUND
;
1017 status
= dcerpc_samr_AddGroupMember(b
, talloc_tos(),
1022 if (!NT_STATUS_IS_OK(status
)) {
1023 werr
= ntstatus_to_werror(status
);
1026 if (!NT_STATUS_IS_OK(result
)) {
1027 werr
= ntstatus_to_werror(result
);
1034 if (is_valid_policy_hnd(&group_handle
)) {
1035 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
1038 if (ctx
->disable_policy_handle_cache
) {
1039 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1040 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1046 /****************************************************************
1047 ****************************************************************/
1049 WERROR
NetGroupAddUser_l(struct libnetapi_ctx
*ctx
,
1050 struct NetGroupAddUser
*r
)
1052 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupAddUser
);
1055 /****************************************************************
1056 ****************************************************************/
1058 WERROR
NetGroupDelUser_r(struct libnetapi_ctx
*ctx
,
1059 struct NetGroupDelUser
*r
)
1061 struct rpc_pipe_client
*pipe_cli
= NULL
;
1062 NTSTATUS status
, result
;
1064 struct policy_handle connect_handle
, domain_handle
, group_handle
;
1065 struct lsa_String lsa_group_name
, lsa_user_name
;
1066 struct dom_sid2
*domain_sid
= NULL
;
1067 struct dcerpc_binding_handle
*b
= NULL
;
1069 struct samr_Ids rids
;
1070 struct samr_Ids types
;
1072 ZERO_STRUCT(connect_handle
);
1073 ZERO_STRUCT(domain_handle
);
1074 ZERO_STRUCT(group_handle
);
1076 if (!r
->in
.group_name
) {
1077 return WERR_INVALID_PARAM
;
1080 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1083 if (!W_ERROR_IS_OK(werr
)) {
1087 b
= pipe_cli
->binding_handle
;
1089 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1090 SAMR_ACCESS_ENUM_DOMAINS
|
1091 SAMR_ACCESS_LOOKUP_DOMAIN
,
1092 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1096 if (!W_ERROR_IS_OK(werr
)) {
1100 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
1102 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1109 if (!NT_STATUS_IS_OK(status
)) {
1110 werr
= ntstatus_to_werror(status
);
1113 if (!NT_STATUS_IS_OK(result
)) {
1114 werr
= WERR_GROUPNOTFOUND
;
1117 if (rids
.count
!= 1) {
1118 werr
= WERR_BAD_NET_RESP
;
1121 if (types
.count
!= 1) {
1122 werr
= WERR_BAD_NET_RESP
;
1126 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
1127 werr
= WERR_GROUPNOTFOUND
;
1131 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
1133 SAMR_GROUP_ACCESS_REMOVE_MEMBER
,
1137 if (!NT_STATUS_IS_OK(status
)) {
1138 werr
= ntstatus_to_werror(status
);
1141 if (!NT_STATUS_IS_OK(result
)) {
1142 werr
= ntstatus_to_werror(result
);
1146 init_lsa_String(&lsa_user_name
, r
->in
.user_name
);
1148 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1155 if (!NT_STATUS_IS_OK(status
)) {
1156 werr
= ntstatus_to_werror(status
);
1160 if (!NT_STATUS_IS_OK(result
)) {
1161 werr
= WERR_USER_NOT_FOUND
;
1164 if (rids
.count
!= 1) {
1165 werr
= WERR_BAD_NET_RESP
;
1168 if (types
.count
!= 1) {
1169 werr
= WERR_BAD_NET_RESP
;
1173 if (types
.ids
[0] != SID_NAME_USER
) {
1174 werr
= WERR_USER_NOT_FOUND
;
1178 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
1182 if (!NT_STATUS_IS_OK(status
)) {
1183 werr
= ntstatus_to_werror(status
);
1186 if (!NT_STATUS_IS_OK(result
)) {
1187 werr
= ntstatus_to_werror(result
);
1194 if (is_valid_policy_hnd(&group_handle
)) {
1195 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
1198 if (ctx
->disable_policy_handle_cache
) {
1199 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1200 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1206 /****************************************************************
1207 ****************************************************************/
1209 WERROR
NetGroupDelUser_l(struct libnetapi_ctx
*ctx
,
1210 struct NetGroupDelUser
*r
)
1212 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupDelUser
);
1215 /****************************************************************
1216 ****************************************************************/
1218 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_0_buffer(TALLOC_CTX
*mem_ctx
,
1219 struct samr_DispInfoFullGroups
*groups
,
1222 struct GROUP_INFO_0
*g0
;
1225 g0
= talloc_zero_array(mem_ctx
, struct GROUP_INFO_0
, groups
->count
);
1226 W_ERROR_HAVE_NO_MEMORY(g0
);
1228 for (i
=0; i
<groups
->count
; i
++) {
1229 g0
[i
].grpi0_name
= talloc_strdup(mem_ctx
,
1230 groups
->entries
[i
].account_name
.string
);
1231 W_ERROR_HAVE_NO_MEMORY(g0
[i
].grpi0_name
);
1234 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g0
,
1235 sizeof(struct GROUP_INFO_0
) * groups
->count
);
1236 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1241 /****************************************************************
1242 ****************************************************************/
1244 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_1_buffer(TALLOC_CTX
*mem_ctx
,
1245 struct samr_DispInfoFullGroups
*groups
,
1248 struct GROUP_INFO_1
*g1
;
1251 g1
= talloc_zero_array(mem_ctx
, struct GROUP_INFO_1
, groups
->count
);
1252 W_ERROR_HAVE_NO_MEMORY(g1
);
1254 for (i
=0; i
<groups
->count
; i
++) {
1255 g1
[i
].grpi1_name
= talloc_strdup(mem_ctx
,
1256 groups
->entries
[i
].account_name
.string
);
1257 g1
[i
].grpi1_comment
= talloc_strdup(mem_ctx
,
1258 groups
->entries
[i
].description
.string
);
1259 W_ERROR_HAVE_NO_MEMORY(g1
[i
].grpi1_name
);
1262 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g1
,
1263 sizeof(struct GROUP_INFO_1
) * groups
->count
);
1264 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1269 /****************************************************************
1270 ****************************************************************/
1272 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_2_buffer(TALLOC_CTX
*mem_ctx
,
1273 struct samr_DispInfoFullGroups
*groups
,
1276 struct GROUP_INFO_2
*g2
;
1279 g2
= talloc_zero_array(mem_ctx
, struct GROUP_INFO_2
, groups
->count
);
1280 W_ERROR_HAVE_NO_MEMORY(g2
);
1282 for (i
=0; i
<groups
->count
; i
++) {
1283 g2
[i
].grpi2_name
= talloc_strdup(mem_ctx
,
1284 groups
->entries
[i
].account_name
.string
);
1285 g2
[i
].grpi2_comment
= talloc_strdup(mem_ctx
,
1286 groups
->entries
[i
].description
.string
);
1287 g2
[i
].grpi2_group_id
= groups
->entries
[i
].rid
;
1288 g2
[i
].grpi2_attributes
= groups
->entries
[i
].acct_flags
;
1289 W_ERROR_HAVE_NO_MEMORY(g2
[i
].grpi2_name
);
1292 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g2
,
1293 sizeof(struct GROUP_INFO_2
) * groups
->count
);
1294 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1299 /****************************************************************
1300 ****************************************************************/
1302 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_3_buffer(TALLOC_CTX
*mem_ctx
,
1303 struct samr_DispInfoFullGroups
*groups
,
1304 const struct dom_sid
*domain_sid
,
1307 struct GROUP_INFO_3
*g3
;
1310 g3
= talloc_zero_array(mem_ctx
, struct GROUP_INFO_3
, groups
->count
);
1311 W_ERROR_HAVE_NO_MEMORY(g3
);
1313 for (i
=0; i
<groups
->count
; i
++) {
1317 if (!sid_compose(&sid
, domain_sid
, groups
->entries
[i
].rid
)) {
1321 g3
[i
].grpi3_name
= talloc_strdup(mem_ctx
,
1322 groups
->entries
[i
].account_name
.string
);
1323 g3
[i
].grpi3_comment
= talloc_strdup(mem_ctx
,
1324 groups
->entries
[i
].description
.string
);
1325 g3
[i
].grpi3_group_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
1326 g3
[i
].grpi3_attributes
= groups
->entries
[i
].acct_flags
;
1327 W_ERROR_HAVE_NO_MEMORY(g3
[i
].grpi3_name
);
1330 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g3
,
1331 sizeof(struct GROUP_INFO_3
) * groups
->count
);
1332 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1337 /****************************************************************
1338 ****************************************************************/
1340 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_buffer(TALLOC_CTX
*mem_ctx
,
1342 struct samr_DispInfoFullGroups
*groups
,
1343 const struct dom_sid
*domain_sid
,
1344 uint32_t *entries_read
,
1348 *entries_read
= groups
->count
;
1353 return convert_samr_disp_groups_to_GROUP_INFO_0_buffer(mem_ctx
, groups
, buffer
);
1355 return convert_samr_disp_groups_to_GROUP_INFO_1_buffer(mem_ctx
, groups
, buffer
);
1357 return convert_samr_disp_groups_to_GROUP_INFO_2_buffer(mem_ctx
, groups
, buffer
);
1359 return convert_samr_disp_groups_to_GROUP_INFO_3_buffer(mem_ctx
, groups
, domain_sid
, buffer
);
1361 return WERR_UNKNOWN_LEVEL
;
1365 /****************************************************************
1366 ****************************************************************/
1368 WERROR
NetGroupEnum_r(struct libnetapi_ctx
*ctx
,
1369 struct NetGroupEnum
*r
)
1371 struct rpc_pipe_client
*pipe_cli
= NULL
;
1372 struct policy_handle connect_handle
;
1373 struct dom_sid2
*domain_sid
= NULL
;
1374 struct policy_handle domain_handle
;
1375 union samr_DispInfo info
;
1376 union samr_DomainInfo
*domain_info
= NULL
;
1377 struct dcerpc_binding_handle
*b
= NULL
;
1379 uint32_t total_size
= 0;
1380 uint32_t returned_size
= 0;
1382 NTSTATUS result
= NT_STATUS_OK
;
1383 NTSTATUS status
= NT_STATUS_OK
;
1384 WERROR werr
, tmp_werr
;
1386 ZERO_STRUCT(connect_handle
);
1387 ZERO_STRUCT(domain_handle
);
1389 switch (r
->in
.level
) {
1396 return WERR_UNKNOWN_LEVEL
;
1399 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1402 if (!W_ERROR_IS_OK(werr
)) {
1406 b
= pipe_cli
->binding_handle
;
1408 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1409 SAMR_ACCESS_ENUM_DOMAINS
|
1410 SAMR_ACCESS_LOOKUP_DOMAIN
,
1411 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1412 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1413 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1417 if (!W_ERROR_IS_OK(werr
)) {
1421 status
= dcerpc_samr_QueryDomainInfo(b
, talloc_tos(),
1426 if (!NT_STATUS_IS_OK(status
)) {
1427 werr
= ntstatus_to_werror(status
);
1430 if (!NT_STATUS_IS_OK(result
)) {
1431 werr
= ntstatus_to_werror(result
);
1435 if (r
->out
.total_entries
) {
1436 *r
->out
.total_entries
= domain_info
->general
.num_groups
;
1439 status
= dcerpc_samr_QueryDisplayInfo2(b
,
1443 r
->in
.resume_handle
?
1444 *r
->in
.resume_handle
: 0,
1451 if (!NT_STATUS_IS_OK(status
)) {
1452 werr
= ntstatus_to_werror(status
);
1456 werr
= ntstatus_to_werror(result
);
1457 if (NT_STATUS_IS_ERR(result
)) {
1461 if (r
->out
.resume_handle
&& info
.info3
.count
> 0) {
1462 *r
->out
.resume_handle
=
1463 info
.info3
.entries
[info
.info3
.count
-1].idx
;
1466 tmp_werr
= convert_samr_disp_groups_to_GROUP_INFO_buffer(ctx
,
1470 r
->out
.entries_read
,
1472 if (!W_ERROR_IS_OK(tmp_werr
)) {
1479 if (NT_STATUS_IS_OK(result
) ||
1480 NT_STATUS_IS_ERR(result
)) {
1482 if (ctx
->disable_policy_handle_cache
) {
1483 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1484 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1491 /****************************************************************
1492 ****************************************************************/
1494 WERROR
NetGroupEnum_l(struct libnetapi_ctx
*ctx
,
1495 struct NetGroupEnum
*r
)
1497 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupEnum
);
1500 /****************************************************************
1501 ****************************************************************/
1503 WERROR
NetGroupGetUsers_r(struct libnetapi_ctx
*ctx
,
1504 struct NetGroupGetUsers
*r
)
1506 /* FIXME: this call needs to cope with large replies */
1508 struct rpc_pipe_client
*pipe_cli
= NULL
;
1509 struct policy_handle connect_handle
, domain_handle
, group_handle
;
1510 struct lsa_String lsa_account_name
;
1511 struct dom_sid2
*domain_sid
= NULL
;
1512 struct samr_Ids group_rids
, name_types
;
1513 struct samr_RidAttrArray
*rid_array
= NULL
;
1514 struct lsa_Strings names
;
1515 struct samr_Ids member_types
;
1516 struct dcerpc_binding_handle
*b
= NULL
;
1519 uint32_t entries_read
= 0;
1521 NTSTATUS status
= NT_STATUS_OK
;
1522 NTSTATUS result
= NT_STATUS_OK
;
1525 ZERO_STRUCT(connect_handle
);
1526 ZERO_STRUCT(domain_handle
);
1527 ZERO_STRUCT(group_handle
);
1529 if (!r
->out
.buffer
) {
1530 return WERR_INVALID_PARAM
;
1533 *r
->out
.buffer
= NULL
;
1534 *r
->out
.entries_read
= 0;
1535 *r
->out
.total_entries
= 0;
1537 switch (r
->in
.level
) {
1542 return WERR_UNKNOWN_LEVEL
;
1546 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1549 if (!W_ERROR_IS_OK(werr
)) {
1553 b
= pipe_cli
->binding_handle
;
1555 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1556 SAMR_ACCESS_ENUM_DOMAINS
|
1557 SAMR_ACCESS_LOOKUP_DOMAIN
,
1558 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1562 if (!W_ERROR_IS_OK(werr
)) {
1566 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
1568 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1575 if (!NT_STATUS_IS_OK(status
)) {
1576 werr
= ntstatus_to_werror(status
);
1579 if (!NT_STATUS_IS_OK(result
)) {
1580 werr
= ntstatus_to_werror(result
);
1583 if (group_rids
.count
!= 1) {
1584 werr
= WERR_BAD_NET_RESP
;
1587 if (name_types
.count
!= 1) {
1588 werr
= WERR_BAD_NET_RESP
;
1592 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
1594 SAMR_GROUP_ACCESS_GET_MEMBERS
,
1598 if (!NT_STATUS_IS_OK(status
)) {
1599 werr
= ntstatus_to_werror(status
);
1602 if (!NT_STATUS_IS_OK(result
)) {
1603 werr
= ntstatus_to_werror(result
);
1607 status
= dcerpc_samr_QueryGroupMember(b
, talloc_tos(),
1611 if (!NT_STATUS_IS_OK(status
)) {
1612 werr
= ntstatus_to_werror(status
);
1615 if (!NT_STATUS_IS_OK(result
)) {
1616 werr
= ntstatus_to_werror(result
);
1620 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
1627 if (!NT_STATUS_IS_OK(status
)) {
1628 werr
= ntstatus_to_werror(status
);
1631 if (!NT_STATUS_IS_OK(result
)) {
1632 werr
= ntstatus_to_werror(result
);
1635 if (names
.count
!= rid_array
->count
) {
1636 werr
= WERR_BAD_NET_RESP
;
1639 if (member_types
.count
!= rid_array
->count
) {
1640 werr
= WERR_BAD_NET_RESP
;
1644 for (i
=0; i
< names
.count
; i
++) {
1646 if (member_types
.ids
[i
] != SID_NAME_USER
) {
1650 status
= add_GROUP_USERS_INFO_X_buffer(ctx
,
1652 names
.names
[i
].string
,
1656 if (!NT_STATUS_IS_OK(status
)) {
1657 werr
= ntstatus_to_werror(status
);
1662 *r
->out
.entries_read
= entries_read
;
1663 *r
->out
.total_entries
= entries_read
;
1668 if (is_valid_policy_hnd(&group_handle
)) {
1669 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
1672 if (ctx
->disable_policy_handle_cache
) {
1673 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1674 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1680 /****************************************************************
1681 ****************************************************************/
1683 WERROR
NetGroupGetUsers_l(struct libnetapi_ctx
*ctx
,
1684 struct NetGroupGetUsers
*r
)
1686 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupGetUsers
);
1689 /****************************************************************
1690 ****************************************************************/
1692 WERROR
NetGroupSetUsers_r(struct libnetapi_ctx
*ctx
,
1693 struct NetGroupSetUsers
*r
)
1695 struct rpc_pipe_client
*pipe_cli
= NULL
;
1696 struct policy_handle connect_handle
, domain_handle
, group_handle
;
1697 struct lsa_String lsa_account_name
;
1698 struct dom_sid2
*domain_sid
= NULL
;
1699 union samr_GroupInfo
*group_info
= NULL
;
1700 struct samr_Ids user_rids
, name_types
;
1701 struct samr_Ids group_rids
, group_types
;
1702 struct samr_RidAttrArray
*rid_array
= NULL
;
1703 struct lsa_String
*lsa_names
= NULL
;
1704 struct dcerpc_binding_handle
*b
= NULL
;
1706 uint32_t *add_rids
= NULL
;
1707 uint32_t *del_rids
= NULL
;
1708 size_t num_add_rids
= 0;
1709 size_t num_del_rids
= 0;
1711 uint32_t *member_rids
= NULL
;
1713 struct GROUP_USERS_INFO_0
*i0
= NULL
;
1714 struct GROUP_USERS_INFO_1
*i1
= NULL
;
1718 NTSTATUS status
= NT_STATUS_OK
;
1719 NTSTATUS result
= NT_STATUS_OK
;
1722 ZERO_STRUCT(connect_handle
);
1723 ZERO_STRUCT(domain_handle
);
1724 ZERO_STRUCT(group_handle
);
1726 if (!r
->in
.buffer
) {
1727 return WERR_INVALID_PARAM
;
1730 switch (r
->in
.level
) {
1735 return WERR_UNKNOWN_LEVEL
;
1738 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1741 if (!W_ERROR_IS_OK(werr
)) {
1745 b
= pipe_cli
->binding_handle
;
1747 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1748 SAMR_ACCESS_ENUM_DOMAINS
|
1749 SAMR_ACCESS_LOOKUP_DOMAIN
,
1750 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1754 if (!W_ERROR_IS_OK(werr
)) {
1758 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
1760 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1767 if (!NT_STATUS_IS_OK(status
)) {
1768 werr
= ntstatus_to_werror(status
);
1771 if (!NT_STATUS_IS_OK(result
)) {
1772 werr
= ntstatus_to_werror(result
);
1775 if (group_rids
.count
!= 1) {
1776 werr
= WERR_BAD_NET_RESP
;
1779 if (group_types
.count
!= 1) {
1780 werr
= WERR_BAD_NET_RESP
;
1784 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
1786 SAMR_GROUP_ACCESS_GET_MEMBERS
|
1787 SAMR_GROUP_ACCESS_ADD_MEMBER
|
1788 SAMR_GROUP_ACCESS_REMOVE_MEMBER
|
1789 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
1793 if (!NT_STATUS_IS_OK(status
)) {
1794 werr
= ntstatus_to_werror(status
);
1797 if (!NT_STATUS_IS_OK(result
)) {
1798 werr
= ntstatus_to_werror(result
);
1802 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
1804 GROUPINFOATTRIBUTES
,
1807 if (!NT_STATUS_IS_OK(status
)) {
1808 werr
= ntstatus_to_werror(status
);
1811 if (!NT_STATUS_IS_OK(result
)) {
1812 werr
= ntstatus_to_werror(result
);
1816 switch (r
->in
.level
) {
1818 i0
= (struct GROUP_USERS_INFO_0
*)r
->in
.buffer
;
1821 i1
= (struct GROUP_USERS_INFO_1
*)r
->in
.buffer
;
1825 lsa_names
= talloc_array(ctx
, struct lsa_String
, r
->in
.num_entries
);
1831 for (i
=0; i
< r
->in
.num_entries
; i
++) {
1833 switch (r
->in
.level
) {
1835 init_lsa_String(&lsa_names
[i
], i0
->grui0_name
);
1839 init_lsa_String(&lsa_names
[i
], i1
->grui1_name
);
1845 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1852 if (!NT_STATUS_IS_OK(status
)) {
1853 werr
= ntstatus_to_werror(status
);
1856 if (!NT_STATUS_IS_OK(result
)) {
1857 werr
= ntstatus_to_werror(result
);
1861 if (r
->in
.num_entries
!= user_rids
.count
) {
1862 werr
= WERR_BAD_NET_RESP
;
1865 if (r
->in
.num_entries
!= name_types
.count
) {
1866 werr
= WERR_BAD_NET_RESP
;
1870 member_rids
= user_rids
.ids
;
1872 status
= dcerpc_samr_QueryGroupMember(b
, talloc_tos(),
1876 if (!NT_STATUS_IS_OK(status
)) {
1877 werr
= ntstatus_to_werror(status
);
1880 if (!NT_STATUS_IS_OK(result
)) {
1881 werr
= ntstatus_to_werror(result
);
1887 for (i
=0; i
< r
->in
.num_entries
; i
++) {
1888 bool already_member
= false;
1889 for (k
=0; k
< rid_array
->count
; k
++) {
1890 if (member_rids
[i
] == rid_array
->rids
[k
]) {
1891 already_member
= true;
1895 if (!already_member
) {
1896 if (!add_rid_to_array_unique(ctx
,
1898 &add_rids
, &num_add_rids
)) {
1899 werr
= WERR_GENERAL_FAILURE
;
1907 for (k
=0; k
< rid_array
->count
; k
++) {
1908 bool keep_member
= false;
1909 for (i
=0; i
< r
->in
.num_entries
; i
++) {
1910 if (member_rids
[i
] == rid_array
->rids
[k
]) {
1916 if (!add_rid_to_array_unique(ctx
,
1918 &del_rids
, &num_del_rids
)) {
1919 werr
= WERR_GENERAL_FAILURE
;
1927 for (i
=0; i
< num_add_rids
; i
++) {
1928 status
= dcerpc_samr_AddGroupMember(b
, talloc_tos(),
1933 if (!NT_STATUS_IS_OK(status
)) {
1934 werr
= ntstatus_to_werror(status
);
1937 if (!NT_STATUS_IS_OK(result
)) {
1938 werr
= ntstatus_to_werror(result
);
1945 for (i
=0; i
< num_del_rids
; i
++) {
1946 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
1950 if (!NT_STATUS_IS_OK(status
)) {
1951 werr
= ntstatus_to_werror(status
);
1954 if (!NT_STATUS_IS_OK(result
)) {
1955 werr
= ntstatus_to_werror(result
);
1963 if (is_valid_policy_hnd(&group_handle
)) {
1964 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
1967 if (ctx
->disable_policy_handle_cache
) {
1968 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1969 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1975 /****************************************************************
1976 ****************************************************************/
1978 WERROR
NetGroupSetUsers_l(struct libnetapi_ctx
*ctx
,
1979 struct NetGroupSetUsers
*r
)
1981 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupSetUsers
);