Blame SOURCES/0026-SSSD-Load-a-user-to-run-a-service-as-from-configurat.patch

905b4d
From b8a3625690f39e22d8cd699598384bad472b6373 Mon Sep 17 00:00:00 2001
905b4d
From: Jakub Hrozek <jhrozek@redhat.com>
905b4d
Date: Tue, 5 Aug 2014 13:52:48 +0200
905b4d
Subject: [PATCH 26/46] SSSD: Load a user to run a service as from
905b4d
 configuration
905b4d
905b4d
Related:
905b4d
    https://fedorahosted.org/sssd/ticket/2370
905b4d
905b4d
Adds a option, user to run as, that is specified in the [sssd] section. When
905b4d
this option is specified, SSSD will run as this user and his private
905b4d
group. When these are not specified, SSSD will run as the configure-time
905b4d
user and group (usually root).
905b4d
905b4d
Currently all services and providers are started as root. There is a
905b4d
temporary svc_supported_as_nonroot() function that returns true for a
905b4d
service if that service runs and was tested as nonroot and false
905b4d
otherwise. Currently this function always returns false, but will be
905b4d
amended in future patches.
905b4d
905b4d
Reviewed-by: Pavel Reichl <preichl@redhat.com>
905b4d
Reviewed-by: Simo Sorce <simo@redhat.com>
905b4d
(cherry picked from commit a10ac1d0a7210def232205a48c53a075930e82f6)
905b4d
---
905b4d
 src/confdb/confdb.h                  |  1 +
905b4d
 src/config/SSSDConfig/__init__.py.in |  1 +
905b4d
 src/config/SSSDConfigTest.py         |  1 +
905b4d
 src/config/etc/sssd.api.conf         |  1 +
905b4d
 src/man/sssd.conf.5.xml              | 13 +++++++++
905b4d
 src/monitor/monitor.c                | 56 ++++++++++++++++++++++++++++++++++++
905b4d
 6 files changed, 73 insertions(+)
905b4d
905b4d
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
905b4d
index 34d4610654c24017bcad8608332c71232d665d40..159aa9f2c44ed91c94a40c98d5a7710793f0aa85 100644
905b4d
--- a/src/confdb/confdb.h
905b4d
+++ b/src/confdb/confdb.h
905b4d
@@ -69,6 +69,7 @@
905b4d
 #define CONFDB_MONITOR_KRB5_RCACHEDIR "krb5_rcache_dir"
905b4d
 #define CONFDB_MONITOR_DEFAULT_DOMAIN "default_domain_suffix"
905b4d
 #define CONFDB_MONITOR_OVERRIDE_SPACE "override_space"
905b4d
+#define CONFDB_MONITOR_USER_RUNAS "user"
905b4d
 
905b4d
 /* Both monitor and domains */
905b4d
 #define CONFDB_NAME_REGEX   "re_expression"
905b4d
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
905b4d
index 6c95530868d7c078ccf13622f3ba916392b0c732..b4560ea2b33f2c3b82bff42fb6a36302a146c99f 100644
905b4d
--- a/src/config/SSSDConfig/__init__.py.in
905b4d
+++ b/src/config/SSSDConfig/__init__.py.in
905b4d
@@ -56,6 +56,7 @@ option_strings = {
905b4d
     'full_name_format' : _('Printf-compatible format for displaying fully-qualified names'),
905b4d
     'krb5_rcache_dir' : _('Directory on the filesystem where SSSD should store Kerberos replay cache files.'),
905b4d
     'default_domain_suffix' : _('Domain to add to names without a domain component.'),
905b4d
+    'user' : _('The user to drop privileges to'),
905b4d
 
905b4d
     # [nss]
905b4d
     'enum_cache_timeout' : _('Enumeration cache timeout length (seconds)'),
905b4d
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
905b4d
index 2d12bc02af1768d22c8bfa9a21b1fc24bf199af4..78e22f6eff19aac8289d769dc9f565b2d548f4b3 100755
905b4d
--- a/src/config/SSSDConfigTest.py
905b4d
+++ b/src/config/SSSDConfigTest.py
905b4d
@@ -280,6 +280,7 @@ class SSSDConfigTestSSSDService(unittest.TestCase):
905b4d
             're_expression',
905b4d
             'full_name_format',
905b4d
             'krb5_rcache_dir',
905b4d
+            'user',
905b4d
             'default_domain_suffix',
905b4d
             'debug_level',
905b4d
             'debug_timestamps',
905b4d
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
905b4d
index a20f5aa44dbadd24f644bffc9954df9e088979b9..c16769a3985f495922d255dacebccc11f6a0ea1d 100644
905b4d
--- a/src/config/etc/sssd.api.conf
905b4d
+++ b/src/config/etc/sssd.api.conf
905b4d
@@ -23,6 +23,7 @@ sbus_timeout = int, None, false
905b4d
 re_expression = str, None, false
905b4d
 full_name_format = str, None, false
905b4d
 krb5_rcache_dir = str, None, false
905b4d
+user = str, None, false
905b4d
 default_domain_suffix = str, None, false
905b4d
 
905b4d
 [nss]
905b4d
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
905b4d
index 77690432b841221328d65403830cf4a1ac12dba0..e2cb0b81b61063750995064b6ce83f9615049534 100644
905b4d
--- a/src/man/sssd.conf.5.xml
905b4d
+++ b/src/man/sssd.conf.5.xml
905b4d
@@ -297,6 +297,19 @@
905b4d
                         </listitem>
905b4d
                     </varlistentry>
905b4d
                     <varlistentry>
905b4d
+                        <term>user (string)</term>
905b4d
+                        <listitem>
905b4d
+                            <para>
905b4d
+                                The user to drop the privileges to where
905b4d
+                                appropriate to avoid running as the
905b4d
+                                root user.
905b4d
+                            </para>
905b4d
+                            <para>
905b4d
+                                Default: not set, process will run as root
905b4d
+                            </para>
905b4d
+                        </listitem>
905b4d
+                    </varlistentry>
905b4d
+                    <varlistentry>
905b4d
                         <term>default_domain_suffix (string)</term>
905b4d
                         <listitem>
905b4d
                             <para>
905b4d
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
905b4d
index edd1c2dfc674d8a7ca9d069d6499c0dcc959f210..df1cd5ca14c759f7aab98094a2b8ad35731c35e6 100644
905b4d
--- a/src/monitor/monitor.c
905b4d
+++ b/src/monitor/monitor.c
905b4d
@@ -170,6 +170,10 @@ struct mt_ctx {
905b4d
     struct sss_sigchild_ctx *sigchld_ctx;
905b4d
     bool is_daemon;
905b4d
     pid_t parent_pid;
905b4d
+
905b4d
+    /* For running unprivileged services */
905b4d
+    uid_t uid;
905b4d
+    gid_t gid;
905b4d
 };
905b4d
 
905b4d
 static int start_service(struct mt_svc *mt_svc);
905b4d
@@ -910,6 +914,29 @@ static char *check_services(char **services)
905b4d
     return NULL;
905b4d
 }
