From f91333767425810d47b6299816ed21547b303de2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 15 Jan 2015 13:52:31 +0100
Subject: [PATCH 4/8] IFP: add org.freedesktop.sssd.infopipe.Users

Resolves:
https://fedorahosted.org/sssd/ticket/2150
---
 Makefile.am                                        |   2 +
 src/responder/ifp/ifp_iface.c                      |  10 +
 src/responder/ifp/ifp_iface.xml                    |  24 +++
 src/responder/ifp/ifp_iface_generated.c            | 168 +++++++++++++++++
 src/responder/ifp/ifp_iface_generated.h            |  31 ++++
 src/responder/ifp/ifp_users.c                      | 202 +++++++++++++++++++++
 src/responder/ifp/ifp_users.h                      |  57 ++++++
 .../ifp/org.freedesktop.sssd.infopipe.conf         |   1 +
 8 files changed, 495 insertions(+)
 create mode 100644 src/responder/ifp/ifp_users.c
 create mode 100644 src/responder/ifp/ifp_users.h

diff --git a/Makefile.am b/Makefile.am
index d41d4b5adf53dd186e598bfdd35b8cd8294b808f..2c210fed0da84fd7975e5e8dbdd389b076eb0ff2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -542,6 +542,7 @@ dist_noinst_HEADERS = \
     src/responder/ifp/ifp_private.h \
     src/responder/ifp/ifp_domains.h \
     src/responder/ifp/ifp_components.h \
+    src/responder/ifp/ifp_users.h \
     src/sbus/sbus_client.h \
     src/sbus/sssd_dbus.h \
     src/sbus/sssd_dbus_meta.h \
@@ -1082,6 +1083,7 @@ sssd_ifp_SOURCES = \
     src/responder/ifp/ifpsrv_util.c \
     src/responder/ifp/ifp_domains.c \
     src/responder/ifp/ifp_components.c \
+    src/responder/ifp/ifp_users.c \
     $(SSSD_UTIL_OBJ) \
     $(SSSD_RESPONDER_OBJ)
 sssd_ifp_CFLAGS = \
diff --git a/src/responder/ifp/ifp_iface.c b/src/responder/ifp/ifp_iface.c
index c82a2e65df54997ca7d003ccc9a3a0a0037edd90..753bad1269fbecad12cc9e6fea5455cce23aeb8e 100644
--- a/src/responder/ifp/ifp_iface.c
+++ b/src/responder/ifp/ifp_iface.c
@@ -24,6 +24,7 @@
 #include "responder/ifp/ifp_iface_generated.h"
 #include "responder/ifp/ifp_domains.h"
 #include "responder/ifp/ifp_components.h"
