summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2014-08-05 13:52:48 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-22 15:44:13 +0200
commita10ac1d0a7210def232205a48c53a075930e82f6 (patch)
tree4067620172ce1ff8a1849786a2ecac9d7fcf4a04
parentfa24dabfd480e1ce346009336c7979ab59520c44 (diff)
downloadsssd-a10ac1d0a7210def232205a48c53a075930e82f6.tar.gz
sssd-a10ac1d0a7210def232205a48c53a075930e82f6.tar.xz
sssd-a10ac1d0a7210def232205a48c53a075930e82f6.zip
SSSD: Load a user to run a service as from configuration
Related: https://fedorahosted.org/sssd/ticket/2370 Adds a option, user to run as, that is specified in the [sssd] section. When this option is specified, SSSD will run as this user and his private group. When these are not specified, SSSD will run as the configure-time user and group (usually root). Currently all services and providers are started as root. There is a temporary svc_supported_as_nonroot() function that returns true for a service if that service runs and was tested as nonroot and false otherwise. Currently this function always returns false, but will be amended in future patches. Reviewed-by: Pavel Reichl <preichl@redhat.com> Reviewed-by: Simo Sorce <simo@redhat.com>
-rw-r--r--src/confdb/confdb.h1
-rw-r--r--src/config/SSSDConfig/__init__.py.in1
-rwxr-xr-xsrc/config/SSSDConfigTest.py1
-rw-r--r--src/config/etc/sssd.api.conf1
-rw-r--r--src/man/sssd.conf.5.xml13
-rw-r--r--src/monitor/monitor.c56
6 files changed, 73 insertions, 0 deletions
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 34d461065..159aa9f2c 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -69,6 +69,7 @@
#define CONFDB_MONITOR_KRB5_RCACHEDIR "krb5_rcache_dir"
#define CONFDB_MONITOR_DEFAULT_DOMAIN "default_domain_suffix"
#define CONFDB_MONITOR_OVERRIDE_SPACE "override_space"
+#define CONFDB_MONITOR_USER_RUNAS "user"
/* Both monitor and domains */
#define CONFDB_NAME_REGEX "re_expression"
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 6c9553086..b4560ea2b 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -56,6 +56,7 @@ option_strings = {
'full_name_format' : _('Printf-compatible format for displaying fully-qualified names'),
'krb5_rcache_dir' : _('Directory on the filesystem where SSSD should store Kerberos replay cache files.'),
'default_domain_suffix' : _('Domain to add to names without a domain component.'),
+ 'user' : _('The user to drop privileges to'),
# [nss]
'enum_cache_timeout' : _('Enumeration cache timeout length (seconds)'),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 2d12bc02a..78e22f6ef 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -280,6 +280,7 @@ class SSSDConfigTestSSSDService(unittest.TestCase):
're_expression',
'full_name_format',
'krb5_rcache_dir',
+ 'user',
'default_domain_suffix',
'debug_level',
'debug_timestamps',
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index a20f5aa44..c16769a39 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -23,6 +23,7 @@ sbus_timeout = int, None, false
re_expression = str, None, false
full_name_format = str, None, false
krb5_rcache_dir = str, None, false
+user = str, None, false
default_domain_suffix = str, None, false
[nss]
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index d57341661..d6bc42ca0 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -297,6 +297,19 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term>user (string)</term>
+ <listitem>
+ <para>
+ The user to drop the privileges to where
+ appropriate to avoid running as the
+ root user.
+ </para>
+ <para>
+ Default: not set, process will run as root
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term>default_domain_suffix (string)</term>
<listitem>
<para>
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index edd1c2dfc..df1cd5ca1 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -170,6 +170,10 @@ struct mt_ctx {
struct sss_sigchild_ctx *sigchld_ctx;
bool is_daemon;
pid_t parent_pid;
+
+ /* For running unprivileged services */
+ uid_t uid;
+ gid_t gid;
};
static int start_service(struct mt_svc *mt_svc);
@@ -910,6 +914,29 @@ static char *check_services(char **services)
return NULL;
}
+static int get_service_user(struct mt_ctx *ctx)
+{
+ errno_t ret;
+ char *user_str;
+
+ ret = confdb_get_string(ctx->cdb, ctx, CONFDB_MONITOR_CONF_ENTRY,
+ CONFDB_MONITOR_USER_RUNAS,
+ SSSD_USER, &user_str);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get the user to run as\n");
+ return ret;
+ }
+
+ ret = sss_user_by_name_or_uid(user_str, &ctx->uid, &ctx->gid);
+ talloc_free(user_str);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set allowed UIDs.\n");
+ return ret;
+ }
+
+ return EOK;
+}
+
static int get_monitor_config(struct mt_ctx *ctx)
{
int ret;
@@ -955,6 +982,12 @@ static int get_monitor_config(struct mt_ctx *ctx)
ctx->num_services++;
}
+ ret = get_service_user(ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get the unprivileged user\n");
+ return ret;
+ }
+
ret = confdb_get_domains(ctx->cdb, &ctx->domains);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE, "No domains configured.\n");
@@ -1020,6 +1053,14 @@ static errno_t get_ping_config(struct mt_ctx *ctx, const char *path,
return EOK;
}
+/* This is a temporary function that returns false if the service
+ * being started was only tested when running as root.
+ */
+static bool svc_supported_as_nonroot(const char *svc_name)
+{
+ return false;
+}
+
static int get_service_config(struct mt_ctx *ctx, const char *name,
struct mt_svc **svc_cfg)
{
@@ -1027,6 +1068,8 @@ static int get_service_config(struct mt_ctx *ctx, const char *name,
char *path;
struct mt_svc *svc;
time_t now = time(NULL);
+ uid_t uid = 0;
+ gid_t gid = 0;
*svc_cfg = NULL;
@@ -1066,6 +1109,11 @@ static int get_service_config(struct mt_ctx *ctx, const char *name,
return ret;
}
+ if (svc_supported_as_nonroot(svc->name)) {
+ uid = ctx->uid;
+ gid = ctx->gid;
+ }
+
if (!svc->command) {
svc->command = talloc_asprintf(
svc, "%s/sssd_%s", SSSD_LIBEXEC_PATH, svc->name
@@ -1075,6 +1123,14 @@ static int get_service_config(struct mt_ctx *ctx, const char *name,
return ENOMEM;
}
+ svc->command = talloc_asprintf_append(svc->command,
+ " --uid %"SPRIuid" --gid %"SPRIgid,
+ uid, gid);
+ if (!svc->command) {
+ talloc_free(svc);
+ return ENOMEM;
+ }
+
if (cmdline_debug_level != SSSDBG_UNRESOLVED) {
svc->command = talloc_asprintf_append(
svc->command, " -d %#.4x", cmdline_debug_level