From 5a5ba6a525c058c312af96bc735434fecd6183c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 16 Jun 2016 13:56:12 +0200
Subject: [PATCH 24/25] IFP: Provide domain and failover status

---
 src/providers/data_provider/dp_iface.c             |   2 +-
 src/responder/ifp/ifp_domains.c                    | 116 +++++++++++++++++++++
 src/responder/ifp/ifp_domains.h                    |   6 ++
 src/responder/ifp/ifp_iface.c                      |   7 ++
 src/responder/ifp/ifp_iface.xml                    |  12 +++
 src/responder/ifp/ifp_iface_generated.c            |  55 ++++++++++
 src/responder/ifp/ifp_iface_generated.h            |  21 ++++
 .../ifp/org.freedesktop.sssd.infopipe.conf         |   1 +
 8 files changed, 219 insertions(+), 1 deletion(-)

diff --git a/src/providers/data_provider/dp_iface.c b/src/providers/data_provider/dp_iface.c
index 1270c8b96a84315101593157d0b16e8b4673a011..8ed7274f0dd7b59598e2cf21e0dd59d16666df0b 100644
--- a/src/providers/data_provider/dp_iface.c
+++ b/src/providers/data_provider/dp_iface.c
@@ -42,7 +42,7 @@ struct iface_dp_backend iface_dp_backend = {
 };
 
 struct iface_dp_failover iface_dp_failover = {
-    {&iface_dp_backend_meta, 0},
+    {&iface_dp_failover_meta, 0},
     .ListServices = dp_failover_list_services
 };
 
diff --git a/src/responder/ifp/ifp_domains.c b/src/responder/ifp/ifp_domains.c
index 5ad9952c9ad20c96c207a20700565788a6a9f3ea..5333b25275e0847015f9cdd294eab5dbdda32f6c 100644
--- a/src/responder/ifp/ifp_domains.c
+++ b/src/responder/ifp/ifp_domains.c
@@ -28,6 +28,9 @@
 #include "confdb/confdb.h"
 #include "responder/common/responder.h"
 #include "responder/ifp/ifp_domains.h"
+#include "responder/common/data_provider/rdp.h"
+#include "sbus/sssd_dbus_errors.h"
+#include "providers/data_provider/dp_responder_iface.h"
 
 #define RETURN_DOM_PROP_AS_STRING(dbus_req, pvt_data, out, property) do { \
     struct sss_domain_info *__dom;                                        \
@@ -534,3 +537,116 @@ void ifp_dom_get_parent_domain(struct sbus_request *dbus_req,
     *_out = sbus_opath_compose(dbus_req, IFP_PATH_DOMAINS,
                                dom->parent->name);
 }
