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, PI_SAMR, &pipe_cli);
80 if (!W_ERROR_IS_OK(werr)) {
84 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
85 SAMR_ACCESS_ENUM_DOMAINS |
86 SAMR_ACCESS_OPEN_DOMAIN,
87 SAMR_DOMAIN_ACCESS_CREATE_GROUP |
88 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
92 if (!W_ERROR_IS_OK(werr)) {
96 switch (r->in.level) {
98 init_lsa_String(&lsa_group_name, info0->grpi0_name);
101 init_lsa_String(&lsa_group_name, info1->grpi1_name);
104 init_lsa_String(&lsa_group_name, info2->grpi2_name);
107 init_lsa_String(&lsa_group_name, info3->grpi3_name);
111 status = rpccli_samr_CreateDomainGroup(pipe_cli, ctx,
115 SAMR_GROUP_ACCESS_SET_INFO,
119 if (!NT_STATUS_IS_OK(status)) {
120 werr = ntstatus_to_werror(status);
124 switch (r->in.level) {
126 if (info1->grpi1_comment) {
127 init_lsa_String(&info.description,
128 info1->grpi1_comment);
130 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
132 GROUPINFODESCRIPTION,
137 if (info2->grpi2_comment) {
138 init_lsa_String(&info.description,
139 info2->grpi2_comment);
141 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
143 GROUPINFODESCRIPTION,
145 if (!NT_STATUS_IS_OK(status)) {
146 werr = ntstatus_to_werror(status);
151 if (info2->grpi2_attributes != 0) {
152 info.attributes.attributes = info2->grpi2_attributes;
153 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
161 if (info3->grpi3_comment) {
162 init_lsa_String(&info.description,
163 info3->grpi3_comment);
165 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
167 GROUPINFODESCRIPTION,
169 if (!NT_STATUS_IS_OK(status)) {
170 werr = ntstatus_to_werror(status);
175 if (info3->grpi3_attributes != 0) {
176 info.attributes.attributes = info3->grpi3_attributes;
177 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
187 if (!NT_STATUS_IS_OK(status)) {
188 werr = ntstatus_to_werror(status);
196 rpccli_samr_DeleteDomainGroup(pipe_cli, ctx,
204 if (is_valid_policy_hnd(&group_handle)) {
205 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
208 if (ctx->disable_policy_handle_cache) {
209 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
210 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
216 /****************************************************************
217 ****************************************************************/
219 WERROR NetGroupAdd_l(struct libnetapi_ctx *ctx,
220 struct NetGroupAdd *r)
222 return NetGroupAdd_r(ctx, r);
225 /****************************************************************
226 ****************************************************************/
228 WERROR NetGroupDel_r(struct libnetapi_ctx *ctx,
229 struct NetGroupDel *r)
231 struct cli_state *cli = NULL;
232 struct rpc_pipe_client *pipe_cli = NULL;
235 POLICY_HND connect_handle, domain_handle, group_handle;
236 struct lsa_String lsa_group_name;
237 struct dom_sid2 *domain_sid = NULL;
240 struct samr_Ids rids;
241 struct samr_Ids types;
242 union samr_GroupInfo *info = NULL;
243 struct samr_RidTypeArray *rid_array = NULL;
245 ZERO_STRUCT(connect_handle);
246 ZERO_STRUCT(domain_handle);
247 ZERO_STRUCT(group_handle);
249 if (!r->in.group_name) {
250 return WERR_INVALID_PARAM;
253 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
254 if (!W_ERROR_IS_OK(werr)) {
258 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
259 if (!W_ERROR_IS_OK(werr)) {
263 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
264 SAMR_ACCESS_ENUM_DOMAINS |
265 SAMR_ACCESS_OPEN_DOMAIN,
266 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
270 if (!W_ERROR_IS_OK(werr)) {
274 init_lsa_String(&lsa_group_name, r->in.group_name);
276 status = rpccli_samr_LookupNames(pipe_cli, ctx,
282 if (!NT_STATUS_IS_OK(status)) {
283 werr = ntstatus_to_werror(status);
287 if (types.ids[0] != SID_NAME_DOM_GRP) {
288 werr = WERR_INVALID_DATATYPE;
292 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
295 SAMR_GROUP_ACCESS_GET_MEMBERS |
296 SAMR_GROUP_ACCESS_REMOVE_MEMBER |
297 SAMR_GROUP_ACCESS_ADD_MEMBER |
298 SAMR_GROUP_ACCESS_LOOKUP_INFO,
301 if (!NT_STATUS_IS_OK(status)) {
302 werr = ntstatus_to_werror(status);
306 status = rpccli_samr_QueryGroupInfo(pipe_cli, ctx,
310 if (!NT_STATUS_IS_OK(status)) {
311 werr = ntstatus_to_werror(status);
316 /* breaks against NT4 */
317 if (!(info->attributes.attributes & SE_GROUP_ENABLED)) {
318 werr = WERR_ACCESS_DENIED;
322 status = rpccli_samr_QueryGroupMember(pipe_cli, ctx,
325 if (!NT_STATUS_IS_OK(status)) {
326 werr = ntstatus_to_werror(status);
331 struct lsa_Strings names;
332 struct samr_Ids member_types;
334 status = rpccli_samr_LookupRids(pipe_cli, ctx,
340 if (!NT_STATUS_IS_OK(status)) {
341 werr = ntstatus_to_werror(status);
346 for (i=0; i < rid_array->count; i++) {
348 status = rpccli_samr_DeleteGroupMember(pipe_cli, ctx,
351 if (!NT_STATUS_IS_OK(status)) {
352 werr = ntstatus_to_werror(status);
357 status = rpccli_samr_DeleteDomainGroup(pipe_cli, ctx,
359 if (!NT_STATUS_IS_OK(status)) {
360 werr = ntstatus_to_werror(status);
364 ZERO_STRUCT(group_handle);
373 if (is_valid_policy_hnd(&group_handle)) {
374 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
377 if (ctx->disable_policy_handle_cache) {
378 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
379 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
385 /****************************************************************
386 ****************************************************************/
388 WERROR NetGroupDel_l(struct libnetapi_ctx *ctx,
389 struct NetGroupDel *r)
391 return NetGroupDel_r(ctx, r);
394 /****************************************************************
395 ****************************************************************/
397 WERROR NetGroupSetInfo_r(struct libnetapi_ctx *ctx,
398 struct NetGroupSetInfo *r)
400 struct cli_state *cli = NULL;
401 struct rpc_pipe_client *pipe_cli = NULL;
404 POLICY_HND connect_handle, domain_handle, group_handle;
405 struct lsa_String lsa_group_name;
406 struct dom_sid2 *domain_sid = NULL;
408 struct samr_Ids rids;
409 struct samr_Ids types;
410 union samr_GroupInfo info;
411 struct GROUP_INFO_0 *g0;
412 struct GROUP_INFO_1 *g1;
413 struct GROUP_INFO_2 *g2;
414 struct GROUP_INFO_3 *g3;
415 struct GROUP_INFO_1002 *g1002;
416 struct GROUP_INFO_1005 *g1005;
418 ZERO_STRUCT(connect_handle);
419 ZERO_STRUCT(domain_handle);
420 ZERO_STRUCT(group_handle);
422 if (!r->in.group_name) {
423 return WERR_INVALID_PARAM;
426 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
427 if (!W_ERROR_IS_OK(werr)) {
431 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
432 if (!W_ERROR_IS_OK(werr)) {
436 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
437 SAMR_ACCESS_ENUM_DOMAINS |
438 SAMR_ACCESS_OPEN_DOMAIN,
439 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
443 if (!W_ERROR_IS_OK(werr)) {
447 init_lsa_String(&lsa_group_name, r->in.group_name);
449 status = rpccli_samr_LookupNames(pipe_cli, ctx,
455 if (!NT_STATUS_IS_OK(status)) {
456 werr = ntstatus_to_werror(status);
460 if (types.ids[0] != SID_NAME_DOM_GRP) {
461 werr = WERR_INVALID_DATATYPE;
465 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
467 SAMR_GROUP_ACCESS_SET_INFO |
468 SAMR_GROUP_ACCESS_LOOKUP_INFO,
471 if (!NT_STATUS_IS_OK(status)) {
472 werr = ntstatus_to_werror(status);
476 switch (r->in.level) {
478 g0 = (struct GROUP_INFO_0 *)r->in.buf;
479 init_lsa_String(&info.name, g0->grpi0_name);
480 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
486 g1 = (struct GROUP_INFO_1 *)r->in.buf;
487 init_lsa_String(&info.description, g1->grpi1_comment);
488 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
490 GROUPINFODESCRIPTION,
494 g2 = (struct GROUP_INFO_2 *)r->in.buf;
495 init_lsa_String(&info.description, g2->grpi2_comment);
496 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
498 GROUPINFODESCRIPTION,
500 if (!NT_STATUS_IS_OK(status)) {
501 werr = ntstatus_to_werror(status);
504 info.attributes.attributes = g2->grpi2_attributes;
505 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
511 g3 = (struct GROUP_INFO_3 *)r->in.buf;
512 init_lsa_String(&info.description, g3->grpi3_comment);
513 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
515 GROUPINFODESCRIPTION,
517 if (!NT_STATUS_IS_OK(status)) {
518 werr = ntstatus_to_werror(status);
521 info.attributes.attributes = g3->grpi3_attributes;
522 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
528 g1002 = (struct GROUP_INFO_1002 *)r->in.buf;
529 init_lsa_String(&info.description, g1002->grpi1002_comment);
530 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
532 GROUPINFODESCRIPTION,
536 g1005 = (struct GROUP_INFO_1005 *)r->in.buf;
537 info.attributes.attributes = g1005->grpi1005_attributes;
538 status = rpccli_samr_SetGroupInfo(pipe_cli, ctx,
544 status = NT_STATUS_INVALID_LEVEL;
548 if (!NT_STATUS_IS_OK(status)) {
549 werr = ntstatus_to_werror(status);
560 if (is_valid_policy_hnd(&group_handle)) {
561 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
564 if (ctx->disable_policy_handle_cache) {
565 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
566 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
572 /****************************************************************
573 ****************************************************************/
575 WERROR NetGroupSetInfo_l(struct libnetapi_ctx *ctx,
576 struct NetGroupSetInfo *r)
578 return NetGroupSetInfo_r(ctx, r);
581 /****************************************************************
582 ****************************************************************/
584 static WERROR map_group_info_to_buffer(TALLOC_CTX *mem_ctx,
586 struct samr_GroupInfoAll *info,
587 struct dom_sid2 *domain_sid,
591 struct GROUP_INFO_0 info0;
592 struct GROUP_INFO_1 info1;
593 struct GROUP_INFO_2 info2;
594 struct GROUP_INFO_3 info3;
599 info0.grpi0_name = info->name.string;
601 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0, sizeof(info0));
605 info1.grpi1_name = info->name.string;
606 info1.grpi1_comment = info->description.string;
608 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1, sizeof(info1));
612 info2.grpi2_name = info->name.string;
613 info2.grpi2_comment = info->description.string;
614 info2.grpi2_group_id = rid;
615 info2.grpi2_attributes = info->attributes;
617 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2, sizeof(info2));
621 if (!sid_compose(&sid, domain_sid, rid)) {
625 info3.grpi3_name = info->name.string;
626 info3.grpi3_comment = info->description.string;
627 info3.grpi3_attributes = info->attributes;
628 info3.grpi3_group_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
630 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3, sizeof(info3));
634 return WERR_UNKNOWN_LEVEL;
637 W_ERROR_HAVE_NO_MEMORY(*buffer);
642 /****************************************************************
643 ****************************************************************/
645 WERROR NetGroupGetInfo_r(struct libnetapi_ctx *ctx,
646 struct NetGroupGetInfo *r)
648 struct cli_state *cli = NULL;
649 struct rpc_pipe_client *pipe_cli = NULL;
652 POLICY_HND connect_handle, domain_handle, group_handle;
653 struct lsa_String lsa_group_name;
654 struct dom_sid2 *domain_sid = NULL;
656 struct samr_Ids rids;
657 struct samr_Ids types;
658 union samr_GroupInfo *info = NULL;
659 bool group_info_all = false;
661 ZERO_STRUCT(connect_handle);
662 ZERO_STRUCT(domain_handle);
663 ZERO_STRUCT(group_handle);
665 if (!r->in.group_name) {
666 return WERR_INVALID_PARAM;
669 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
670 if (!W_ERROR_IS_OK(werr)) {
674 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
675 if (!W_ERROR_IS_OK(werr)) {
679 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
680 SAMR_ACCESS_ENUM_DOMAINS |
681 SAMR_ACCESS_OPEN_DOMAIN,
682 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
686 if (!W_ERROR_IS_OK(werr)) {
690 init_lsa_String(&lsa_group_name, r->in.group_name);
692 status = rpccli_samr_LookupNames(pipe_cli, ctx,
698 if (!NT_STATUS_IS_OK(status)) {
699 werr = ntstatus_to_werror(status);
703 if (types.ids[0] != SID_NAME_DOM_GRP) {
704 werr = WERR_INVALID_DATATYPE;
708 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
710 SAMR_GROUP_ACCESS_LOOKUP_INFO,
713 if (!NT_STATUS_IS_OK(status)) {
714 werr = ntstatus_to_werror(status);
718 status = rpccli_samr_QueryGroupInfo(pipe_cli, ctx,
722 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
723 status = rpccli_samr_QueryGroupInfo(pipe_cli, ctx,
727 group_info_all = true;
730 if (!NT_STATUS_IS_OK(status)) {
731 werr = ntstatus_to_werror(status);
735 werr = map_group_info_to_buffer(ctx, r->in.level,
736 group_info_all ? &info->all : &info->all2,
737 domain_sid, rids.ids[0],
739 if (!W_ERROR_IS_OK(werr)) {
747 if (is_valid_policy_hnd(&group_handle)) {
748 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
751 if (ctx->disable_policy_handle_cache) {
752 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
753 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
759 /****************************************************************
760 ****************************************************************/
762 WERROR NetGroupGetInfo_l(struct libnetapi_ctx *ctx,
763 struct NetGroupGetInfo *r)
765 return NetGroupGetInfo_r(ctx, r);
768 /****************************************************************
769 ****************************************************************/
771 WERROR NetGroupAddUser_r(struct libnetapi_ctx *ctx,
772 struct NetGroupAddUser *r)
774 struct cli_state *cli = NULL;
775 struct rpc_pipe_client *pipe_cli = NULL;
778 POLICY_HND connect_handle, domain_handle, group_handle;
779 struct lsa_String lsa_group_name, lsa_user_name;
780 struct dom_sid2 *domain_sid = NULL;
782 struct samr_Ids rids;
783 struct samr_Ids types;
785 ZERO_STRUCT(connect_handle);
786 ZERO_STRUCT(domain_handle);
787 ZERO_STRUCT(group_handle);
789 if (!r->in.group_name) {
790 return WERR_INVALID_PARAM;
793 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
794 if (!W_ERROR_IS_OK(werr)) {
798 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
799 if (!W_ERROR_IS_OK(werr)) {
803 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
804 SAMR_ACCESS_ENUM_DOMAINS |
805 SAMR_ACCESS_OPEN_DOMAIN,
806 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
810 if (!W_ERROR_IS_OK(werr)) {
814 init_lsa_String(&lsa_group_name, r->in.group_name);
816 status = rpccli_samr_LookupNames(pipe_cli, ctx,
822 if (!NT_STATUS_IS_OK(status)) {
823 werr = WERR_GROUP_NOT_FOUND;
827 if (types.ids[0] != SID_NAME_DOM_GRP) {
828 werr = WERR_GROUP_NOT_FOUND;
832 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
834 SAMR_GROUP_ACCESS_ADD_MEMBER,
837 if (!NT_STATUS_IS_OK(status)) {
838 werr = ntstatus_to_werror(status);
842 init_lsa_String(&lsa_user_name, r->in.user_name);
844 status = rpccli_samr_LookupNames(pipe_cli, ctx,
850 if (!NT_STATUS_IS_OK(status)) {
851 werr = WERR_USER_NOT_FOUND;
855 if (types.ids[0] != SID_NAME_USER) {
856 werr = WERR_USER_NOT_FOUND;
860 status = rpccli_samr_AddGroupMember(pipe_cli, ctx,
864 if (!NT_STATUS_IS_OK(status)) {
865 werr = ntstatus_to_werror(status);
876 if (is_valid_policy_hnd(&group_handle)) {
877 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
880 if (ctx->disable_policy_handle_cache) {
881 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
882 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
888 /****************************************************************
889 ****************************************************************/
891 WERROR NetGroupAddUser_l(struct libnetapi_ctx *ctx,
892 struct NetGroupAddUser *r)
894 return NetGroupAddUser_r(ctx, r);
897 /****************************************************************
898 ****************************************************************/
900 WERROR NetGroupDelUser_r(struct libnetapi_ctx *ctx,
901 struct NetGroupDelUser *r)
903 struct cli_state *cli = NULL;
904 struct rpc_pipe_client *pipe_cli = NULL;
907 POLICY_HND connect_handle, domain_handle, group_handle;
908 struct lsa_String lsa_group_name, lsa_user_name;
909 struct dom_sid2 *domain_sid = NULL;
911 struct samr_Ids rids;
912 struct samr_Ids types;
914 ZERO_STRUCT(connect_handle);
915 ZERO_STRUCT(domain_handle);
916 ZERO_STRUCT(group_handle);
918 if (!r->in.group_name) {
919 return WERR_INVALID_PARAM;
922 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
923 if (!W_ERROR_IS_OK(werr)) {
927 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
928 if (!W_ERROR_IS_OK(werr)) {
932 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
933 SAMR_ACCESS_ENUM_DOMAINS |
934 SAMR_ACCESS_OPEN_DOMAIN,
935 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
939 if (!W_ERROR_IS_OK(werr)) {
943 init_lsa_String(&lsa_group_name, r->in.group_name);
945 status = rpccli_samr_LookupNames(pipe_cli, ctx,
951 if (!NT_STATUS_IS_OK(status)) {
952 werr = WERR_GROUP_NOT_FOUND;
956 if (types.ids[0] != SID_NAME_DOM_GRP) {
957 werr = WERR_GROUP_NOT_FOUND;
961 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
963 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
966 if (!NT_STATUS_IS_OK(status)) {
967 werr = ntstatus_to_werror(status);
971 init_lsa_String(&lsa_user_name, r->in.user_name);
973 status = rpccli_samr_LookupNames(pipe_cli, ctx,
979 if (!NT_STATUS_IS_OK(status)) {
980 werr = WERR_USER_NOT_FOUND;
984 if (types.ids[0] != SID_NAME_USER) {
985 werr = WERR_USER_NOT_FOUND;
989 status = rpccli_samr_DeleteGroupMember(pipe_cli, ctx,
992 if (!NT_STATUS_IS_OK(status)) {
993 werr = ntstatus_to_werror(status);
1004 if (is_valid_policy_hnd(&group_handle)) {
1005 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
1008 if (ctx->disable_policy_handle_cache) {
1009 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1010 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1016 /****************************************************************
1017 ****************************************************************/
1019 WERROR NetGroupDelUser_l(struct libnetapi_ctx *ctx,
1020 struct NetGroupDelUser *r)
1022 return NetGroupDelUser_r(ctx, r);
1025 /****************************************************************
1026 ****************************************************************/
1028 static WERROR convert_samr_disp_groups_to_GROUP_INFO_0_buffer(TALLOC_CTX *mem_ctx,
1029 struct samr_DispInfoFullGroups *groups,
1032 struct GROUP_INFO_0 *g0;
1035 g0 = TALLOC_ZERO_ARRAY(mem_ctx, struct GROUP_INFO_0, groups->count);
1036 W_ERROR_HAVE_NO_MEMORY(g0);
1038 for (i=0; i<groups->count; i++) {
1039 g0[i].grpi0_name = talloc_strdup(mem_ctx,
1040 groups->entries[i].account_name.string);
1041 W_ERROR_HAVE_NO_MEMORY(g0[i].grpi0_name);
1044 *buffer = (uint8_t *)talloc_memdup(mem_ctx, g0,
1045 sizeof(struct GROUP_INFO_0) * groups->count);
1046 W_ERROR_HAVE_NO_MEMORY(*buffer);
1051 /****************************************************************
1052 ****************************************************************/
1054 static WERROR convert_samr_disp_groups_to_GROUP_INFO_1_buffer(TALLOC_CTX *mem_ctx,
1055 struct samr_DispInfoFullGroups *groups,
1058 struct GROUP_INFO_1 *g1;
1061 g1 = TALLOC_ZERO_ARRAY(mem_ctx, struct GROUP_INFO_1, groups->count);
1062 W_ERROR_HAVE_NO_MEMORY(g1);
1064 for (i=0; i<groups->count; i++) {
1065 g1[i].grpi1_name = talloc_strdup(mem_ctx,
1066 groups->entries[i].account_name.string);
1067 g1[i].grpi1_comment = talloc_strdup(mem_ctx,
1068 groups->entries[i].description.string);
1069 W_ERROR_HAVE_NO_MEMORY(g1[i].grpi1_name);
1072 *buffer = (uint8_t *)talloc_memdup(mem_ctx, g1,
1073 sizeof(struct GROUP_INFO_1) * groups->count);
1074 W_ERROR_HAVE_NO_MEMORY(*buffer);
1079 /****************************************************************
1080 ****************************************************************/
1082 static WERROR convert_samr_disp_groups_to_GROUP_INFO_2_buffer(TALLOC_CTX *mem_ctx,
1083 struct samr_DispInfoFullGroups *groups,
1086 struct GROUP_INFO_2 *g2;
1089 g2 = TALLOC_ZERO_ARRAY(mem_ctx, struct GROUP_INFO_2, groups->count);
1090 W_ERROR_HAVE_NO_MEMORY(g2);
1092 for (i=0; i<groups->count; i++) {
1093 g2[i].grpi2_name = talloc_strdup(mem_ctx,
1094 groups->entries[i].account_name.string);
1095 g2[i].grpi2_comment = talloc_strdup(mem_ctx,
1096 groups->entries[i].description.string);
1097 g2[i].grpi2_group_id = groups->entries[i].rid;
1098 g2[i].grpi2_attributes = groups->entries[i].acct_flags;
1099 W_ERROR_HAVE_NO_MEMORY(g2[i].grpi2_name);
1102 *buffer = (uint8_t *)talloc_memdup(mem_ctx, g2,
1103 sizeof(struct GROUP_INFO_2) * groups->count);
1104 W_ERROR_HAVE_NO_MEMORY(*buffer);
1109 /****************************************************************
1110 ****************************************************************/
1112 static WERROR convert_samr_disp_groups_to_GROUP_INFO_3_buffer(TALLOC_CTX *mem_ctx,
1113 struct samr_DispInfoFullGroups *groups,
1114 const struct dom_sid *domain_sid,
1117 struct GROUP_INFO_3 *g3;
1120 g3 = TALLOC_ZERO_ARRAY(mem_ctx, struct GROUP_INFO_3, groups->count);
1121 W_ERROR_HAVE_NO_MEMORY(g3);
1123 for (i=0; i<groups->count; i++) {
1127 if (!sid_compose(&sid, domain_sid, groups->entries[i].rid)) {
1131 g3[i].grpi3_name = talloc_strdup(mem_ctx,
1132 groups->entries[i].account_name.string);
1133 g3[i].grpi3_comment = talloc_strdup(mem_ctx,
1134 groups->entries[i].description.string);
1135 g3[i].grpi3_group_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
1136 g3[i].grpi3_attributes = groups->entries[i].acct_flags;
1137 W_ERROR_HAVE_NO_MEMORY(g3[i].grpi3_name);
1140 *buffer = (uint8_t *)talloc_memdup(mem_ctx, g3,
1141 sizeof(struct GROUP_INFO_3) * groups->count);
1142 W_ERROR_HAVE_NO_MEMORY(*buffer);
1147 /****************************************************************
1148 ****************************************************************/
1150 static WERROR convert_samr_disp_groups_to_GROUP_INFO_buffer(TALLOC_CTX *mem_ctx,
1152 struct samr_DispInfoFullGroups *groups,
1153 const struct dom_sid *domain_sid,
1154 uint32_t *entries_read,
1158 *entries_read = groups->count;
1163 return convert_samr_disp_groups_to_GROUP_INFO_0_buffer(mem_ctx, groups, buffer);
1165 return convert_samr_disp_groups_to_GROUP_INFO_1_buffer(mem_ctx, groups, buffer);
1167 return convert_samr_disp_groups_to_GROUP_INFO_2_buffer(mem_ctx, groups, buffer);
1169 return convert_samr_disp_groups_to_GROUP_INFO_3_buffer(mem_ctx, groups, domain_sid, buffer);
1171 return WERR_UNKNOWN_LEVEL;
1175 /****************************************************************
1176 ****************************************************************/
1178 WERROR NetGroupEnum_r(struct libnetapi_ctx *ctx,
1179 struct NetGroupEnum *r)
1181 struct cli_state *cli = NULL;
1182 struct rpc_pipe_client *pipe_cli = NULL;
1183 struct policy_handle connect_handle;
1184 struct dom_sid2 *domain_sid = NULL;
1185 struct policy_handle domain_handle;
1186 union samr_DispInfo info;
1187 union samr_DomainInfo *domain_info = NULL;
1189 uint32_t total_size = 0;
1190 uint32_t returned_size = 0;
1192 NTSTATUS status = NT_STATUS_OK;
1193 WERROR werr, tmp_werr;
1195 ZERO_STRUCT(connect_handle);
1196 ZERO_STRUCT(domain_handle);
1198 switch (r->in.level) {
1205 return WERR_UNKNOWN_LEVEL;
1208 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1209 if (!W_ERROR_IS_OK(werr)) {
1213 werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli);
1214 if (!W_ERROR_IS_OK(werr)) {
1218 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1219 SAMR_ACCESS_ENUM_DOMAINS |
1220 SAMR_ACCESS_OPEN_DOMAIN,
1221 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1222 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1223 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1227 if (!W_ERROR_IS_OK(werr)) {
1231 status = rpccli_samr_QueryDomainInfo(pipe_cli, ctx,
1235 if (!NT_STATUS_IS_OK(status)) {
1236 werr = ntstatus_to_werror(status);
1240 if (r->out.total_entries) {
1241 *r->out.total_entries = domain_info->info2.num_groups;
1244 status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
1248 r->in.resume_handle ?
1249 *r->in.resume_handle : 0,
1255 werr = ntstatus_to_werror(status);
1256 if (NT_STATUS_IS_ERR(status)) {
1260 if (r->out.resume_handle) {
1261 *r->out.resume_handle =
1262 info.info3.entries[info.info3.count-1].idx;
1265 tmp_werr = convert_samr_disp_groups_to_GROUP_INFO_buffer(ctx,
1269 r->out.entries_read,
1271 if (!W_ERROR_IS_OK(tmp_werr)) {
1282 if (NT_STATUS_IS_OK(status) ||
1283 NT_STATUS_IS_ERR(status)) {
1285 if (ctx->disable_policy_handle_cache) {
1286 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1287 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1294 /****************************************************************
1295 ****************************************************************/
1297 WERROR NetGroupEnum_l(struct libnetapi_ctx *ctx,
1298 struct NetGroupEnum *r)
1300 return NetGroupEnum_r(ctx, r);