905b4d
 
905b4d
+static int get_service_user(struct mt_ctx *ctx)
905b4d
+{
905b4d
+    errno_t ret;
905b4d
+    char *user_str;
905b4d
+
905b4d
+    ret = confdb_get_string(ctx->cdb, ctx, CONFDB_MONITOR_CONF_ENTRY,
905b4d
+                            CONFDB_MONITOR_USER_RUNAS,
905b4d
+                            SSSD_USER, &user_str);
905b4d
+    if (ret != EOK) {
905b4d
+        DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get the user to run as\n");
905b4d
+        return ret;
905b4d
+    }
905b4d
+
905b4d
+    ret = sss_user_by_name_or_uid(user_str, &ctx->uid, &ctx->gid);
905b4d
+    talloc_free(user_str);
905b4d
+    if (ret != EOK) {
905b4d
+        DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set allowed UIDs.\n");
905b4d
+        return ret;
905b4d
+    }
905b4d
+
905b4d
+    return EOK;
905b4d
+}
905b4d
+
905b4d
 static int get_monitor_config(struct mt_ctx *ctx)
905b4d
 {
905b4d
     int ret;
905b4d
@@ -955,6 +982,12 @@ static int get_monitor_config(struct mt_ctx *ctx)
905b4d
         ctx->num_services++;
905b4d
     }
905b4d
 
905b4d
+    ret = get_service_user(ctx);
905b4d
+    if (ret != EOK) {
905b4d
+        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get the unprivileged user\n");
905b4d
+        return ret;
905b4d
+    }
905b4d
+
905b4d
     ret = confdb_get_domains(ctx->cdb, &ctx->domains);
905b4d
     if (ret != EOK) {
905b4d
         DEBUG(SSSDBG_FATAL_FAILURE, "No domains configured.\n");
905b4d
@@ -1020,6 +1053,14 @@ static errno_t get_ping_config(struct mt_ctx *ctx, const char *path,
905b4d
     return EOK;
905b4d
 }
905b4d
 
905b4d
+/* This is a temporary function that returns false if the service
905b4d
+ * being started was only tested when running as root.
905b4d
+ */
905b4d
+static bool svc_supported_as_nonroot(const char *svc_name)
905b4d
+{
905b4d
+    return false;
905b4d
+}
905b4d
+
905b4d
 static int get_service_config(struct mt_ctx *ctx, const char *name,
905b4d
                               struct mt_svc **svc_cfg)
905b4d
 {
905b4d
@@ -1027,6 +1068,8 @@ static int get_service_config(struct mt_ctx *ctx, const char *name,
905b4d
     char *path;
905b4d
     struct mt_svc *svc;
905b4d
     time_t now = time(NULL);
905b4d
+    uid_t uid = 0;
905b4d
+    gid_t gid = 0;
905b4d
 
905b4d
     *svc_cfg = NULL;
905b4d
 
905b4d
@@ -1066,6 +1109,11 @@ static int get_service_config(struct mt_ctx *ctx, const char *name,
905b4d
         return ret;
905b4d
     }
905b4d
 
905b4d
+    if (svc_supported_as_nonroot(svc->name)) {
905b4d
+        uid = ctx->uid;
905b4d
+        gid = ctx->gid;
905b4d
+    }
905b4d
+
905b4d
     if (!svc->command) {
905b4d
         svc->command = talloc_asprintf(
905b4d
             svc, "%s/sssd_%s", SSSD_LIBEXEC_PATH, svc->name
905b4d
@@ -1075,6 +1123,14 @@ static int get_service_config(struct mt_ctx *ctx, const char *name,
905b4d
             return ENOMEM;
905b4d
         }
905b4d
 
905b4d
+        svc->command = talloc_asprintf_append(svc->command,
905b4d
+                " --uid %"SPRIuid" --gid %"SPRIgid,
905b4d
+                uid, gid);
905b4d
+        if (!svc->command) {
905b4d
+            talloc_free(svc);
905b4d
+            return ENOMEM;
905b4d
+        }
905b4d
+
905b4d
         if (cmdline_debug_level != SSSDBG_UNRESOLVED) {
905b4d
             svc->command = talloc_asprintf_append(
905b4d
                 svc->command, " -d %#.4x", cmdline_debug_level
905b4d
-- 
905b4d
1.9.3
905b4d