URL: https://github.com/SSSD/sssd/pull/30
Author: pbrezina
 Title: #30: sssctl: use systemd D-Bus API
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/30/head:pr30
git checkout pr30
From 1123f7df5fc6da1e0d2f1518e268fc4a2acaf619 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Wed, 21 Sep 2016 12:25:43 +0200
Subject: [PATCH 1/2] sssctl: use systemd D-Bus API

If systemd is used we leverage it's D-Bus API instead of running systemctl.

Resolves:
https://fedorahosted.org/sssd/ticket/3056
---
 Makefile.am                       |   1 +
 src/tools/sssctl/sssctl.c         |  23 ++++---
 src/tools/sssctl/sssctl.h         |   4 ++
 src/tools/sssctl/sssctl_systemd.c | 136 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 154 insertions(+), 10 deletions(-)
 create mode 100644 src/tools/sssctl/sssctl_systemd.c

diff --git a/Makefile.am b/Makefile.am
index 1ea8f50..b5f300a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1573,6 +1573,7 @@ sss_override_CFLAGS = \
 
 sssctl_SOURCES = \
     src/tools/sssctl/sssctl.c \
+    src/tools/sssctl/sssctl_systemd.c \
     src/tools/sssctl/sssctl_cache.c \
     src/tools/sssctl/sssctl_data.c \
     src/tools/sssctl/sssctl_logs.c \
diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c
index 20ea26f..2ccb30e 100644
--- a/src/tools/sssctl/sssctl.c
+++ b/src/tools/sssctl/sssctl.c
@@ -26,12 +26,6 @@
 #include "tools/common/sss_tools.h"
 #include "tools/common/sss_process.h"
 
