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_PARAMETER
;
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_INVALID_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 (any_nt_status_not_ok(status
, result
, &status
)) {
124 werr
= ntstatus_to_werror(status
);
128 switch (r
->in
.level
) {
130 if (info1
->grpi1_comment
) {
131 init_lsa_String(&info
.description
,
132 info1
->grpi1_comment
);
134 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
136 GROUPINFODESCRIPTION
,
142 if (info2
->grpi2_comment
) {
143 init_lsa_String(&info
.description
,
144 info2
->grpi2_comment
);
146 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
148 GROUPINFODESCRIPTION
,
151 if (any_nt_status_not_ok(
152 status
, result
, &status
)) {
153 werr
= ntstatus_to_werror(status
);
158 if (info2
->grpi2_attributes
!= 0) {
159 info
.attributes
.attributes
= info2
->grpi2_attributes
;
160 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
169 if (info3
->grpi3_comment
) {
170 init_lsa_String(&info
.description
,
171 info3
->grpi3_comment
);
173 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
175 GROUPINFODESCRIPTION
,
178 if (any_nt_status_not_ok(
179 status
, result
, &status
)) {
180 werr
= ntstatus_to_werror(status
);
185 if (info3
->grpi3_attributes
!= 0) {
186 info
.attributes
.attributes
= info3
->grpi3_attributes
;
187 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
198 if (any_nt_status_not_ok(status
, result
, &status
)) {
199 werr
= ntstatus_to_werror(status
);
207 dcerpc_samr_DeleteDomainGroup(b
, talloc_tos(),
208 &group_handle
, &result
);
211 if (is_valid_policy_hnd(&group_handle
)) {
212 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
215 if (ctx
->disable_policy_handle_cache
) {
216 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
217 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
223 /****************************************************************
224 ****************************************************************/
226 WERROR
NetGroupAdd_l(struct libnetapi_ctx
*ctx
,
227 struct NetGroupAdd
*r
)
229 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupAdd
);
232 /****************************************************************
233 ****************************************************************/
235 WERROR
NetGroupDel_r(struct libnetapi_ctx
*ctx
,
236 struct NetGroupDel
*r
)
238 struct rpc_pipe_client
*pipe_cli
= NULL
;
239 NTSTATUS status
, result
;
241 struct policy_handle connect_handle
, domain_handle
, group_handle
;
242 struct lsa_String lsa_group_name
;
243 struct dom_sid2
*domain_sid
= NULL
;
245 struct dcerpc_binding_handle
*b
= NULL
;
247 struct samr_Ids rids
;
248 struct samr_Ids types
;
249 union samr_GroupInfo
*info
= NULL
;
250 struct samr_RidAttrArray
*rid_array
= NULL
;
252 ZERO_STRUCT(connect_handle
);
253 ZERO_STRUCT(domain_handle
);
254 ZERO_STRUCT(group_handle
);
256 if (!r
->in
.group_name
) {
257 return WERR_INVALID_PARAMETER
;
260 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
263 if (!W_ERROR_IS_OK(werr
)) {
267 b
= pipe_cli
->binding_handle
;
269 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
270 SAMR_ACCESS_ENUM_DOMAINS
|
271 SAMR_ACCESS_LOOKUP_DOMAIN
,
272 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
276 if (!W_ERROR_IS_OK(werr
)) {
280 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
282 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
289 if (any_nt_status_not_ok(status
, result
, &status
)) {
290 werr
= ntstatus_to_werror(status
);
294 if (rids
.count
!= 1) {
295 werr
= WERR_BAD_NET_RESP
;
298 if (types
.count
!= 1) {
299 werr
= WERR_BAD_NET_RESP
;
303 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
304 werr
= WERR_INVALID_DATATYPE
;
308 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
311 SAMR_GROUP_ACCESS_GET_MEMBERS
|
312 SAMR_GROUP_ACCESS_REMOVE_MEMBER
|
313 SAMR_GROUP_ACCESS_ADD_MEMBER
|
314 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
318 if (any_nt_status_not_ok(status
, result
, &status
)) {
319 werr
= ntstatus_to_werror(status
);
323 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
328 if (any_nt_status_not_ok(status
, result
, &status
)) {
329 werr
= ntstatus_to_werror(status
);
334 /* breaks against NT4 */
335 if (!(info
->attributes
.attributes
& SE_GROUP_ENABLED
)) {
336 werr
= WERR_ACCESS_DENIED
;
340 status
= dcerpc_samr_QueryGroupMember(b
, talloc_tos(),
344 if (any_nt_status_not_ok(status
, result
, &status
)) {
345 werr
= ntstatus_to_werror(status
);
350 struct lsa_Strings names
;
351 struct samr_Ids member_types
;
353 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
360 if (any_nt_status_not_ok(status
, result
, &status
)) {
361 werr
= ntstatus_to_werror(status
);
364 if (names
.count
!= rid_array
->count
) {
365 werr
= WERR_BAD_NET_RESP
;
368 if (member_types
.count
!= rid_array
->count
) {
369 werr
= WERR_BAD_NET_RESP
;
374 for (i
=0; i
< rid_array
->count
; i
++) {
376 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
380 if (any_nt_status_not_ok(status
, result
, &status
)) {
381 werr
= ntstatus_to_werror(status
);
386 status
= dcerpc_samr_DeleteDomainGroup(b
, talloc_tos(),
389 if (any_nt_status_not_ok(status
, result
, &status
)) {
390 werr
= ntstatus_to_werror(status
);
394 ZERO_STRUCT(group_handle
);
399 if (is_valid_policy_hnd(&group_handle
)) {
400 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
403 if (ctx
->disable_policy_handle_cache
) {
404 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
405 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
411 /****************************************************************
412 ****************************************************************/
414 WERROR
NetGroupDel_l(struct libnetapi_ctx
*ctx
,
415 struct NetGroupDel
*r
)
417 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupDel
);
420 /****************************************************************
421 ****************************************************************/
423 WERROR
NetGroupSetInfo_r(struct libnetapi_ctx
*ctx
,
424 struct NetGroupSetInfo
*r
)
426 struct rpc_pipe_client
*pipe_cli
= NULL
;
427 NTSTATUS status
, result
;
429 struct policy_handle connect_handle
, domain_handle
, group_handle
;
430 struct lsa_String lsa_group_name
;
431 struct dom_sid2
*domain_sid
= NULL
;
432 struct dcerpc_binding_handle
*b
= NULL
;
434 struct samr_Ids rids
;
435 struct samr_Ids types
;
436 union samr_GroupInfo info
;
437 struct GROUP_INFO_0
*g0
;
438 struct GROUP_INFO_1
*g1
;
439 struct GROUP_INFO_2
*g2
;
440 struct GROUP_INFO_3
*g3
;
441 struct GROUP_INFO_1002
*g1002
;
442 struct GROUP_INFO_1005
*g1005
;
444 ZERO_STRUCT(connect_handle
);
445 ZERO_STRUCT(domain_handle
);
446 ZERO_STRUCT(group_handle
);
448 if (!r
->in
.group_name
) {
449 return WERR_INVALID_PARAMETER
;
452 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
455 if (!W_ERROR_IS_OK(werr
)) {
459 b
= pipe_cli
->binding_handle
;
461 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
462 SAMR_ACCESS_ENUM_DOMAINS
|
463 SAMR_ACCESS_LOOKUP_DOMAIN
,
464 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
468 if (!W_ERROR_IS_OK(werr
)) {
472 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
474 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
481 if (any_nt_status_not_ok(status
, result
, &status
)) {
482 werr
= ntstatus_to_werror(status
);
485 if (rids
.count
!= 1) {
486 werr
= WERR_BAD_NET_RESP
;
489 if (types
.count
!= 1) {
490 werr
= WERR_BAD_NET_RESP
;
494 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
495 werr
= WERR_INVALID_DATATYPE
;
499 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
501 SAMR_GROUP_ACCESS_SET_INFO
|
502 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
506 if (any_nt_status_not_ok(status
, result
, &status
)) {
507 werr
= ntstatus_to_werror(status
);
511 switch (r
->in
.level
) {
513 g0
= (struct GROUP_INFO_0
*)r
->in
.buffer
;
514 init_lsa_String(&info
.name
, g0
->grpi0_name
);
515 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
522 g1
= (struct GROUP_INFO_1
*)r
->in
.buffer
;
523 init_lsa_String(&info
.description
, g1
->grpi1_comment
);
524 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
526 GROUPINFODESCRIPTION
,
531 g2
= (struct GROUP_INFO_2
*)r
->in
.buffer
;
532 init_lsa_String(&info
.description
, g2
->grpi2_comment
);
533 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
535 GROUPINFODESCRIPTION
,
538 if (any_nt_status_not_ok(status
, result
, &status
)) {
539 werr
= ntstatus_to_werror(status
);
543 info
.attributes
.attributes
= g2
->grpi2_attributes
;
544 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
551 g3
= (struct GROUP_INFO_3
*)r
->in
.buffer
;
552 init_lsa_String(&info
.description
, g3
->grpi3_comment
);
553 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
555 GROUPINFODESCRIPTION
,
558 if (any_nt_status_not_ok(status
, result
, &status
)) {
559 werr
= ntstatus_to_werror(status
);
563 info
.attributes
.attributes
= g3
->grpi3_attributes
;
564 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
571 g1002
= (struct GROUP_INFO_1002
*)r
->in
.buffer
;
572 init_lsa_String(&info
.description
, g1002
->grpi1002_comment
);
573 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
575 GROUPINFODESCRIPTION
,
580 g1005
= (struct GROUP_INFO_1005
*)r
->in
.buffer
;
581 info
.attributes
.attributes
= g1005
->grpi1005_attributes
;
582 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
589 status
= NT_STATUS_INVALID_LEVEL
;
593 if (any_nt_status_not_ok(status
, result
, &status
)) {
594 werr
= ntstatus_to_werror(status
);
601 if (is_valid_policy_hnd(&group_handle
)) {
602 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
605 if (ctx
->disable_policy_handle_cache
) {
606 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
607 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
613 /****************************************************************
614 ****************************************************************/
616 WERROR
NetGroupSetInfo_l(struct libnetapi_ctx
*ctx
,
617 struct NetGroupSetInfo
*r
)
619 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupSetInfo
);
622 /****************************************************************
623 ****************************************************************/
625 static WERROR
map_group_info_to_buffer(TALLOC_CTX
*mem_ctx
,
627 struct samr_GroupInfoAll
*info
,
628 struct dom_sid2
*domain_sid
,
632 struct GROUP_INFO_0 info0
;
633 struct GROUP_INFO_1 info1
;
634 struct GROUP_INFO_2 info2
;
635 struct GROUP_INFO_3 info3
;
640 info0
.grpi0_name
= info
->name
.string
;
642 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info0
, sizeof(info0
));
646 info1
.grpi1_name
= info
->name
.string
;
647 info1
.grpi1_comment
= info
->description
.string
;
649 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info1
, sizeof(info1
));
653 info2
.grpi2_name
= info
->name
.string
;
654 info2
.grpi2_comment
= info
->description
.string
;
655 info2
.grpi2_group_id
= rid
;
656 info2
.grpi2_attributes
= info
->attributes
;
658 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info2
, sizeof(info2
));
662 if (!sid_compose(&sid
, domain_sid
, rid
)) {
663 return WERR_NOT_ENOUGH_MEMORY
;
666 info3
.grpi3_name
= info
->name
.string
;
667 info3
.grpi3_comment
= info
->description
.string
;
668 info3
.grpi3_attributes
= info
->attributes
;
669 info3
.grpi3_group_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
671 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info3
, sizeof(info3
));
675 return WERR_INVALID_LEVEL
;
678 W_ERROR_HAVE_NO_MEMORY(*buffer
);
683 /****************************************************************
684 ****************************************************************/
686 WERROR
NetGroupGetInfo_r(struct libnetapi_ctx
*ctx
,
687 struct NetGroupGetInfo
*r
)
689 struct rpc_pipe_client
*pipe_cli
= NULL
;
690 NTSTATUS status
, result
;
692 struct policy_handle connect_handle
, domain_handle
, group_handle
;
693 struct lsa_String lsa_group_name
;
694 struct dom_sid2
*domain_sid
= NULL
;
695 struct dcerpc_binding_handle
*b
= NULL
;
697 struct samr_Ids rids
;
698 struct samr_Ids types
;
699 union samr_GroupInfo
*info
= NULL
;
700 bool group_info_all
= false;
702 ZERO_STRUCT(connect_handle
);
703 ZERO_STRUCT(domain_handle
);
704 ZERO_STRUCT(group_handle
);
706 if (!r
->in
.group_name
) {
707 return WERR_INVALID_PARAMETER
;
710 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
713 if (!W_ERROR_IS_OK(werr
)) {
717 b
= pipe_cli
->binding_handle
;
719 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
720 SAMR_ACCESS_ENUM_DOMAINS
|
721 SAMR_ACCESS_LOOKUP_DOMAIN
,
722 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
726 if (!W_ERROR_IS_OK(werr
)) {
730 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
732 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
739 if (any_nt_status_not_ok(status
, result
, &status
)) {
740 werr
= ntstatus_to_werror(status
);
743 if (rids
.count
!= 1) {
744 werr
= WERR_BAD_NET_RESP
;
747 if (types
.count
!= 1) {
748 werr
= WERR_BAD_NET_RESP
;
752 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
753 werr
= WERR_INVALID_DATATYPE
;
757 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
759 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
763 if (any_nt_status_not_ok(status
, result
, &status
)) {
764 werr
= ntstatus_to_werror(status
);
768 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
773 if (!NT_STATUS_IS_OK(status
)) {
774 werr
= ntstatus_to_werror(status
);
778 if (NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_INFO_CLASS
)) {
779 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
784 group_info_all
= true;
785 if (!NT_STATUS_IS_OK(status
)) {
786 werr
= ntstatus_to_werror(status
);
791 if (!NT_STATUS_IS_OK(result
)) {
792 werr
= ntstatus_to_werror(result
);
796 werr
= map_group_info_to_buffer(ctx
, r
->in
.level
,
797 group_info_all
? &info
->all
: &info
->all2
,
798 domain_sid
, rids
.ids
[0],
800 if (!W_ERROR_IS_OK(werr
)) {
804 if (is_valid_policy_hnd(&group_handle
)) {
805 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
808 if (ctx
->disable_policy_handle_cache
) {
809 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
810 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
816 /****************************************************************
817 ****************************************************************/
819 WERROR
NetGroupGetInfo_l(struct libnetapi_ctx
*ctx
,
820 struct NetGroupGetInfo
*r
)
822 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupGetInfo
);
825 /****************************************************************
826 ****************************************************************/
828 WERROR
NetGroupAddUser_r(struct libnetapi_ctx
*ctx
,
829 struct NetGroupAddUser
*r
)
831 struct rpc_pipe_client
*pipe_cli
= NULL
;
832 NTSTATUS status
, result
;
834 struct policy_handle connect_handle
, domain_handle
, group_handle
;
835 struct lsa_String lsa_group_name
, lsa_user_name
;
836 struct dom_sid2
*domain_sid
= NULL
;
837 struct dcerpc_binding_handle
*b
= NULL
;
839 struct samr_Ids rids
;
840 struct samr_Ids types
;
842 ZERO_STRUCT(connect_handle
);
843 ZERO_STRUCT(domain_handle
);
844 ZERO_STRUCT(group_handle
);
846 if (!r
->in
.group_name
) {
847 return WERR_INVALID_PARAMETER
;
850 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
853 if (!W_ERROR_IS_OK(werr
)) {
857 b
= pipe_cli
->binding_handle
;
859 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
860 SAMR_ACCESS_ENUM_DOMAINS
|
861 SAMR_ACCESS_LOOKUP_DOMAIN
,
862 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
866 if (!W_ERROR_IS_OK(werr
)) {
870 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
872 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
879 if (!NT_STATUS_IS_OK(status
)) {
880 werr
= ntstatus_to_werror(status
);
883 if (!NT_STATUS_IS_OK(result
)) {
884 werr
= WERR_NERR_GROUPNOTFOUND
;
887 if (rids
.count
!= 1) {
888 werr
= WERR_BAD_NET_RESP
;
891 if (types
.count
!= 1) {
892 werr
= WERR_BAD_NET_RESP
;
896 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
897 werr
= WERR_NERR_GROUPNOTFOUND
;
901 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
903 SAMR_GROUP_ACCESS_ADD_MEMBER
,
907 if (any_nt_status_not_ok(status
, result
, &status
)) {
908 werr
= ntstatus_to_werror(status
);
912 init_lsa_String(&lsa_user_name
, r
->in
.user_name
);
914 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
921 if (!NT_STATUS_IS_OK(status
)) {
922 werr
= ntstatus_to_werror(status
);
925 if (!NT_STATUS_IS_OK(result
)) {
926 werr
= WERR_NERR_USERNOTFOUND
;
929 if (rids
.count
!= 1) {
930 werr
= WERR_BAD_NET_RESP
;
933 if (types
.count
!= 1) {
934 werr
= WERR_BAD_NET_RESP
;
938 if (types
.ids
[0] != SID_NAME_USER
) {
939 werr
= WERR_NERR_USERNOTFOUND
;
943 status
= dcerpc_samr_AddGroupMember(b
, talloc_tos(),
948 if (any_nt_status_not_ok(status
, result
, &status
)) {
949 werr
= ntstatus_to_werror(status
);
956 if (is_valid_policy_hnd(&group_handle
)) {
957 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
960 if (ctx
->disable_policy_handle_cache
) {
961 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
962 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
968 /****************************************************************
969 ****************************************************************/
971 WERROR
NetGroupAddUser_l(struct libnetapi_ctx
*ctx
,
972 struct NetGroupAddUser
*r
)
974 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupAddUser
);
977 /****************************************************************
978 ****************************************************************/
980 WERROR
NetGroupDelUser_r(struct libnetapi_ctx
*ctx
,
981 struct NetGroupDelUser
*r
)
983 struct rpc_pipe_client
*pipe_cli
= NULL
;
984 NTSTATUS status
, result
;
986 struct policy_handle connect_handle
, domain_handle
, group_handle
;
987 struct lsa_String lsa_group_name
, lsa_user_name
;
988 struct dom_sid2
*domain_sid
= NULL
;
989 struct dcerpc_binding_handle
*b
= NULL
;
991 struct samr_Ids rids
;
992 struct samr_Ids types
;
994 ZERO_STRUCT(connect_handle
);
995 ZERO_STRUCT(domain_handle
);
996 ZERO_STRUCT(group_handle
);
998 if (!r
->in
.group_name
) {
999 return WERR_INVALID_PARAMETER
;
1002 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1005 if (!W_ERROR_IS_OK(werr
)) {
1009 b
= pipe_cli
->binding_handle
;
1011 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1012 SAMR_ACCESS_ENUM_DOMAINS
|
1013 SAMR_ACCESS_LOOKUP_DOMAIN
,
1014 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1018 if (!W_ERROR_IS_OK(werr
)) {
1022 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
1024 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1031 if (!NT_STATUS_IS_OK(status
)) {
1032 werr
= ntstatus_to_werror(status
);
1035 if (!NT_STATUS_IS_OK(result
)) {
1036 werr
= WERR_NERR_GROUPNOTFOUND
;
1039 if (rids
.count
!= 1) {
1040 werr
= WERR_BAD_NET_RESP
;
1043 if (types
.count
!= 1) {
1044 werr
= WERR_BAD_NET_RESP
;
1048 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
1049 werr
= WERR_NERR_GROUPNOTFOUND
;
1053 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
1055 SAMR_GROUP_ACCESS_REMOVE_MEMBER
,
1059 if (any_nt_status_not_ok(status
, result
, &status
)) {
1060 werr
= ntstatus_to_werror(status
);
1064 init_lsa_String(&lsa_user_name
, r
->in
.user_name
);
1066 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1073 if (!NT_STATUS_IS_OK(status
)) {
1074 werr
= ntstatus_to_werror(status
);
1078 if (!NT_STATUS_IS_OK(result
)) {
1079 werr
= WERR_NERR_USERNOTFOUND
;
1082 if (rids
.count
!= 1) {
1083 werr
= WERR_BAD_NET_RESP
;
1086 if (types
.count
!= 1) {
1087 werr
= WERR_BAD_NET_RESP
;
1091 if (types
.ids
[0] != SID_NAME_USER
) {
1092 werr
= WERR_NERR_USERNOTFOUND
;
1096 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
1100 if (any_nt_status_not_ok(status
, result
, &status
)) {
1101 werr
= ntstatus_to_werror(status
);
1108 if (is_valid_policy_hnd(&group_handle
)) {
1109 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
1112 if (ctx
->disable_policy_handle_cache
) {
1113 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1114 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1120 /****************************************************************
1121 ****************************************************************/
1123 WERROR
NetGroupDelUser_l(struct libnetapi_ctx
*ctx
,
1124 struct NetGroupDelUser
*r
)
1126 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupDelUser
);
1129 /****************************************************************
1130 ****************************************************************/
1132 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_0_buffer(TALLOC_CTX
*mem_ctx
,
1133 struct samr_DispInfoFullGroups
*groups
,
1136 struct GROUP_INFO_0
*g0
;
1139 g0
= talloc_zero_array(mem_ctx
, struct GROUP_INFO_0
, groups
->count
);
1140 W_ERROR_HAVE_NO_MEMORY(g0
);
1142 for (i
=0; i
<groups
->count
; i
++) {
1143 g0
[i
].grpi0_name
= talloc_strdup(mem_ctx
,
1144 groups
->entries
[i
].account_name
.string
);
1145 W_ERROR_HAVE_NO_MEMORY(g0
[i
].grpi0_name
);
1148 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g0
,
1149 sizeof(struct GROUP_INFO_0
) * groups
->count
);
1150 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1155 /****************************************************************
1156 ****************************************************************/
1158 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_1_buffer(TALLOC_CTX
*mem_ctx
,
1159 struct samr_DispInfoFullGroups
*groups
,
1162 struct GROUP_INFO_1
*g1
;
1165 g1
= talloc_zero_array(mem_ctx
, struct GROUP_INFO_1
, groups
->count
);
1166 W_ERROR_HAVE_NO_MEMORY(g1
);
1168 for (i
=0; i
<groups
->count
; i
++) {
1169 g1
[i
].grpi1_name
= talloc_strdup(mem_ctx
,
1170 groups
->entries
[i
].account_name
.string
);
1171 g1
[i
].grpi1_comment
= talloc_strdup(mem_ctx
,
1172 groups
->entries
[i
].description
.string
);
1173 W_ERROR_HAVE_NO_MEMORY(g1
[i
].grpi1_name
);
1176 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g1
,
1177 sizeof(struct GROUP_INFO_1
) * groups
->count
);
1178 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1183 /****************************************************************
1184 ****************************************************************/
1186 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_2_buffer(TALLOC_CTX
*mem_ctx
,
1187 struct samr_DispInfoFullGroups
*groups
,
1190 struct GROUP_INFO_2
*g2
;
1193 g2
= talloc_zero_array(mem_ctx
, struct GROUP_INFO_2
, groups
->count
);
1194 W_ERROR_HAVE_NO_MEMORY(g2
);
1196 for (i
=0; i
<groups
->count
; i
++) {
1197 g2
[i
].grpi2_name
= talloc_strdup(mem_ctx
,
1198 groups
->entries
[i
].account_name
.string
);
1199 g2
[i
].grpi2_comment
= talloc_strdup(mem_ctx
,
1200 groups
->entries
[i
].description
.string
);
1201 g2
[i
].grpi2_group_id
= groups
->entries
[i
].rid
;
1202 g2
[i
].grpi2_attributes
= groups
->entries
[i
].acct_flags
;
1203 W_ERROR_HAVE_NO_MEMORY(g2
[i
].grpi2_name
);
1206 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g2
,
1207 sizeof(struct GROUP_INFO_2
) * groups
->count
);
1208 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1213 /****************************************************************
1214 ****************************************************************/
1216 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_3_buffer(TALLOC_CTX
*mem_ctx
,
1217 struct samr_DispInfoFullGroups
*groups
,
1218 const struct dom_sid
*domain_sid
,
1221 struct GROUP_INFO_3
*g3
;
1224 g3
= talloc_zero_array(mem_ctx
, struct GROUP_INFO_3
, groups
->count
);
1225 W_ERROR_HAVE_NO_MEMORY(g3
);
1227 for (i
=0; i
<groups
->count
; i
++) {
1231 if (!sid_compose(&sid
, domain_sid
, groups
->entries
[i
].rid
)) {
1232 return WERR_NOT_ENOUGH_MEMORY
;
1235 g3
[i
].grpi3_name
= talloc_strdup(mem_ctx
,
1236 groups
->entries
[i
].account_name
.string
);
1237 g3
[i
].grpi3_comment
= talloc_strdup(mem_ctx
,
1238 groups
->entries
[i
].description
.string
);
1239 g3
[i
].grpi3_group_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
1240 g3
[i
].grpi3_attributes
= groups
->entries
[i
].acct_flags
;
1241 W_ERROR_HAVE_NO_MEMORY(g3
[i
].grpi3_name
);
1244 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g3
,
1245 sizeof(struct GROUP_INFO_3
) * groups
->count
);
1246 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1251 /****************************************************************
1252 ****************************************************************/
1254 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_buffer(TALLOC_CTX
*mem_ctx
,
1256 struct samr_DispInfoFullGroups
*groups
,
1257 const struct dom_sid
*domain_sid
,
1258 uint32_t *entries_read
,
1262 *entries_read
= groups
->count
;
1267 return convert_samr_disp_groups_to_GROUP_INFO_0_buffer(mem_ctx
, groups
, buffer
);
1269 return convert_samr_disp_groups_to_GROUP_INFO_1_buffer(mem_ctx
, groups
, buffer
);
1271 return convert_samr_disp_groups_to_GROUP_INFO_2_buffer(mem_ctx
, groups
, buffer
);
1273 return convert_samr_disp_groups_to_GROUP_INFO_3_buffer(mem_ctx
, groups
, domain_sid
, buffer
);
1275 return WERR_INVALID_LEVEL
;
1279 /****************************************************************
1280 ****************************************************************/
1282 WERROR
NetGroupEnum_r(struct libnetapi_ctx
*ctx
,
1283 struct NetGroupEnum
*r
)
1285 struct rpc_pipe_client
*pipe_cli
= NULL
;
1286 struct policy_handle connect_handle
;
1287 struct dom_sid2
*domain_sid
= NULL
;
1288 struct policy_handle domain_handle
;
1289 union samr_DispInfo info
;
1290 union samr_DomainInfo
*domain_info
= NULL
;
1291 struct dcerpc_binding_handle
*b
= NULL
;
1293 uint32_t total_size
= 0;
1294 uint32_t returned_size
= 0;
1296 NTSTATUS result
= NT_STATUS_OK
;
1298 WERROR werr
, tmp_werr
;
1300 ZERO_STRUCT(connect_handle
);
1301 ZERO_STRUCT(domain_handle
);
1303 switch (r
->in
.level
) {
1310 return WERR_INVALID_LEVEL
;
1313 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1316 if (!W_ERROR_IS_OK(werr
)) {
1320 b
= pipe_cli
->binding_handle
;
1322 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1323 SAMR_ACCESS_ENUM_DOMAINS
|
1324 SAMR_ACCESS_LOOKUP_DOMAIN
,
1325 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1326 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1327 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1331 if (!W_ERROR_IS_OK(werr
)) {
1335 status
= dcerpc_samr_QueryDomainInfo(b
, talloc_tos(),
1340 if (any_nt_status_not_ok(status
, result
, &status
)) {
1341 werr
= ntstatus_to_werror(status
);
1345 if (r
->out
.total_entries
) {
1346 *r
->out
.total_entries
= domain_info
->general
.num_groups
;
1349 status
= dcerpc_samr_QueryDisplayInfo2(b
,
1353 r
->in
.resume_handle
?
1354 *r
->in
.resume_handle
: 0,
1361 if (!NT_STATUS_IS_OK(status
)) {
1362 werr
= ntstatus_to_werror(status
);
1366 werr
= ntstatus_to_werror(result
);
1367 if (NT_STATUS_IS_ERR(result
)) {
1371 if (r
->out
.resume_handle
&& info
.info3
.count
> 0) {
1372 *r
->out
.resume_handle
=
1373 info
.info3
.entries
[info
.info3
.count
-1].idx
;
1376 tmp_werr
= convert_samr_disp_groups_to_GROUP_INFO_buffer(ctx
,
1380 r
->out
.entries_read
,
1382 if (!W_ERROR_IS_OK(tmp_werr
)) {
1389 if (NT_STATUS_IS_OK(result
) ||
1390 NT_STATUS_IS_ERR(result
)) {
1392 if (ctx
->disable_policy_handle_cache
) {
1393 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1394 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1401 /****************************************************************
1402 ****************************************************************/
1404 WERROR
NetGroupEnum_l(struct libnetapi_ctx
*ctx
,
1405 struct NetGroupEnum
*r
)
1407 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupEnum
);
1410 /****************************************************************
1411 ****************************************************************/
1413 WERROR
NetGroupGetUsers_r(struct libnetapi_ctx
*ctx
,
1414 struct NetGroupGetUsers
*r
)
1416 /* FIXME: this call needs to cope with large replies */
1418 struct rpc_pipe_client
*pipe_cli
= NULL
;
1419 struct policy_handle connect_handle
, domain_handle
, group_handle
;
1420 struct lsa_String lsa_account_name
;
1421 struct dom_sid2
*domain_sid
= NULL
;
1422 struct samr_Ids group_rids
, name_types
;
1423 struct samr_RidAttrArray
*rid_array
= NULL
;
1424 struct lsa_Strings names
;
1425 struct samr_Ids member_types
;
1426 struct dcerpc_binding_handle
*b
= NULL
;
1429 uint32_t entries_read
= 0;
1432 NTSTATUS result
= NT_STATUS_OK
;
1435 ZERO_STRUCT(connect_handle
);
1436 ZERO_STRUCT(domain_handle
);
1437 ZERO_STRUCT(group_handle
);
1439 if (!r
->out
.buffer
) {
1440 return WERR_INVALID_PARAMETER
;
1443 *r
->out
.buffer
= NULL
;
1444 *r
->out
.entries_read
= 0;
1445 *r
->out
.total_entries
= 0;
1447 switch (r
->in
.level
) {
1452 return WERR_INVALID_LEVEL
;
1456 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1459 if (!W_ERROR_IS_OK(werr
)) {
1463 b
= pipe_cli
->binding_handle
;
1465 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1466 SAMR_ACCESS_ENUM_DOMAINS
|
1467 SAMR_ACCESS_LOOKUP_DOMAIN
,
1468 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1472 if (!W_ERROR_IS_OK(werr
)) {
1476 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
1478 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1485 if (any_nt_status_not_ok(status
, result
, &status
)) {
1486 werr
= ntstatus_to_werror(status
);
1489 if (group_rids
.count
!= 1) {
1490 werr
= WERR_BAD_NET_RESP
;
1493 if (name_types
.count
!= 1) {
1494 werr
= WERR_BAD_NET_RESP
;
1498 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
1500 SAMR_GROUP_ACCESS_GET_MEMBERS
,
1504 if (any_nt_status_not_ok(status
, result
, &status
)) {
1505 werr
= ntstatus_to_werror(status
);
1509 status
= dcerpc_samr_QueryGroupMember(b
, talloc_tos(),
1513 if (any_nt_status_not_ok(status
, result
, &status
)) {
1514 werr
= ntstatus_to_werror(status
);
1518 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
1525 if (any_nt_status_not_ok(status
, result
, &status
)) {
1526 werr
= ntstatus_to_werror(status
);
1529 if (names
.count
!= rid_array
->count
) {
1530 werr
= WERR_BAD_NET_RESP
;
1533 if (member_types
.count
!= rid_array
->count
) {
1534 werr
= WERR_BAD_NET_RESP
;
1538 for (i
=0; i
< names
.count
; i
++) {
1540 if (member_types
.ids
[i
] != SID_NAME_USER
) {
1544 status
= add_GROUP_USERS_INFO_X_buffer(ctx
,
1546 names
.names
[i
].string
,
1550 if (!NT_STATUS_IS_OK(status
)) {
1551 werr
= ntstatus_to_werror(status
);
1556 *r
->out
.entries_read
= entries_read
;
1557 *r
->out
.total_entries
= entries_read
;
1562 if (is_valid_policy_hnd(&group_handle
)) {
1563 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
1566 if (ctx
->disable_policy_handle_cache
) {
1567 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1568 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1574 /****************************************************************
1575 ****************************************************************/
1577 WERROR
NetGroupGetUsers_l(struct libnetapi_ctx
*ctx
,
1578 struct NetGroupGetUsers
*r
)
1580 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupGetUsers
);
1583 /****************************************************************
1584 ****************************************************************/
1586 WERROR
NetGroupSetUsers_r(struct libnetapi_ctx
*ctx
,
1587 struct NetGroupSetUsers
*r
)
1589 struct rpc_pipe_client
*pipe_cli
= NULL
;
1590 struct policy_handle connect_handle
, domain_handle
, group_handle
;
1591 struct lsa_String lsa_account_name
;
1592 struct dom_sid2
*domain_sid
= NULL
;
1593 union samr_GroupInfo
*group_info
= NULL
;
1594 struct samr_Ids user_rids
, name_types
;
1595 struct samr_Ids group_rids
, group_types
;
1596 struct samr_RidAttrArray
*rid_array
= NULL
;
1597 struct lsa_String
*lsa_names
= NULL
;
1598 struct dcerpc_binding_handle
*b
= NULL
;
1600 uint32_t *add_rids
= NULL
;
1601 uint32_t *del_rids
= NULL
;
1602 size_t num_add_rids
= 0;
1603 size_t num_del_rids
= 0;
1605 uint32_t *member_rids
= NULL
;
1607 struct GROUP_USERS_INFO_0
*i0
= NULL
;
1608 struct GROUP_USERS_INFO_1
*i1
= NULL
;
1613 NTSTATUS result
= NT_STATUS_OK
;
1616 ZERO_STRUCT(connect_handle
);
1617 ZERO_STRUCT(domain_handle
);
1618 ZERO_STRUCT(group_handle
);
1620 if (!r
->in
.buffer
) {
1621 return WERR_INVALID_PARAMETER
;
1624 switch (r
->in
.level
) {
1629 return WERR_INVALID_LEVEL
;
1632 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1635 if (!W_ERROR_IS_OK(werr
)) {
1639 b
= pipe_cli
->binding_handle
;
1641 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1642 SAMR_ACCESS_ENUM_DOMAINS
|
1643 SAMR_ACCESS_LOOKUP_DOMAIN
,
1644 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1648 if (!W_ERROR_IS_OK(werr
)) {
1652 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
1654 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1661 if (any_nt_status_not_ok(status
, result
, &status
)) {
1662 werr
= ntstatus_to_werror(status
);
1665 if (group_rids
.count
!= 1) {
1666 werr
= WERR_BAD_NET_RESP
;
1669 if (group_types
.count
!= 1) {
1670 werr
= WERR_BAD_NET_RESP
;
1674 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
1676 SAMR_GROUP_ACCESS_GET_MEMBERS
|
1677 SAMR_GROUP_ACCESS_ADD_MEMBER
|
1678 SAMR_GROUP_ACCESS_REMOVE_MEMBER
|
1679 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
1683 if (any_nt_status_not_ok(status
, result
, &status
)) {
1684 werr
= ntstatus_to_werror(status
);
1688 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
1690 GROUPINFOATTRIBUTES
,
1693 if (any_nt_status_not_ok(status
, result
, &status
)) {
1694 werr
= ntstatus_to_werror(status
);
1698 switch (r
->in
.level
) {
1700 i0
= (struct GROUP_USERS_INFO_0
*)r
->in
.buffer
;
1703 i1
= (struct GROUP_USERS_INFO_1
*)r
->in
.buffer
;
1707 lsa_names
= talloc_array(ctx
, struct lsa_String
, r
->in
.num_entries
);
1709 werr
= WERR_NOT_ENOUGH_MEMORY
;
1713 for (i
=0; i
< r
->in
.num_entries
; i
++) {
1715 switch (r
->in
.level
) {
1717 init_lsa_String(&lsa_names
[i
], i0
->grui0_name
);
1721 init_lsa_String(&lsa_names
[i
], i1
->grui1_name
);
1727 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1734 if (any_nt_status_not_ok(status
, result
, &status
)) {
1735 werr
= ntstatus_to_werror(status
);
1739 if (r
->in
.num_entries
!= user_rids
.count
) {
1740 werr
= WERR_BAD_NET_RESP
;
1743 if (r
->in
.num_entries
!= name_types
.count
) {
1744 werr
= WERR_BAD_NET_RESP
;
1748 member_rids
= user_rids
.ids
;
1750 status
= dcerpc_samr_QueryGroupMember(b
, talloc_tos(),
1754 if (any_nt_status_not_ok(status
, result
, &status
)) {
1755 werr
= ntstatus_to_werror(status
);
1761 for (i
=0; i
< r
->in
.num_entries
; i
++) {
1762 bool already_member
= false;
1763 for (k
=0; k
< rid_array
->count
; k
++) {
1764 if (member_rids
[i
] == rid_array
->rids
[k
]) {
1765 already_member
= true;
1769 if (!already_member
) {
1770 if (!add_rid_to_array_unique(ctx
,
1772 &add_rids
, &num_add_rids
)) {
1773 werr
= WERR_GEN_FAILURE
;
1781 for (k
=0; k
< rid_array
->count
; k
++) {
1782 bool keep_member
= false;
1783 for (i
=0; i
< r
->in
.num_entries
; i
++) {
1784 if (member_rids
[i
] == rid_array
->rids
[k
]) {
1790 if (!add_rid_to_array_unique(ctx
,
1792 &del_rids
, &num_del_rids
)) {
1793 werr
= WERR_GEN_FAILURE
;
1801 for (i
=0; i
< num_add_rids
; i
++) {
1802 status
= dcerpc_samr_AddGroupMember(b
, talloc_tos(),
1807 if (any_nt_status_not_ok(status
, result
, &status
)) {
1808 werr
= ntstatus_to_werror(status
);
1815 for (i
=0; i
< num_del_rids
; i
++) {
1816 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
1820 if (any_nt_status_not_ok(status
, result
, &status
)) {
1821 werr
= ntstatus_to_werror(status
);
1829 if (is_valid_policy_hnd(&group_handle
)) {
1830 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
1833 if (ctx
->disable_policy_handle_cache
) {
1834 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1835 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1841 /****************************************************************
1842 ****************************************************************/
1844 WERROR
NetGroupSetUsers_l(struct libnetapi_ctx
*ctx
,
1845 struct NetGroupSetUsers
*r
)
1847 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupSetUsers
);