Blame SOURCES/0093-sbus-add-utility-function-to-simplify-message-and-re.patch

b2d430
From 420e47f6a0e173e774faa426d172c6e2160b8302 Mon Sep 17 00:00:00 2001
b2d430
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
b2d430
Date: Wed, 29 Jun 2016 12:35:59 +0200
b2d430
Subject: [PATCH 093/102] sbus: add utility function to simplify message and
b2d430
 reply handling
b2d430
MIME-Version: 1.0
b2d430
Content-Type: text/plain; charset=UTF-8
b2d430
Content-Transfer-Encoding: 8bit
b2d430
b2d430
This patch adds the ability to hook DBusMessage to a talloc context
b2d430
to remove the need of calling dbus_message_unref(). It also provides
b2d430
an automatical way to detect error in a reply so the caller does
b2d430
not need to parse it manually and the whole code around DBusError
b2d430
can be avoided.
b2d430
b2d430
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
b2d430
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
b2d430
(cherry picked from commit 439e08cdc5c83b3e5835cb0435983f1da2ffbaf1)
b2d430
---
b2d430
 Makefile.am                                      |   2 +
b2d430
 src/responder/common/data_provider/rdp_message.c |  85 ++-------
b2d430
 src/sbus/sssd_dbus.h                             |   2 +
b2d430
 src/sbus/sssd_dbus_utils.c                       | 226 +++++++++++++++++++++++
b2d430
 src/sbus/sssd_dbus_utils.h                       |  64 +++++++
b2d430
 src/tools/sssctl/sssctl_domains.c                |  32 +---
b2d430
 6 files changed, 313 insertions(+), 98 deletions(-)
b2d430
 create mode 100644 src/sbus/sssd_dbus_utils.c
b2d430
 create mode 100644 src/sbus/sssd_dbus_utils.h
b2d430
b2d430
diff --git a/Makefile.am b/Makefile.am
b2d430
index ee9b48c666a44781b582ba5d83102b705e898f29..1837e36da7302cb51c0b90e51b762ce0a87cd65f 100644
b2d430
--- a/Makefile.am
b2d430
+++ b/Makefile.am
b2d430
@@ -634,6 +634,7 @@ dist_noinst_HEADERS = \
b2d430
     src/sbus/sssd_dbus_private.h \
b2d430
     src/sbus/sssd_dbus_invokers.h \
b2d430
     src/sbus/sssd_dbus_errors.h \
b2d430
+    src/sbus/sssd_dbus_utils.h \
b2d430
     src/db/sysdb.h \
b2d430
     src/db/sysdb_sudo.h \
b2d430
     src/db/sysdb_autofs.h \
b2d430
@@ -915,6 +916,7 @@ libsss_util_la_SOURCES = \
b2d430
     src/sbus/sssd_dbus_server.c \
b2d430
     src/sbus/sssd_dbus_signals.c \
b2d430
     src/sbus/sssd_dbus_common_signals.c \
b2d430
+    src/sbus/sssd_dbus_utils.c \
b2d430
     src/util/util.c \
b2d430
     src/util/memory.c \
b2d430
     src/util/safe-format-string.c \
b2d430
diff --git a/src/responder/common/data_provider/rdp_message.c b/src/responder/common/data_provider/rdp_message.c
b2d430
index e226401567e4a1b2b9784a9aba21540ff5f0bc8d..6ad2ba056e992cd89b87b478d422d1a4259a12d9 100644
b2d430
--- a/src/responder/common/data_provider/rdp_message.c
b2d430
+++ b/src/responder/common/data_provider/rdp_message.c
b2d430
@@ -26,33 +26,6 @@
b2d430
 #include "sbus/sssd_dbus_errors.h"
b2d430
 #include "util/util.h"
b2d430
 
