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
,
79 &ndr_table_samr
.syntax_id
,
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
,
275 &ndr_table_samr
.syntax_id
,
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 (types
.ids
[0] != SID_NAME_DOM_GRP
) {
313 werr
= WERR_INVALID_DATATYPE
;
317 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
320 SAMR_GROUP_ACCESS_GET_MEMBERS
|
321 SAMR_GROUP_ACCESS_REMOVE_MEMBER
|
322 SAMR_GROUP_ACCESS_ADD_MEMBER
|
323 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
327 if (!NT_STATUS_IS_OK(status
)) {
328 werr
= ntstatus_to_werror(status
);
331 if (!NT_STATUS_IS_OK(result
)) {
332 werr
= ntstatus_to_werror(result
);
336 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
341 if (!NT_STATUS_IS_OK(status
)) {
342 werr
= ntstatus_to_werror(status
);
345 if (!NT_STATUS_IS_OK(result
)) {
346 werr
= ntstatus_to_werror(result
);
351 /* breaks against NT4 */
352 if (!(info
->attributes
.attributes
& SE_GROUP_ENABLED
)) {
353 werr
= WERR_ACCESS_DENIED
;
357 status
= dcerpc_samr_QueryGroupMember(b
, talloc_tos(),
361 if (!NT_STATUS_IS_OK(status
)) {
362 werr
= ntstatus_to_werror(status
);
365 if (!NT_STATUS_IS_OK(result
)) {
366 werr
= ntstatus_to_werror(result
);
371 struct lsa_Strings names
;
372 struct samr_Ids member_types
;
374 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
381 if (!NT_STATUS_IS_OK(status
)) {
382 werr
= ntstatus_to_werror(status
);
385 if (!NT_STATUS_IS_OK(result
)) {
386 werr
= ntstatus_to_werror(result
);
391 for (i
=0; i
< rid_array
->count
; i
++) {
393 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
397 if (!NT_STATUS_IS_OK(status
)) {
398 werr
= ntstatus_to_werror(status
);
401 if (!NT_STATUS_IS_OK(result
)) {
402 werr
= ntstatus_to_werror(result
);
407 status
= dcerpc_samr_DeleteDomainGroup(b
, talloc_tos(),
410 if (!NT_STATUS_IS_OK(status
)) {
411 werr
= ntstatus_to_werror(status
);
414 if (!NT_STATUS_IS_OK(result
)) {
415 werr
= ntstatus_to_werror(result
);
419 ZERO_STRUCT(group_handle
);
424 if (is_valid_policy_hnd(&group_handle
)) {
425 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
428 if (ctx
->disable_policy_handle_cache
) {
429 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
430 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
436 /****************************************************************
437 ****************************************************************/
439 WERROR
NetGroupDel_l(struct libnetapi_ctx
*ctx
,
440 struct NetGroupDel
*r
)
442 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupDel
);
445 /****************************************************************
446 ****************************************************************/
448 WERROR
NetGroupSetInfo_r(struct libnetapi_ctx
*ctx
,
449 struct NetGroupSetInfo
*r
)
451 struct rpc_pipe_client
*pipe_cli
= NULL
;
452 NTSTATUS status
, result
;
454 struct policy_handle connect_handle
, domain_handle
, group_handle
;
455 struct lsa_String lsa_group_name
;
456 struct dom_sid2
*domain_sid
= NULL
;
457 struct dcerpc_binding_handle
*b
= NULL
;
459 struct samr_Ids rids
;
460 struct samr_Ids types
;
461 union samr_GroupInfo info
;
462 struct GROUP_INFO_0
*g0
;
463 struct GROUP_INFO_1
*g1
;
464 struct GROUP_INFO_2
*g2
;
465 struct GROUP_INFO_3
*g3
;
466 struct GROUP_INFO_1002
*g1002
;
467 struct GROUP_INFO_1005
*g1005
;
469 ZERO_STRUCT(connect_handle
);
470 ZERO_STRUCT(domain_handle
);
471 ZERO_STRUCT(group_handle
);
473 if (!r
->in
.group_name
) {
474 return WERR_INVALID_PARAM
;
477 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
478 &ndr_table_samr
.syntax_id
,
480 if (!W_ERROR_IS_OK(werr
)) {
484 b
= pipe_cli
->binding_handle
;
486 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
487 SAMR_ACCESS_ENUM_DOMAINS
|
488 SAMR_ACCESS_LOOKUP_DOMAIN
,
489 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
493 if (!W_ERROR_IS_OK(werr
)) {
497 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
499 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
506 if (!NT_STATUS_IS_OK(status
)) {
507 werr
= ntstatus_to_werror(status
);
510 if (!NT_STATUS_IS_OK(result
)) {
511 werr
= ntstatus_to_werror(result
);
515 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
516 werr
= WERR_INVALID_DATATYPE
;
520 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
522 SAMR_GROUP_ACCESS_SET_INFO
|
523 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
527 if (!NT_STATUS_IS_OK(status
)) {
528 werr
= ntstatus_to_werror(status
);
531 if (!NT_STATUS_IS_OK(result
)) {
532 werr
= ntstatus_to_werror(result
);
536 switch (r
->in
.level
) {
538 g0
= (struct GROUP_INFO_0
*)r
->in
.buffer
;
539 init_lsa_String(&info
.name
, g0
->grpi0_name
);
540 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
547 g1
= (struct GROUP_INFO_1
*)r
->in
.buffer
;
548 init_lsa_String(&info
.description
, g1
->grpi1_comment
);
549 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
551 GROUPINFODESCRIPTION
,
556 g2
= (struct GROUP_INFO_2
*)r
->in
.buffer
;
557 init_lsa_String(&info
.description
, g2
->grpi2_comment
);
558 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
560 GROUPINFODESCRIPTION
,
563 if (!NT_STATUS_IS_OK(status
)) {
564 werr
= ntstatus_to_werror(status
);
567 if (!NT_STATUS_IS_OK(result
)) {
568 werr
= ntstatus_to_werror(result
);
572 info
.attributes
.attributes
= g2
->grpi2_attributes
;
573 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
580 g3
= (struct GROUP_INFO_3
*)r
->in
.buffer
;
581 init_lsa_String(&info
.description
, g3
->grpi3_comment
);
582 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
584 GROUPINFODESCRIPTION
,
587 if (!NT_STATUS_IS_OK(status
)) {
588 werr
= ntstatus_to_werror(status
);
591 if (!NT_STATUS_IS_OK(result
)) {
592 werr
= ntstatus_to_werror(result
);
596 info
.attributes
.attributes
= g3
->grpi3_attributes
;
597 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
604 g1002
= (struct GROUP_INFO_1002
*)r
->in
.buffer
;
605 init_lsa_String(&info
.description
, g1002
->grpi1002_comment
);
606 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
608 GROUPINFODESCRIPTION
,
613 g1005
= (struct GROUP_INFO_1005
*)r
->in
.buffer
;
614 info
.attributes
.attributes
= g1005
->grpi1005_attributes
;
615 status
= dcerpc_samr_SetGroupInfo(b
, talloc_tos(),
622 status
= NT_STATUS_INVALID_LEVEL
;
626 if (!NT_STATUS_IS_OK(status
)) {
627 werr
= ntstatus_to_werror(status
);
630 if (!NT_STATUS_IS_OK(result
)) {
631 werr
= ntstatus_to_werror(result
);
638 if (is_valid_policy_hnd(&group_handle
)) {
639 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
642 if (ctx
->disable_policy_handle_cache
) {
643 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
644 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
650 /****************************************************************
651 ****************************************************************/
653 WERROR
NetGroupSetInfo_l(struct libnetapi_ctx
*ctx
,
654 struct NetGroupSetInfo
*r
)
656 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupSetInfo
);
659 /****************************************************************
660 ****************************************************************/
662 static WERROR
map_group_info_to_buffer(TALLOC_CTX
*mem_ctx
,
664 struct samr_GroupInfoAll
*info
,
665 struct dom_sid2
*domain_sid
,
669 struct GROUP_INFO_0 info0
;
670 struct GROUP_INFO_1 info1
;
671 struct GROUP_INFO_2 info2
;
672 struct GROUP_INFO_3 info3
;
677 info0
.grpi0_name
= info
->name
.string
;
679 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info0
, sizeof(info0
));
683 info1
.grpi1_name
= info
->name
.string
;
684 info1
.grpi1_comment
= info
->description
.string
;
686 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info1
, sizeof(info1
));
690 info2
.grpi2_name
= info
->name
.string
;
691 info2
.grpi2_comment
= info
->description
.string
;
692 info2
.grpi2_group_id
= rid
;
693 info2
.grpi2_attributes
= info
->attributes
;
695 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info2
, sizeof(info2
));
699 if (!sid_compose(&sid
, domain_sid
, rid
)) {
703 info3
.grpi3_name
= info
->name
.string
;
704 info3
.grpi3_comment
= info
->description
.string
;
705 info3
.grpi3_attributes
= info
->attributes
;
706 info3
.grpi3_group_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
708 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info3
, sizeof(info3
));
712 return WERR_UNKNOWN_LEVEL
;
715 W_ERROR_HAVE_NO_MEMORY(*buffer
);
720 /****************************************************************
721 ****************************************************************/
723 WERROR
NetGroupGetInfo_r(struct libnetapi_ctx
*ctx
,
724 struct NetGroupGetInfo
*r
)
726 struct rpc_pipe_client
*pipe_cli
= NULL
;
727 NTSTATUS status
, result
;
729 struct policy_handle connect_handle
, domain_handle
, group_handle
;
730 struct lsa_String lsa_group_name
;
731 struct dom_sid2
*domain_sid
= NULL
;
732 struct dcerpc_binding_handle
*b
= NULL
;
734 struct samr_Ids rids
;
735 struct samr_Ids types
;
736 union samr_GroupInfo
*info
= NULL
;
737 bool group_info_all
= false;
739 ZERO_STRUCT(connect_handle
);
740 ZERO_STRUCT(domain_handle
);
741 ZERO_STRUCT(group_handle
);
743 if (!r
->in
.group_name
) {
744 return WERR_INVALID_PARAM
;
747 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
748 &ndr_table_samr
.syntax_id
,
750 if (!W_ERROR_IS_OK(werr
)) {
754 b
= pipe_cli
->binding_handle
;
756 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
757 SAMR_ACCESS_ENUM_DOMAINS
|
758 SAMR_ACCESS_LOOKUP_DOMAIN
,
759 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
763 if (!W_ERROR_IS_OK(werr
)) {
767 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
769 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
776 if (!NT_STATUS_IS_OK(status
)) {
777 werr
= ntstatus_to_werror(status
);
780 if (!NT_STATUS_IS_OK(result
)) {
781 werr
= ntstatus_to_werror(result
);
785 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
786 werr
= WERR_INVALID_DATATYPE
;
790 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
792 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
796 if (!NT_STATUS_IS_OK(status
)) {
797 werr
= ntstatus_to_werror(status
);
800 if (!NT_STATUS_IS_OK(result
)) {
801 werr
= ntstatus_to_werror(result
);
805 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
810 if (!NT_STATUS_IS_OK(status
)) {
811 werr
= ntstatus_to_werror(status
);
815 if (NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_INFO_CLASS
)) {
816 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
821 group_info_all
= true;
822 if (!NT_STATUS_IS_OK(status
)) {
823 werr
= ntstatus_to_werror(status
);
828 if (!NT_STATUS_IS_OK(result
)) {
829 werr
= ntstatus_to_werror(result
);
833 werr
= map_group_info_to_buffer(ctx
, r
->in
.level
,
834 group_info_all
? &info
->all
: &info
->all2
,
835 domain_sid
, rids
.ids
[0],
837 if (!W_ERROR_IS_OK(werr
)) {
841 if (is_valid_policy_hnd(&group_handle
)) {
842 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
845 if (ctx
->disable_policy_handle_cache
) {
846 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
847 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
853 /****************************************************************
854 ****************************************************************/
856 WERROR
NetGroupGetInfo_l(struct libnetapi_ctx
*ctx
,
857 struct NetGroupGetInfo
*r
)
859 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupGetInfo
);
862 /****************************************************************
863 ****************************************************************/
865 WERROR
NetGroupAddUser_r(struct libnetapi_ctx
*ctx
,
866 struct NetGroupAddUser
*r
)
868 struct rpc_pipe_client
*pipe_cli
= NULL
;
869 NTSTATUS status
, result
;
871 struct policy_handle connect_handle
, domain_handle
, group_handle
;
872 struct lsa_String lsa_group_name
, lsa_user_name
;
873 struct dom_sid2
*domain_sid
= NULL
;
874 struct dcerpc_binding_handle
*b
= NULL
;
876 struct samr_Ids rids
;
877 struct samr_Ids types
;
879 ZERO_STRUCT(connect_handle
);
880 ZERO_STRUCT(domain_handle
);
881 ZERO_STRUCT(group_handle
);
883 if (!r
->in
.group_name
) {
884 return WERR_INVALID_PARAM
;
887 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
888 &ndr_table_samr
.syntax_id
,
890 if (!W_ERROR_IS_OK(werr
)) {
894 b
= pipe_cli
->binding_handle
;
896 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
897 SAMR_ACCESS_ENUM_DOMAINS
|
898 SAMR_ACCESS_LOOKUP_DOMAIN
,
899 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
903 if (!W_ERROR_IS_OK(werr
)) {
907 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
909 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
916 if (!NT_STATUS_IS_OK(status
)) {
917 werr
= ntstatus_to_werror(status
);
920 if (!NT_STATUS_IS_OK(result
)) {
921 werr
= WERR_GROUPNOTFOUND
;
925 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
926 werr
= WERR_GROUPNOTFOUND
;
930 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
932 SAMR_GROUP_ACCESS_ADD_MEMBER
,
936 if (!NT_STATUS_IS_OK(status
)) {
937 werr
= ntstatus_to_werror(status
);
940 if (!NT_STATUS_IS_OK(result
)) {
941 werr
= ntstatus_to_werror(result
);
945 init_lsa_String(&lsa_user_name
, r
->in
.user_name
);
947 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
954 if (!NT_STATUS_IS_OK(status
)) {
955 werr
= ntstatus_to_werror(status
);
958 if (!NT_STATUS_IS_OK(result
)) {
959 werr
= WERR_USER_NOT_FOUND
;
963 if (types
.ids
[0] != SID_NAME_USER
) {
964 werr
= WERR_USER_NOT_FOUND
;
968 status
= dcerpc_samr_AddGroupMember(b
, talloc_tos(),
973 if (!NT_STATUS_IS_OK(status
)) {
974 werr
= ntstatus_to_werror(status
);
977 if (!NT_STATUS_IS_OK(result
)) {
978 werr
= ntstatus_to_werror(result
);
985 if (is_valid_policy_hnd(&group_handle
)) {
986 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
989 if (ctx
->disable_policy_handle_cache
) {
990 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
991 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
997 /****************************************************************
998 ****************************************************************/
1000 WERROR
NetGroupAddUser_l(struct libnetapi_ctx
*ctx
,
1001 struct NetGroupAddUser
*r
)
1003 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupAddUser
);
1006 /****************************************************************
1007 ****************************************************************/
1009 WERROR
NetGroupDelUser_r(struct libnetapi_ctx
*ctx
,
1010 struct NetGroupDelUser
*r
)
1012 struct rpc_pipe_client
*pipe_cli
= NULL
;
1013 NTSTATUS status
, result
;
1015 struct policy_handle connect_handle
, domain_handle
, group_handle
;
1016 struct lsa_String lsa_group_name
, lsa_user_name
;
1017 struct dom_sid2
*domain_sid
= NULL
;
1018 struct dcerpc_binding_handle
*b
= NULL
;
1020 struct samr_Ids rids
;
1021 struct samr_Ids types
;
1023 ZERO_STRUCT(connect_handle
);
1024 ZERO_STRUCT(domain_handle
);
1025 ZERO_STRUCT(group_handle
);
1027 if (!r
->in
.group_name
) {
1028 return WERR_INVALID_PARAM
;
1031 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1032 &ndr_table_samr
.syntax_id
,
1034 if (!W_ERROR_IS_OK(werr
)) {
1038 b
= pipe_cli
->binding_handle
;
1040 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1041 SAMR_ACCESS_ENUM_DOMAINS
|
1042 SAMR_ACCESS_LOOKUP_DOMAIN
,
1043 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1047 if (!W_ERROR_IS_OK(werr
)) {
1051 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
1053 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1060 if (!NT_STATUS_IS_OK(status
)) {
1061 werr
= ntstatus_to_werror(status
);
1064 if (!NT_STATUS_IS_OK(result
)) {
1065 werr
= WERR_GROUPNOTFOUND
;
1069 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
1070 werr
= WERR_GROUPNOTFOUND
;
1074 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
1076 SAMR_GROUP_ACCESS_REMOVE_MEMBER
,
1080 if (!NT_STATUS_IS_OK(status
)) {
1081 werr
= ntstatus_to_werror(status
);
1084 if (!NT_STATUS_IS_OK(result
)) {
1085 werr
= ntstatus_to_werror(result
);
1089 init_lsa_String(&lsa_user_name
, r
->in
.user_name
);
1091 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1098 if (!NT_STATUS_IS_OK(status
)) {
1099 werr
= ntstatus_to_werror(status
);
1103 if (!NT_STATUS_IS_OK(result
)) {
1104 werr
= WERR_USER_NOT_FOUND
;
1108 if (types
.ids
[0] != SID_NAME_USER
) {
1109 werr
= WERR_USER_NOT_FOUND
;
1113 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
1117 if (!NT_STATUS_IS_OK(status
)) {
1118 werr
= ntstatus_to_werror(status
);
1121 if (!NT_STATUS_IS_OK(result
)) {
1122 werr
= ntstatus_to_werror(result
);
1129 if (is_valid_policy_hnd(&group_handle
)) {
1130 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
1133 if (ctx
->disable_policy_handle_cache
) {
1134 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1135 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1141 /****************************************************************
1142 ****************************************************************/
1144 WERROR
NetGroupDelUser_l(struct libnetapi_ctx
*ctx
,
1145 struct NetGroupDelUser
*r
)
1147 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupDelUser
);
1150 /****************************************************************
1151 ****************************************************************/
1153 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_0_buffer(TALLOC_CTX
*mem_ctx
,
1154 struct samr_DispInfoFullGroups
*groups
,
1157 struct GROUP_INFO_0
*g0
;
1160 g0
= TALLOC_ZERO_ARRAY(mem_ctx
, struct GROUP_INFO_0
, groups
->count
);
1161 W_ERROR_HAVE_NO_MEMORY(g0
);
1163 for (i
=0; i
<groups
->count
; i
++) {
1164 g0
[i
].grpi0_name
= talloc_strdup(mem_ctx
,
1165 groups
->entries
[i
].account_name
.string
);
1166 W_ERROR_HAVE_NO_MEMORY(g0
[i
].grpi0_name
);
1169 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g0
,
1170 sizeof(struct GROUP_INFO_0
) * groups
->count
);
1171 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1176 /****************************************************************
1177 ****************************************************************/
1179 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_1_buffer(TALLOC_CTX
*mem_ctx
,
1180 struct samr_DispInfoFullGroups
*groups
,
1183 struct GROUP_INFO_1
*g1
;
1186 g1
= TALLOC_ZERO_ARRAY(mem_ctx
, struct GROUP_INFO_1
, groups
->count
);
1187 W_ERROR_HAVE_NO_MEMORY(g1
);
1189 for (i
=0; i
<groups
->count
; i
++) {
1190 g1
[i
].grpi1_name
= talloc_strdup(mem_ctx
,
1191 groups
->entries
[i
].account_name
.string
);
1192 g1
[i
].grpi1_comment
= talloc_strdup(mem_ctx
,
1193 groups
->entries
[i
].description
.string
);
1194 W_ERROR_HAVE_NO_MEMORY(g1
[i
].grpi1_name
);
1197 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g1
,
1198 sizeof(struct GROUP_INFO_1
) * groups
->count
);
1199 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1204 /****************************************************************
1205 ****************************************************************/
1207 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_2_buffer(TALLOC_CTX
*mem_ctx
,
1208 struct samr_DispInfoFullGroups
*groups
,
1211 struct GROUP_INFO_2
*g2
;
1214 g2
= TALLOC_ZERO_ARRAY(mem_ctx
, struct GROUP_INFO_2
, groups
->count
);
1215 W_ERROR_HAVE_NO_MEMORY(g2
);
1217 for (i
=0; i
<groups
->count
; i
++) {
1218 g2
[i
].grpi2_name
= talloc_strdup(mem_ctx
,
1219 groups
->entries
[i
].account_name
.string
);
1220 g2
[i
].grpi2_comment
= talloc_strdup(mem_ctx
,
1221 groups
->entries
[i
].description
.string
);
1222 g2
[i
].grpi2_group_id
= groups
->entries
[i
].rid
;
1223 g2
[i
].grpi2_attributes
= groups
->entries
[i
].acct_flags
;
1224 W_ERROR_HAVE_NO_MEMORY(g2
[i
].grpi2_name
);
1227 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g2
,
1228 sizeof(struct GROUP_INFO_2
) * groups
->count
);
1229 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1234 /****************************************************************
1235 ****************************************************************/
1237 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_3_buffer(TALLOC_CTX
*mem_ctx
,
1238 struct samr_DispInfoFullGroups
*groups
,
1239 const struct dom_sid
*domain_sid
,
1242 struct GROUP_INFO_3
*g3
;
1245 g3
= TALLOC_ZERO_ARRAY(mem_ctx
, struct GROUP_INFO_3
, groups
->count
);
1246 W_ERROR_HAVE_NO_MEMORY(g3
);
1248 for (i
=0; i
<groups
->count
; i
++) {
1252 if (!sid_compose(&sid
, domain_sid
, groups
->entries
[i
].rid
)) {
1256 g3
[i
].grpi3_name
= talloc_strdup(mem_ctx
,
1257 groups
->entries
[i
].account_name
.string
);
1258 g3
[i
].grpi3_comment
= talloc_strdup(mem_ctx
,
1259 groups
->entries
[i
].description
.string
);
1260 g3
[i
].grpi3_group_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
1261 g3
[i
].grpi3_attributes
= groups
->entries
[i
].acct_flags
;
1262 W_ERROR_HAVE_NO_MEMORY(g3
[i
].grpi3_name
);
1265 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g3
,
1266 sizeof(struct GROUP_INFO_3
) * groups
->count
);
1267 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1272 /****************************************************************
1273 ****************************************************************/
1275 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_buffer(TALLOC_CTX
*mem_ctx
,
1277 struct samr_DispInfoFullGroups
*groups
,
1278 const struct dom_sid
*domain_sid
,
1279 uint32_t *entries_read
,
1283 *entries_read
= groups
->count
;
1288 return convert_samr_disp_groups_to_GROUP_INFO_0_buffer(mem_ctx
, groups
, buffer
);
1290 return convert_samr_disp_groups_to_GROUP_INFO_1_buffer(mem_ctx
, groups
, buffer
);
1292 return convert_samr_disp_groups_to_GROUP_INFO_2_buffer(mem_ctx
, groups
, buffer
);
1294 return convert_samr_disp_groups_to_GROUP_INFO_3_buffer(mem_ctx
, groups
, domain_sid
, buffer
);
1296 return WERR_UNKNOWN_LEVEL
;
1300 /****************************************************************
1301 ****************************************************************/
1303 WERROR
NetGroupEnum_r(struct libnetapi_ctx
*ctx
,
1304 struct NetGroupEnum
*r
)
1306 struct rpc_pipe_client
*pipe_cli
= NULL
;
1307 struct policy_handle connect_handle
;
1308 struct dom_sid2
*domain_sid
= NULL
;
1309 struct policy_handle domain_handle
;
1310 union samr_DispInfo info
;
1311 union samr_DomainInfo
*domain_info
= NULL
;
1312 struct dcerpc_binding_handle
*b
= NULL
;
1314 uint32_t total_size
= 0;
1315 uint32_t returned_size
= 0;
1317 NTSTATUS result
= NT_STATUS_OK
;
1318 NTSTATUS status
= NT_STATUS_OK
;
1319 WERROR werr
, tmp_werr
;
1321 ZERO_STRUCT(connect_handle
);
1322 ZERO_STRUCT(domain_handle
);
1324 switch (r
->in
.level
) {
1331 return WERR_UNKNOWN_LEVEL
;
1334 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1335 &ndr_table_samr
.syntax_id
,
1337 if (!W_ERROR_IS_OK(werr
)) {
1341 b
= pipe_cli
->binding_handle
;
1343 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1344 SAMR_ACCESS_ENUM_DOMAINS
|
1345 SAMR_ACCESS_LOOKUP_DOMAIN
,
1346 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1347 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1348 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1352 if (!W_ERROR_IS_OK(werr
)) {
1356 status
= dcerpc_samr_QueryDomainInfo(b
, talloc_tos(),
1361 if (!NT_STATUS_IS_OK(status
)) {
1362 werr
= ntstatus_to_werror(status
);
1365 if (!NT_STATUS_IS_OK(result
)) {
1366 werr
= ntstatus_to_werror(result
);
1370 if (r
->out
.total_entries
) {
1371 *r
->out
.total_entries
= domain_info
->general
.num_groups
;
1374 status
= dcerpc_samr_QueryDisplayInfo2(b
,
1378 r
->in
.resume_handle
?
1379 *r
->in
.resume_handle
: 0,
1386 if (!NT_STATUS_IS_OK(status
)) {
1387 werr
= ntstatus_to_werror(status
);
1391 werr
= ntstatus_to_werror(result
);
1392 if (NT_STATUS_IS_ERR(result
)) {
1396 if (r
->out
.resume_handle
&& info
.info3
.count
> 0) {
1397 *r
->out
.resume_handle
=
1398 info
.info3
.entries
[info
.info3
.count
-1].idx
;
1401 tmp_werr
= convert_samr_disp_groups_to_GROUP_INFO_buffer(ctx
,
1405 r
->out
.entries_read
,
1407 if (!W_ERROR_IS_OK(tmp_werr
)) {
1414 if (NT_STATUS_IS_OK(result
) ||
1415 NT_STATUS_IS_ERR(result
)) {
1417 if (ctx
->disable_policy_handle_cache
) {
1418 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1419 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1426 /****************************************************************
1427 ****************************************************************/
1429 WERROR
NetGroupEnum_l(struct libnetapi_ctx
*ctx
,
1430 struct NetGroupEnum
*r
)
1432 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupEnum
);
1435 /****************************************************************
1436 ****************************************************************/
1438 WERROR
NetGroupGetUsers_r(struct libnetapi_ctx
*ctx
,
1439 struct NetGroupGetUsers
*r
)
1441 /* FIXME: this call needs to cope with large replies */
1443 struct rpc_pipe_client
*pipe_cli
= NULL
;
1444 struct policy_handle connect_handle
, domain_handle
, group_handle
;
1445 struct lsa_String lsa_account_name
;
1446 struct dom_sid2
*domain_sid
= NULL
;
1447 struct samr_Ids group_rids
, name_types
;
1448 struct samr_RidAttrArray
*rid_array
= NULL
;
1449 struct lsa_Strings names
;
1450 struct samr_Ids member_types
;
1451 struct dcerpc_binding_handle
*b
= NULL
;
1454 uint32_t entries_read
= 0;
1456 NTSTATUS status
= NT_STATUS_OK
;
1457 NTSTATUS result
= NT_STATUS_OK
;
1460 ZERO_STRUCT(connect_handle
);
1461 ZERO_STRUCT(domain_handle
);
1463 if (!r
->out
.buffer
) {
1464 return WERR_INVALID_PARAM
;
1467 *r
->out
.buffer
= NULL
;
1468 *r
->out
.entries_read
= 0;
1469 *r
->out
.total_entries
= 0;
1471 switch (r
->in
.level
) {
1476 return WERR_UNKNOWN_LEVEL
;
1480 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1481 &ndr_table_samr
.syntax_id
,
1483 if (!W_ERROR_IS_OK(werr
)) {
1487 b
= pipe_cli
->binding_handle
;
1489 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1490 SAMR_ACCESS_ENUM_DOMAINS
|
1491 SAMR_ACCESS_LOOKUP_DOMAIN
,
1492 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1496 if (!W_ERROR_IS_OK(werr
)) {
1500 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
1502 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1509 if (!NT_STATUS_IS_OK(status
)) {
1510 werr
= ntstatus_to_werror(status
);
1513 if (!NT_STATUS_IS_OK(result
)) {
1514 werr
= ntstatus_to_werror(result
);
1518 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
1520 SAMR_GROUP_ACCESS_GET_MEMBERS
,
1524 if (!NT_STATUS_IS_OK(status
)) {
1525 werr
= ntstatus_to_werror(status
);
1528 if (!NT_STATUS_IS_OK(result
)) {
1529 werr
= ntstatus_to_werror(result
);
1533 status
= dcerpc_samr_QueryGroupMember(b
, talloc_tos(),
1537 if (!NT_STATUS_IS_OK(status
)) {
1538 werr
= ntstatus_to_werror(status
);
1541 if (!NT_STATUS_IS_OK(result
)) {
1542 werr
= ntstatus_to_werror(result
);
1546 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
1553 if (!NT_STATUS_IS_OK(status
)) {
1554 werr
= ntstatus_to_werror(status
);
1557 if (!NT_STATUS_IS_OK(result
)) {
1558 werr
= ntstatus_to_werror(result
);
1562 for (i
=0; i
< names
.count
; i
++) {
1564 if (member_types
.ids
[i
] != SID_NAME_USER
) {
1568 status
= add_GROUP_USERS_INFO_X_buffer(ctx
,
1570 names
.names
[i
].string
,
1574 if (!NT_STATUS_IS_OK(status
)) {
1575 werr
= ntstatus_to_werror(status
);
1580 *r
->out
.entries_read
= entries_read
;
1581 *r
->out
.total_entries
= entries_read
;
1586 if (is_valid_policy_hnd(&group_handle
)) {
1587 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
1590 if (ctx
->disable_policy_handle_cache
) {
1591 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1592 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1598 /****************************************************************
1599 ****************************************************************/
1601 WERROR
NetGroupGetUsers_l(struct libnetapi_ctx
*ctx
,
1602 struct NetGroupGetUsers
*r
)
1604 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupGetUsers
);
1607 /****************************************************************
1608 ****************************************************************/
1610 WERROR
NetGroupSetUsers_r(struct libnetapi_ctx
*ctx
,
1611 struct NetGroupSetUsers
*r
)
1613 struct rpc_pipe_client
*pipe_cli
= NULL
;
1614 struct policy_handle connect_handle
, domain_handle
, group_handle
;
1615 struct lsa_String lsa_account_name
;
1616 struct dom_sid2
*domain_sid
= NULL
;
1617 union samr_GroupInfo
*group_info
= NULL
;
1618 struct samr_Ids user_rids
, name_types
;
1619 struct samr_Ids group_rids
, group_types
;
1620 struct samr_RidAttrArray
*rid_array
= NULL
;
1621 struct lsa_String
*lsa_names
= NULL
;
1622 struct dcerpc_binding_handle
*b
= NULL
;
1624 uint32_t *add_rids
= NULL
;
1625 uint32_t *del_rids
= NULL
;
1626 size_t num_add_rids
= 0;
1627 size_t num_del_rids
= 0;
1629 uint32_t *member_rids
= NULL
;
1631 struct GROUP_USERS_INFO_0
*i0
= NULL
;
1632 struct GROUP_USERS_INFO_1
*i1
= NULL
;
1636 NTSTATUS status
= NT_STATUS_OK
;
1637 NTSTATUS result
= NT_STATUS_OK
;
1640 ZERO_STRUCT(connect_handle
);
1641 ZERO_STRUCT(domain_handle
);
1643 if (!r
->in
.buffer
) {
1644 return WERR_INVALID_PARAM
;
1647 switch (r
->in
.level
) {
1652 return WERR_UNKNOWN_LEVEL
;
1655 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1656 &ndr_table_samr
.syntax_id
,
1658 if (!W_ERROR_IS_OK(werr
)) {
1662 b
= pipe_cli
->binding_handle
;
1664 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1665 SAMR_ACCESS_ENUM_DOMAINS
|
1666 SAMR_ACCESS_LOOKUP_DOMAIN
,
1667 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1671 if (!W_ERROR_IS_OK(werr
)) {
1675 init_lsa_String(&lsa_account_name
, r
->in
.group_name
);
1677 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1684 if (!NT_STATUS_IS_OK(status
)) {
1685 werr
= ntstatus_to_werror(status
);
1688 if (!NT_STATUS_IS_OK(result
)) {
1689 werr
= ntstatus_to_werror(result
);
1693 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
1695 SAMR_GROUP_ACCESS_GET_MEMBERS
|
1696 SAMR_GROUP_ACCESS_ADD_MEMBER
|
1697 SAMR_GROUP_ACCESS_REMOVE_MEMBER
|
1698 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
1702 if (!NT_STATUS_IS_OK(status
)) {
1703 werr
= ntstatus_to_werror(status
);
1706 if (!NT_STATUS_IS_OK(result
)) {
1707 werr
= ntstatus_to_werror(result
);
1711 status
= dcerpc_samr_QueryGroupInfo(b
, talloc_tos(),
1713 GROUPINFOATTRIBUTES
,
1716 if (!NT_STATUS_IS_OK(status
)) {
1717 werr
= ntstatus_to_werror(status
);
1720 if (!NT_STATUS_IS_OK(result
)) {
1721 werr
= ntstatus_to_werror(result
);
1725 switch (r
->in
.level
) {
1727 i0
= (struct GROUP_USERS_INFO_0
*)r
->in
.buffer
;
1730 i1
= (struct GROUP_USERS_INFO_1
*)r
->in
.buffer
;
1734 lsa_names
= talloc_array(ctx
, struct lsa_String
, r
->in
.num_entries
);
1740 for (i
=0; i
< r
->in
.num_entries
; i
++) {
1742 switch (r
->in
.level
) {
1744 init_lsa_String(&lsa_names
[i
], i0
->grui0_name
);
1748 init_lsa_String(&lsa_names
[i
], i1
->grui1_name
);
1754 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1761 if (!NT_STATUS_IS_OK(status
)) {
1762 werr
= ntstatus_to_werror(status
);
1765 if (!NT_STATUS_IS_OK(result
)) {
1766 werr
= ntstatus_to_werror(result
);
1770 member_rids
= user_rids
.ids
;
1772 status
= dcerpc_samr_QueryGroupMember(b
, talloc_tos(),
1776 if (!NT_STATUS_IS_OK(status
)) {
1777 werr
= ntstatus_to_werror(status
);
1780 if (!NT_STATUS_IS_OK(result
)) {
1781 werr
= ntstatus_to_werror(result
);
1787 for (i
=0; i
< r
->in
.num_entries
; i
++) {
1788 bool already_member
= false;
1789 for (k
=0; k
< rid_array
->count
; k
++) {
1790 if (member_rids
[i
] == rid_array
->rids
[k
]) {
1791 already_member
= true;
1795 if (!already_member
) {
1796 if (!add_rid_to_array_unique(ctx
,
1798 &add_rids
, &num_add_rids
)) {
1799 werr
= WERR_GENERAL_FAILURE
;
1807 for (k
=0; k
< rid_array
->count
; k
++) {
1808 bool keep_member
= false;
1809 for (i
=0; i
< r
->in
.num_entries
; i
++) {
1810 if (member_rids
[i
] == rid_array
->rids
[k
]) {
1816 if (!add_rid_to_array_unique(ctx
,
1818 &del_rids
, &num_del_rids
)) {
1819 werr
= WERR_GENERAL_FAILURE
;
1827 for (i
=0; i
< num_add_rids
; i
++) {
1828 status
= dcerpc_samr_AddGroupMember(b
, talloc_tos(),
1833 if (!NT_STATUS_IS_OK(status
)) {
1834 werr
= ntstatus_to_werror(status
);
1837 if (!NT_STATUS_IS_OK(result
)) {
1838 werr
= ntstatus_to_werror(result
);
1845 for (i
=0; i
< num_del_rids
; i
++) {
1846 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
1850 if (!NT_STATUS_IS_OK(status
)) {
1851 werr
= ntstatus_to_werror(status
);
1854 if (!NT_STATUS_IS_OK(result
)) {
1855 werr
= ntstatus_to_werror(result
);
1863 if (is_valid_policy_hnd(&group_handle
)) {
1864 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
1867 if (ctx
->disable_policy_handle_cache
) {
1868 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1869 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1875 /****************************************************************
1876 ****************************************************************/
1878 WERROR
NetGroupSetUsers_l(struct libnetapi_ctx
*ctx
,
1879 struct NetGroupSetUsers
*r
)
1881 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetGroupSetUsers
);