+#include "responder/ifp/ifp_users.h"
 
 struct iface_ifp iface_ifp = {
     { &iface_ifp_meta, 0 },
@@ -76,6 +77,14 @@ struct iface_ifp_domains iface_ifp_domains = {
     .get_parent_domain = ifp_dom_get_parent_domain
 };
 
+struct iface_ifp_users iface_ifp_users = {
+    { &iface_ifp_users_meta, 0 },
+    .FindByName = ifp_users_find_by_name,
+    .FindByID = ifp_users_find_by_id,
+    .ListByName = ifp_users_list_by_name,
+    .ListByDomainAndName = ifp_users_list_by_domain_and_name
+};
+
 struct iface_map {
     const char *path;
     struct sbus_vtable *vtable;
@@ -85,6 +94,7 @@ static struct iface_map iface_map[] = {
     { IFP_PATH, &iface_ifp.vtable },
     { IFP_PATH_DOMAINS_TREE, &iface_ifp_domains.vtable },
     { IFP_PATH_COMPONENTS_TREE, &iface_ifp_components.vtable },
+    { IFP_PATH_USERS, &iface_ifp_users.vtable },
     { NULL, NULL },
 };
 
diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml
index 81d4dbf8be5a4a6fe60e83edb502ad409044ebaa..d0c835949f62c2bad44f24ae251f4a2a273a093d 100644
--- a/src/responder/ifp/ifp_iface.xml
+++ b/src/responder/ifp/ifp_iface.xml
@@ -101,4 +101,28 @@
         <property name="subdomain" type="b" access="read"/>
         <property name="parent_domain" type="o" access="read"/>
     </interface>
+
+    <interface name="org.freedesktop.sssd.infopipe.Users">
+        <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="iface_ifp_users"/>
+
+        <method name="FindByName">
+            <arg name="name" type="s" direction="in" />
+            <arg name="result" type="o" direction="out" />
+        </method>
+        <method name="FindByID">
+            <arg name="id" type="u" direction="in" />
+            <arg name="result" type="o" direction="out" />
+        </method>
+        <method name="ListByName">
+            <arg name="name_filter" type="s" direction="in" />
+            <arg name="limit" type="u" direction="in" />
+            <arg name="result" type="ao" direction="out" />
+        </method>
+        <method name="ListByDomainAndName">
+            <arg name="domain_name" type="s" direction="in" />
+            <arg name="name_filter" type="s" direction="in" />
+            <arg name="limit" type="u" direction="in" />
+            <arg name="result" type="ao" direction="out"/>
+        </method>
+    </interface>
 </node>
diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c
index 9c00a8c59bd36f7a83ab299d51b3f1a8bf0994e0..40a416bc4d45e0600af3767c53fdab4f532c9cd0 100644
--- a/src/responder/ifp/ifp_iface_generated.c
+++ b/src/responder/ifp/ifp_iface_generated.c
@@ -12,6 +12,12 @@ static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr);
 /* invokes a handler with a 'u' DBus signature */
 static int invoke_u_method(struct sbus_request *dbus_req, void *function_ptr);
 
+/* invokes a handler with a 'su' DBus signature */
+static int invoke_su_method(struct sbus_request *dbus_req, void *function_ptr);
+
+/* invokes a handler with a 'ssu' DBus signature */
+static int invoke_ssu_method(struct sbus_request *dbus_req, void *function_ptr);
+
 /* arguments for org.freedesktop.sssd.infopipe.ListComponents */
 const struct sbus_arg_meta iface_ifp_ListComponents__out[] = {
     { "components", "ao" },
@@ -525,6 +531,149 @@ const struct sbus_interface_meta iface_ifp_domains_meta = {
     sbus_invoke_get_all, /* GetAll invoker */
 };
 
+/* arguments for org.freedesktop.sssd.infopipe.Users.FindByName */
+const struct sbus_arg_meta iface_ifp_users_FindByName__in[] = {
+    { "name", "s" },
+    { NULL, }
+};
+
+/* arguments for org.freedesktop.sssd.infopipe.Users.FindByName */
+const struct sbus_arg_meta iface_ifp_users_FindByName__out[] = {
+    { "result", "o" },
+    { NULL, }
+};
+
+int iface_ifp_users_FindByName_finish(struct sbus_request *req, const char *arg_result)
+{
+   return sbus_request_return_and_finish(req,
+                                         DBUS_TYPE_OBJECT_PATH, &arg_result,
+                                         DBUS_TYPE_INVALID);
+}
+
+/* arguments for org.freedesktop.sssd.infopipe.Users.FindByID */
+const struct sbus_arg_meta iface_ifp_users_FindByID__in[] = {
+    { "id", "u" },
+    { NULL, }
+};
+
+/* arguments for org.freedesktop.sssd.infopipe.Users.FindByID */
+const struct sbus_arg_meta iface_ifp_users_FindByID__out[] = {
+    { "result", "o" },
+    { NULL, }
+};
+
+int iface_ifp_users_FindByID_finish(struct sbus_request *req, const char *arg_result)
+{
+   return sbus_request_return_and_finish(req,
+                                         DBUS_TYPE_OBJECT_PATH, &arg_result,
+                                         DBUS_TYPE_INVALID);
+}
+
+/* arguments for org.freedesktop.sssd.infopipe.Users.ListByName */
+const struct sbus_arg_meta iface_ifp_users_ListByName__in[] = {
+    { "name_filter", "s" },
+    { "limit", "u" },
+    { NULL, }
+};
+
+/* arguments for org.freedesktop.sssd.infopipe.Users.ListByName */
+const struct sbus_arg_meta iface_ifp_users_ListByName__out[] = {
+    { "result", "ao" },
+    { NULL, }
+};
+
+int iface_ifp_users_ListByName_finish(struct sbus_request *req, const char *arg_result[], int len_result)
+{
+   return sbus_request_return_and_finish(req,
+                                         DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_result, len_result,
+                                         DBUS_TYPE_INVALID);
+}
+
+/* arguments for org.freedesktop.sssd.infopipe.Users.ListByDomainAndName */
+const struct sbus_arg_meta iface_ifp_users_ListByDomainAndName__in[] = {
+    { "domain_name", "s" },
+    { "name_filter", "s" },
+    { "limit", "u" },
+    { NULL, }
+};
+
+/* arguments for org.freedesktop.sssd.infopipe.Users.ListByDomainAndName */
+const struct sbus_arg_meta iface_ifp_users_ListByDomainAndName__out[] = {
+    { "result", "ao" },
+    { NULL, }
+};
+
+int iface_ifp_users_ListByDomainAndName_finish(struct sbus_request *req, const char *arg_result[], int len_result)
+{
+   return sbus_request_return_and_finish(req,
+                                         DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_result, len_result,
+                                         DBUS_TYPE_INVALID);
+}
+
+/* methods for org.freedesktop.sssd.infopipe.Users */
+const struct sbus_method_meta iface_ifp_users__methods[] = {
+    {
+        "FindByName", /* name */
+        iface_ifp_users_FindByName__in,
+        iface_ifp_users_FindByName__out,
+        offsetof(struct iface_ifp_users, FindByName),
+        invoke_s_method,
+    },
+    {
+        "FindByID", /* name */
+        iface_ifp_users_FindByID__in,
+        iface_ifp_users_FindByID__out,
+        offsetof(struct iface_ifp_users, FindByID),
+        invoke_u_method,
+    },
+    {
+        "ListByName", /* name */
+        iface_ifp_users_ListByName__in,
+        iface_ifp_users_ListByName__out,
+        offsetof(struct iface_ifp_users, ListByName),
+        invoke_su_method,
+    },
+    {
+        "ListByDomainAndName", /* name */
+        iface_ifp_users_ListByDomainAndName__in,
+        iface_ifp_users_ListByDomainAndName__out,
+        offsetof(struct iface_ifp_users, ListByDomainAndName),
+        invoke_ssu_method,
+    },
+    { NULL, }
+};
+
+/* interface info for org.freedesktop.sssd.infopipe.Users */
+const struct sbus_interface_meta iface_ifp_users_meta = {
+    "org.freedesktop.sssd.infopipe.Users", /* name */
+    iface_ifp_users__methods,
+    NULL, /* no signals */
+    NULL, /* no 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)
+{
+    const char * arg_0;
+    const char * arg_1;
+    uint32_t arg_2;
+    int (*handler)(struct sbus_request *, void *, const char *, const char *, uint32_t) = function_ptr;
+
+    if (!sbus_request_parse_or_finish(dbus_req,
+                               DBUS_TYPE_STRING, &arg_0,
+                               DBUS_TYPE_STRING, &arg_1,
+                               DBUS_TYPE_UINT32, &arg_2,
+                               DBUS_TYPE_INVALID)) {
+         return EOK; /* request handled */
+    }
+
+    return (handler)(dbus_req, dbus_req->intf->handler_data,
+                     arg_0,
+                     arg_1,
+                     arg_2);
+}
+
 /* invokes a handler with a 's' DBus signature */
 static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr)
 {
@@ -556,3 +705,22 @@ static int invoke_u_method(struct sbus_request *dbus_req, void *function_ptr)
     return (handler)(dbus_req, dbus_req->intf->handler_data,
                      arg_0);
 }