+
+static void ifp_domains_domain_is_online_done(struct tevent_req *req);
+
+int ifp_domains_domain_is_online(struct sbus_request *sbus_req,
+                                 void *data)
+{
+    struct ifp_ctx *ifp_ctx;
+    struct sss_domain_info *dom;
+    struct tevent_req *req;
+    DBusError *error;
+
+    ifp_ctx = talloc_get_type(data, struct ifp_ctx);
+
+    dom = get_domain_info_from_req(sbus_req, data);
+    if (dom == NULL) {
+        error = sbus_error_new(sbus_req, SBUS_ERROR_UNKNOWN_DOMAIN,
+                               "Unknown domain");
+        sbus_request_fail_and_finish(sbus_req, error);
+        return EOK;
+    }
+
+    req = rdp_message_send(sbus_req, ifp_ctx->rctx, dom, DP_PATH,
+                           IFACE_DP_BACKEND, IFACE_DP_BACKEND_ISONLINE,
+                           DBUS_TYPE_STRING, &dom->name);
+    if (req == NULL) {
+        return ENOMEM;
+    }
+
+    tevent_req_set_callback(req, ifp_domains_domain_is_online_done, sbus_req);
+
+    return EOK;
+}
+
+static void ifp_domains_domain_is_online_done(struct tevent_req *req)
+{
+    struct sbus_request *sbus_req;
+    DBusError *error;
+    bool is_online;
+    errno_t ret;
+
+    sbus_req = tevent_req_callback_data(req, struct sbus_request);
+
+    ret = rdp_message_recv(req, DBUS_TYPE_BOOLEAN, &is_online);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "Unable to get online status [%d]: %s\n",
+              ret, sss_strerror(ret));
+        error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED,
+                               "Unable to get online status [%d]: %s",
+                               ret, sss_strerror(ret));
+        sbus_request_fail_and_finish(sbus_req, error);
+        return;
+    }
+
+    iface_ifp_domains_domain_IsOnline_finish(sbus_req, is_online);
+}
+
+static void ifp_domains_domain_list_services_done(struct tevent_req *req);
+
+int ifp_domains_domain_list_services(struct sbus_request *sbus_req,
+                                     void *data)
+{
+    struct ifp_ctx *ifp_ctx;
+    struct sss_domain_info *dom;
+    struct tevent_req *req;
+    DBusError *error;
+
+    ifp_ctx = talloc_get_type(data, struct ifp_ctx);
+
+    dom = get_domain_info_from_req(sbus_req, data);
+    if (dom == NULL) {
+        error = sbus_error_new(sbus_req, SBUS_ERROR_UNKNOWN_DOMAIN,
+                               "Unknown domain");
+        sbus_request_fail_and_finish(sbus_req, error);
+        return EOK;
+    }
+
+    req = rdp_message_send(sbus_req, ifp_ctx->rctx, dom, DP_PATH,
+                           IFACE_DP_FAILOVER, IFACE_DP_FAILOVER_LISTSERVICES,
+                           DBUS_TYPE_STRING, &dom->name);
+    if (req == NULL) {
+        return ENOMEM;
+    }
+
+    tevent_req_set_callback(req, ifp_domains_domain_list_services_done, sbus_req);
+
+    return EOK;
+}
+
+static void ifp_domains_domain_list_services_done(struct tevent_req *req)
+{
+    struct sbus_request *sbus_req;
+    DBusError *error;
+    int num_services;
+    const char **services;
+    errno_t ret;
+
+    sbus_req = tevent_req_callback_data(req, struct sbus_request);
+
+    ret = rdp_message_recv(req, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
+                           &services, &num_services);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "Unable to get failover services [%d]: %s\n",
+              ret, sss_strerror(ret));
+        error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED,
+                               "Unable to get failover services [%d]: %s",
+                               ret, sss_strerror(ret));
+        sbus_request_fail_and_finish(sbus_req, error);
+        return;
+    }
+
+    iface_ifp_domains_domain_ListServices_finish(sbus_req, services,
+                                                 num_services);
+}
diff --git a/src/responder/ifp/ifp_domains.h b/src/responder/ifp/ifp_domains.h
index 966851b3b9a6a8f365b1010cfdee779322f04615..91645e60701f8f75e89a42e93e2c066def67b018 100644
--- a/src/responder/ifp/ifp_domains.h
+++ b/src/responder/ifp/ifp_domains.h
@@ -94,4 +94,10 @@ void ifp_dom_get_parent_domain(struct sbus_request *dbus_req,
                               void *data,
                               const char **_out);
 
+int ifp_domains_domain_is_online(struct sbus_request *sbus_req,
+                                 void *data);
+
+int ifp_domains_domain_list_services(struct sbus_request *sbus_req,
+                                     void *data);
+
 #endif /* IFP_DOMAINS_H_ */
diff --git a/src/responder/ifp/ifp_iface.c b/src/responder/ifp/ifp_iface.c
index 53f3aa1de8f487d2f67d75b05af8b0f15a50302a..90bb52b2ccf5207034abbe12bddbfa1eeaf875f7 100644
--- a/src/responder/ifp/ifp_iface.c
+++ b/src/responder/ifp/ifp_iface.c
@@ -78,6 +78,12 @@ struct iface_ifp_domains iface_ifp_domains = {
     .get_parent_domain = ifp_dom_get_parent_domain
 };
 