-#ifdef HAVE_SYSTEMD
-    #define SSSD_SVC_CMD(cmd) "systemctl " cmd " sssd.service"
-#else
-    #define SSSD_SVC_CMD(cmd) "service sssd " cmd
-#endif
-
 static const char *
 sssctl_prompt_str(enum sssctl_prompt_result result)
 {
@@ -125,14 +119,23 @@ errno_t sssctl_run_command(const char *command)
 
 static errno_t sssctl_manage_service(enum sssctl_svc_action action)
 {
-#if defined(HAVE_SYSTEMD) || defined(HAVE_SERVICE)
+#ifdef HAVE_SYSTEMD
+    switch (action) {
+    case SSSCTL_SVC_START:
+        return sssctl_systemd_start();
+    case SSSCTL_SVC_STOP:
+        return sssctl_systemd_stop();
+    case SSSCTL_SVC_RESTART:
+        return sssctl_systemd_restart();
+    }
+#elif HAVE_SERVICE
     switch (action) {
     case SSSCTL_SVC_START:
-        return sssctl_run_command(SSSD_SVC_CMD("start"));
+        return sssctl_run_command("service sssd start");
     case SSSCTL_SVC_STOP:
-        return sssctl_run_command(SSSD_SVC_CMD("stop"));
+        return sssctl_run_command("service sssd stop");
     case SSSCTL_SVC_RESTART:
-        return sssctl_run_command(SSSD_SVC_CMD("restart"));
+        return sssctl_run_command("service sssd restart");
     }
 #endif
 
diff --git a/src/tools/sssctl/sssctl.h b/src/tools/sssctl/sssctl.h
index d4e3359..5270a9e 100644
--- a/src/tools/sssctl/sssctl.h
+++ b/src/tools/sssctl/sssctl.h
@@ -70,6 +70,10 @@ sss_sifp_error _sssctl_sifp_send(TALLOC_CTX *mem_ctx,
     _sssctl_sifp_send(mem_ctx, sifp, reply, path, iface, method,         \
                       ##__VA_ARGS__, DBUS_TYPE_INVALID);
 
+errno_t sssctl_systemd_start(void);
+errno_t sssctl_systemd_stop(void);
+errno_t sssctl_systemd_restart(void);
+
 errno_t sssctl_domain_list(struct sss_cmdline *cmdline,
                            struct sss_tool_ctx *tool_ctx,
                            void *pvt);
diff --git a/src/tools/sssctl/sssctl_systemd.c b/src/tools/sssctl/sssctl_systemd.c
new file mode 100644
index 0000000..d5ce3b6
--- /dev/null
+++ b/src/tools/sssctl/sssctl_systemd.c
@@ -0,0 +1,136 @@
+/*
+    Authors:
+        Pavel Březina <pbrez...@redhat.com>
+
+    Copyright (C) 2016 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 <dbus/dbus.h>
+#include <errno.h>
+
+#include "util/util.h"
+#include "tools/sssctl/sssctl.h"
+
+#define SSS_SYSTEMD_BUS   "org.freedesktop.systemd1"
+#define SSS_SYSTEMD_PATH  "/org/freedesktop/systemd1"
+#define SSS_SYSTEMD_IFACE "org.freedesktop.systemd1.Manager"
+#define SSS_SYSTEMD_UNIT  "sssd.service"
+#define SSS_SYSTEMD_MODE  "replace" /* replace queued job if present */
+
+static DBusConnection *
+sssctl_systemd_connect(void)
+{
+    DBusConnection *conn;
+    DBusError error;
+
+    dbus_error_init(&error);
+
+    conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+    if (dbus_error_is_set(&error)) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to connect to systemd D-Bus "
+              "[%s]: %s\n", error.name, error.message);
+        conn = NULL;
+        goto done;
+    }
+
+done:
+    dbus_error_free(&error);
+    return conn;
+}
+
+static errno_t sssctl_systemd_call(const char *method)
+{
+    DBusConnection *conn = NULL;
+    DBusMessage *reply = NULL;
+    DBusMessage *msg = NULL;
+    DBusError error;
+    const char *unit = SSS_SYSTEMD_UNIT;
+    const char *mode = SSS_SYSTEMD_MODE;
+    const char *job;
+    errno_t ret;
+
+    dbus_error_init(&error);
+
+    conn = sssctl_systemd_connect();
+    if (conn == NULL) {
+        ret = EIO;
+        goto done;
+    }
+
+    msg = sbus_create_message(NULL, SSS_SYSTEMD_BUS, SSS_SYSTEMD_PATH,
+                              SSS_SYSTEMD_IFACE, method,
+                              DBUS_TYPE_STRING, &unit,
+                              DBUS_TYPE_STRING, &mode);
+    if (msg == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create D-Bus Message!\n");
+        ret = ENOMEM;
+        goto done;
+    }
+
+    reply = dbus_connection_send_with_reply_and_block(conn, msg, 5000, &error);
+    if (dbus_error_is_set(&error)) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send D-Bus message "
+                      "[%s]: %s\n", error.name, error.message);
+        ret = EIO;
+        goto done;
+    }
+
+    ret = sbus_parse_message(reply, DBUS_TYPE_OBJECT_PATH, &job);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get D-Bus reply [%d]: %s!\n",
+              ret, sss_strerror(ret));
+        goto done;
+    }
+
+    DEBUG(SSSDBG_TRACE_FUNC, "New systemd job created: %s\n", job);
+
+done:
+    if (msg != NULL) {
+        dbus_message_unref(msg);
+    }
+
+    if (reply != NULL) {
+        dbus_message_unref(reply);
+    }
+
+    if (conn != NULL) {
+        dbus_connection_unref(conn);
+    }
+
+    return ret;
+}
+
+errno_t sssctl_systemd_start(void)
+{
+    DEBUG(SSSDBG_TRACE_FUNC, "Starting SSSD via systemd...\n");
+
+    return sssctl_systemd_call("StartUnit");
+}
+
+errno_t sssctl_systemd_stop(void)
+{
+    DEBUG(SSSDBG_TRACE_FUNC, "Stopping SSSD via systemd...\n");
+
+    return sssctl_systemd_call("StopUnit");
+}
+
+errno_t sssctl_systemd_restart(void)
+{
+    DEBUG(SSSDBG_TRACE_FUNC, "Restarting SSSD via systemd...\n");
+
+    return sssctl_systemd_call("RestartUnit");
+}

From d894abbd86aa983a0ed7e582dc9514b7e1cb704d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Fri, 23 Sep 2016 12:02:11 +0200
Subject: [PATCH 2/2] sssctl: call service with absolute path

---
 src/tools/sssctl/sssctl.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c
index 2ccb30e..89f5d76 100644
--- a/src/tools/sssctl/sssctl.c
+++ b/src/tools/sssctl/sssctl.c
@@ -131,11 +131,11 @@ static errno_t sssctl_manage_service(enum sssctl_svc_action action)
 #elif HAVE_SERVICE
     switch (action) {
     case SSSCTL_SVC_START:
-        return sssctl_run_command("service sssd start");
+        return sssctl_run_command("/sbin/service sssd start");
     case SSSCTL_SVC_STOP:
-        return sssctl_run_command("service sssd stop");
+        return sssctl_run_command("/sbin/service sssd stop");
     case SSSCTL_SVC_RESTART:
-        return sssctl_run_command("service sssd restart");
+        return sssctl_run_command("/sbin/service sssd restart");
     }
 #endif
 
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org

Reply via email to