+
+/* invokes a handler with a 'su' DBus signature */
+static int invoke_su_method(struct sbus_request *dbus_req, void *function_ptr)
+{
+    const char * arg_0;
+    uint32_t arg_1;
+    int (*handler)(struct sbus_request *, void *, const char *, uint32_t) = function_ptr;
+
+    if (!sbus_request_parse_or_finish(dbus_req,
+                               DBUS_TYPE_STRING, &arg_0,
+                               DBUS_TYPE_UINT32, &arg_1,
+                               DBUS_TYPE_INVALID)) {
+         return EOK; /* request handled */
+    }
+
+    return (handler)(dbus_req, dbus_req->intf->handler_data,
+                     arg_0,
+                     arg_1);
+}
diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h
index e2f5a7eaf8a8d3452f9044ecc9c4ee7568a9b2cf..83ac75b06d4c747cd3a8d45b8f04d08b80e179db 100644
--- a/src/responder/ifp/ifp_iface_generated.h
+++ b/src/responder/ifp/ifp_iface_generated.h
@@ -54,6 +54,13 @@
 #define IFACE_IFP_DOMAINS_SUBDOMAIN "subdomain"
 #define IFACE_IFP_DOMAINS_PARENT_DOMAIN "parent_domain"
 
+/* constants for org.freedesktop.sssd.infopipe.Users */
+#define IFACE_IFP_USERS "org.freedesktop.sssd.infopipe.Users"
+#define IFACE_IFP_USERS_FINDBYNAME "FindByName"
+#define IFACE_IFP_USERS_FINDBYID "FindByID"
+#define IFACE_IFP_USERS_LISTBYNAME "ListByName"
+#define IFACE_IFP_USERS_LISTBYDOMAINANDNAME "ListByDomainAndName"
+
 /* ------------------------------------------------------------------------
  * DBus handlers
  *
@@ -160,6 +167,27 @@ struct iface_ifp_domains {
     void (*get_parent_domain)(struct sbus_request *, void *data, const char * *);
 };
 
+/* vtable for org.freedesktop.sssd.infopipe.Users */
+struct iface_ifp_users {
+    struct sbus_vtable vtable; /* derive from sbus_vtable */
+    int (*FindByName)(struct sbus_request *req, void *data, const char *arg_name);
+    int (*FindByID)(struct sbus_request *req, void *data, uint32_t arg_id);
+    int (*ListByName)(struct sbus_request *req, void *data, const char *arg_name_filter, uint32_t arg_limit);
+    int (*ListByDomainAndName)(struct sbus_request *req, void *data, const char *arg_domain_name, const char *arg_name_filter, uint32_t arg_limit);
+};
+
+/* finish function for FindByName */
+int iface_ifp_users_FindByName_finish(struct sbus_request *req, const char *arg_result);
+
+/* finish function for FindByID */
+int iface_ifp_users_FindByID_finish(struct sbus_request *req, const char *arg_result);
+
+/* finish function for ListByName */
+int iface_ifp_users_ListByName_finish(struct sbus_request *req, const char *arg_result[], int len_result);
+
+/* finish function for ListByDomainAndName */
+int iface_ifp_users_ListByDomainAndName_finish(struct sbus_request *req, const char *arg_result[], int len_result);
+
 /* ------------------------------------------------------------------------
  * DBus Interface Metadata
  *
@@ -179,4 +207,7 @@ extern const struct sbus_interface_meta iface_ifp_components_meta;
 /* interface info for org.freedesktop.sssd.infopipe.Domains */
 extern const struct sbus_interface_meta iface_ifp_domains_meta;
 