+struct iface_ifp_domains_domain iface_ifp_domains_domain = {
+    { &iface_ifp_domains_domain_meta, 0 },
+    .IsOnline = ifp_domains_domain_is_online,
+    .ListServices = ifp_domains_domain_list_services
+};
+
 struct iface_ifp_users iface_ifp_users = {
     { &iface_ifp_users_meta, 0 },
     .FindByName = ifp_users_find_by_name,
@@ -145,6 +151,7 @@ static struct sbus_iface_map iface_map[] = {
     { IFP_PATH, &iface_ifp.vtable },
     { IFP_PATH_DOMAINS, &iface_ifp_domains.vtable },
     { IFP_PATH_DOMAINS_TREE, &iface_ifp_domains.vtable },
+    { IFP_PATH_DOMAINS_TREE, &iface_ifp_domains_domain.vtable },
     { IFP_PATH_COMPONENTS_TREE, &iface_ifp_components.vtable },
     { IFP_PATH_USERS, &iface_ifp_users.vtable },
     { IFP_PATH_USERS, &iface_ifp_cache_user.vtable },
diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml
index 5a56b624a1ba943e2f0fa407dd8cfb25c8dbd016..7f6f47299deeba4b1baa23d1e63ee7bb17304a59 100644
--- a/src/responder/ifp/ifp_iface.xml
+++ b/src/responder/ifp/ifp_iface.xml
@@ -102,6 +102,18 @@
         <property name="parent_domain" type="o" access="read"/>
     </interface>
 
+    <interface name="org.freedesktop.sssd.infopipe.Domains.Domain">
+        <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="iface_ifp_domains_domain"/>
+
+        <method name="IsOnline">
+            <arg name="status" type="b" direction="out" />
+        </method>
+
+        <method name="ListServices">
+            <arg name="services" type="as" direction="out" />
+        </method>
+    </interface>
+
     <interface name="org.freedesktop.sssd.infopipe.Cache">
         <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="iface_ifp_cache"/>
 
diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c
index a4fdd5d12cd5c82e7832de9d07f55ea6eb621fba..4d3bb5727b03ae64adad14fcdbb3eb5366edb406 100644
--- a/src/responder/ifp/ifp_iface_generated.c
+++ b/src/responder/ifp/ifp_iface_generated.c
@@ -531,6 +531,61 @@ const struct sbus_interface_meta iface_ifp_domains_meta = {
     sbus_invoke_get_all, /* GetAll invoker */
 };
 
+/* arguments for org.freedesktop.sssd.infopipe.Domains.Domain.IsOnline */
+const struct sbus_arg_meta iface_ifp_domains_domain_IsOnline__out[] = {
+    { "status", "b" },
+    { NULL, }
+};
+
+int iface_ifp_domains_domain_IsOnline_finish(struct sbus_request *req, bool arg_status)
+{
+    dbus_bool_t cast_status = arg_status;
+   return sbus_request_return_and_finish(req,
+                                         DBUS_TYPE_BOOLEAN, &cast_status,
+                                         DBUS_TYPE_INVALID);
+}
+
+/* arguments for org.freedesktop.sssd.infopipe.Domains.Domain.ListServices */
+const struct sbus_arg_meta iface_ifp_domains_domain_ListServices__out[] = {
+    { "services", "as" },
+    { NULL, }
+};
+
+int iface_ifp_domains_domain_ListServices_finish(struct sbus_request *req, const char *arg_services[], int len_services)
+{
+   return sbus_request_return_and_finish(req,
+                                         DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &arg_services, len_services,
+                                         DBUS_TYPE_INVALID);
+}
+
+/* methods for org.freedesktop.sssd.infopipe.Domains.Domain */
+const struct sbus_method_meta iface_ifp_domains_domain__methods[] = {
+    {
+        "IsOnline", /* name */
+        NULL, /* no in_args */
+        iface_ifp_domains_domain_IsOnline__out,
+        offsetof(struct iface_ifp_domains_domain, IsOnline),
+        NULL, /* no invoker */
+    },
+    {
+        "ListServices", /* name */
+        NULL, /* no in_args */
+        iface_ifp_domains_domain_ListServices__out,
+        offsetof(struct iface_ifp_domains_domain, ListServices),
+        NULL, /* no invoker */
+    },
+    { NULL, }
+};
+
+/* interface info for org.freedesktop.sssd.infopipe.Domains.Domain */
+const struct sbus_interface_meta iface_ifp_domains_domain_meta = {
+    "org.freedesktop.sssd.infopipe.Domains.Domain", /* name */
+    iface_ifp_domains_domain__methods,
+    NULL, /* no signals */
+    NULL, /* no properties */
+    sbus_invoke_get_all, /* GetAll invoker */
+};
+
 /* arguments for org.freedesktop.sssd.infopipe.Cache.List */
 const struct sbus_arg_meta iface_ifp_cache_List__out[] = {
     { "result", "ao" },
diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h
index 4dfe61ddff3763b1d3ee165b9098efd667037663..2eff57410e5292a05818050b96eb85aa3a4f2e16 100644
--- a/src/responder/ifp/ifp_iface_generated.h
+++ b/src/responder/ifp/ifp_iface_generated.h
@@ -54,6 +54,11 @@
 #define IFACE_IFP_DOMAINS_SUBDOMAIN "subdomain"
 #define IFACE_IFP_DOMAINS_PARENT_DOMAIN "parent_domain"
 
+/* constants for org.freedesktop.sssd.infopipe.Domains.Domain */
+#define IFACE_IFP_DOMAINS_DOMAIN "org.freedesktop.sssd.infopipe.Domains.Domain"
+#define IFACE_IFP_DOMAINS_DOMAIN_ISONLINE "IsOnline"
+#define IFACE_IFP_DOMAINS_DOMAIN_LISTSERVICES "ListServices"
+
 /* constants for org.freedesktop.sssd.infopipe.Cache */
 #define IFACE_IFP_CACHE "org.freedesktop.sssd.infopipe.Cache"
 #define IFACE_IFP_CACHE_LIST "List"
@@ -205,6 +210,19 @@ struct iface_ifp_domains {
     void (*get_parent_domain)(struct sbus_request *, void *data, const char **);
 };
 
+/* vtable for org.freedesktop.sssd.infopipe.Domains.Domain */
+struct iface_ifp_domains_domain {
+    struct sbus_vtable vtable; /* derive from sbus_vtable */
+    int (*IsOnline)(struct sbus_request *req, void *data);
+    int (*ListServices)(struct sbus_request *req, void *data);
+};
+
+/* finish function for IsOnline */
+int iface_ifp_domains_domain_IsOnline_finish(struct sbus_request *req, bool arg_status);
+
+/* finish function for ListServices */
+int iface_ifp_domains_domain_ListServices_finish(struct sbus_request *req, const char *arg_services[], int len_services);
+
 /* vtable for org.freedesktop.sssd.infopipe.Cache */
 struct iface_ifp_cache {
     struct sbus_vtable vtable; /* derive from sbus_vtable */
@@ -326,6 +344,9 @@ 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.Domains.Domain */
+extern const struct sbus_interface_meta iface_ifp_domains_domain_meta;
+
 /* interface info for org.freedesktop.sssd.infopipe.Cache */
 extern const struct sbus_interface_meta iface_ifp_cache_meta;
 
diff --git a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
index 56c5644917ef69fb153531e072bc90f5e0d97d7e..4437fb3ba54e0c464a9d9a8ae27921b1dcf8d4c2 100644
--- a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
+++ b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf
@@ -31,6 +31,7 @@
 
     <allow send_interface="org.freedesktop.sssd.infopipe"/>
     <allow send_interface="org.freedesktop.sssd.infopipe.Domains"/>
+    <allow send_interface="org.freedesktop.sssd.infopipe.Domains.Domain"/>
     <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"/>
-- 
2.1.0

