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.buffer;
61 info1 = (struct GROUP_INFO_1 *)r->in.buffer;
64 info2 = (struct GROUP_INFO_2 *)r->in.buffer;
67 info3 = (struct GROUP_INFO_3 *)r->in.buffer;
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.buffer;
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.buffer;
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.buffer;
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.buffer;
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.buffer;
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.buffer;
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);