+/* interface info for org.freedesktop.sssd.infopipe.Users */
+extern const struct sbus_interface_meta iface_ifp_users_meta;
+
 #endif /* __IFP_IFACE_XML__ */
diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c
new file mode 100644
index 0000000000000000000000000000000000000000..04fabf77b9cbb49b4ebd67571f40857b8a3b9c00
--- /dev/null
+++ b/src/responder/ifp/ifp_users.c
@@ -0,0 +1,202 @@
+/*
+    Authors:
+        Pavel Březina <pbrezina@redhat.com>
+
+    Copyright (C) 2015 Red Hat
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <talloc.h>
+#include <tevent.h>
+#include <string.h>
+
+#include "db/sysdb.h"
+#include "util/util.h"
+#include "sbus/sssd_dbus_errors.h"
+#include "responder/common/responder.h"
+#include "responder/common/responder_cache_req.h"
+#include "responder/ifp/ifp_users.h"
+
+char * ifp_users_build_path_from_msg(TALLOC_CTX *mem_ctx,
+                                     struct sss_domain_info *domain,
+                                     struct ldb_message *msg)
+{
+    const char *uid;
+
+    uid = ldb_msg_find_attr_as_string(msg, SYSDB_UIDNUM, NULL);
+
+    if (uid == NULL) {
+        return NULL;
+    }
+
+    return sbus_opath_compose(mem_ctx, IFP_PATH_USERS, domain->name, uid);
+}
+
+static void ifp_users_find_by_name_done(struct tevent_req *req);
+
+int ifp_users_find_by_name(struct sbus_request *sbus_req,
+                           void *data,
+                           const char *name)
+{
+    struct ifp_ctx *ctx;
+    struct tevent_req *req;
+
+    ctx = talloc_get_type(data, struct ifp_ctx);
+    if (ctx == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
+        return ERR_INTERNAL;
+    }
+
+    req = cache_req_user_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx,
+                                      ctx->ncache, ctx->neg_timeout, 0,
+                                      NULL, name);
+    if (req == NULL) {
+        return ENOMEM;
+    }
+
+    tevent_req_set_callback(req, ifp_users_find_by_name_done, sbus_req);
+
+    return EOK;
+}
+
+static void
+ifp_users_find_by_name_done(struct tevent_req *req)
+{
+    DBusError *error;
+    struct sbus_request *sbus_req;
+    struct sss_domain_info *domain;
+    struct ldb_result *result;
+    char *object_path;
+    errno_t ret;
+
+    sbus_req = tevent_req_callback_data(req, struct sbus_request);
+
+    ret = cache_req_user_by_name_recv(sbus_req, req, &result, &domain, NULL);
+    talloc_zfree(req);
+    if (ret == ENOENT) {
+        error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND,
+                               "User not found");
+        goto done;
+    } else if (ret != EOK) {
+        error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
+                               "user [%d]: %s\n", ret, sss_strerror(ret));
+        goto done;
+    }
+
+    object_path = ifp_users_build_path_from_msg(sbus_req, domain,
+                                                result->msgs[0]);
+    if (object_path == NULL) {
+        error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
+                               "Failed to compose object path");
+        goto done;
+    }
+
+    ret = EOK;
+
+done:
+    if (ret != EOK) {
+        sbus_request_fail_and_finish(sbus_req, error);
+        return;
+    }
+
+    iface_ifp_users_FindByName_finish(sbus_req, object_path);
+    return;
+}
+
+static void ifp_users_find_by_id_done(struct tevent_req *req);
+
+int ifp_users_find_by_id(struct sbus_request *sbus_req,
+                         void *data,
+                         uint32_t id)
+{
+    struct ifp_ctx *ctx;
+    struct tevent_req *req;
+
+    ctx = talloc_get_type(data, struct ifp_ctx);
+    if (ctx == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
+        return ERR_INTERNAL;
+    }
+
+    req = cache_req_user_by_id_send(sbus_req, ctx->rctx->ev, ctx->rctx,
+                                    ctx->ncache, ctx->neg_timeout, 0,
+                                    NULL, id);
+    if (req == NULL) {
+        return ENOMEM;
+    }
+
+    tevent_req_set_callback(req, ifp_users_find_by_id_done, sbus_req);
+
+    return EOK;
+}
+
+static void
+ifp_users_find_by_id_done(struct tevent_req *req)
+{
+    DBusError *error;
+    struct sbus_request *sbus_req;
+    struct sss_domain_info *domain;
+    struct ldb_result *result;
+    char *object_path;
+    errno_t ret;
+
+    sbus_req = tevent_req_callback_data(req, struct sbus_request);
+
+    ret = cache_req_user_by_id_recv(sbus_req, req, &result, &domain);
+    talloc_zfree(req);
+    if (ret == ENOENT) {
+        error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND,
+                               "User not found");
+        goto done;
+    } else if (ret != EOK) {
+        error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
+                               "user [%d]: %s\n", ret, sss_strerror(ret));
+        goto done;
+    }
+
+    object_path = ifp_users_build_path_from_msg(sbus_req, domain,
+                                                result->msgs[0]);
+    if (object_path == NULL) {
+        error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
+                               "Failed to compose object path");
+        goto done;
+    }
+
+done:
+    if (ret != EOK) {
+        sbus_request_fail_and_finish(sbus_req, error);
+        return;
+    }
+
+    iface_ifp_users_FindByID_finish(sbus_req, object_path);
+    return;
+}
+
+int ifp_users_list_by_name(struct sbus_request *sbus_req,
+                           void *data,
+                           const char *filter,
+                           uint32_t limit)
+{
+    return EOK;
+}
+
+int ifp_users_list_by_domain_and_name(struct sbus_request *sbus_req,
+                                      void *data,
+                                      const char *domain,
+                                      const char *filter,
+                                      uint32_t limit)
+{
+    return EOK;
+}
diff --git a/src/responder/ifp/ifp_users.h b/src/responder/ifp/ifp_users.h
new file mode 100644
index 0000000000000000000000000000000000000000..a0a079f482553e8b7b3fd874140cedfc29fdb7f8
--- /dev/null
+++ b/src/responder/ifp/ifp_users.h
@@ -0,0 +1,57 @@
+/*
+    Authors:
+        Pavel Březina <pbrezina@redhat.com>
+
+    Copyright (C) 2015 Red Hat
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef IFP_USERS_H_
+#define IFP_USERS_H_
+
+#include "responder/ifp/ifp_iface_generated.h"
+#include "responder/ifp/ifp_private.h"
+
+#define IFP_PATH_USERS "/org/freedesktop/sssd/infopipe/Users"
+#define IFP_PATH_USERS_TREE IFP_PATH_USERS SBUS_SUBTREE_SUFFIX
+
+/* Utility functions */
+
+char * ifp_users_build_path_from_msg(TALLOC_CTX *mem_ctx,
+                                     struct sss_domain_info *domain,
+                                     struct ldb_message *msg);
+
+/* org.freedesktop.sssd.infopipe.Users */
+
+int ifp_users_find_by_name(struct sbus_request *sbus_req,
+                           void *data,
+                           const char *name);
+
+int ifp_users_find_by_id(struct sbus_request *sbus_req,
+                         void *data,
+                         uint32_t id);
+
+int ifp_users_list_by_name(struct sbus_request *sbus_req,
+                           void *data,
+                           const char *filter,
+                           uint32_t limit);
+
+int ifp_users_list_by_domain_and_name(struct sbus_request *sbus_req,
+                                      void *data,
+                                      const char *domain,
+                                      const char *filter,
+                                      uint32_t limit);
+
+#endif /* IFP_USERS_H_ */
diff --git a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
index a6f379afc83b1537d284466f30b1aad308335502..195e73aa9b00455af5732a079052cd49baae8624 100644
--- a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
+++ b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
@@ -30,6 +30,7 @@
            send_member="Set"/>
 
     <allow send_interface="org.freedesktop.sssd.infopipe"/>
+    <allow send_interface="org.freedesktop.sssd.infopipe.Users"/>
   </policy>
 
   <policy user="root">
-- 
2.1.0

