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"
27 /****************************************************************
28 ****************************************************************/
30 WERROR
NetGroupAdd_r(struct libnetapi_ctx
*ctx
,
31 struct NetGroupAdd
*r
)
33 struct cli_state
*cli
= NULL
;
34 struct rpc_pipe_client
*pipe_cli
= NULL
;
37 POLICY_HND connect_handle
, domain_handle
, group_handle
;
38 struct lsa_String lsa_group_name
;
39 struct dom_sid2
*domain_sid
= NULL
;
42 struct GROUP_INFO_0
*info0
= NULL
;
43 struct GROUP_INFO_1
*info1
= NULL
;
44 struct GROUP_INFO_2
*info2
= NULL
;
45 struct GROUP_INFO_3
*info3
= NULL
;
46 union samr_GroupInfo info
;
48 ZERO_STRUCT(connect_handle
);
49 ZERO_STRUCT(domain_handle
);
50 ZERO_STRUCT(group_handle
);
53 return WERR_INVALID_PARAM
;
56 switch (r
->in
.level
) {
58 info0
= (struct GROUP_INFO_0
*)r
->in
.buf
;
61 info1
= (struct GROUP_INFO_1
*)r
->in
.buf
;
64 info2
= (struct GROUP_INFO_2
*)r
->in
.buf
;
67 info3
= (struct GROUP_INFO_3
*)r
->in
.buf
;
70 werr
= WERR_UNKNOWN_LEVEL
;
74 werr
= libnetapi_open_ipc_connection(ctx
, r
->in
.server_name
, &cli
);
75 if (!W_ERROR_IS_OK(werr
)) {
79 werr
= libnetapi_open_pipe(ctx
, cli
, &ndr_table_samr
.syntax_id
,
81 if (!W_ERROR_IS_OK(werr
)) {
85 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
86 SAMR_ACCESS_ENUM_DOMAINS
|
87 SAMR_ACCESS_OPEN_DOMAIN
,
88 SAMR_DOMAIN_ACCESS_CREATE_GROUP
|
89 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
93 if (!W_ERROR_IS_OK(werr
)) {
97 switch (r
->in
.level
) {
99 init_lsa_String(&lsa_group_name
, info0
->grpi0_name
);
102 init_lsa_String(&lsa_group_name
, info1
->grpi1_name
);
105 init_lsa_String(&lsa_group_name
, info2
->grpi2_name
);
108 init_lsa_String(&lsa_group_name
, info3
->grpi3_name
);
112 status
= rpccli_samr_CreateDomainGroup(pipe_cli
, ctx
,
116 SAMR_GROUP_ACCESS_SET_INFO
,
120 if (!NT_STATUS_IS_OK(status
)) {
121 werr
= ntstatus_to_werror(status
);
125 switch (r
->in
.level
) {
127 if (info1
->grpi1_comment
) {
128 init_lsa_String(&info
.description
,
129 info1
->grpi1_comment
);
131 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
133 GROUPINFODESCRIPTION
,
138 if (info2
->grpi2_comment
) {
139 init_lsa_String(&info
.description
,
140 info2
->grpi2_comment
);
142 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
144 GROUPINFODESCRIPTION
,
146 if (!NT_STATUS_IS_OK(status
)) {
147 werr
= ntstatus_to_werror(status
);
152 if (info2
->grpi2_attributes
!= 0) {
153 info
.attributes
.attributes
= info2
->grpi2_attributes
;
154 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
162 if (info3
->grpi3_comment
) {
163 init_lsa_String(&info
.description
,
164 info3
->grpi3_comment
);
166 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
168 GROUPINFODESCRIPTION
,
170 if (!NT_STATUS_IS_OK(status
)) {
171 werr
= ntstatus_to_werror(status
);
176 if (info3
->grpi3_attributes
!= 0) {
177 info
.attributes
.attributes
= info3
->grpi3_attributes
;
178 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
188 if (!NT_STATUS_IS_OK(status
)) {
189 werr
= ntstatus_to_werror(status
);
197 rpccli_samr_DeleteDomainGroup(pipe_cli
, ctx
,
205 if (is_valid_policy_hnd(&group_handle
)) {
206 rpccli_samr_Close(pipe_cli
, ctx
, &group_handle
);
209 if (ctx
->disable_policy_handle_cache
) {
210 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
211 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
217 /****************************************************************
218 ****************************************************************/
220 WERROR
NetGroupAdd_l(struct libnetapi_ctx
*ctx
,
221 struct NetGroupAdd
*r
)
223 return NetGroupAdd_r(ctx
, r
);
226 /****************************************************************
227 ****************************************************************/
229 WERROR
NetGroupDel_r(struct libnetapi_ctx
*ctx
,
230 struct NetGroupDel
*r
)
232 struct cli_state
*cli
= NULL
;
233 struct rpc_pipe_client
*pipe_cli
= NULL
;
236 POLICY_HND connect_handle
, domain_handle
, group_handle
;
237 struct lsa_String lsa_group_name
;
238 struct dom_sid2
*domain_sid
= NULL
;
241 struct samr_Ids rids
;
242 struct samr_Ids types
;
243 union samr_GroupInfo
*info
= NULL
;
244 struct samr_RidTypeArray
*rid_array
= NULL
;
246 ZERO_STRUCT(connect_handle
);
247 ZERO_STRUCT(domain_handle
);
248 ZERO_STRUCT(group_handle
);
250 if (!r
->in
.group_name
) {
251 return WERR_INVALID_PARAM
;
254 werr
= libnetapi_open_ipc_connection(ctx
, r
->in
.server_name
, &cli
);
255 if (!W_ERROR_IS_OK(werr
)) {
259 werr
= libnetapi_open_pipe(ctx
, cli
, &ndr_table_samr
.syntax_id
,
261 if (!W_ERROR_IS_OK(werr
)) {
265 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
266 SAMR_ACCESS_ENUM_DOMAINS
|
267 SAMR_ACCESS_OPEN_DOMAIN
,
268 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
272 if (!W_ERROR_IS_OK(werr
)) {
276 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
278 status
= rpccli_samr_LookupNames(pipe_cli
, ctx
,
284 if (!NT_STATUS_IS_OK(status
)) {
285 werr
= ntstatus_to_werror(status
);
289 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
290 werr
= WERR_INVALID_DATATYPE
;
294 status
= rpccli_samr_OpenGroup(pipe_cli
, ctx
,
297 SAMR_GROUP_ACCESS_GET_MEMBERS
|
298 SAMR_GROUP_ACCESS_REMOVE_MEMBER
|
299 SAMR_GROUP_ACCESS_ADD_MEMBER
|
300 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
303 if (!NT_STATUS_IS_OK(status
)) {
304 werr
= ntstatus_to_werror(status
);
308 status
= rpccli_samr_QueryGroupInfo(pipe_cli
, ctx
,
312 if (!NT_STATUS_IS_OK(status
)) {
313 werr
= ntstatus_to_werror(status
);
318 /* breaks against NT4 */
319 if (!(info
->attributes
.attributes
& SE_GROUP_ENABLED
)) {
320 werr
= WERR_ACCESS_DENIED
;
324 status
= rpccli_samr_QueryGroupMember(pipe_cli
, ctx
,
327 if (!NT_STATUS_IS_OK(status
)) {
328 werr
= ntstatus_to_werror(status
);
333 struct lsa_Strings names
;
334 struct samr_Ids member_types
;
336 status
= rpccli_samr_LookupRids(pipe_cli
, ctx
,
342 if (!NT_STATUS_IS_OK(status
)) {
343 werr
= ntstatus_to_werror(status
);
348 for (i
=0; i
< rid_array
->count
; i
++) {
350 status
= rpccli_samr_DeleteGroupMember(pipe_cli
, ctx
,
353 if (!NT_STATUS_IS_OK(status
)) {
354 werr
= ntstatus_to_werror(status
);
359 status
= rpccli_samr_DeleteDomainGroup(pipe_cli
, ctx
,
361 if (!NT_STATUS_IS_OK(status
)) {
362 werr
= ntstatus_to_werror(status
);
366 ZERO_STRUCT(group_handle
);
375 if (is_valid_policy_hnd(&group_handle
)) {
376 rpccli_samr_Close(pipe_cli
, ctx
, &group_handle
);
379 if (ctx
->disable_policy_handle_cache
) {
380 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
381 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
387 /****************************************************************
388 ****************************************************************/
390 WERROR
NetGroupDel_l(struct libnetapi_ctx
*ctx
,
391 struct NetGroupDel
*r
)
393 return NetGroupDel_r(ctx
, r
);
396 /****************************************************************
397 ****************************************************************/
399 WERROR
NetGroupSetInfo_r(struct libnetapi_ctx
*ctx
,
400 struct NetGroupSetInfo
*r
)
402 struct cli_state
*cli
= NULL
;
403 struct rpc_pipe_client
*pipe_cli
= NULL
;
406 POLICY_HND connect_handle
, domain_handle
, group_handle
;
407 struct lsa_String lsa_group_name
;
408 struct dom_sid2
*domain_sid
= NULL
;
410 struct samr_Ids rids
;
411 struct samr_Ids types
;
412 union samr_GroupInfo info
;
413 struct GROUP_INFO_0
*g0
;
414 struct GROUP_INFO_1
*g1
;
415 struct GROUP_INFO_2
*g2
;
416 struct GROUP_INFO_3
*g3
;
417 struct GROUP_INFO_1002
*g1002
;
418 struct GROUP_INFO_1005
*g1005
;
420 ZERO_STRUCT(connect_handle
);
421 ZERO_STRUCT(domain_handle
);
422 ZERO_STRUCT(group_handle
);
424 if (!r
->in
.group_name
) {
425 return WERR_INVALID_PARAM
;
428 werr
= libnetapi_open_ipc_connection(ctx
, r
->in
.server_name
, &cli
);
429 if (!W_ERROR_IS_OK(werr
)) {
433 werr
= libnetapi_open_pipe(ctx
, cli
, &ndr_table_samr
.syntax_id
,
435 if (!W_ERROR_IS_OK(werr
)) {
439 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
440 SAMR_ACCESS_ENUM_DOMAINS
|
441 SAMR_ACCESS_OPEN_DOMAIN
,
442 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
446 if (!W_ERROR_IS_OK(werr
)) {
450 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
452 status
= rpccli_samr_LookupNames(pipe_cli
, ctx
,
458 if (!NT_STATUS_IS_OK(status
)) {
459 werr
= ntstatus_to_werror(status
);
463 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
464 werr
= WERR_INVALID_DATATYPE
;
468 status
= rpccli_samr_OpenGroup(pipe_cli
, ctx
,
470 SAMR_GROUP_ACCESS_SET_INFO
|
471 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
474 if (!NT_STATUS_IS_OK(status
)) {
475 werr
= ntstatus_to_werror(status
);
479 switch (r
->in
.level
) {
481 g0
= (struct GROUP_INFO_0
*)r
->in
.buf
;
482 init_lsa_String(&info
.name
, g0
->grpi0_name
);
483 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
489 g1
= (struct GROUP_INFO_1
*)r
->in
.buf
;
490 init_lsa_String(&info
.description
, g1
->grpi1_comment
);
491 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
493 GROUPINFODESCRIPTION
,
497 g2
= (struct GROUP_INFO_2
*)r
->in
.buf
;
498 init_lsa_String(&info
.description
, g2
->grpi2_comment
);
499 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
501 GROUPINFODESCRIPTION
,
503 if (!NT_STATUS_IS_OK(status
)) {
504 werr
= ntstatus_to_werror(status
);
507 info
.attributes
.attributes
= g2
->grpi2_attributes
;
508 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
514 g3
= (struct GROUP_INFO_3
*)r
->in
.buf
;
515 init_lsa_String(&info
.description
, g3
->grpi3_comment
);
516 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
518 GROUPINFODESCRIPTION
,
520 if (!NT_STATUS_IS_OK(status
)) {
521 werr
= ntstatus_to_werror(status
);
524 info
.attributes
.attributes
= g3
->grpi3_attributes
;
525 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
531 g1002
= (struct GROUP_INFO_1002
*)r
->in
.buf
;
532 init_lsa_String(&info
.description
, g1002
->grpi1002_comment
);
533 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
535 GROUPINFODESCRIPTION
,
539 g1005
= (struct GROUP_INFO_1005
*)r
->in
.buf
;
540 info
.attributes
.attributes
= g1005
->grpi1005_attributes
;
541 status
= rpccli_samr_SetGroupInfo(pipe_cli
, ctx
,
547 status
= NT_STATUS_INVALID_LEVEL
;
551 if (!NT_STATUS_IS_OK(status
)) {
552 werr
= ntstatus_to_werror(status
);
563 if (is_valid_policy_hnd(&group_handle
)) {
564 rpccli_samr_Close(pipe_cli
, ctx
, &group_handle
);
567 if (ctx
->disable_policy_handle_cache
) {
568 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
569 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
575 /****************************************************************
576 ****************************************************************/
578 WERROR
NetGroupSetInfo_l(struct libnetapi_ctx
*ctx
,
579 struct NetGroupSetInfo
*r
)
581 return NetGroupSetInfo_r(ctx
, r
);
584 /****************************************************************
585 ****************************************************************/
587 static WERROR
map_group_info_to_buffer(TALLOC_CTX
*mem_ctx
,
589 struct samr_GroupInfoAll
*info
,
590 struct dom_sid2
*domain_sid
,
594 struct GROUP_INFO_0 info0
;
595 struct GROUP_INFO_1 info1
;
596 struct GROUP_INFO_2 info2
;
597 struct GROUP_INFO_3 info3
;
602 info0
.grpi0_name
= info
->name
.string
;
604 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info0
, sizeof(info0
));
608 info1
.grpi1_name
= info
->name
.string
;
609 info1
.grpi1_comment
= info
->description
.string
;
611 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info1
, sizeof(info1
));
615 info2
.grpi2_name
= info
->name
.string
;
616 info2
.grpi2_comment
= info
->description
.string
;
617 info2
.grpi2_group_id
= rid
;
618 info2
.grpi2_attributes
= info
->attributes
;
620 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info2
, sizeof(info2
));
624 if (!sid_compose(&sid
, domain_sid
, rid
)) {
628 info3
.grpi3_name
= info
->name
.string
;
629 info3
.grpi3_comment
= info
->description
.string
;
630 info3
.grpi3_attributes
= info
->attributes
;
631 info3
.grpi3_group_sid
= (struct domsid
*)sid_dup_talloc(mem_ctx
, &sid
);
633 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info3
, sizeof(info3
));
637 return WERR_UNKNOWN_LEVEL
;
640 W_ERROR_HAVE_NO_MEMORY(*buffer
);
645 /****************************************************************
646 ****************************************************************/
648 WERROR
NetGroupGetInfo_r(struct libnetapi_ctx
*ctx
,
649 struct NetGroupGetInfo
*r
)
651 struct cli_state
*cli
= NULL
;
652 struct rpc_pipe_client
*pipe_cli
= NULL
;
655 POLICY_HND connect_handle
, domain_handle
, group_handle
;
656 struct lsa_String lsa_group_name
;
657 struct dom_sid2
*domain_sid
= NULL
;
659 struct samr_Ids rids
;
660 struct samr_Ids types
;
661 union samr_GroupInfo
*info
= NULL
;
662 bool group_info_all
= false;
664 ZERO_STRUCT(connect_handle
);
665 ZERO_STRUCT(domain_handle
);
666 ZERO_STRUCT(group_handle
);
668 if (!r
->in
.group_name
) {
669 return WERR_INVALID_PARAM
;
672 werr
= libnetapi_open_ipc_connection(ctx
, r
->in
.server_name
, &cli
);
673 if (!W_ERROR_IS_OK(werr
)) {
677 werr
= libnetapi_open_pipe(ctx
, cli
, &ndr_table_samr
.syntax_id
,
679 if (!W_ERROR_IS_OK(werr
)) {
683 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
684 SAMR_ACCESS_ENUM_DOMAINS
|
685 SAMR_ACCESS_OPEN_DOMAIN
,
686 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
690 if (!W_ERROR_IS_OK(werr
)) {
694 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
696 status
= rpccli_samr_LookupNames(pipe_cli
, ctx
,
702 if (!NT_STATUS_IS_OK(status
)) {
703 werr
= ntstatus_to_werror(status
);
707 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
708 werr
= WERR_INVALID_DATATYPE
;
712 status
= rpccli_samr_OpenGroup(pipe_cli
, ctx
,
714 SAMR_GROUP_ACCESS_LOOKUP_INFO
,
717 if (!NT_STATUS_IS_OK(status
)) {
718 werr
= ntstatus_to_werror(status
);
722 status
= rpccli_samr_QueryGroupInfo(pipe_cli
, ctx
,
726 if (NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
727 status
= rpccli_samr_QueryGroupInfo(pipe_cli
, ctx
,
731 group_info_all
= true;
734 if (!NT_STATUS_IS_OK(status
)) {
735 werr
= ntstatus_to_werror(status
);
739 werr
= map_group_info_to_buffer(ctx
, r
->in
.level
,
740 group_info_all
? &info
->all
: &info
->all2
,
741 domain_sid
, rids
.ids
[0],
743 if (!W_ERROR_IS_OK(werr
)) {
751 if (is_valid_policy_hnd(&group_handle
)) {
752 rpccli_samr_Close(pipe_cli
, ctx
, &group_handle
);
755 if (ctx
->disable_policy_handle_cache
) {
756 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
757 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
763 /****************************************************************
764 ****************************************************************/
766 WERROR
NetGroupGetInfo_l(struct libnetapi_ctx
*ctx
,
767 struct NetGroupGetInfo
*r
)
769 return NetGroupGetInfo_r(ctx
, r
);
772 /****************************************************************
773 ****************************************************************/
775 WERROR
NetGroupAddUser_r(struct libnetapi_ctx
*ctx
,
776 struct NetGroupAddUser
*r
)
778 struct cli_state
*cli
= NULL
;
779 struct rpc_pipe_client
*pipe_cli
= NULL
;
782 POLICY_HND connect_handle
, domain_handle
, group_handle
;
783 struct lsa_String lsa_group_name
, lsa_user_name
;
784 struct dom_sid2
*domain_sid
= NULL
;
786 struct samr_Ids rids
;
787 struct samr_Ids types
;
789 ZERO_STRUCT(connect_handle
);
790 ZERO_STRUCT(domain_handle
);
791 ZERO_STRUCT(group_handle
);
793 if (!r
->in
.group_name
) {
794 return WERR_INVALID_PARAM
;
797 werr
= libnetapi_open_ipc_connection(ctx
, r
->in
.server_name
, &cli
);
798 if (!W_ERROR_IS_OK(werr
)) {
802 werr
= libnetapi_open_pipe(ctx
, cli
, &ndr_table_samr
.syntax_id
,
804 if (!W_ERROR_IS_OK(werr
)) {
808 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
809 SAMR_ACCESS_ENUM_DOMAINS
|
810 SAMR_ACCESS_OPEN_DOMAIN
,
811 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
815 if (!W_ERROR_IS_OK(werr
)) {
819 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
821 status
= rpccli_samr_LookupNames(pipe_cli
, ctx
,
827 if (!NT_STATUS_IS_OK(status
)) {
828 werr
= WERR_GROUP_NOT_FOUND
;
832 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
833 werr
= WERR_GROUP_NOT_FOUND
;
837 status
= rpccli_samr_OpenGroup(pipe_cli
, ctx
,
839 SAMR_GROUP_ACCESS_ADD_MEMBER
,
842 if (!NT_STATUS_IS_OK(status
)) {
843 werr
= ntstatus_to_werror(status
);
847 init_lsa_String(&lsa_user_name
, r
->in
.user_name
);
849 status
= rpccli_samr_LookupNames(pipe_cli
, ctx
,
855 if (!NT_STATUS_IS_OK(status
)) {
856 werr
= WERR_USER_NOT_FOUND
;
860 if (types
.ids
[0] != SID_NAME_USER
) {
861 werr
= WERR_USER_NOT_FOUND
;
865 status
= rpccli_samr_AddGroupMember(pipe_cli
, ctx
,
869 if (!NT_STATUS_IS_OK(status
)) {
870 werr
= ntstatus_to_werror(status
);
881 if (is_valid_policy_hnd(&group_handle
)) {
882 rpccli_samr_Close(pipe_cli
, ctx
, &group_handle
);
885 if (ctx
->disable_policy_handle_cache
) {
886 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
887 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
893 /****************************************************************
894 ****************************************************************/
896 WERROR
NetGroupAddUser_l(struct libnetapi_ctx
*ctx
,
897 struct NetGroupAddUser
*r
)
899 return NetGroupAddUser_r(ctx
, r
);
902 /****************************************************************
903 ****************************************************************/
905 WERROR
NetGroupDelUser_r(struct libnetapi_ctx
*ctx
,
906 struct NetGroupDelUser
*r
)
908 struct cli_state
*cli
= NULL
;
909 struct rpc_pipe_client
*pipe_cli
= NULL
;
912 POLICY_HND connect_handle
, domain_handle
, group_handle
;
913 struct lsa_String lsa_group_name
, lsa_user_name
;
914 struct dom_sid2
*domain_sid
= NULL
;
916 struct samr_Ids rids
;
917 struct samr_Ids types
;
919 ZERO_STRUCT(connect_handle
);
920 ZERO_STRUCT(domain_handle
);
921 ZERO_STRUCT(group_handle
);
923 if (!r
->in
.group_name
) {
924 return WERR_INVALID_PARAM
;
927 werr
= libnetapi_open_ipc_connection(ctx
, r
->in
.server_name
, &cli
);
928 if (!W_ERROR_IS_OK(werr
)) {
932 werr
= libnetapi_open_pipe(ctx
, cli
, &ndr_table_samr
.syntax_id
,
934 if (!W_ERROR_IS_OK(werr
)) {
938 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
939 SAMR_ACCESS_ENUM_DOMAINS
|
940 SAMR_ACCESS_OPEN_DOMAIN
,
941 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
945 if (!W_ERROR_IS_OK(werr
)) {
949 init_lsa_String(&lsa_group_name
, r
->in
.group_name
);
951 status
= rpccli_samr_LookupNames(pipe_cli
, ctx
,
957 if (!NT_STATUS_IS_OK(status
)) {
958 werr
= WERR_GROUP_NOT_FOUND
;
962 if (types
.ids
[0] != SID_NAME_DOM_GRP
) {
963 werr
= WERR_GROUP_NOT_FOUND
;
967 status
= rpccli_samr_OpenGroup(pipe_cli
, ctx
,
969 SAMR_GROUP_ACCESS_REMOVE_MEMBER
,
972 if (!NT_STATUS_IS_OK(status
)) {
973 werr
= ntstatus_to_werror(status
);
977 init_lsa_String(&lsa_user_name
, r
->in
.user_name
);
979 status
= rpccli_samr_LookupNames(pipe_cli
, ctx
,
985 if (!NT_STATUS_IS_OK(status
)) {
986 werr
= WERR_USER_NOT_FOUND
;
990 if (types
.ids
[0] != SID_NAME_USER
) {
991 werr
= WERR_USER_NOT_FOUND
;
995 status
= rpccli_samr_DeleteGroupMember(pipe_cli
, ctx
,
998 if (!NT_STATUS_IS_OK(status
)) {
999 werr
= ntstatus_to_werror(status
);
1010 if (is_valid_policy_hnd(&group_handle
)) {
1011 rpccli_samr_Close(pipe_cli
, ctx
, &group_handle
);
1014 if (ctx
->disable_policy_handle_cache
) {
1015 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1016 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1022 /****************************************************************
1023 ****************************************************************/
1025 WERROR
NetGroupDelUser_l(struct libnetapi_ctx
*ctx
,
1026 struct NetGroupDelUser
*r
)
1028 return NetGroupDelUser_r(ctx
, r
);
1031 /****************************************************************
1032 ****************************************************************/
1034 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_0_buffer(TALLOC_CTX
*mem_ctx
,
1035 struct samr_DispInfoFullGroups
*groups
,
1038 struct GROUP_INFO_0
*g0
;
1041 g0
= TALLOC_ZERO_ARRAY(mem_ctx
, struct GROUP_INFO_0
, groups
->count
);
1042 W_ERROR_HAVE_NO_MEMORY(g0
);
1044 for (i
=0; i
<groups
->count
; i
++) {
1045 g0
[i
].grpi0_name
= talloc_strdup(mem_ctx
,
1046 groups
->entries
[i
].account_name
.string
);
1047 W_ERROR_HAVE_NO_MEMORY(g0
[i
].grpi0_name
);
1050 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g0
,
1051 sizeof(struct GROUP_INFO_0
) * groups
->count
);
1052 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1057 /****************************************************************
1058 ****************************************************************/
1060 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_1_buffer(TALLOC_CTX
*mem_ctx
,
1061 struct samr_DispInfoFullGroups
*groups
,
1064 struct GROUP_INFO_1
*g1
;
1067 g1
= TALLOC_ZERO_ARRAY(mem_ctx
, struct GROUP_INFO_1
, groups
->count
);
1068 W_ERROR_HAVE_NO_MEMORY(g1
);
1070 for (i
=0; i
<groups
->count
; i
++) {
1071 g1
[i
].grpi1_name
= talloc_strdup(mem_ctx
,
1072 groups
->entries
[i
].account_name
.string
);
1073 g1
[i
].grpi1_comment
= talloc_strdup(mem_ctx
,
1074 groups
->entries
[i
].description
.string
);
1075 W_ERROR_HAVE_NO_MEMORY(g1
[i
].grpi1_name
);
1078 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g1
,
1079 sizeof(struct GROUP_INFO_1
) * groups
->count
);
1080 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1085 /****************************************************************
1086 ****************************************************************/
1088 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_2_buffer(TALLOC_CTX
*mem_ctx
,
1089 struct samr_DispInfoFullGroups
*groups
,
1092 struct GROUP_INFO_2
*g2
;
1095 g2
= TALLOC_ZERO_ARRAY(mem_ctx
, struct GROUP_INFO_2
, groups
->count
);
1096 W_ERROR_HAVE_NO_MEMORY(g2
);
1098 for (i
=0; i
<groups
->count
; i
++) {
1099 g2
[i
].grpi2_name
= talloc_strdup(mem_ctx
,
1100 groups
->entries
[i
].account_name
.string
);
1101 g2
[i
].grpi2_comment
= talloc_strdup(mem_ctx
,
1102 groups
->entries
[i
].description
.string
);
1103 g2
[i
].grpi2_group_id
= groups
->entries
[i
].rid
;
1104 g2
[i
].grpi2_attributes
= groups
->entries
[i
].acct_flags
;
1105 W_ERROR_HAVE_NO_MEMORY(g2
[i
].grpi2_name
);
1108 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g2
,
1109 sizeof(struct GROUP_INFO_2
) * groups
->count
);
1110 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1115 /****************************************************************
1116 ****************************************************************/
1118 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_3_buffer(TALLOC_CTX
*mem_ctx
,
1119 struct samr_DispInfoFullGroups
*groups
,
1120 const struct dom_sid
*domain_sid
,
1123 struct GROUP_INFO_3
*g3
;
1126 g3
= TALLOC_ZERO_ARRAY(mem_ctx
, struct GROUP_INFO_3
, groups
->count
);
1127 W_ERROR_HAVE_NO_MEMORY(g3
);
1129 for (i
=0; i
<groups
->count
; i
++) {
1133 if (!sid_compose(&sid
, domain_sid
, groups
->entries
[i
].rid
)) {
1137 g3
[i
].grpi3_name
= talloc_strdup(mem_ctx
,
1138 groups
->entries
[i
].account_name
.string
);
1139 g3
[i
].grpi3_comment
= talloc_strdup(mem_ctx
,
1140 groups
->entries
[i
].description
.string
);
1141 g3
[i
].grpi3_group_sid
= (struct domsid
*)sid_dup_talloc(mem_ctx
, &sid
);
1142 g3
[i
].grpi3_attributes
= groups
->entries
[i
].acct_flags
;
1143 W_ERROR_HAVE_NO_MEMORY(g3
[i
].grpi3_name
);
1146 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, g3
,
1147 sizeof(struct GROUP_INFO_3
) * groups
->count
);
1148 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1153 /****************************************************************
1154 ****************************************************************/
1156 static WERROR
convert_samr_disp_groups_to_GROUP_INFO_buffer(TALLOC_CTX
*mem_ctx
,
1158 struct samr_DispInfoFullGroups
*groups
,
1159 const struct dom_sid
*domain_sid
,
1160 uint32_t *entries_read
,
1164 *entries_read
= groups
->count
;
1169 return convert_samr_disp_groups_to_GROUP_INFO_0_buffer(mem_ctx
, groups
, buffer
);
1171 return convert_samr_disp_groups_to_GROUP_INFO_1_buffer(mem_ctx
, groups
, buffer
);
1173 return convert_samr_disp_groups_to_GROUP_INFO_2_buffer(mem_ctx
, groups
, buffer
);
1175 return convert_samr_disp_groups_to_GROUP_INFO_3_buffer(mem_ctx
, groups
, domain_sid
, buffer
);
1177 return WERR_UNKNOWN_LEVEL
;
1181 /****************************************************************
1182 ****************************************************************/
1184 WERROR
NetGroupEnum_r(struct libnetapi_ctx
*ctx
,
1185 struct NetGroupEnum
*r
)
1187 struct cli_state
*cli
= NULL
;
1188 struct rpc_pipe_client
*pipe_cli
= NULL
;
1189 struct policy_handle connect_handle
;
1190 struct dom_sid2
*domain_sid
= NULL
;
1191 struct policy_handle domain_handle
;
1192 union samr_DispInfo info
;
1193 union samr_DomainInfo
*domain_info
= NULL
;
1195 uint32_t total_size
= 0;
1196 uint32_t returned_size
= 0;
1198 NTSTATUS status
= NT_STATUS_OK
;
1199 WERROR werr
, tmp_werr
;
1201 ZERO_STRUCT(connect_handle
);
1202 ZERO_STRUCT(domain_handle
);
1204 switch (r
->in
.level
) {
1211 return WERR_UNKNOWN_LEVEL
;
1214 werr
= libnetapi_open_ipc_connection(ctx
, r
->in
.server_name
, &cli
);
1215 if (!W_ERROR_IS_OK(werr
)) {
1219 werr
= libnetapi_open_pipe(ctx
, cli
, &ndr_table_samr
.syntax_id
,
1221 if (!W_ERROR_IS_OK(werr
)) {
1225 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1226 SAMR_ACCESS_ENUM_DOMAINS
|
1227 SAMR_ACCESS_OPEN_DOMAIN
,
1228 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1229 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1230 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1234 if (!W_ERROR_IS_OK(werr
)) {
1238 status
= rpccli_samr_QueryDomainInfo(pipe_cli
, ctx
,
1242 if (!NT_STATUS_IS_OK(status
)) {
1243 werr
= ntstatus_to_werror(status
);
1247 if (r
->out
.total_entries
) {
1248 *r
->out
.total_entries
= domain_info
->info2
.num_groups
;
1251 status
= rpccli_samr_QueryDisplayInfo2(pipe_cli
,
1255 r
->in
.resume_handle
?
1256 *r
->in
.resume_handle
: 0,
1262 werr
= ntstatus_to_werror(status
);
1263 if (NT_STATUS_IS_ERR(status
)) {
1267 if (r
->out
.resume_handle
) {
1268 *r
->out
.resume_handle
=
1269 info
.info3
.entries
[info
.info3
.count
-1].idx
;
1272 tmp_werr
= convert_samr_disp_groups_to_GROUP_INFO_buffer(ctx
,
1276 r
->out
.entries_read
,
1278 if (!W_ERROR_IS_OK(tmp_werr
)) {
1289 if (NT_STATUS_IS_OK(status
) ||
1290 NT_STATUS_IS_ERR(status
)) {
1292 if (ctx
->disable_policy_handle_cache
) {
1293 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1294 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1301 /****************************************************************
1302 ****************************************************************/
1304 WERROR
NetGroupEnum_l(struct libnetapi_ctx
*ctx
,
1305 struct NetGroupEnum
*r
)
1307 return NetGroupEnum_r(ctx
, r
);