b2d430
-static errno_t rdp_error_to_errno(DBusError *error)
b2d430
-{
b2d430
-    static struct {
b2d430
-        const char *name;
b2d430
-        errno_t ret;
b2d430
-    } list[] = {{SBUS_ERROR_INTERNAL, ERR_INTERNAL},
b2d430
-                {SBUS_ERROR_NOT_FOUND, ENOENT},
b2d430
-                {SBUS_ERROR_DP_FATAL, ERR_TERMINATED},
b2d430
-                {SBUS_ERROR_DP_OFFLINE, ERR_OFFLINE},
b2d430
-                {SBUS_ERROR_DP_NOTSUP, ENOTSUP},
b2d430
-                {NULL, ERR_INTERNAL}
b2d430
-    };
b2d430
-    int i;
b2d430
-
b2d430
-    if (!dbus_error_is_set(error)) {
b2d430
-        return EOK;
b2d430
-    }
b2d430
-
b2d430
-    for (i = 0; list[i].name != NULL; i ++) {
b2d430
-        if (dbus_error_has_name(error, list[i].name)) {
b2d430
-            return list[i].ret;
b2d430
-        }
b2d430
-    }
b2d430
-
b2d430
-    return EIO;
b2d430
-}
b2d430
-
b2d430
 static errno_t
b2d430
 rdp_message_send_internal(struct resp_ctx *rctx,
b2d430
                           struct sss_domain_info *domain,
b2d430
@@ -110,7 +83,8 @@ done:
b2d430
     return ret;
b2d430
 }
b2d430
 
