2 * Unix SMB/CIFS implementation.
4 * Copyright (C) Guenther Deschner 2008
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "librpc/gen_ndr/libnetapi.h"
23 #include "lib/netapi/netapi.h"
24 #include "lib/netapi/netapi_private.h"
25 #include "lib/netapi/libnetapi.h"
26 #include "rpc_client/rpc_client.h"
27 #include "../librpc/gen_ndr/ndr_samr_c.h"
28 #include "rpc_client/init_lsa.h"
29 #include "../libcli/security/security.h"
31 /****************************************************************
32 ****************************************************************/
34 WERROR NetGroupAdd_r(struct libnetapi_ctx *ctx,
35 struct NetGroupAdd *r)
37 struct rpc_pipe_client *pipe_cli = NULL;
38 NTSTATUS status, result;
40 struct policy_handle connect_handle, domain_handle, group_handle;
41 struct lsa_String lsa_group_name;
42 struct dom_sid2 *domain_sid = NULL;
44 struct dcerpc_binding_handle *b = NULL;
46 struct GROUP_INFO_0 *info0 = NULL;
47 struct GROUP_INFO_1 *info1 = NULL;
48 struct GROUP_INFO_2 *info2 = NULL;
49 struct GROUP_INFO_3 *info3 = NULL;
50 union samr_GroupInfo info;
52 ZERO_STRUCT(connect_handle);
53 ZERO_STRUCT(domain_handle);
54 ZERO_STRUCT(group_handle);
57 return WERR_INVALID_PARAMETER;
60 switch (r->in.level) {
62 info0 = (struct GROUP_INFO_0 *)r->in.buffer;
65 info1 = (struct GROUP_INFO_1 *)r->in.buffer;
68 info2 = (struct GROUP_INFO_2 *)r->in.buffer;
71 info3 = (struct GROUP_INFO_3 *)r->in.buffer;
74 werr = WERR_UNKNOWN_LEVEL;
78 werr = libnetapi_open_pipe(ctx, r->in.server_name,
81 if (!W_ERROR_IS_OK(werr)) {
85 b = pipe_cli->binding_handle;
87 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
88 SAMR_ACCESS_ENUM_DOMAINS |
89 SAMR_ACCESS_LOOKUP_DOMAIN,
90 SAMR_DOMAIN_ACCESS_CREATE_GROUP |
91 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
95 if (!W_ERROR_IS_OK(werr)) {
99 switch (r->in.level) {
101 init_lsa_String(&lsa_group_name, info0->grpi0_name);
104 init_lsa_String(&lsa_group_name, info1->grpi1_name);
107 init_lsa_String(&lsa_group_name, info2->grpi2_name);
110 init_lsa_String(&lsa_group_name, info3->grpi3_name);
114 status = dcerpc_samr_CreateDomainGroup(b, talloc_tos(),
118 SAMR_GROUP_ACCESS_SET_INFO,
123 if (!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_PARAMETER;
274 werr = libnetapi_open_pipe(ctx, r->in.server_name,
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 (rids.count != 1) {
313 werr = WERR_BAD_NET_RESP;
316 if (types.count != 1) {
317 werr = WERR_BAD_NET_RESP;
321 if (types.ids[0] != SID_NAME_DOM_GRP) {
322 werr = WERR_INVALID_DATATYPE;
326 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
329 SAMR_GROUP_ACCESS_GET_MEMBERS |
330 SAMR_GROUP_ACCESS_REMOVE_MEMBER |
331 SAMR_GROUP_ACCESS_ADD_MEMBER |
332 SAMR_GROUP_ACCESS_LOOKUP_INFO,
336 if (!NT_STATUS_IS_OK(status)) {
337 werr = ntstatus_to_werror(status);
340 if (!NT_STATUS_IS_OK(result)) {
341 werr = ntstatus_to_werror(result);
345 status = dcerpc_samr_QueryGroupInfo(b, talloc_tos(),
350 if (!NT_STATUS_IS_OK(status)) {
351 werr = ntstatus_to_werror(status);
354 if (!NT_STATUS_IS_OK(result)) {
355 werr = ntstatus_to_werror(result);
360 /* breaks against NT4 */
361 if (!(info->attributes.attributes & SE_GROUP_ENABLED)) {
362 werr = WERR_ACCESS_DENIED;
366 status = dcerpc_samr_QueryGroupMember(b, talloc_tos(),
370 if (!NT_STATUS_IS_OK(status)) {
371 werr = ntstatus_to_werror(status);
374 if (!NT_STATUS_IS_OK(result)) {
375 werr = ntstatus_to_werror(result);
380 struct lsa_Strings names;
381 struct samr_Ids member_types;
383 status = dcerpc_samr_LookupRids(b, talloc_tos(),
390 if (!NT_STATUS_IS_OK(status)) {
391 werr = ntstatus_to_werror(status);
394 if (!NT_STATUS_IS_OK(result)) {
395 werr = ntstatus_to_werror(result);
398 if (names.count != rid_array->count) {
399 werr = WERR_BAD_NET_RESP;
402 if (member_types.count != rid_array->count) {
403 werr = WERR_BAD_NET_RESP;
408 for (i=0; i < rid_array->count; i++) {
410 status = dcerpc_samr_DeleteGroupMember(b, talloc_tos(),
414 if (!NT_STATUS_IS_OK(status)) {
415 werr = ntstatus_to_werror(status);
418 if (!NT_STATUS_IS_OK(result)) {
419 werr = ntstatus_to_werror(result);
424 status = dcerpc_samr_DeleteDomainGroup(b, talloc_tos(),
427 if (!NT_STATUS_IS_OK(status)) {
428 werr = ntstatus_to_werror(status);
431 if (!NT_STATUS_IS_OK(result)) {
432 werr = ntstatus_to_werror(result);
436 ZERO_STRUCT(group_handle);
441 if (is_valid_policy_hnd(&group_handle)) {
442 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
445 if (ctx->disable_policy_handle_cache) {
446 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
447 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
453 /****************************************************************
454 ****************************************************************/
456 WERROR NetGroupDel_l(struct libnetapi_ctx *ctx,
457 struct NetGroupDel *r)
459 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupDel);
462 /****************************************************************
463 ****************************************************************/
465 WERROR NetGroupSetInfo_r(struct libnetapi_ctx *ctx,
466 struct NetGroupSetInfo *r)
468 struct rpc_pipe_client *pipe_cli = NULL;
469 NTSTATUS status, result;
471 struct policy_handle connect_handle, domain_handle, group_handle;
472 struct lsa_String lsa_group_name;
473 struct dom_sid2 *domain_sid = NULL;
474 struct dcerpc_binding_handle *b = NULL;
476 struct samr_Ids rids;
477 struct samr_Ids types;
478 union samr_GroupInfo info;
479 struct GROUP_INFO_0 *g0;
480 struct GROUP_INFO_1 *g1;
481 struct GROUP_INFO_2 *g2;
482 struct GROUP_INFO_3 *g3;
483 struct GROUP_INFO_1002 *g1002;
484 struct GROUP_INFO_1005 *g1005;
486 ZERO_STRUCT(connect_handle);
487 ZERO_STRUCT(domain_handle);
488 ZERO_STRUCT(group_handle);
490 if (!r->in.group_name) {
491 return WERR_INVALID_PARAMETER;
494 werr = libnetapi_open_pipe(ctx, r->in.server_name,
497 if (!W_ERROR_IS_OK(werr)) {
501 b = pipe_cli->binding_handle;
503 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
504 SAMR_ACCESS_ENUM_DOMAINS |
505 SAMR_ACCESS_LOOKUP_DOMAIN,
506 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
510 if (!W_ERROR_IS_OK(werr)) {
514 init_lsa_String(&lsa_group_name, r->in.group_name);
516 status = dcerpc_samr_LookupNames(b, talloc_tos(),
523 if (!NT_STATUS_IS_OK(status)) {
524 werr = ntstatus_to_werror(status);
527 if (!NT_STATUS_IS_OK(result)) {
528 werr = ntstatus_to_werror(result);
531 if (rids.count != 1) {
532 werr = WERR_BAD_NET_RESP;
535 if (types.count != 1) {
536 werr = WERR_BAD_NET_RESP;
540 if (types.ids[0] != SID_NAME_DOM_GRP) {
541 werr = WERR_INVALID_DATATYPE;
545 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
547 SAMR_GROUP_ACCESS_SET_INFO |
548 SAMR_GROUP_ACCESS_LOOKUP_INFO,
552 if (!NT_STATUS_IS_OK(status)) {
553 werr = ntstatus_to_werror(status);
556 if (!NT_STATUS_IS_OK(result)) {
557 werr = ntstatus_to_werror(result);
561 switch (r->in.level) {
563 g0 = (struct GROUP_INFO_0 *)r->in.buffer;
564 init_lsa_String(&info.name, g0->grpi0_name);
565 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
572 g1 = (struct GROUP_INFO_1 *)r->in.buffer;
573 init_lsa_String(&info.description, g1->grpi1_comment);
574 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
576 GROUPINFODESCRIPTION,
581 g2 = (struct GROUP_INFO_2 *)r->in.buffer;
582 init_lsa_String(&info.description, g2->grpi2_comment);
583 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
585 GROUPINFODESCRIPTION,
588 if (!NT_STATUS_IS_OK(status)) {
589 werr = ntstatus_to_werror(status);
592 if (!NT_STATUS_IS_OK(result)) {
593 werr = ntstatus_to_werror(result);
597 info.attributes.attributes = g2->grpi2_attributes;
598 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
605 g3 = (struct GROUP_INFO_3 *)r->in.buffer;
606 init_lsa_String(&info.description, g3->grpi3_comment);
607 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
609 GROUPINFODESCRIPTION,
612 if (!NT_STATUS_IS_OK(status)) {
613 werr = ntstatus_to_werror(status);
616 if (!NT_STATUS_IS_OK(result)) {
617 werr = ntstatus_to_werror(result);
621 info.attributes.attributes = g3->grpi3_attributes;
622 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
629 g1002 = (struct GROUP_INFO_1002 *)r->in.buffer;
630 init_lsa_String(&info.description, g1002->grpi1002_comment);
631 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
633 GROUPINFODESCRIPTION,
638 g1005 = (struct GROUP_INFO_1005 *)r->in.buffer;
639 info.attributes.attributes = g1005->grpi1005_attributes;
640 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
647 status = NT_STATUS_INVALID_LEVEL;
651 if (!NT_STATUS_IS_OK(status)) {
652 werr = ntstatus_to_werror(status);
655 if (!NT_STATUS_IS_OK(result)) {
656 werr = ntstatus_to_werror(result);
663 if (is_valid_policy_hnd(&group_handle)) {
664 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
667 if (ctx->disable_policy_handle_cache) {
668 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
669 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
675 /****************************************************************
676 ****************************************************************/
678 WERROR NetGroupSetInfo_l(struct libnetapi_ctx *ctx,
679 struct NetGroupSetInfo *r)
681 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupSetInfo);
684 /****************************************************************
685 ****************************************************************/
687 static WERROR map_group_info_to_buffer(TALLOC_CTX *mem_ctx,
689 struct samr_GroupInfoAll *info,
690 struct dom_sid2 *domain_sid,
694 struct GROUP_INFO_0 info0;
695 struct GROUP_INFO_1 info1;
696 struct GROUP_INFO_2 info2;
697 struct GROUP_INFO_3 info3;
702 info0.grpi0_name = info->name.string;
704 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0, sizeof(info0));
708 info1.grpi1_name = info->name.string;
709 info1.grpi1_comment = info->description.string;
711 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1, sizeof(info1));
715 info2.grpi2_name = info->name.string;
716 info2.grpi2_comment = info->description.string;
717 info2.grpi2_group_id = rid;
718 info2.grpi2_attributes = info->attributes;
720 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2, sizeof(info2));
724 if (!sid_compose(&sid, domain_sid, rid)) {
725 return WERR_NOT_ENOUGH_MEMORY;
728 info3.grpi3_name = info->name.string;
729 info3.grpi3_comment = info->description.string;
730 info3.grpi3_attributes = info->attributes;
731 info3.grpi3_group_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
733 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3, sizeof(info3));
737 return WERR_UNKNOWN_LEVEL;
740 W_ERROR_HAVE_NO_MEMORY(*buffer);
745 /****************************************************************
746 ****************************************************************/
748 WERROR NetGroupGetInfo_r(struct libnetapi_ctx *ctx,
749 struct NetGroupGetInfo *r)
751 struct rpc_pipe_client *pipe_cli = NULL;
752 NTSTATUS status, result;
754 struct policy_handle connect_handle, domain_handle, group_handle;
755 struct lsa_String lsa_group_name;
756 struct dom_sid2 *domain_sid = NULL;
757 struct dcerpc_binding_handle *b = NULL;
759 struct samr_Ids rids;
760 struct samr_Ids types;
761 union samr_GroupInfo *info = NULL;
762 bool group_info_all = false;
764 ZERO_STRUCT(connect_handle);
765 ZERO_STRUCT(domain_handle);
766 ZERO_STRUCT(group_handle);
768 if (!r->in.group_name) {
769 return WERR_INVALID_PARAMETER;
772 werr = libnetapi_open_pipe(ctx, r->in.server_name,
775 if (!W_ERROR_IS_OK(werr)) {
779 b = pipe_cli->binding_handle;
781 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
782 SAMR_ACCESS_ENUM_DOMAINS |
783 SAMR_ACCESS_LOOKUP_DOMAIN,
784 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
788 if (!W_ERROR_IS_OK(werr)) {
792 init_lsa_String(&lsa_group_name, r->in.group_name);
794 status = dcerpc_samr_LookupNames(b, talloc_tos(),
801 if (!NT_STATUS_IS_OK(status)) {
802 werr = ntstatus_to_werror(status);
805 if (!NT_STATUS_IS_OK(result)) {
806 werr = ntstatus_to_werror(result);
809 if (rids.count != 1) {
810 werr = WERR_BAD_NET_RESP;
813 if (types.count != 1) {
814 werr = WERR_BAD_NET_RESP;
818 if (types.ids[0] != SID_NAME_DOM_GRP) {
819 werr = WERR_INVALID_DATATYPE;
823 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
825 SAMR_GROUP_ACCESS_LOOKUP_INFO,
829 if (!NT_STATUS_IS_OK(status)) {
830 werr = ntstatus_to_werror(status);
833 if (!NT_STATUS_IS_OK(result)) {
834 werr = ntstatus_to_werror(result);
838 status = dcerpc_samr_QueryGroupInfo(b, talloc_tos(),
843 if (!NT_STATUS_IS_OK(status)) {
844 werr = ntstatus_to_werror(status);
848 if (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_INFO_CLASS)) {
849 status = dcerpc_samr_QueryGroupInfo(b, talloc_tos(),
854 group_info_all = true;
855 if (!NT_STATUS_IS_OK(status)) {
856 werr = ntstatus_to_werror(status);
861 if (!NT_STATUS_IS_OK(result)) {
862 werr = ntstatus_to_werror(result);
866 werr = map_group_info_to_buffer(ctx, r->in.level,
867 group_info_all ? &info->all : &info->all2,
868 domain_sid, rids.ids[0],
870 if (!W_ERROR_IS_OK(werr)) {
874 if (is_valid_policy_hnd(&group_handle)) {
875 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
878 if (ctx->disable_policy_handle_cache) {
879 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
880 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
886 /****************************************************************
887 ****************************************************************/
889 WERROR NetGroupGetInfo_l(struct libnetapi_ctx *ctx,
890 struct NetGroupGetInfo *r)
892 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupGetInfo);
895 /****************************************************************
896 ****************************************************************/
898 WERROR NetGroupAddUser_r(struct libnetapi_ctx *ctx,
899 struct NetGroupAddUser *r)
901 struct rpc_pipe_client *pipe_cli = NULL;
902 NTSTATUS status, result;
904 struct policy_handle connect_handle, domain_handle, group_handle;
905 struct lsa_String lsa_group_name, lsa_user_name;
906 struct dom_sid2 *domain_sid = NULL;
907 struct dcerpc_binding_handle *b = NULL;
909 struct samr_Ids rids;
910 struct samr_Ids types;
912 ZERO_STRUCT(connect_handle);
913 ZERO_STRUCT(domain_handle);
914 ZERO_STRUCT(group_handle);
916 if (!r->in.group_name) {
917 return WERR_INVALID_PARAMETER;
920 werr = libnetapi_open_pipe(ctx, r->in.server_name,
923 if (!W_ERROR_IS_OK(werr)) {
927 b = pipe_cli->binding_handle;
929 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
930 SAMR_ACCESS_ENUM_DOMAINS |
931 SAMR_ACCESS_LOOKUP_DOMAIN,
932 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
936 if (!W_ERROR_IS_OK(werr)) {
940 init_lsa_String(&lsa_group_name, r->in.group_name);
942 status = dcerpc_samr_LookupNames(b, talloc_tos(),
949 if (!NT_STATUS_IS_OK(status)) {
950 werr = ntstatus_to_werror(status);
953 if (!NT_STATUS_IS_OK(result)) {
954 werr = WERR_NERR_GROUPNOTFOUND;
957 if (rids.count != 1) {
958 werr = WERR_BAD_NET_RESP;
961 if (types.count != 1) {
962 werr = WERR_BAD_NET_RESP;
966 if (types.ids[0] != SID_NAME_DOM_GRP) {
967 werr = WERR_NERR_GROUPNOTFOUND;
971 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
973 SAMR_GROUP_ACCESS_ADD_MEMBER,
977 if (!NT_STATUS_IS_OK(status)) {
978 werr = ntstatus_to_werror(status);
981 if (!NT_STATUS_IS_OK(result)) {
982 werr = ntstatus_to_werror(result);
986 init_lsa_String(&lsa_user_name, r->in.user_name);
988 status = dcerpc_samr_LookupNames(b, talloc_tos(),
995 if (!NT_STATUS_IS_OK(status)) {
996 werr = ntstatus_to_werror(status);
999 if (!NT_STATUS_IS_OK(result)) {
1000 werr = WERR_USER_NOT_FOUND;
1003 if (rids.count != 1) {
1004 werr = WERR_BAD_NET_RESP;
1007 if (types.count != 1) {
1008 werr = WERR_BAD_NET_RESP;
1012 if (types.ids[0] != SID_NAME_USER) {
1013 werr = WERR_USER_NOT_FOUND;
1017 status = dcerpc_samr_AddGroupMember(b, talloc_tos(),
1022 if (!NT_STATUS_IS_OK(status)) {
1023 werr = ntstatus_to_werror(status);
1026 if (!NT_STATUS_IS_OK(result)) {
1027 werr = ntstatus_to_werror(result);
1034 if (is_valid_policy_hnd(&group_handle)) {
1035 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
1038 if (ctx->disable_policy_handle_cache) {
1039 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1040 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1046 /****************************************************************
1047 ****************************************************************/
1049 WERROR NetGroupAddUser_l(struct libnetapi_ctx *ctx,
1050 struct NetGroupAddUser *r)
1052 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupAddUser);
1055 /****************************************************************
1056 ****************************************************************/
1058 WERROR NetGroupDelUser_r(struct libnetapi_ctx *ctx,
1059 struct NetGroupDelUser *r)
1061 struct rpc_pipe_client *pipe_cli = NULL;
1062 NTSTATUS status, result;
1064 struct policy_handle connect_handle, domain_handle, group_handle;
1065 struct lsa_String lsa_group_name, lsa_user_name;
1066 struct dom_sid2 *domain_sid = NULL;
1067 struct dcerpc_binding_handle *b = NULL;
1069 struct samr_Ids rids;
1070 struct samr_Ids types;
1072 ZERO_STRUCT(connect_handle);
1073 ZERO_STRUCT(domain_handle);
1074 ZERO_STRUCT(group_handle);
1076 if (!r->in.group_name) {
1077 return WERR_INVALID_PARAMETER;
1080 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1083 if (!W_ERROR_IS_OK(werr)) {
1087 b = pipe_cli->binding_handle;
1089 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1090 SAMR_ACCESS_ENUM_DOMAINS |
1091 SAMR_ACCESS_LOOKUP_DOMAIN,
1092 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1096 if (!W_ERROR_IS_OK(werr)) {
1100 init_lsa_String(&lsa_group_name, r->in.group_name);
1102 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1109 if (!NT_STATUS_IS_OK(status)) {
1110 werr = ntstatus_to_werror(status);
1113 if (!NT_STATUS_IS_OK(result)) {
1114 werr = WERR_NERR_GROUPNOTFOUND;
1117 if (rids.count != 1) {
1118 werr = WERR_BAD_NET_RESP;
1121 if (types.count != 1) {
1122 werr = WERR_BAD_NET_RESP;
1126 if (types.ids[0] != SID_NAME_DOM_GRP) {
1127 werr = WERR_NERR_GROUPNOTFOUND;
1131 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
1133 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
1137 if (!NT_STATUS_IS_OK(status)) {
1138 werr = ntstatus_to_werror(status);
1141 if (!NT_STATUS_IS_OK(result)) {
1142 werr = ntstatus_to_werror(result);
1146 init_lsa_String(&lsa_user_name, r->in.user_name);
1148 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1155 if (!NT_STATUS_IS_OK(status)) {
1156 werr = ntstatus_to_werror(status);
1160 if (!NT_STATUS_IS_OK(result)) {
1161 werr = WERR_USER_NOT_FOUND;
1164 if (rids.count != 1) {
1165 werr = WERR_BAD_NET_RESP;
1168 if (types.count != 1) {
1169 werr = WERR_BAD_NET_RESP;
1173 if (types.ids[0] != SID_NAME_USER) {
1174 werr = WERR_USER_NOT_FOUND;
1178 status = dcerpc_samr_DeleteGroupMember(b, talloc_tos(),
1182 if (!NT_STATUS_IS_OK(status)) {
1183 werr = ntstatus_to_werror(status);
1186 if (!NT_STATUS_IS_OK(result)) {
1187 werr = ntstatus_to_werror(result);
1194 if (is_valid_policy_hnd(&group_handle)) {
1195 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
1198 if (ctx->disable_policy_handle_cache) {
1199 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1200 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1206 /****************************************************************
1207 ****************************************************************/
1209 WERROR NetGroupDelUser_l(struct libnetapi_ctx *ctx,
1210 struct NetGroupDelUser *r)
1212 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupDelUser);
1215 /****************************************************************
1216 ****************************************************************/
1218 static WERROR convert_samr_disp_groups_to_GROUP_INFO_0_buffer(TALLOC_CTX *mem_ctx,
1219 struct samr_DispInfoFullGroups *groups,
1222 struct GROUP_INFO_0 *g0;
1225 g0 = talloc_zero_array(mem_ctx, struct GROUP_INFO_0, groups->count);
1226 W_ERROR_HAVE_NO_MEMORY(g0);
1228 for (i=0; i<groups->count; i++) {
1229 g0[i].grpi0_name = talloc_strdup(mem_ctx,
1230 groups->entries[i].account_name.string);
1231 W_ERROR_HAVE_NO_MEMORY(g0[i].grpi0_name);
1234 *buffer = (uint8_t *)talloc_memdup(mem_ctx, g0,
1235 sizeof(struct GROUP_INFO_0) * groups->count);
1236 W_ERROR_HAVE_NO_MEMORY(*buffer);
1241 /****************************************************************
1242 ****************************************************************/
1244 static WERROR convert_samr_disp_groups_to_GROUP_INFO_1_buffer(TALLOC_CTX *mem_ctx,
1245 struct samr_DispInfoFullGroups *groups,
1248 struct GROUP_INFO_1 *g1;
1251 g1 = talloc_zero_array(mem_ctx, struct GROUP_INFO_1, groups->count);
1252 W_ERROR_HAVE_NO_MEMORY(g1);
1254 for (i=0; i<groups->count; i++) {
1255 g1[i].grpi1_name = talloc_strdup(mem_ctx,
1256 groups->entries[i].account_name.string);
1257 g1[i].grpi1_comment = talloc_strdup(mem_ctx,
1258 groups->entries[i].description.string);
1259 W_ERROR_HAVE_NO_MEMORY(g1[i].grpi1_name);
1262 *buffer = (uint8_t *)talloc_memdup(mem_ctx, g1,
1263 sizeof(struct GROUP_INFO_1) * groups->count);
1264 W_ERROR_HAVE_NO_MEMORY(*buffer);
1269 /****************************************************************
1270 ****************************************************************/
1272 static WERROR convert_samr_disp_groups_to_GROUP_INFO_2_buffer(TALLOC_CTX *mem_ctx,
1273 struct samr_DispInfoFullGroups *groups,
1276 struct GROUP_INFO_2 *g2;
1279 g2 = talloc_zero_array(mem_ctx, struct GROUP_INFO_2, groups->count);
1280 W_ERROR_HAVE_NO_MEMORY(g2);
1282 for (i=0; i<groups->count; i++) {
1283 g2[i].grpi2_name = talloc_strdup(mem_ctx,
1284 groups->entries[i].account_name.string);
1285 g2[i].grpi2_comment = talloc_strdup(mem_ctx,
1286 groups->entries[i].description.string);
1287 g2[i].grpi2_group_id = groups->entries[i].rid;
1288 g2[i].grpi2_attributes = groups->entries[i].acct_flags;
1289 W_ERROR_HAVE_NO_MEMORY(g2[i].grpi2_name);
1292 *buffer = (uint8_t *)talloc_memdup(mem_ctx, g2,
1293 sizeof(struct GROUP_INFO_2) * groups->count);
1294 W_ERROR_HAVE_NO_MEMORY(*buffer);
1299 /****************************************************************
1300 ****************************************************************/
1302 static WERROR convert_samr_disp_groups_to_GROUP_INFO_3_buffer(TALLOC_CTX *mem_ctx,
1303 struct samr_DispInfoFullGroups *groups,
1304 const struct dom_sid *domain_sid,
1307 struct GROUP_INFO_3 *g3;
1310 g3 = talloc_zero_array(mem_ctx, struct GROUP_INFO_3, groups->count);
1311 W_ERROR_HAVE_NO_MEMORY(g3);
1313 for (i=0; i<groups->count; i++) {
1317 if (!sid_compose(&sid, domain_sid, groups->entries[i].rid)) {
1318 return WERR_NOT_ENOUGH_MEMORY;
1321 g3[i].grpi3_name = talloc_strdup(mem_ctx,
1322 groups->entries[i].account_name.string);
1323 g3[i].grpi3_comment = talloc_strdup(mem_ctx,
1324 groups->entries[i].description.string);
1325 g3[i].grpi3_group_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
1326 g3[i].grpi3_attributes = groups->entries[i].acct_flags;
1327 W_ERROR_HAVE_NO_MEMORY(g3[i].grpi3_name);
1330 *buffer = (uint8_t *)talloc_memdup(mem_ctx, g3,
1331 sizeof(struct GROUP_INFO_3) * groups->count);
1332 W_ERROR_HAVE_NO_MEMORY(*buffer);
1337 /****************************************************************
1338 ****************************************************************/
1340 static WERROR convert_samr_disp_groups_to_GROUP_INFO_buffer(TALLOC_CTX *mem_ctx,
1342 struct samr_DispInfoFullGroups *groups,
1343 const struct dom_sid *domain_sid,
1344 uint32_t *entries_read,
1348 *entries_read = groups->count;
1353 return convert_samr_disp_groups_to_GROUP_INFO_0_buffer(mem_ctx, groups, buffer);
1355 return convert_samr_disp_groups_to_GROUP_INFO_1_buffer(mem_ctx, groups, buffer);
1357 return convert_samr_disp_groups_to_GROUP_INFO_2_buffer(mem_ctx, groups, buffer);
1359 return convert_samr_disp_groups_to_GROUP_INFO_3_buffer(mem_ctx, groups, domain_sid, buffer);
1361 return WERR_UNKNOWN_LEVEL;
1365 /****************************************************************
1366 ****************************************************************/
1368 WERROR NetGroupEnum_r(struct libnetapi_ctx *ctx,
1369 struct NetGroupEnum *r)
1371 struct rpc_pipe_client *pipe_cli = NULL;
1372 struct policy_handle connect_handle;
1373 struct dom_sid2 *domain_sid = NULL;
1374 struct policy_handle domain_handle;
1375 union samr_DispInfo info;
1376 union samr_DomainInfo *domain_info = NULL;
1377 struct dcerpc_binding_handle *b = NULL;
1379 uint32_t total_size = 0;
1380 uint32_t returned_size = 0;
1382 NTSTATUS result = NT_STATUS_OK;
1383 NTSTATUS status = NT_STATUS_OK;
1384 WERROR werr, tmp_werr;
1386 ZERO_STRUCT(connect_handle);
1387 ZERO_STRUCT(domain_handle);
1389 switch (r->in.level) {
1396 return WERR_UNKNOWN_LEVEL;
1399 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1402 if (!W_ERROR_IS_OK(werr)) {
1406 b = pipe_cli->binding_handle;
1408 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1409 SAMR_ACCESS_ENUM_DOMAINS |
1410 SAMR_ACCESS_LOOKUP_DOMAIN,
1411 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1412 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1413 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1417 if (!W_ERROR_IS_OK(werr)) {
1421 status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(),
1426 if (!NT_STATUS_IS_OK(status)) {
1427 werr = ntstatus_to_werror(status);
1430 if (!NT_STATUS_IS_OK(result)) {
1431 werr = ntstatus_to_werror(result);
1435 if (r->out.total_entries) {
1436 *r->out.total_entries = domain_info->general.num_groups;
1439 status = dcerpc_samr_QueryDisplayInfo2(b,
1443 r->in.resume_handle ?
1444 *r->in.resume_handle : 0,
1451 if (!NT_STATUS_IS_OK(status)) {
1452 werr = ntstatus_to_werror(status);
1456 werr = ntstatus_to_werror(result);
1457 if (NT_STATUS_IS_ERR(result)) {
1461 if (r->out.resume_handle && info.info3.count > 0) {
1462 *r->out.resume_handle =
1463 info.info3.entries[info.info3.count-1].idx;
1466 tmp_werr = convert_samr_disp_groups_to_GROUP_INFO_buffer(ctx,
1470 r->out.entries_read,
1472 if (!W_ERROR_IS_OK(tmp_werr)) {
1479 if (NT_STATUS_IS_OK(result) ||
1480 NT_STATUS_IS_ERR(result)) {
1482 if (ctx->disable_policy_handle_cache) {
1483 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1484 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1491 /****************************************************************
1492 ****************************************************************/
1494 WERROR NetGroupEnum_l(struct libnetapi_ctx *ctx,
1495 struct NetGroupEnum *r)
1497 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupEnum);
1500 /****************************************************************
1501 ****************************************************************/
1503 WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx,
1504 struct NetGroupGetUsers *r)
1506 /* FIXME: this call needs to cope with large replies */
1508 struct rpc_pipe_client *pipe_cli = NULL;
1509 struct policy_handle connect_handle, domain_handle, group_handle;
1510 struct lsa_String lsa_account_name;
1511 struct dom_sid2 *domain_sid = NULL;
1512 struct samr_Ids group_rids, name_types;
1513 struct samr_RidAttrArray *rid_array = NULL;
1514 struct lsa_Strings names;
1515 struct samr_Ids member_types;
1516 struct dcerpc_binding_handle *b = NULL;
1519 uint32_t entries_read = 0;
1521 NTSTATUS status = NT_STATUS_OK;
1522 NTSTATUS result = NT_STATUS_OK;
1525 ZERO_STRUCT(connect_handle);
1526 ZERO_STRUCT(domain_handle);
1527 ZERO_STRUCT(group_handle);
1529 if (!r->out.buffer) {
1530 return WERR_INVALID_PARAMETER;
1533 *r->out.buffer = NULL;
1534 *r->out.entries_read = 0;
1535 *r->out.total_entries = 0;
1537 switch (r->in.level) {
1542 return WERR_UNKNOWN_LEVEL;
1546 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1549 if (!W_ERROR_IS_OK(werr)) {
1553 b = pipe_cli->binding_handle;
1555 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1556 SAMR_ACCESS_ENUM_DOMAINS |
1557 SAMR_ACCESS_LOOKUP_DOMAIN,
1558 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1562 if (!W_ERROR_IS_OK(werr)) {
1566 init_lsa_String(&lsa_account_name, r->in.group_name);
1568 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1575 if (!NT_STATUS_IS_OK(status)) {
1576 werr = ntstatus_to_werror(status);
1579 if (!NT_STATUS_IS_OK(result)) {
1580 werr = ntstatus_to_werror(result);
1583 if (group_rids.count != 1) {
1584 werr = WERR_BAD_NET_RESP;
1587 if (name_types.count != 1) {
1588 werr = WERR_BAD_NET_RESP;
1592 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
1594 SAMR_GROUP_ACCESS_GET_MEMBERS,
1598 if (!NT_STATUS_IS_OK(status)) {
1599 werr = ntstatus_to_werror(status);
1602 if (!NT_STATUS_IS_OK(result)) {
1603 werr = ntstatus_to_werror(result);
1607 status = dcerpc_samr_QueryGroupMember(b, talloc_tos(),
1611 if (!NT_STATUS_IS_OK(status)) {
1612 werr = ntstatus_to_werror(status);
1615 if (!NT_STATUS_IS_OK(result)) {
1616 werr = ntstatus_to_werror(result);
1620 status = dcerpc_samr_LookupRids(b, talloc_tos(),
1627 if (!NT_STATUS_IS_OK(status)) {
1628 werr = ntstatus_to_werror(status);
1631 if (!NT_STATUS_IS_OK(result)) {
1632 werr = ntstatus_to_werror(result);
1635 if (names.count != rid_array->count) {
1636 werr = WERR_BAD_NET_RESP;
1639 if (member_types.count != rid_array->count) {
1640 werr = WERR_BAD_NET_RESP;
1644 for (i=0; i < names.count; i++) {
1646 if (member_types.ids[i] != SID_NAME_USER) {
1650 status = add_GROUP_USERS_INFO_X_buffer(ctx,
1652 names.names[i].string,
1656 if (!NT_STATUS_IS_OK(status)) {
1657 werr = ntstatus_to_werror(status);
1662 *r->out.entries_read = entries_read;
1663 *r->out.total_entries = entries_read;
1668 if (is_valid_policy_hnd(&group_handle)) {
1669 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
1672 if (ctx->disable_policy_handle_cache) {
1673 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1674 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1680 /****************************************************************
1681 ****************************************************************/
1683 WERROR NetGroupGetUsers_l(struct libnetapi_ctx *ctx,
1684 struct NetGroupGetUsers *r)
1686 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupGetUsers);
1689 /****************************************************************
1690 ****************************************************************/
1692 WERROR NetGroupSetUsers_r(struct libnetapi_ctx *ctx,
1693 struct NetGroupSetUsers *r)
1695 struct rpc_pipe_client *pipe_cli = NULL;
1696 struct policy_handle connect_handle, domain_handle, group_handle;
1697 struct lsa_String lsa_account_name;
1698 struct dom_sid2 *domain_sid = NULL;
1699 union samr_GroupInfo *group_info = NULL;
1700 struct samr_Ids user_rids, name_types;
1701 struct samr_Ids group_rids, group_types;
1702 struct samr_RidAttrArray *rid_array = NULL;
1703 struct lsa_String *lsa_names = NULL;
1704 struct dcerpc_binding_handle *b = NULL;
1706 uint32_t *add_rids = NULL;
1707 uint32_t *del_rids = NULL;
1708 size_t num_add_rids = 0;
1709 size_t num_del_rids = 0;
1711 uint32_t *member_rids = NULL;
1713 struct GROUP_USERS_INFO_0 *i0 = NULL;
1714 struct GROUP_USERS_INFO_1 *i1 = NULL;
1718 NTSTATUS status = NT_STATUS_OK;
1719 NTSTATUS result = NT_STATUS_OK;
1722 ZERO_STRUCT(connect_handle);
1723 ZERO_STRUCT(domain_handle);
1724 ZERO_STRUCT(group_handle);
1726 if (!r->in.buffer) {
1727 return WERR_INVALID_PARAMETER;
1730 switch (r->in.level) {
1735 return WERR_UNKNOWN_LEVEL;
1738 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1741 if (!W_ERROR_IS_OK(werr)) {
1745 b = pipe_cli->binding_handle;
1747 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1748 SAMR_ACCESS_ENUM_DOMAINS |
1749 SAMR_ACCESS_LOOKUP_DOMAIN,
1750 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1754 if (!W_ERROR_IS_OK(werr)) {
1758 init_lsa_String(&lsa_account_name, r->in.group_name);
1760 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1767 if (!NT_STATUS_IS_OK(status)) {
1768 werr = ntstatus_to_werror(status);
1771 if (!NT_STATUS_IS_OK(result)) {
1772 werr = ntstatus_to_werror(result);
1775 if (group_rids.count != 1) {
1776 werr = WERR_BAD_NET_RESP;
1779 if (group_types.count != 1) {
1780 werr = WERR_BAD_NET_RESP;
1784 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
1786 SAMR_GROUP_ACCESS_GET_MEMBERS |
1787 SAMR_GROUP_ACCESS_ADD_MEMBER |
1788 SAMR_GROUP_ACCESS_REMOVE_MEMBER |
1789 SAMR_GROUP_ACCESS_LOOKUP_INFO,
1793 if (!NT_STATUS_IS_OK(status)) {
1794 werr = ntstatus_to_werror(status);
1797 if (!NT_STATUS_IS_OK(result)) {
1798 werr = ntstatus_to_werror(result);
1802 status = dcerpc_samr_QueryGroupInfo(b, talloc_tos(),
1804 GROUPINFOATTRIBUTES,
1807 if (!NT_STATUS_IS_OK(status)) {
1808 werr = ntstatus_to_werror(status);
1811 if (!NT_STATUS_IS_OK(result)) {
1812 werr = ntstatus_to_werror(result);
1816 switch (r->in.level) {
1818 i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
1821 i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
1825 lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
1827 werr = WERR_NOT_ENOUGH_MEMORY;
1831 for (i=0; i < r->in.num_entries; i++) {
1833 switch (r->in.level) {
1835 init_lsa_String(&lsa_names[i], i0->grui0_name);
1839 init_lsa_String(&lsa_names[i], i1->grui1_name);
1845 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1852 if (!NT_STATUS_IS_OK(status)) {
1853 werr = ntstatus_to_werror(status);
1856 if (!NT_STATUS_IS_OK(result)) {
1857 werr = ntstatus_to_werror(result);
1861 if (r->in.num_entries != user_rids.count) {
1862 werr = WERR_BAD_NET_RESP;
1865 if (r->in.num_entries != name_types.count) {
1866 werr = WERR_BAD_NET_RESP;
1870 member_rids = user_rids.ids;
1872 status = dcerpc_samr_QueryGroupMember(b, talloc_tos(),
1876 if (!NT_STATUS_IS_OK(status)) {
1877 werr = ntstatus_to_werror(status);
1880 if (!NT_STATUS_IS_OK(result)) {
1881 werr = ntstatus_to_werror(result);
1887 for (i=0; i < r->in.num_entries; i++) {
1888 bool already_member = false;
1889 for (k=0; k < rid_array->count; k++) {
1890 if (member_rids[i] == rid_array->rids[k]) {
1891 already_member = true;
1895 if (!already_member) {
1896 if (!add_rid_to_array_unique(ctx,
1898 &add_rids, &num_add_rids)) {
1899 werr = WERR_GEN_FAILURE;
1907 for (k=0; k < rid_array->count; k++) {
1908 bool keep_member = false;
1909 for (i=0; i < r->in.num_entries; i++) {
1910 if (member_rids[i] == rid_array->rids[k]) {
1916 if (!add_rid_to_array_unique(ctx,
1918 &del_rids, &num_del_rids)) {
1919 werr = WERR_GEN_FAILURE;
1927 for (i=0; i < num_add_rids; i++) {
1928 status = dcerpc_samr_AddGroupMember(b, talloc_tos(),
1933 if (!NT_STATUS_IS_OK(status)) {
1934 werr = ntstatus_to_werror(status);
1937 if (!NT_STATUS_IS_OK(result)) {
1938 werr = ntstatus_to_werror(result);
1945 for (i=0; i < num_del_rids; i++) {
1946 status = dcerpc_samr_DeleteGroupMember(b, talloc_tos(),
1950 if (!NT_STATUS_IS_OK(status)) {
1951 werr = ntstatus_to_werror(status);
1954 if (!NT_STATUS_IS_OK(result)) {
1955 werr = ntstatus_to_werror(result);
1963 if (is_valid_policy_hnd(&group_handle)) {
1964 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
1967 if (ctx->disable_policy_handle_cache) {
1968 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1969 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1975 /****************************************************************
1976 ****************************************************************/
1978 WERROR NetGroupSetUsers_l(struct libnetapi_ctx *ctx,
1979 struct NetGroupSetUsers *r)
1981 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupSetUsers);