summaryrefslogtreecommitdiffstats
path: root/src/responder/ifp
diff options
context:
space:
mode:
Diffstat (limited to 'src/responder/ifp')
-rw-r--r--src/responder/ifp/ifp_groups.c521
-rw-r--r--src/responder/ifp/ifp_groups.h23
-rw-r--r--src/responder/ifp/ifp_iface.c10
-rw-r--r--src/responder/ifp/ifp_iface.xml11
-rw-r--r--src/responder/ifp/ifp_iface_generated.c68
-rw-r--r--src/responder/ifp/ifp_iface_generated.h24
-rw-r--r--src/responder/ifp/org.freedesktop.sssd.infopipe.conf1
7 files changed, 658 insertions, 0 deletions
diff --git a/src/responder/ifp/ifp_groups.c b/src/responder/ifp/ifp_groups.c
index e362002d3..f1f86ce1a 100644
--- a/src/responder/ifp/ifp_groups.c
+++ b/src/responder/ifp/ifp_groups.c
@@ -23,10 +23,12 @@
#include "util/util.h"
#include "db/sysdb.h"
+#include "util/strtonum.h"
#include "sbus/sssd_dbus_errors.h"
#include "responder/common/responder.h"
#include "responder/common/responder_cache_req.h"
#include "responder/ifp/ifp_groups.h"
+#include "responder/ifp/ifp_users.h"
char * ifp_groups_build_path_from_msg(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
@@ -43,6 +45,41 @@ char * ifp_groups_build_path_from_msg(TALLOC_CTX *mem_ctx,
return sbus_opath_compose(mem_ctx, IFP_PATH_GROUPS, domain->name, gid);
}
+static errno_t ifp_groups_decompose_path(struct sss_domain_info *domains,
+ const char *path,
+ struct sss_domain_info **_domain,
+ gid_t *_gid)
+{
+ char **parts = NULL;
+ struct sss_domain_info *domain;
+ gid_t gid;
+ errno_t ret;
+
+ ret = sbus_opath_decompose_exact(NULL, path, IFP_PATH_GROUPS, 2, &parts);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ domain = find_domain_by_name(domains, parts[0], false);
+ if (domain == NULL) {
+ ret = ERR_DOMAIN_NOT_FOUND;
+ goto done;
+ }
+
+ gid = strtouint32(parts[1], NULL, 10);
+ if (errno != 0) {
+ ret = errno;
+ goto done;
+ }
+
+ *_domain = domain;
+ *_gid = gid;
+
+done:
+ talloc_free(parts);
+ return ret;
+}
+
static void ifp_groups_find_by_name_done(struct tevent_req *req);
int ifp_groups_find_by_name(struct sbus_request *sbus_req,
@@ -199,3 +236,487 @@ int ifp_groups_list_by_domain_and_name(struct sbus_request *sbus_req,
{
return EOK;
}
+
+static errno_t
+ifp_groups_group_get(struct sbus_request *sbus_req,
+ void *data,
+ gid_t *_gid,
+ struct sss_domain_info **_domain,
+ struct ldb_message **_group)
+{
+ struct ifp_ctx *ctx;
+ struct sss_domain_info *domain;
+ struct ldb_result *res;
+ uid_t gid;
+ errno_t ret;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
+ return ERR_INTERNAL;
+ }
+
+ ret = ifp_groups_decompose_path(ctx->rctx->domains, sbus_req->path,
+ &domain, &gid);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to decompose object path"
+ "[%s] [%d]: %s\n", sbus_req->path, ret, sss_strerror(ret));
+ return ret;
+ }
+
+ if (_group != NULL) {
+ ret = sysdb_getgrgid_with_views(sbus_req, domain, gid, &res);
+ if (ret == EOK && res->count == 0) {
+ *_group = NULL;
+ ret = ENOENT;
+ }
+
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup group %u@%s [%d]: %s\n",
+ gid, domain->name, ret, sss_strerror(ret));
+ } else {
+ *_group = res->msgs[0];
+ }
+ }
+
+ if (ret == EOK || ret == ENOENT) {
+ if (_gid != NULL) {
+ *_gid = gid;
+ }
+
+ if (_domain != NULL) {
+ *_domain = domain;
+ }
+ }
+
+ return ret;
+}
+
+struct resolv_ghosts_state {
+ struct tevent_context *ev;
+ struct sbus_request *sbus_req;
+ struct ifp_ctx *ctx;
+ void *data;
+
+ struct sss_domain_info *domain;
+ const char **ghosts;
+ int index;
+};
+
+static void resolv_ghosts_group_done(struct tevent_req *subreq);
+static errno_t resolv_ghosts_step(struct tevent_req *req);
+static void resolv_ghosts_done(struct tevent_req *subreq);
+
+static struct tevent_req *resolv_ghosts_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sbus_request *sbus_req,
+ void *data)
+{
+ struct resolv_ghosts_state *state;
+ struct sss_domain_info *domain;
+ struct tevent_req *req;
+ struct tevent_req *subreq;
+ struct ldb_message *group;
+ struct ifp_ctx *ctx;
+ const char *name;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state, struct resolv_ghosts_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
+ return NULL;
+ }
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
+ ret = ERR_INTERNAL;
+ goto immediately;
+ }
+
+ state->ev = ev;
+ state->sbus_req = sbus_req;
+ state->ctx = ctx;
+ state->data = data;
+
+ ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group);
+ if (ret != EOK) {
+ goto immediately;
+ }
+
+ name = ldb_msg_find_attr_as_string(group, SYSDB_NAME, NULL);
+ if (name == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Group name is empty!\n");
+ ret = ERR_INTERNAL;
+ goto immediately;
+ }
+
+ subreq = cache_req_group_by_name_send(state, ev, ctx->rctx,
+ ctx->ncache, ctx->neg_timeout, 0,
+ domain->name, name);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ tevent_req_set_callback(subreq, resolv_ghosts_group_done, req);
+
+ return req;
+
+immediately:
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
+ tevent_req_post(req, ev);
+
+ return req;
+}
+
+static void resolv_ghosts_group_done(struct tevent_req *subreq)
+{
+ struct resolv_ghosts_state *state;
+ struct ldb_message_element *el;
+ struct ldb_message *group;
+ struct tevent_req *req;
+ errno_t ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct resolv_ghosts_state);
+
+ ret = ifp_groups_group_get(state->sbus_req, state->data, NULL,
+ &state->domain, &group);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ el = ldb_msg_find_element(group, SYSDB_GHOST);
+ if (el == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ if (el->num_values == 0) {
+ ret = EOK;
+ goto done;
+ }
+
+ state->ghosts = sss_ldb_el_to_string_list(state, el);
+ if (state->ghosts == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ state->index = 0;
+ ret = resolv_ghosts_step(req);
+
+done:
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else if (ret != EAGAIN) {
+ tevent_req_error(req, ret);
+ }
+}
+
+errno_t resolv_ghosts_step(struct tevent_req *req)
+{
+ struct resolv_ghosts_state *state;
+ struct tevent_req *subreq;
+
+ state = tevent_req_data(req, struct resolv_ghosts_state);
+
+ if (state->ghosts[state->index] == NULL) {
+ return EOK;
+ }
+
+ subreq = cache_req_user_by_name_send(state, state->ev, state->ctx->rctx,
+ state->ctx->ncache, state->ctx->neg_timeout,
+ 0, state->domain->name,
+ state->ghosts[state->index]);
+ if (subreq == NULL) {
+ return ENOMEM;
+ }
+
+ tevent_req_set_callback(subreq, resolv_ghosts_done, req);
+
+ state->index++;
+
+ return EAGAIN;
+}
+
+static void resolv_ghosts_done(struct tevent_req *subreq)
+{
+ struct resolv_ghosts_state *state = NULL;
+ struct tevent_req *req = NULL;
+ errno_t ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct resolv_ghosts_state);
+
+ ret = cache_req_user_by_name_recv(state, subreq, NULL, NULL, NULL);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = resolv_ghosts_step(req);
+
+done:
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else if (ret != EAGAIN) {
+ tevent_req_error(req, ret);
+ }
+}
+
+static errno_t resolv_ghosts_recv(struct tevent_req *req)
+{
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ return EOK;
+}
+
+static void ifp_groups_group_update_member_list_done(struct tevent_req *req);
+
+int ifp_groups_group_update_member_list(struct sbus_request *sbus_req,
+ void *data)
+{
+ struct tevent_req *subreq;
+ struct ifp_ctx *ctx;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
+ return ERR_INTERNAL;
+ }
+
+ subreq = resolv_ghosts_send(sbus_req, ctx->rctx->ev, sbus_req, data);
+ if (subreq == NULL) {
+ return ENOMEM;
+ }
+
+ tevent_req_set_callback(subreq, ifp_groups_group_update_member_list_done,
+ sbus_req);
+
+ return EOK;
+}
+
+static void ifp_groups_group_update_member_list_done(struct tevent_req *subreq)
+{
+ DBusError *error;
+ struct sbus_request *sbus_req;
+ errno_t ret;
+
+ sbus_req = tevent_req_callback_data(subreq, struct sbus_request);
+
+ ret = resolv_ghosts_recv(subreq);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED,
+ "Unable to resolve ghost members [%d]: %s\n",
+ ret, sss_strerror(ret));
+ sbus_request_fail_and_finish(sbus_req, error);
+ return;
+ }
+
+ iface_ifp_groups_group_UpdateMemberList_finish(sbus_req);
+ return;
+}
+
+void ifp_groups_group_get_name(struct sbus_request *sbus_req,
+ void *data,
+ const char **_out)
+{
+ struct ldb_message *msg;
+ struct sss_domain_info *domain;
+ errno_t ret;
+
+ ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &msg);
+ if (ret != EOK) {
+ *_out = NULL;
+ return;
+ }
+
+ *_out = sss_view_ldb_msg_find_attr_as_string(domain, msg, SYSDB_NAME, NULL);
+
+ return;
+}
+
+void ifp_groups_group_get_gid_number(struct sbus_request *sbus_req,
+ void *data,
+ uint32_t *_out)
+{
+ struct ldb_message *msg;
+ struct sss_domain_info *domain;
+ errno_t ret;
+
+ ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &msg);
+ if (ret != EOK) {
+ *_out = 0;
+ return;
+ }
+
+ *_out = sss_view_ldb_msg_find_attr_as_uint64(domain, msg, SYSDB_GIDNUM, 0);
+
+ return;
+}
+
+static errno_t
+ifp_groups_group_get_members(TALLOC_CTX *mem_ctx,
+ struct sbus_request *sbus_req,
+ void *data,
+ const char ***_users,
+ int *_num_users,
+ const char ***_groups,
+ int *_num_groups)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct sss_domain_info *domain;
+ struct ldb_message *group;
+ struct ldb_message **members;
+ size_t num_members;
+ const char *class;
+ const char **users;
+ const char **groups;
+ int num_users;
+ int num_groups;
+ int i;
+ errno_t ret;
+ const char *attrs[] = {SYSDB_OBJECTCLASS, SYSDB_UIDNUM,
+ SYSDB_GIDNUM, NULL};
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sysdb_asq_search(tmp_ctx, domain, group->dn, NULL, SYSDB_MEMBER,
+ attrs, &num_members, &members);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to perform ASQ search [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ if (num_members == 0) {
+ users = NULL;
+ groups = NULL;
+ num_users = 0;
+ num_groups = 0;
+ ret = EOK;
+ goto done;
+ }
+
+ users = talloc_zero_array(tmp_ctx, const char *, num_members + 1);
+ if (users == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ groups = talloc_zero_array(tmp_ctx, const char *, num_members + 1);
+ if (groups == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ num_users = 0;
+ num_groups = 0;
+ for (i = 0; i < num_members; i++) {
+ class = ldb_msg_find_attr_as_string(members[i], SYSDB_OBJECTCLASS,
+ NULL);
+ if (class == NULL) {
+ ret = ERR_INTERNAL;
+ goto done;
+ }
+
+ if (strcmp(class, SYSDB_USER_CLASS) == 0) {
+ users[num_users] = ifp_users_build_path_from_msg(users, domain,
+ members[i]);
+ if (users[num_users] == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ num_users++;
+ } else if (strcmp(class, SYSDB_GROUP_CLASS) == 0) {
+ groups[num_groups] = ifp_groups_build_path_from_msg(groups,
+ domain, members[i]);
+ if (groups[num_groups] == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ num_groups++;
+ } else {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected object class %s\n", class);
+ ret = ERR_INTERNAL;
+ goto done;
+ }
+ }
+
+ ret = EOK;
+
+done:
+ if (ret == EOK) {
+ if (_users != NULL) {
+ *_users = talloc_steal(mem_ctx, users);
+ }
+
+ if (_num_users != NULL) {
+ *_num_users = num_users;
+ }
+
+ if (_groups != NULL) {
+ *_groups = talloc_steal(mem_ctx, groups);
+ }
+
+ if (_num_groups != NULL) {
+ *_num_groups = num_groups;
+ }
+ }
+
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+void ifp_groups_group_get_users(struct sbus_request *sbus_req,
+ void *data,
+ const char ***_out,
+ int *_size)
+{
+ errno_t ret;
+
+ *_out = NULL;
+ *_size = 0;
+
+ ret = ifp_groups_group_get_members(sbus_req, sbus_req, data, _out, _size,
+ NULL, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to acquire groups members\n");
+ }
+}
+
+void ifp_groups_group_get_groups(struct sbus_request *sbus_req,
+ void *data,
+ const char ***_out,
+ int *_size)
+{
+ errno_t ret;
+
+ *_out = NULL;
+ *_size = 0;
+
+ ret = ifp_groups_group_get_members(sbus_req, sbus_req, data, NULL, NULL,
+ _out, _size);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to acquire groups members\n");
+ }
+}
diff --git a/src/responder/ifp/ifp_groups.h b/src/responder/ifp/ifp_groups.h
index b93757326..0474ca44f 100644
--- a/src/responder/ifp/ifp_groups.h
+++ b/src/responder/ifp/ifp_groups.h
@@ -54,4 +54,27 @@ int ifp_groups_list_by_domain_and_name(struct sbus_request *sbus_req,
const char *filter,
uint32_t limit);
+/* org.freedesktop.sssd.infopipe.Groups.Group */
+
+int ifp_groups_group_update_member_list(struct sbus_request *sbus_req,
+ void *data);
+
+void ifp_groups_group_get_name(struct sbus_request *sbus_req,
+ void *data,
+ const char **_out);
+
+void ifp_groups_group_get_gid_number(struct sbus_request *sbus_req,
+ void *data,
+ uint32_t *_out);
+
+void ifp_groups_group_get_users(struct sbus_request *sbus_req,
+ void *data,
+ const char ***_out,
+ int *_size);
+
+void ifp_groups_group_get_groups(struct sbus_request *sbus_req,
+ void *data,
+ const char ***_out,
+ int *_size);
+
#endif /* IFP_GROUPS_H_ */
diff --git a/src/responder/ifp/ifp_iface.c b/src/responder/ifp/ifp_iface.c
index e762ffa28..ce987b607 100644
--- a/src/responder/ifp/ifp_iface.c
+++ b/src/responder/ifp/ifp_iface.c
@@ -107,6 +107,15 @@ struct iface_ifp_groups iface_ifp_groups = {
.ListByDomainAndName = ifp_groups_list_by_domain_and_name
};
+struct iface_ifp_groups_group iface_ifp_groups_group = {
+ { &iface_ifp_groups_group_meta, 0 },
+ .UpdateMemberList = ifp_groups_group_update_member_list,
+ .get_name = ifp_groups_group_get_name,
+ .get_gidNumber = ifp_groups_group_get_gid_number,
+ .get_users = ifp_groups_group_get_users,
+ .get_groups = ifp_groups_group_get_groups
+};
+
struct iface_map {
const char *path;
struct sbus_vtable *vtable;
@@ -119,6 +128,7 @@ static struct iface_map iface_map[] = {
{ IFP_PATH_USERS, &iface_ifp_users.vtable },
{ IFP_PATH_USERS_TREE, &iface_ifp_users_user.vtable },
{ IFP_PATH_GROUPS, &iface_ifp_groups.vtable },
+ { IFP_PATH_GROUPS_TREE, &iface_ifp_groups_group.vtable },
{ NULL, NULL },
};
diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml
index 31fb529fe..fbd3d3f5a 100644
--- a/src/responder/ifp/ifp_iface.xml
+++ b/src/responder/ifp/ifp_iface.xml
@@ -164,4 +164,15 @@
<arg name="result" type="ao" direction="out"/>
</method>
</interface>
+
+ <interface name="org.freedesktop.sssd.infopipe.Groups.Group">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="iface_ifp_groups_group"/>
+
+ <method name="UpdateMemberList" />
+
+ <property name="name" type="s" access="read" />
+ <property name="gidNumber" type="u" access="read" />
+ <property name="users" type="ao" access="read" />
+ <property name="groups" type="ao" access="read" />
+ </interface>
</node>
diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c
index 355db6e84..ff00be8ea 100644
--- a/src/responder/ifp/ifp_iface_generated.c
+++ b/src/responder/ifp/ifp_iface_generated.c
@@ -877,6 +877,74 @@ const struct sbus_interface_meta iface_ifp_groups_meta = {
sbus_invoke_get_all, /* GetAll invoker */
};
+int iface_ifp_groups_group_UpdateMemberList_finish(struct sbus_request *req)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_INVALID);
+}
+
+/* methods for org.freedesktop.sssd.infopipe.Groups.Group */
+const struct sbus_method_meta iface_ifp_groups_group__methods[] = {
+ {
+ "UpdateMemberList", /* name */
+ NULL, /* no in_args */
+ NULL, /* no out_args */
+ offsetof(struct iface_ifp_groups_group, UpdateMemberList),
+ NULL, /* no invoker */
+ },
+ { NULL, }
+};
+
+/* property info for org.freedesktop.sssd.infopipe.Groups.Group */
+const struct sbus_property_meta iface_ifp_groups_group__properties[] = {
+ {
+ "name", /* name */
+ "s", /* type */
+ SBUS_PROPERTY_READABLE,
+ offsetof(struct iface_ifp_groups_group, get_name),
+ sbus_invoke_get_s,
+ 0, /* not writable */
+ NULL, /* no invoker */
+ },
+ {
+ "gidNumber", /* name */
+ "u", /* type */
+ SBUS_PROPERTY_READABLE,
+ offsetof(struct iface_ifp_groups_group, get_gidNumber),
+ sbus_invoke_get_u,
+ 0, /* not writable */
+ NULL, /* no invoker */
+ },
+ {
+ "users", /* name */
+ "ao", /* type */
+ SBUS_PROPERTY_READABLE,
+ offsetof(struct iface_ifp_groups_group, get_users),
+ sbus_invoke_get_ao,
+ 0, /* not writable */
+ NULL, /* no invoker */
+ },
+ {
+ "groups", /* name */
+ "ao", /* type */
+ SBUS_PROPERTY_READABLE,
+ offsetof(struct iface_ifp_groups_group, get_groups),
+ sbus_invoke_get_ao,
+ 0, /* not writable */
+ NULL, /* no invoker */
+ },
+ { NULL, }
+};
+
+/* interface info for org.freedesktop.sssd.infopipe.Groups.Group */
+const struct sbus_interface_meta iface_ifp_groups_group_meta = {
+ "org.freedesktop.sssd.infopipe.Groups.Group", /* name */
+ iface_ifp_groups_group__methods,
+ NULL, /* no signals */
+ iface_ifp_groups_group__properties,
+ sbus_invoke_get_all, /* GetAll invoker */
+};
+
/* invokes a handler with a 'ssu' DBus signature */
static int invoke_ssu_method(struct sbus_request *dbus_req, void *function_ptr)
{
diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h
index 09db24b73..1bd2a448f 100644
--- a/src/responder/ifp/ifp_iface_generated.h
+++ b/src/responder/ifp/ifp_iface_generated.h
@@ -80,6 +80,14 @@
#define IFACE_IFP_GROUPS_LISTBYNAME "ListByName"
#define IFACE_IFP_GROUPS_LISTBYDOMAINANDNAME "ListByDomainAndName"
+/* constants for org.freedesktop.sssd.infopipe.Groups.Group */
+#define IFACE_IFP_GROUPS_GROUP "org.freedesktop.sssd.infopipe.Groups.Group"
+#define IFACE_IFP_GROUPS_GROUP_UPDATEMEMBERLIST "UpdateMemberList"
+#define IFACE_IFP_GROUPS_GROUP_NAME "name"
+#define IFACE_IFP_GROUPS_GROUP_GIDNUMBER "gidNumber"
+#define IFACE_IFP_GROUPS_GROUP_USERS "users"
+#define IFACE_IFP_GROUPS_GROUP_GROUPS "groups"
+
/* ------------------------------------------------------------------------
* DBus handlers
*
@@ -245,6 +253,19 @@ int iface_ifp_groups_ListByName_finish(struct sbus_request *req, const char *arg
/* finish function for ListByDomainAndName */
int iface_ifp_groups_ListByDomainAndName_finish(struct sbus_request *req, const char *arg_result[], int len_result);
+/* vtable for org.freedesktop.sssd.infopipe.Groups.Group */
+struct iface_ifp_groups_group {
+ struct sbus_vtable vtable; /* derive from sbus_vtable */
+ int (*UpdateMemberList)(struct sbus_request *req, void *data);
+ void (*get_name)(struct sbus_request *, void *data, const char **);
+ void (*get_gidNumber)(struct sbus_request *, void *data, uint32_t*);
+ void (*get_users)(struct sbus_request *, void *data, const char ***, int *);
+ void (*get_groups)(struct sbus_request *, void *data, const char ***, int *);
+};
+
+/* finish function for UpdateMemberList */
+int iface_ifp_groups_group_UpdateMemberList_finish(struct sbus_request *req);
+
/* ------------------------------------------------------------------------
* DBus Interface Metadata
*
@@ -273,4 +294,7 @@ extern const struct sbus_interface_meta iface_ifp_users_user_meta;
/* interface info for org.freedesktop.sssd.infopipe.Groups */
extern const struct sbus_interface_meta iface_ifp_groups_meta;
+/* interface info for org.freedesktop.sssd.infopipe.Groups.Group */
+extern const struct sbus_interface_meta iface_ifp_groups_group_meta;
+
#endif /* __IFP_IFACE_XML__ */
diff --git a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
index 916218c8b..b8df49350 100644
--- a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
+++ b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
@@ -33,6 +33,7 @@
<allow send_interface="org.freedesktop.sssd.infopipe.Users"/>
<allow send_interface="org.freedesktop.sssd.infopipe.Users.User"/>
<allow send_interface="org.freedesktop.sssd.infopipe.Groups"/>
+ <allow send_interface="org.freedesktop.sssd.infopipe.Groups.Group"/>
</policy>
<policy user="root">