b2d430
-static errno_t rdp_process_pending_call(DBusPendingCall *pending,
b2d430
+static errno_t rdp_process_pending_call(TALLOC_CTX *mem_ctx,
b2d430
+                                        DBusPendingCall *pending,
b2d430
                                         DBusMessage **_reply)
b2d430
 {
b2d430
     DBusMessage *reply;
b2d430
@@ -130,6 +104,11 @@ static errno_t rdp_process_pending_call(DBusPendingCall *pending,
b2d430
         goto done;
b2d430
     }
b2d430
 
b2d430
+    ret = sbus_talloc_bound_message(mem_ctx, reply);
b2d430
+    if (ret != EOK) {
b2d430
+        return ret;
b2d430
+    }
b2d430
+
b2d430
     switch (dbus_message_get_type(reply)) {
b2d430
     case DBUS_MESSAGE_TYPE_METHOD_RETURN:
b2d430
         DEBUG(SSSDBG_TRACE_FUNC, "DP Success\n");
b2d430
@@ -146,10 +125,9 @@ static errno_t rdp_process_pending_call(DBusPendingCall *pending,
b2d430
 
b2d430
         DEBUG(SSSDBG_CRIT_FAILURE, "DP Error [%s]: %s\n",
b2d430
               error.name, (error.message == NULL ? "(null)" : error.message));
b2d430
-        ret = rdp_error_to_errno(&error);
b2d430
+        ret = sbus_error_to_errno(&error);
b2d430
         break;
b2d430
     default:
b2d430
-        dbus_message_unref(reply);
b2d430
         DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected type?\n");
b2d430
         ret = ERR_INTERNAL;
b2d430
         goto done;
b2d430
@@ -168,15 +146,6 @@ struct rdp_message_state {
b2d430
     struct DBusMessage *reply;
b2d430
 };
b2d430
 
b2d430
-static int rdp_message_state_destructor(struct rdp_message_state *state)
b2d430
-{
b2d430
-    if (state->reply != NULL) {
b2d430
-        dbus_message_unref(state->reply);
b2d430
-    }
b2d430
-
b2d430
-    return 0;
b2d430
-}
b2d430
-
b2d430
 static void rdp_message_done(DBusPendingCall *pending, void *ptr);
b2d430
 
b2d430
 struct tevent_req *_rdp_message_send(TALLOC_CTX *mem_ctx,
b2d430
@@ -199,8 +168,6 @@ struct tevent_req *_rdp_message_send(TALLOC_CTX *mem_ctx,
b2d430
         return NULL;
b2d430
     }
b2d430
 
b2d430
-    talloc_set_destructor(state, rdp_message_state_destructor);
b2d430
-
b2d430
     va_start(va, first_arg_type);
b2d430
     ret = rdp_message_send_internal(rctx, domain, rdp_message_done, req,
b2d430
                                     path, iface, method, first_arg_type, va);
b2d430
@@ -233,14 +200,8 @@ static void rdp_message_done(DBusPendingCall *pending, void *ptr)
b2d430
     req = talloc_get_type(ptr, struct tevent_req);
b2d430
     state = tevent_req_data(req, struct rdp_message_state);
b2d430
 
b2d430
-    ret = rdp_process_pending_call(pending, &state->reply);
b2d430
+    ret = rdp_process_pending_call(state, pending, &state->reply);
b2d430
     if (ret != EOK) {
b2d430
-        if (state->reply != NULL) {
b2d430
-            dbus_message_unref(state->reply);
b2d430
-        }
b2d430
-
b2d430
-        state->reply = NULL;
b2d430
-
b2d430
         tevent_req_error(req, ret);
b2d430
         return;
b2d430
     }
b2d430
@@ -253,35 +214,17 @@ errno_t _rdp_message_recv(struct tevent_req *req,
b2d430
                           ...)
b2d430
 {
b2d430
     struct rdp_message_state *state;
b2d430
-    DBusError error;
b2d430
-    dbus_bool_t bret;
b2d430
     errno_t ret;
b2d430
     va_list va;
b2d430
 
b2d430
     TEVENT_REQ_RETURN_ON_ERROR(req);
b2d430
 
b2d430
     state = tevent_req_data(req, struct rdp_message_state);
b2d430
-    dbus_error_init(&error);
b2d430
 
b2d430
     va_start(va, first_arg_type);
b2d430
-    bret = dbus_message_get_args_valist(state->reply, &error, first_arg_type, va);
b2d430
+    ret = sbus_parse_message_valist(state->reply, false, first_arg_type, va);
b2d430
     va_end(va);
b2d430
 
b2d430
-    if (bret == false) {
b2d430
-        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse reply\n");
b2d430
-        ret = EIO;
b2d430
-        goto done;
b2d430
-    }
b2d430
-
b2d430
-    ret = rdp_error_to_errno(&error);
b2d430
-    if (ret != EOK) {
b2d430
-        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse message [%s]: %s\n",
b2d430
-              error.name, error.message);
b2d430
-        goto done;
b2d430
-    }
b2d430
-
b2d430
-done:
b2d430
-    dbus_error_free(&error);
b2d430
     return ret;
b2d430
 }
b2d430
 
b2d430
@@ -317,7 +260,7 @@ static void rdp_message_send_and_reply_done(DBusPendingCall *pending,
b2d430
                                             void *ptr)
b2d430
 {
b2d430
     struct sbus_request *sbus_req;
b2d430
-    DBusMessage *reply = NULL;
b2d430
+    DBusMessage *reply;
b2d430
     dbus_uint32_t serial;
b2d430
     const char *sender;
b2d430
     dbus_bool_t dbret;
b2d430
@@ -325,7 +268,7 @@ static void rdp_message_send_and_reply_done(DBusPendingCall *pending,
b2d430
 
b2d430
     sbus_req = talloc_get_type(ptr, struct sbus_request);
b2d430
 
b2d430
-    ret = rdp_process_pending_call(pending, &reply);
b2d430
+    ret = rdp_process_pending_call(sbus_req, pending, &reply);
b2d430
     if (reply == NULL) {
b2d430
         /* Something bad happened. Just kill the request. */
b2d430
         ret = EIO;
b2d430
@@ -358,10 +301,6 @@ static void rdp_message_send_and_reply_done(DBusPendingCall *pending,
b2d430
     ret = EOK;
b2d430
 
b2d430
 done:
b2d430
-    if (reply != NULL) {
b2d430
-        dbus_message_unref(reply);
b2d430
-    }
b2d430
-
b2d430
     if (ret != EOK) {
b2d430
         /* Something bad happend, just kill the request. */
b2d430
         talloc_free(sbus_req);
b2d430
diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h
b2d430
index c0aedf36b496bfda05dcde921ea7060efb4cc91f..15e3b117e1a467f4e250cdf4ba8fd0326e4d380e 100644
b2d430
--- a/src/sbus/sssd_dbus.h
b2d430
+++ b/src/sbus/sssd_dbus.h
b2d430
@@ -29,6 +29,8 @@ struct sbus_request;
b2d430
 #include <dbus/dbus.h>
b2d430
 #include <sys/types.h>
b2d430
 #include "util/util.h"
b2d430
+#include "sbus/sssd_dbus_errors.h"
b2d430
+#include "sbus/sssd_dbus_utils.h"
b2d430
 
b2d430
 /* Older platforms (such as RHEL-6) might not have these error constants
b2d430
  * defined */
b2d430
diff --git a/src/sbus/sssd_dbus_utils.c b/src/sbus/sssd_dbus_utils.c
b2d430
new file mode 100644
b2d430
index 0000000000000000000000000000000000000000..4c33f9fd75cac2d4a56a5638982f8ecb73da8e2e
b2d430
--- /dev/null
b2d430
+++ b/src/sbus/sssd_dbus_utils.c
b2d430
@@ -0,0 +1,226 @@
b2d430
+/*
b2d430
+    Authors:
b2d430
+        Pavel Březina <pbrezina@redhat.com>
b2d430
+
b2d430
+    Copyright (C) 2016 Red Hat
b2d430
+
b2d430
+    This program is free software; you can redistribute it and/or modify
b2d430
+    it under the terms of the GNU General Public License as published by
b2d430
+    the Free Software Foundation; either version 3 of the License, or
b2d430
+    (at your option) any later version.
b2d430
+
b2d430
+    This program is distributed in the hope that it will be useful,
b2d430
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
b2d430
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
b2d430
+    GNU General Public License for more details.
b2d430
+
b2d430
+    You should have received a copy of the GNU General Public License
b2d430
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
b2d430
+*/
b2d430
+
b2d430
+#include <talloc.h>
b2d430
+
b2d430
+#include "sbus/sssd_dbus.h"
b2d430
+#include "util/util.h"
b2d430
+
b2d430
+struct sbus_talloc_msg {
b2d430
+    DBusMessage *msg;
b2d430
+};
b2d430
+
b2d430
+static int sbus_talloc_msg_destructor(struct sbus_talloc_msg *talloc_msg)
b2d430
+{
b2d430
+    if (talloc_msg->msg == NULL) {
b2d430
+        return 0;
b2d430
+    }
b2d430
+
b2d430
+    dbus_message_unref(talloc_msg->msg);
b2d430
+    return 0;
b2d430
+}
b2d430
+
b2d430
+errno_t sbus_talloc_bound_message(TALLOC_CTX *mem_ctx, DBusMessage *msg)
b2d430
+{
b2d430
+    struct sbus_talloc_msg *talloc_msg;
b2d430
+
b2d430
+    talloc_msg = talloc(mem_ctx, struct sbus_talloc_msg);
b2d430
+    if (talloc_msg == NULL) {
b2d430
+        DEBUG(SSSDBG_CRIT_FAILURE,
b2d430
+              "Unable to bound D-Bus message with talloc context!\n");
b2d430
+        return ENOMEM;
b2d430
+    }
b2d430
+
b2d430
+    talloc_msg->msg = msg;
b2d430
+
b2d430
+    talloc_set_destructor(talloc_msg, sbus_talloc_msg_destructor);
b2d430
+
b2d430
+    return EOK;
b2d430
+}
b2d430
+
b2d430
+errno_t sbus_error_to_errno(DBusError *error)
b2d430
+{
b2d430
+    static struct {
b2d430
+        const char *name;
b2d430
+        errno_t ret;
b2d430
+    } list[] = { { SBUS_ERROR_INTERNAL, ERR_INTERNAL },
b2d430
+                 { SBUS_ERROR_NOT_FOUND, ENOENT },
b2d430
+                 { SBUS_ERROR_UNKNOWN_DOMAIN, ERR_DOMAIN_NOT_FOUND },
b2d430
+                 { SBUS_ERROR_DP_FATAL, ERR_TERMINATED },
b2d430
+                 { SBUS_ERROR_DP_OFFLINE, ERR_OFFLINE },
b2d430
+                 { SBUS_ERROR_DP_NOTSUP, ENOTSUP },
b2d430
+                 { NULL, ERR_INTERNAL } };
b2d430
+    int i;
b2d430
+
b2d430
+    if (!dbus_error_is_set(error)) {
b2d430
+        return EOK;
b2d430
+    }
b2d430
+
b2d430
+    for (i = 0; list[i].name != NULL; i++) {
b2d430
+        if (dbus_error_has_name(error, list[i].name)) {
b2d430
+            return list[i].ret;
b2d430
+        }
b2d430
+    }
b2d430
+
b2d430
+    return EIO;
b2d430
+}
b2d430
+
b2d430
+errno_t sbus_check_reply(DBusMessage *reply)
b2d430
+{
b2d430
+    dbus_bool_t bret;
b2d430
+    DBusError error;
b2d430
+    errno_t ret;
b2d430
+
b2d430
+    dbus_error_init(&error);
b2d430
+
b2d430
+    switch (dbus_message_get_type(reply)) {
b2d430
+    case DBUS_MESSAGE_TYPE_METHOD_RETURN:
b2d430
+        ret = EOK;
b2d430
+        goto done;
b2d430
+
b2d430
+    case DBUS_MESSAGE_TYPE_ERROR:
b2d430
+        bret = dbus_set_error_from_message(&error, reply);
b2d430
+        if (bret == false) {
b2d430
+            DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read error from message\n");
b2d430
+            ret = EIO;
b2d430
+            goto done;
b2d430
+        }
b2d430
+
b2d430
+        DEBUG(SSSDBG_CRIT_FAILURE, "D-Bus error [%s]: %s\n",
b2d430
+              error.name, (error.message == NULL ? "(null)" : error.message));
b2d430
+        ret = sbus_error_to_errno(&error);
b2d430
+        goto done;
b2d430
+    default:
b2d430
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected D-Bus message type?\n");
b2d430
+        ret = ERR_INTERNAL;
b2d430
+        goto done;
b2d430
+    }
b2d430
+
b2d430
+done:
b2d430
+    dbus_error_free(&error);
b2d430
+
b2d430
+    return ret;
b2d430
+}
b2d430
+
b2d430
+DBusMessage *sbus_create_message_valist(TALLOC_CTX *mem_ctx,
b2d430
+                                        const char *bus,
b2d430
+                                        const char *path,
b2d430
+                                        const char *iface,
b2d430
+                                        const char *method,
b2d430
+                                        int first_arg_type,
b2d430
+                                        va_list va)
b2d430
+{
b2d430
+    DBusMessage *msg;
b2d430
+    dbus_bool_t bret;
b2d430
+    errno_t ret;
b2d430
+
b2d430
+    msg = dbus_message_new_method_call(bus, path, iface, method);
b2d430
+    if (msg == NULL) {
b2d430
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create message\n");
b2d430
+        return NULL;
b2d430
+    }
b2d430
+
b2d430
+    bret = dbus_message_append_args_valist(msg, first_arg_type, va);
b2d430
+    if (!bret) {
b2d430
+        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n");
b2d430
+        ret = EIO;
b2d430
+        goto done;
b2d430
+    }
b2d430
+
b2d430
+    ret = sbus_talloc_bound_message(mem_ctx, msg);
b2d430
+
b2d430
+done:
b2d430
+    if (ret != EOK) {
b2d430
+        dbus_message_unref(msg);
b2d430
+    }
b2d430
+
b2d430
+    return msg;
b2d430
+}
b2d430
+
b2d430
+DBusMessage *_sbus_create_message(TALLOC_CTX *mem_ctx,
b2d430
+                                  const char *bus,
b2d430
+                                  const char *path,
b2d430
+                                  const char *iface,
b2d430
+                                  const char *method,
b2d430
+                                  int first_arg_type,
b2d430
+                                  ...)
b2d430
+{
b2d430
+    DBusMessage *msg;
b2d430
+    va_list va;
b2d430
+
b2d430
+    va_start(va, first_arg_type);
b2d430
+    msg = sbus_create_message_valist(mem_ctx, bus, path, iface, method,
b2d430
+                                     first_arg_type, va);
b2d430
+    va_end(va);
b2d430
+
b2d430
+    return msg;
b2d430
+}
b2d430
+
b2d430
+errno_t sbus_parse_message_valist(DBusMessage *msg,
b2d430
+                                  bool check_reply,
b2d430
+                                  int first_arg_type,
b2d430
+                                  va_list va)
b2d430
+{
b2d430
+    DBusError error;
b2d430
+    dbus_bool_t bret;
b2d430
+    errno_t ret;
b2d430
+
b2d430
+    if (check_reply) {
b2d430
+        ret = sbus_check_reply(msg);
b2d430
+        if (ret != EOK) {
b2d430
+            return ret;
b2d430
+        }
b2d430
+    }
b2d430
+
b2d430
+    dbus_error_init(&error);
b2d430
+
b2d430
+    bret = dbus_message_get_args_valist(msg, &error, first_arg_type, va);
b2d430
+    if (bret == false) {
b2d430
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse D-Bus message\n");
b2d430
+        ret = EIO;
b2d430
+        goto done;
b2d430
+    }
b2d430
+
b2d430
+    ret = sbus_error_to_errno(&error);
b2d430
+    if (ret != EOK) {
b2d430
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse D-Bus message [%s]: %s\n",
b2d430
+              error.name, error.message);
b2d430
+        goto done;
b2d430
+    }
b2d430
+
b2d430
+done:
b2d430
+    dbus_error_free(&error);
b2d430
+    return ret;
b2d430
+}
b2d430
+
b2d430
+errno_t _sbus_parse_message(DBusMessage *msg,
b2d430
+                            bool check_reply,
b2d430
+                            int first_arg_type,
b2d430
+                            ...)
b2d430
+{
b2d430
+    errno_t ret;
b2d430
+    va_list va;
b2d430
+
b2d430
+    va_start(va, first_arg_type);
b2d430
+    ret = sbus_parse_message_valist(msg, check_reply, first_arg_type, va);
b2d430
+    va_end(va);
b2d430
+
b2d430
+    return ret;
b2d430
+}
b2d430
diff --git a/src/sbus/sssd_dbus_utils.h b/src/sbus/sssd_dbus_utils.h
b2d430
new file mode 100644
b2d430
index 0000000000000000000000000000000000000000..74c21fb7930c7f5f5417b6a2587cf691b1bc0b19
b2d430
--- /dev/null
b2d430
+++ b/src/sbus/sssd_dbus_utils.h
b2d430
@@ -0,0 +1,64 @@
b2d430
+/*
b2d430
+    Authors:
b2d430
+        Pavel Březina <pbrezina@redhat.com>
b2d430
+
b2d430
+    Copyright (C) 2016 Red Hat
b2d430
+
b2d430
+    This program is free software; you can redistribute it and/or modify
b2d430
+    it under the terms of the GNU General Public License as published by
b2d430
+    the Free Software Foundation; either version 3 of the License, or
b2d430
+    (at your option) any later version.
b2d430
+
b2d430
+    This program is distributed in the hope that it will be useful,
b2d430
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
b2d430
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
b2d430
+    GNU General Public License for more details.
b2d430
+
b2d430
+    You should have received a copy of the GNU General Public License
b2d430
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
b2d430
+*/
b2d430
+
b2d430
+#ifndef SSSD_DBUS_UTILS_H_
b2d430
+#define SSSD_DBUS_UTILS_H_
b2d430
+
b2d430
+errno_t sbus_talloc_bound_message(TALLOC_CTX *mem_ctx, DBusMessage *msg);
b2d430
+errno_t sbus_error_to_errno(DBusError *error);
b2d430
+errno_t sbus_check_reply(DBusMessage *reply);
b2d430
+
b2d430
+DBusMessage *sbus_create_message_valist(TALLOC_CTX *mem_ctx,
b2d430
+                                        const char *bus,
b2d430
+                                        const char *path,
b2d430
+                                        const char *iface,
b2d430
+                                        const char *method,
b2d430
+                                        int first_arg_type,
b2d430
+                                        va_list va);
b2d430
+
b2d430
+DBusMessage *_sbus_create_message(TALLOC_CTX *mem_ctx,
b2d430
+                                  const char *bus,
b2d430
+                                  const char *path,
b2d430
+                                  const char *iface,
b2d430
+                                  const char *method,
b2d430
+                                  int first_arg_type,
b2d430
+                                  ...);
b2d430
+
b2d430
+#define sbus_create_message(mem_ctx, bus, path, iface, method, ...) \
b2d430
+    _sbus_create_message(mem_ctx, bus, path, iface, method,         \
b2d430
+                         ##__VA_ARGS__, DBUS_TYPE_INVALID)
b2d430
+
b2d430
+errno_t sbus_parse_message_valist(DBusMessage *msg,
b2d430
+                                  bool check_reply,
b2d430
+                                  int first_arg_type,
b2d430
+                                  va_list va);
b2d430
+
b2d430
+errno_t _sbus_parse_message(DBusMessage *msg,
b2d430
+                            bool check_reply,
b2d430
+                            int first_arg_type,
b2d430
+                            ...);
b2d430
+
b2d430
+#define sbus_parse_message(msg, ...) \
b2d430
+    _sbus_parse_message(msg, false, ##__VA_ARGS__, DBUS_TYPE_INVALID)
b2d430
+
b2d430
+#define sbus_parse_reply(msg, ...) \
b2d430
+    _sbus_parse_message(msg, true, ##__VA_ARGS__, DBUS_TYPE_INVALID)
b2d430
+
b2d430
+#endif /* SSSD_DBUS_UTILS_H_ */
b2d430
diff --git a/src/tools/sssctl/sssctl_domains.c b/src/tools/sssctl/sssctl_domains.c
b2d430
index cfc4e56133213e27496350033d4d28c3f5b5c63d..17ad670f39dfc045ba090210ffcfa77df713c306 100644
b2d430
--- a/src/tools/sssctl/sssctl_domains.c
b2d430
+++ b/src/tools/sssctl/sssctl_domains.c
b2d430
@@ -79,15 +79,11 @@ static errno_t sssctl_domain_status_online(struct sss_tool_ctx *tool_ctx,
b2d430
 {
b2d430
     sss_sifp_ctx *sifp;
b2d430
     sss_sifp_error sifp_error;
b2d430
-    DBusError dbus_error;
b2d430
     DBusMessage *reply = NULL;
b2d430
-    DBusMessage *msg = NULL;
b2d430
+    DBusMessage *msg;
b2d430
     bool is_online;
b2d430
-    dbus_bool_t dbret;
b2d430
     errno_t ret;
b2d430
 
b2d430
-    dbus_error_init(&dbus_error);
b2d430
-
b2d430
     if (!sssctl_start_sssd(force_start)) {
b2d430
         ret = ERR_SSSD_NOT_RUNNING;
b2d430
         goto done;
b2d430
@@ -100,16 +96,15 @@ static errno_t sssctl_domain_status_online(struct sss_tool_ctx *tool_ctx,
b2d430
         goto done;
b2d430
     }
b2d430
 
b2d430
-
b2d430
-    msg = sss_sifp_create_message(domain_path, IFACE_IFP_DOMAINS_DOMAIN,
b2d430
-                                  IFACE_IFP_DOMAINS_DOMAIN_ISONLINE);
b2d430
+    msg = sbus_create_message(tool_ctx, SSS_SIFP_ADDRESS, domain_path,
b2d430
+                              IFACE_IFP_DOMAINS_DOMAIN,
b2d430
+                              IFACE_IFP_DOMAINS_DOMAIN_ISONLINE);
b2d430
     if (msg == NULL) {
b2d430
         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create D-Bus message\n");
b2d430
         ret = ENOMEM;
b2d430
         goto done;
b2d430
     }
b2d430
 
b2d430
-
b2d430
     sifp_error = sss_sifp_send_message(sifp, msg, &reply);
b2d430
     if (sifp_error != SSS_SIFP_OK) {
b2d430
         sssctl_sifp_error(sifp, sifp_error, "Unable to get online status");
b2d430
@@ -117,16 +112,9 @@ static errno_t sssctl_domain_status_online(struct sss_tool_ctx *tool_ctx,
b2d430
         goto done;
b2d430
     }
b2d430
 
b2d430
-    dbret = dbus_message_get_args(reply, &dbus_error,
b2d430
-                                  DBUS_TYPE_BOOLEAN, &is_online,
b2d430
-                                  DBUS_TYPE_INVALID);
b2d430
-    if (!dbret) {
b2d430
-        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse D-Bus reply\n");
b2d430
-        if (dbus_error_is_set(&dbus_error)) {
b2d430
-            DEBUG(SSSDBG_CRIT_FAILURE, "%s: %s\n",
b2d430
-                  dbus_error.name, dbus_error.message);
b2d430
-        }
b2d430
-        ret = EIO;
b2d430
+    ret = sbus_parse_reply(reply, DBUS_TYPE_BOOLEAN, &is_online);
b2d430
+    if (ret != EOK) {
b2d430
+        fprintf(stderr, _("Unable to get information from SSSD\n"));
b2d430
         goto done;
b2d430
     }
b2d430
 
b2d430
@@ -135,16 +123,10 @@ static errno_t sssctl_domain_status_online(struct sss_tool_ctx *tool_ctx,
b2d430
     ret = EOK;
b2d430
 
b2d430
 done:
b2d430
-    if (msg != NULL) {
b2d430
-        dbus_message_unref(msg);
b2d430
-    }
b2d430
-
b2d430
     if (reply != NULL) {
b2d430
         dbus_message_unref(reply);
b2d430
     }
b2d430
 
b2d430
-    dbus_error_free(&dbus_error);
b2d430
-
b2d430
     return ret;
b2d430
 }
b2d430
 
b2d430
-- 
b2d430
2.4.11
b2d430