summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/winbindd/winbindd_group.c72
-rw-r--r--source3/winbindd/winbindd_proto.h3
2 files changed, 75 insertions, 0 deletions
diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c
index 63105dea1a..2893f571f4 100644
--- a/source3/winbindd/winbindd_group.c
+++ b/source3/winbindd/winbindd_group.c
@@ -1771,4 +1771,76 @@ enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain,
return WINBINDD_OK;
}
+struct getgr_countmem {
+ int num;
+ size_t len;
+};
+
+static int getgr_calc_memberlen(DATA_BLOB key, void *data, void *priv)
+{
+ struct wbint_GroupMember *m = talloc_get_type_abort(
+ data, struct wbint_GroupMember);
+ struct getgr_countmem *buf = (struct getgr_countmem *)priv;
+ buf->num += 1;
+ buf->len += strlen(m->name) + 1;
+ return 0;
+}
+
+struct getgr_stringmem {
+ size_t ofs;
+ char *buf;
+};
+
+static int getgr_unparse_members(DATA_BLOB key, void *data, void *priv)
+{
+ struct wbint_GroupMember *m = talloc_get_type_abort(
+ data, struct wbint_GroupMember);
+ struct getgr_stringmem *buf = (struct getgr_stringmem *)priv;
+ int len;
+
+ len = strlen(m->name);
+
+ memcpy(buf->buf + buf->ofs, m->name, len);
+ buf->ofs += len;
+ buf->buf[buf->ofs] = ',';
+ buf->ofs += 1;
+ return 0;
+}
+
+NTSTATUS winbindd_print_groupmembers(struct talloc_dict *members,
+ TALLOC_CTX *mem_ctx,
+ int *num_members, char **result)
+{
+ struct getgr_countmem c;
+ struct getgr_stringmem m;
+ int res;
+
+ c.num = 0;
+ c.len = 0;
+
+ res = talloc_dict_traverse(members, getgr_calc_memberlen, &c);
+ if (res != 0) {
+ DEBUG(5, ("talloc_dict_traverse failed\n"));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ m.ofs = 0;
+ m.buf = talloc_array(mem_ctx, char, c.len);
+ if (m.buf == NULL) {
+ DEBUG(5, ("talloc failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ res = talloc_dict_traverse(members, getgr_unparse_members, &m);
+ if (res != 0) {
+ DEBUG(5, ("talloc_dict_traverse failed\n"));
+ TALLOC_FREE(m.buf);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ m.buf[c.len-1] = '\0';
+
+ *num_members = c.num;
+ *result = m.buf;
+ return NT_STATUS_OK;
+}
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 0ca37a6df1..6bb3406f78 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -380,6 +380,9 @@ enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *doma
bool get_sam_group_entries(struct getent_state *ent);
bool fill_grent(TALLOC_CTX *mem_ctx, struct winbindd_gr *gr,
const char *dom_name, const char *gr_name, gid_t unix_gid);
+NTSTATUS winbindd_print_groupmembers(struct talloc_dict *members,
+ TALLOC_CTX *mem_ctx,
+ int *num_members, char **result);
/* The following definitions come from winbindd/winbindd_idmap.c */