[SSSD] [PATCH] Monitor and sbus changes for running SSSD as a non-privileged user

Jakub Hrozek jhrozek at redhat.com
Fri Oct 17 16:47:28 UTC 2014


On Thu, Oct 16, 2014 at 10:25:12AM +0200, Jakub Hrozek wrote:
> On Wed, Oct 15, 2014 at 06:19:49PM -0400, Simo Sorce wrote:
> > On Wed, 15 Oct 2014 22:24:04 +0200
> > Jakub Hrozek <jhrozek at redhat.com> wrote:
> > 
> > > Attached are patches that perform changes in the monitor process and
> > > the low-level sbus and sysdb code required to run the NSS responder
> > > as a non-privileged user. Some of the patches call chmod/chown on
> > > files owned by the SSSD, so I'd like to request a very careful review.
> > 
> > Aside from the points raised in the emails already sent the rest looks
> > good to me.
> 
> Thank you very much for the review. I'll send out updated patches.

Attached are patches that implement the corrections Simo and Pavel asked
for with the exception of confdb being read-only for sssd processes,
Michal is still investigating that one.

I also merged some more Michal's patches that help spawn the PAM
privileged pipe before dropping privileges and also dropping privileges
in the other responders.

With this patchset, all responders are able to run as the SSSD user.

I have one question:
is it wise to also set the permissions of directories we create when
we "install -d" them? Or is this something typically done by the
downstream? Previously, we would just rely on the default system umask
when running "make install", maybe we should tighten the permissions in
Makefile.am as part of this effort?

And one comment:
One of Michal's patches moves creating the socket into a separate
function. This function also changes the umask, which I don't think
belongs into a utility function. I realize this is how the code worked
even before Michal's change, but I think it would be better to move the
umask setting into function like sss_process_init().

Thanks again for the review.
-------------- next part --------------
>From db225c54d6e6cb063cfda5f3001457b6fb697329 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 23 Sep 2014 16:27:23 +0200
Subject: [PATCH 01/19] UTIL: Add a function to convert id_t from a number or a
 name

We need a custom function that would convert a numeric or string input
into uid_t. The function will be used to drop privileges in servers and
also in the PAC and IFP responders.

Includes a unit test to test all code that changed as well as a fix for
a misnamed attribute in the csv_to_uid_list function synopsis.
---
 src/responder/common/responder.h        |   2 +-
 src/responder/common/responder_common.c |  17 ++--
 src/tests/cwrap/Makefile.am             |  53 ++++++++++++
 src/tests/cwrap/passwd                  |   3 +-
 src/tests/cwrap/test_responder_common.c | 144 ++++++++++++++++++++++++++++++++
 src/tests/cwrap/test_usertools.c        | 101 ++++++++++++++++++++++
 src/util/usertools.c                    |  45 ++++++++++
 src/util/util.c                         |   1 +
 src/util/util.h                         |   2 +
 9 files changed, 355 insertions(+), 13 deletions(-)
 create mode 100644 src/tests/cwrap/test_responder_common.c
 create mode 100644 src/tests/cwrap/test_usertools.c

diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index 3674d13f2303d0ce248f765a638aaa83d0c16cf3..97552ec472c5baa285b41cc48b51149f3ef6adb5 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -308,7 +308,7 @@ errno_t schedule_get_domains_task(TALLOC_CTX *mem_ctx,
                                   struct tevent_context *ev,
                                   struct resp_ctx *rctx);
 
-errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *cvs_string,
+errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *csv_string,
                                 bool allow_sss_loop,
                                 size_t *_uid_count, uid_t **_uids);
 
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index b7331ac8ab1de51839937d117968e92062af76d7..0ec2372e8d08f1002b303b5edc6897f17cee9699 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -159,7 +159,7 @@ errno_t check_allowed_uids(uid_t uid, size_t allowed_uids_count,
     return EACCES;
 }
 
-errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *cvs_string,
+errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *csv_string,
                                 bool allow_sss_loop,
                                 size_t *_uid_count, uid_t **_uids)
 {
@@ -169,9 +169,8 @@ errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *cvs_string,
     int list_size;
     uid_t *uids = NULL;
     char *endptr;
-    struct passwd *pwd;
 
-    ret = split_on_separator(mem_ctx, cvs_string, ',', true, false,
+    ret = split_on_separator(mem_ctx, csv_string, ',', true, false,
                              &list, &list_size);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, "split_on_separator failed [%d][%s].\n",
@@ -211,17 +210,13 @@ errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *cvs_string,
                 goto done;
             }
 
-            errno = 0;
-            pwd = getpwnam(list[c]);
-            if (pwd == NULL) {
+            ret = sss_user_by_name_or_uid(list[c], &uids[c], NULL);
+            if (ret != EOK) {
                 DEBUG(SSSDBG_OP_FAILURE, "List item [%s] is neither a valid "
-                                          "UID nor a user name which cloud be "
-                                          "resolved by getpwnam().\n", list[c]);
-                ret = EINVAL;
+                                         "UID nor a user name which could be "
+                                         "resolved by getpwnam().\n", list[c]);
                 goto done;
             }
-
-            uids[c] = pwd->pw_uid;
         }
     }
 
diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am
index 3fb30b28c0e94ac9a447a92bfaf1bfcc1013fd57..6f41a4e3c30fa735c7bc285ad0cc3547635d9056 100644
--- a/src/tests/cwrap/Makefile.am
+++ b/src/tests/cwrap/Makefile.am
@@ -45,6 +45,8 @@ if HAVE_UID_WRAPPER
 check_PROGRAMS = \
 	become_user-tests \
 	server-tests \
+	usertools-tests \
+	responder_common-tests \
 	$(NULL)
 endif # HAVE_UID_WRAPPER
 endif # HAVE_NSS_WRAPPER
@@ -105,4 +107,55 @@ server_tests_LDADD = \
     $(abs_top_builddir)/libsss_test_common.la \
     $(NULL)
 
+usertools_tests_SOURCES = \
+    test_usertools.c \
+    ../../../src/util/domain_info_utils.c \
+    ../../../src/util/safe-format-string.c \
+    ../../../src/util/usertools.c \
+    ../../../src/util/strtonum.c \
+    ../../../src/util/backup_file.c \
+    ../../../src/util/atomic_io.c \
+    ../../../src/util/util.c \
+    ../../../src/util/util_errors.c \
+    ../../../src/util/sss_tc_utf8.c \
+    ../../../src/util/sss_utf8.c \
+    ../../../src/confdb/confdb.c \
+    ../../../src/db/sysdb.c \
+    ../../../src/db/sysdb_upgrade.c \
+    ../../../src/db/sysdb_autofs.c \
+    ../../../src/db/sysdb_search.c \
+    ../../../src/db/sysdb_services.c \
+    ../../../src/db/sysdb_ops.c \
+    $(NULL)
+usertools_tests_CFLAGS = \
+    $(AM_CFLAGS) \
+    $(NULL)
+usertools_tests_LDADD = \
+    $(CMOCKA_LIBS) \
+    $(UNICODE_LIBS) \
+    $(SSSD_LIBS) \
+    $(abs_top_builddir)/libsss_debug.la \
+    $(abs_top_builddir)/libsss_crypt.la \
+    $(abs_top_builddir)/libsss_test_common.la \
+    $(NULL)
+
+responder_common_tests_SOURCES =\
+    test_responder_common.c \
+    ../../../src/responder/common/responder_common.c \
+    ../../../src/responder/common/responder_packet.c \
+    ../../../src/responder/common/responder_cmd.c \
+    $(NULL)
+responder_common_tests_CFLAGS = \
+    $(AM_CFLAGS) \
+    $(NULL)
+responder_common_tests_LDADD = \
+    $(CMOCKA_LIBS) \
+    $(UNICODE_LIBS) \
+    $(SSSD_LIBS) \
+    $(abs_top_builddir)/libsss_debug.la \
+    $(abs_top_builddir)/libsss_crypt.la \
+    $(abs_top_builddir)/libsss_util.la \
+    $(abs_top_builddir)/libsss_test_common.la \
+    $(NULL)
+
 tests: $(check_PROGRAMS)
diff --git a/src/tests/cwrap/passwd b/src/tests/cwrap/passwd
index aa0a97db5259172c0b4ab47c7c2346fa5c2aa88e..862ccfe03e40d43c60c56b0c50f328f494d7e6b9 100644
--- a/src/tests/cwrap/passwd
+++ b/src/tests/cwrap/passwd
@@ -1 +1,2 @@
-sssd:x:123:123:sssd unprivileged user:/:/sbin/nologin
+sssd:x:123:456:sssd unprivileged user:/:/sbin/nologin
+foobar:x:10001:10001:User for SSSD testing:/home/foobar:/bin/bash
diff --git a/src/tests/cwrap/test_responder_common.c b/src/tests/cwrap/test_responder_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..23dcf753f184cdecaf39c73c6e9be0e23e6df968
--- /dev/null
+++ b/src/tests/cwrap/test_responder_common.c
@@ -0,0 +1,144 @@
+/*
+    Authors:
+        Jakub Hrozek <jhrozek at redhat.com>
+
+    Copyright (C) 2014 Red Hat
+
+    SSSD tests: User utilities
+
+    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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <popt.h>
+#include "util/util.h"
+#include "responder/common/responder.h"
+#include "tests/cmocka/common_mock.h"
+
+/* Just to satisfy dependencies */
+struct cli_protocol_version *register_cli_protocol_version(void)
+{
+    static struct cli_protocol_version responder_test_cli_protocol_version[] = {
+        {0, NULL, NULL}
+    };
+
+    return responder_test_cli_protocol_version;
+}
+
+void test_uid_csv_to_uid_list(void **state)
+{
+    TALLOC_CTX *tmp_ctx;
+    errno_t ret;
+    size_t count;
+    uid_t *list;
+
+    tmp_ctx = talloc_new(global_talloc_context);
+    assert_non_null(tmp_ctx);
+
+    check_leaks_push(tmp_ctx);
+
+    ret = csv_string_to_uid_array(tmp_ctx, "1, 2, 3", false, &count, &list);
+    assert_int_equal(ret, EOK);
+    assert_int_equal(count, 3);
+    assert_int_equal(list[0], 1);
+    assert_int_equal(list[1], 2);
+    assert_int_equal(list[2], 3);
+
+    talloc_free(list);
+    check_leaks_pop(tmp_ctx);
+    talloc_free(tmp_ctx);
+}
+
+void test_name_csv_to_uid_list(void **state)
+{
+    TALLOC_CTX *tmp_ctx;
+    errno_t ret;
+    size_t count;
+    uid_t *list;
+
+    tmp_ctx = talloc_new(global_talloc_context);
+    assert_non_null(tmp_ctx);
+
+    check_leaks_push(tmp_ctx);
+
+    ret = csv_string_to_uid_array(tmp_ctx, "sssd, foobar", true, &count, &list);
+    assert_int_equal(ret, EOK);
+    assert_int_equal(count, 2);
+    assert_int_equal(list[0], 123);
+    assert_int_equal(list[1], 10001);
+
+    talloc_free(list);
+    check_leaks_pop(tmp_ctx);
+    talloc_free(tmp_ctx);
+}
+
+void test_csv_to_uid_list_neg(void **state)
+{
+    TALLOC_CTX *tmp_ctx;
+    errno_t ret;
+    size_t count;
+    uid_t *list = NULL;
+
+    tmp_ctx = talloc_new(global_talloc_context);
+    assert_non_null(tmp_ctx);
+
+    check_leaks_push(tmp_ctx);
+
+    ret = csv_string_to_uid_array(tmp_ctx, "nosuchuser", true, &count, &list);
+    assert_int_not_equal(ret, EOK);
+
+    check_leaks_pop(tmp_ctx);
+    talloc_free(tmp_ctx);
+}
+
+int main(int argc, const char *argv[])
+{
+    poptContext pc;
+    int opt;
+    struct poptOption long_options[] = {
+        POPT_AUTOHELP
+        SSSD_DEBUG_OPTS
+        POPT_TABLEEND
+    };
+
+    const UnitTest tests[] = {
+        unit_test(test_uid_csv_to_uid_list),
+        unit_test(test_name_csv_to_uid_list),
+        unit_test(test_csv_to_uid_list_neg),
+    };
+
+    /* Set debug level to invalid value so we can deside if -d 0 was used. */
+    debug_level = SSSDBG_INVALID;
+
+    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+    while((opt = poptGetNextOpt(pc)) != -1) {
+        switch(opt) {
+        default:
+            fprintf(stderr, "\nInvalid option %s: %s\n\n",
+                    poptBadOption(pc, 0), poptStrerror(opt));
+            poptPrintUsage(pc, stderr, 0);
+            return 1;
+        }
+    }
+    poptFreeContext(pc);
+
+    DEBUG_CLI_INIT(debug_level);
+
+    tests_set_cwd();
+
+    return run_tests(tests);
+}
diff --git a/src/tests/cwrap/test_usertools.c b/src/tests/cwrap/test_usertools.c
new file mode 100644
index 0000000000000000000000000000000000000000..90d8e114a8dfe24d1a72662bc84bffbe4e9e826d
--- /dev/null
+++ b/src/tests/cwrap/test_usertools.c
@@ -0,0 +1,101 @@
+/*
+    Authors:
+        Jakub Hrozek <jhrozek at redhat.com>
+
+    Copyright (C) 2014 Red Hat
+
+    SSSD tests: User utilities
+
+    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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <popt.h>
+#include "util/util.h"
+#include "tests/cmocka/common_mock.h"
+
+void test_get_user_num(void **state)
+{
+    uid_t uid;
+    gid_t gid;
+    errno_t ret;
+
+    ret = sss_user_by_name_or_uid("123", &uid, &gid);
+    assert_int_equal(ret, EOK);
+    assert_int_equal(uid, 123);
+    assert_int_equal(gid, 123);
+}
+
+void test_get_user_str(void **state)
+{
+    uid_t uid;
+    gid_t gid;
+    errno_t ret;
+
+    ret = sss_user_by_name_or_uid("sssd", &uid, &gid);
+    assert_int_equal(ret, EOK);
+    assert_int_equal(uid, 123);
+    assert_int_equal(gid, 456);
+}
+
+void test_get_user_nullparm(void **state)
+{
+    uid_t uid;
+    errno_t ret;
+
+    ret = sss_user_by_name_or_uid("sssd", &uid, NULL);
+    assert_int_equal(ret, EOK);
+    assert_int_equal(uid, 123);
+}
+
+int main(int argc, const char *argv[])
+{
+    poptContext pc;
+    int opt;
+    struct poptOption long_options[] = {
+        POPT_AUTOHELP
+        SSSD_DEBUG_OPTS
+        POPT_TABLEEND
+    };
+
+    const UnitTest tests[] = {
+        unit_test(test_get_user_num),
+        unit_test(test_get_user_str),
+        unit_test(test_get_user_nullparm),
+    };
+
+    /* Set debug level to invalid value so we can deside if -d 0 was used. */
+    debug_level = SSSDBG_INVALID;
+
+    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+    while((opt = poptGetNextOpt(pc)) != -1) {
+        switch(opt) {
+        default:
+            fprintf(stderr, "\nInvalid option %s: %s\n\n",
+                    poptBadOption(pc, 0), poptStrerror(opt));
+            poptPrintUsage(pc, stderr, 0);
+            return 1;
+        }
+    }
+    poptFreeContext(pc);
+
+    DEBUG_CLI_INIT(debug_level);
+
+    tests_set_cwd();
+
+    return run_tests(tests);
+}
diff --git a/src/util/usertools.c b/src/util/usertools.c
index 809b42d67c7b1cdfa0729c3a7e835fab37297596..a2d3c8d085fbc04c222c3657a0aa379aebe4ef3e 100644
--- a/src/util/usertools.c
+++ b/src/util/usertools.c
@@ -23,8 +23,11 @@
 #include <pcre.h>
 #include <errno.h>
 #include <talloc.h>
+#include <pwd.h>
+#include <grp.h>
 
 #include "confdb/confdb.h"
+#include "util/strtonum.h"
 #include "util/util.h"
 #include "util/safe-format-string.h"
 #include "responder/common/responder.h"
@@ -659,3 +662,45 @@ sss_get_domain_name(TALLOC_CTX *mem_ctx,
 
     return user_name;
 }
+
+errno_t sss_user_by_name_or_uid(const char *input, uid_t *_uid, gid_t *_gid)
+{
+    uid_t uid;
+    gid_t gid;
+    errno_t ret;
+    char *endptr;
+    struct passwd *pwd;
+
+    /* Try if it's an ID first */
+    uid = strtouint32(input, &endptr, 10);
+    gid = uid;
+    if (errno != 0 || *endptr != '\0') {
+        ret = errno;
+        if (ret == ERANGE) {
+            DEBUG(SSSDBG_OP_FAILURE,
+                  "UID [%s] is out of range.\n", input);
+            return ret;
+        }
+
+        /* Nope, maybe a username? */
+        pwd = getpwnam(input);
+        if (pwd == NULL) {
+            DEBUG(SSSDBG_OP_FAILURE,
+                  "[%s] is neither a valid UID nor a user name which could be "
+                  "resolved by getpwnam().\n", input);
+            return EINVAL;
+        }
+
+        uid = pwd->pw_uid;
+        gid = pwd->pw_gid;
+    }
+
+    if (_uid) {
+        *_uid = uid;
+    }
+
+    if (_gid) {
+        *_gid = gid;
+    }
+    return EOK;
+}
diff --git a/src/util/util.c b/src/util/util.c
index 7f80771ecd9868feaf43e34cbd61e44dd8ae5f3a..d78d37d975e6591bca6ac3f2fa36b5b9f4659a29 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -21,6 +21,7 @@
 #include <ctype.h>
 #include <netdb.h>
 #include <poll.h>
+#include <sys/types.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <talloc.h>
diff --git a/src/util/util.h b/src/util/util.h
index 08cd144c1d7c165b37a2367ef6e0d6f86e137acd..f9360d79df9dc9b8b7711d9b963e46495f6a8603 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -403,6 +403,8 @@ bool check_ipv6_addr(struct in6_addr *addr, uint8_t check);
 
 const char * const * get_known_services(void);
 
+errno_t sss_user_by_name_or_uid(const char *input, uid_t *_uid, gid_t *_gid);
+
 int split_on_separator(TALLOC_CTX *mem_ctx, const char *str,
                        const char sep, bool trim, bool skip_empty,
                        char ***_list, int *size);
-- 
1.9.3

-------------- next part --------------
>From 1cb3b8317afcc10031d8b402dfae5b63c05998e2 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 1 Oct 2014 14:47:09 +0200
Subject: [PATCH 02/19] BUILD: Add a config option for sssd user, own private
 directories as the user

Adds two new configure-time options that let you select the user to run
SSSD as. The default is 'root' for backwards compatibility. If user is
specified, but the group is not, the user is also used as group name.

The directories the deamon stores its private data at are also created
as owned by this user during install time.
---
 Makefile.am        | 23 +++++++++++++++++------
 configure.ac       |  1 +
 src/conf_macros.m4 | 19 +++++++++++++++++++
 3 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 405d2aabbac56047921a28e1a37a651b8234e013..9fe0880109ff6fa72cf5b428f0ba7936cc5702f0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -78,6 +78,14 @@ sudolibdir = @sudolibpath@
 UNICODE_LIBS=@UNICODE_LIBS@
 
 MKDIR_P = @MKDIR_P@
+INSTALL = @INSTALL@
+
+SSSD_USER = @SSSD_USER@
+
+INSTALL_USER_DIR_FLAGS = -d
+if SSSD_USER
+INSTALL_USER_DIR_FLAGS += -o $(SSSD_USER) -g $(SSSD_USER)
+endif
 
 AM_CFLAGS =
 if WANT_AUX_INFO
@@ -2721,24 +2729,27 @@ installsssddirs::
     $(DESTDIR)$(bindir) \
     $(DESTDIR)$(sbindir) \
     $(DESTDIR)$(mandir) \
+    $(DESTDIR)$(pidpath) \
     $(DESTDIR)$(pluginpath) \
     $(DESTDIR)$(libdir)/ldb \
     $(DESTDIR)$(dbuspolicydir) \
     $(DESTDIR)$(dbusservicedir) \
-    $(DESTDIR)$(pipepath)/private \
     $(DESTDIR)$(sssdlibdir) \
     $(DESTDIR)$(pkglibdir) \
-    $(DESTDIR)$(sssdconfdir) \
     $(DESTDIR)$(sssddatadir) \
+    $(DESTDIR)$(sudolibdir) \
+    $(DESTDIR)$(autofslibdir) \
+    $(NULL); \
+	$(INSTALL) $(INSTALL_USER_DIR_FLAGS) \
     $(DESTDIR)$(dbpath) \
     $(DESTDIR)$(mcpath) \
-    $(DESTDIR)$(pidpath) \
-    $(DESTDIR)$(logpath) \
+    $(DESTDIR)$(pipepath) \
+    $(DESTDIR)$(pipepath)/private \
     $(DESTDIR)$(pubconfpath) \
     $(DESTDIR)$(pubconfpath)/krb5.include.d \
     $(DESTDIR)$(gpocachepath) \
-    $(DESTDIR)$(sudolibdir) \
-    $(DESTDIR)$(autofslibdir) \
+    $(DESTDIR)$(sssdconfdir) \
+    $(DESTDIR)$(logpath) \
     $(NULL)
 
 if HAVE_DOXYGEN
diff --git a/configure.ac b/configure.ac
index e6745cb454624d1d62e1a827c2fbf557f6502ae9..e5ec204ad9671d15deb1830c60168e066a66f198 100644
--- a/configure.ac
+++ b/configure.ac
@@ -137,6 +137,7 @@ WITH_SAMBA
 WITH_NFS
 WITH_NFS_LIB_PATH
 WITH_LIBWBCLIENT
+WITH_SSSD_USER
 
 m4_include([src/external/pkg.m4])
 m4_include([src/external/libpopt.m4])
diff --git a/src/conf_macros.m4 b/src/conf_macros.m4
index 4aa58138c85db9266fd3f1765fc357b3fd104941..fbee81f56e484b618379f7c987ecee50ae48917e 100644
--- a/src/conf_macros.m4
+++ b/src/conf_macros.m4
@@ -737,3 +737,22 @@ AC_DEFUN([WITH_NFS_LIB_PATH],
     fi
     AC_SUBST(nfslibpath)
   ])
+
+AC_DEFUN([WITH_SSSD_USER],
+  [ AC_ARG_WITH([sssd-user],
+                [AS_HELP_STRING([--with-sssd-user=<user>],
+                                [User for running SSSD (root)]
+                               )
+                ]
+               )
+
+    SSSD_USER=root
+
+    if test x"$with_sssd_user" != x; then
+        SSSD_USER=$with_sssd_user
+    fi
+
+    AC_SUBST(SSSD_USER)
+    AC_DEFINE_UNQUOTED(SSSD_USER, "$SSSD_USER", ["The default user to run SSSD as"])
+    AM_CONDITIONAL([SSSD_USER], [test x"$with_sssd_user" != x])
+  ])
-- 
1.9.3

-------------- next part --------------
>From 3a46b1295a595cb3f39a37f970881fe3b54ea79b Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 5 Aug 2014 13:53:20 +0200
Subject: [PATCH 03/19] RPM: Change file ownership to sssd.sssd

Adds a private SSSD user in the %pre section of SSSD specfile. Also
changes the ownsership of SSSD private directories to sssd.sssd.

Does not change the configure time default, so SSSD will still run as
root. The file and directory ownership does not widen, because the
directories are still only accessible by the private user (whose shell
is /sbin/nologin) and of course the root user.
---
 contrib/sssd.spec.in | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 529304205274ad39e4281e3d298222420d5eb439..e3161d723e04ebb25dec768c92be6079042ce9b4 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -603,17 +603,17 @@ rm -rf $RPM_BUILD_ROOT
 
 %dir %{sssdstatedir}
 %dir %{_localstatedir}/cache/krb5rcache
-%attr(700,root,root) %dir %{dbpath}
-%attr(755,root,root) %dir %{mcpath}
-%ghost %attr(0644,root,root) %verify(not md5 size mtime) %{mcpath}/passwd
-%ghost %attr(0644,root,root) %verify(not md5 size mtime) %{mcpath}/group
-%attr(755,root,root) %dir %{pipepath}
-%attr(755,root,root) %dir %{pubconfpath}
-%attr(755,root,root) %dir %{gpocachepath}
-%attr(700,root,root) %dir %{pipepath}/private
-%attr(750,root,root) %dir %{_var}/log/%{name}
-%attr(711,root,root) %dir %{_sysconfdir}/sssd
-%ghost %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/sssd/sssd.conf
+%attr(700,sssd,sssd) %dir %{dbpath}
+%attr(755,sssd,sssd) %dir %{mcpath}
+%ghost %attr(0644,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/passwd
+%ghost %attr(0644,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/group
+%attr(755,sssd,sssd) %dir %{pipepath}
+%attr(755,sssd,sssd) %dir %{pubconfpath}
+%attr(755,sssd,sssd) %dir %{gpocachepath}
+%attr(700,sssd,sssd) %dir %{pipepath}/private
+%attr(750,sssd,sssd) %dir %{_var}/log/%{name}
+%attr(711,sssd,sssd) %dir %{_sysconfdir}/sssd
+%ghost %attr(0600,sssd,sssd) %config(noreplace) %{_sysconfdir}/sssd/sssd.conf
 %if (0%{?use_systemd} == 1)
 %attr(755,root,root) %dir %{_sysconfdir}/systemd/system/sssd.service.d
 %config(noreplace) %{_sysconfdir}/systemd/system/sssd.service.d/journal.conf
@@ -802,6 +802,10 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/%{name}/modules/libwbclient.so
 %{_libdir}/pkgconfig/wbclient_sssd.pc
 
+%pre common
+getent group sssd >/dev/null || groupadd -r sssd
+getent passwd sssd >/dev/null || useradd -r -g sssd -d / -s /sbin/nologin -c "User for sssd" sssd
+
 %if (0%{?use_systemd} == 1)
 # systemd
 %post common
-- 
1.9.3

-------------- next part --------------
>From 78066ed7cd43e0208f6d15b8b0489e3699b1b4cc Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 5 Aug 2014 13:52:48 +0200
Subject: [PATCH 04/19] SSSD: Load a user to run a service as from
 configuration

Adds two new options, user and group that are specified in the [sssd]
section. When these options are specified, SSSD will run as the user and
group. When these are not specified, SSSD will run as the configure-time
user and group.

The group option only takes effect when user is also specified.

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.
---
 src/confdb/confdb.h                  |  1 +
 src/config/SSSDConfig/__init__.py.in |  1 +
 src/config/SSSDConfigTest.py         |  1 +
 src/config/etc/sssd.api.conf         |  1 +
 src/man/sssd.conf.5.xml              | 13 +++++++++
 src/monitor/monitor.c                | 56 ++++++++++++++++++++++++++++++++++++
 6 files changed, 73 insertions(+)

diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 720b7dc1cc857d6aa34684c6fccd1c5fc5c33172..d8bffc72fc5c3dcea24db986884657bb9744d23e 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 6c95530868d7c078ccf13622f3ba916392b0c732..b4560ea2b33f2c3b82bff42fb6a36302a146c99f 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 2d12bc02af1768d22c8bfa9a21b1fc24bf199af4..78e22f6eff19aac8289d769dc9f565b2d548f4b3 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 a20f5aa44dbadd24f644bffc9954df9e088979b9..c16769a3985f495922d255dacebccc11f6a0ea1d 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 d5734166144a7c3ce7e62914558f8e69121bf774..d6bc42ca06462d0eefb114c34e087866bbf37319 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 edd1c2dfc674d8a7ca9d069d6499c0dcc959f210..cbf66594a65a4e9d81c259fd24af966d19038405 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,
+                            NULL, &user_str);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get the user to run as");
+        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
-- 
1.9.3

-------------- next part --------------
>From 8dc3b80a117dc6d4e8f86035e02e48bd9774e1ba Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 7 Oct 2014 11:30:01 +0200
Subject: [PATCH 05/19] SBUS: Chown the sbus socket if needed

When setting up the sbus server, we might need to chown the sbus socket
to make sure non-root peers, running as the SSSD user are able to access
the file.
---
 src/monitor/monitor.c            |  6 +++++-
 src/providers/data_provider_be.c |  2 +-
 src/providers/proxy/proxy_init.c |  2 +-
 src/sbus/sbus_client.c           | 15 +++++++++++++--
 src/sbus/sssd_dbus.h             |  1 +
 src/sbus/sssd_dbus_server.c      | 12 ++++++++++++
 src/tests/common_dbus.c          |  4 ++--
 7 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index cbf66594a65a4e9d81c259fd24af966d19038405..6d51119b4ac6bcfb29a7f00bf0de766ece5a67d7 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -515,7 +515,11 @@ static int monitor_dbus_init(struct mt_ctx *ctx)
         return ret;
     }
 
-    ret = sbus_new_server(ctx, ctx->ev, monitor_address,
+    /* If a service is running as unprivileged user, we need to make sure this
+     * user can access the monitor sbus server. root is still king, so we don't
+     * lose any access.
+     */
+    ret = sbus_new_server(ctx, ctx->ev, monitor_address, ctx->uid, ctx->gid,
                           false, &ctx->sbus_srv, monitor_service_init, ctx);
 
     talloc_free(monitor_address);
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 18b50214b0795709d583d5891bf4f6fd220bcb11..122c5b091751b641f815ddff5c56ac99ace69939 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -2263,7 +2263,7 @@ static int be_srv_init(struct be_ctx *ctx)
         return ret;
     }
 
-    ret = sbus_new_server(ctx, ctx->ev, sbus_address,
+    ret = sbus_new_server(ctx, ctx->ev, sbus_address, 0, 0,
                           true, &ctx->sbus_srv, be_client_init, ctx);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up sbus server.\n");
diff --git a/src/providers/proxy/proxy_init.c b/src/providers/proxy/proxy_init.c
index dd1b75826fbfc384dd37ba659a8653547cc35bcf..1e734511766f2c0f58cffc7d726a26ecfd6c9a27 100644
--- a/src/providers/proxy/proxy_init.c
+++ b/src/providers/proxy/proxy_init.c
@@ -522,7 +522,7 @@ int sssm_proxy_auth_init(struct be_ctx *bectx,
         goto done;
     }
 
-    ret = sbus_new_server(ctx, bectx->ev, sbus_address,
+    ret = sbus_new_server(ctx, bectx->ev, sbus_address, 0, 0,
                           false, &ctx->sbus_srv, proxy_client_init, ctx);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up sbus server.\n");
diff --git a/src/sbus/sbus_client.c b/src/sbus/sbus_client.c
index 6cf5002dc2b8f3b85a3110298db8255b82172ddd..8ad4c0f36a929e341793cca61fe12808e14f6bc6 100644
--- a/src/sbus/sbus_client.c
+++ b/src/sbus/sbus_client.c
@@ -32,6 +32,8 @@ int sbus_client_init(TALLOC_CTX *mem_ctx,
     struct sbus_connection *conn = NULL;
     int ret;
     char *filename;
+    uid_t check_uid;
+    gid_t check_gid;
 
     /* Validate input */
     if (server_address == NULL) {
@@ -45,8 +47,17 @@ int sbus_client_init(TALLOC_CTX *mem_ctx,
         return EIO;
     }
 
-    ret = check_file(filename,
-                     0, 0, S_IFSOCK|S_IRUSR|S_IWUSR, 0, NULL, true);
+    check_uid = geteuid();
+    check_gid = getegid();
+
+    /* Ignore ownership checks when the server runs as root. This is the
+     * case when privileged monitor is setting up sockets for unprivileged
+     * responders */
+    if (check_uid == 0) check_uid = -1;
+    if (check_gid == 0) check_gid = -1;
+
+    ret = check_file(filename, check_uid, check_gid,
+                     S_IFSOCK|S_IRUSR|S_IWUSR, 0, NULL, true);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, "check_file failed for [%s].\n", filename);
         return EIO;
diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h
index 372521a3575f967b751c9e13a7d830d9c3b43584..d01926368ce0ae5312d8ea0057a89d9a7176836b 100644
--- a/src/sbus/sssd_dbus.h
+++ b/src/sbus/sssd_dbus.h
@@ -132,6 +132,7 @@ sbus_new_interface(TALLOC_CTX *mem_ctx,
 int sbus_new_server(TALLOC_CTX *mem_ctx,
                     struct tevent_context *ev,
                     const char *address,
+                    uid_t uid, gid_t gid,
                     bool use_symlink,
                     struct sbus_connection **server,
                     sbus_server_conn_init_fn init_fn, void *init_pvt_data);
diff --git a/src/sbus/sssd_dbus_server.c b/src/sbus/sssd_dbus_server.c
index 3a7de8ff019160b2305516945740dfb6453d578b..aca51b8e47fd9e313c79aec8b2305b8ba72bc413 100644
--- a/src/sbus/sssd_dbus_server.c
+++ b/src/sbus/sssd_dbus_server.c
@@ -181,6 +181,7 @@ remove_socket_symlink(const char *symlink_name)
 int sbus_new_server(TALLOC_CTX *mem_ctx,
                     struct tevent_context *ev,
                     const char *address,
+                    uid_t uid, gid_t gid,
                     bool use_symlink,
                     struct sbus_connection **_server,
                     sbus_server_conn_init_fn init_fn,
@@ -268,6 +269,17 @@ int sbus_new_server(TALLOC_CTX *mem_ctx,
         }
     }
 
+    if (stat_buf.st_uid != uid || stat_buf.st_gid != gid) {
+        ret = chown(filename, uid, gid);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "chown failed for [%s]: [%d][%s].\n", filename, errno,
+                                                        strerror(errno));
+            ret = EIO;
+            goto done;
+        }
+    }
+
     tmp = dbus_server_get_address(dbus_server);
     DEBUG(SSSDBG_TRACE_FUNC, "D-BUS Server listening on %s\n", tmp);
     free(tmp);
diff --git a/src/tests/common_dbus.c b/src/tests/common_dbus.c
index 3117c080dc3106517bee933a458583f35b04fa63..1b0ae88dc05a1514938218e97a50e9ef7b54b193 100644
--- a/src/tests/common_dbus.c
+++ b/src/tests/common_dbus.c
@@ -112,8 +112,8 @@ mock_server_child(void *data)
     ctx = talloc_new(NULL);
     loop = tevent_context_init(ctx);
 
-    verify_eq (sbus_new_server(ctx, loop, mock->dbus_address, false,
-                               &server, on_accept_connection, mock), EOK);
+    verify_eq (sbus_new_server(ctx, loop, mock->dbus_address, geteuid(), getegid(),
+                               false, &server, on_accept_connection, mock), EOK);
 
     tevent_add_fd(loop, ctx, mock->sync_fds[1], TEVENT_FD_READ,
                   on_sync_fd_written, &stop_server);
-- 
1.9.3

-------------- next part --------------
>From 640bb920e2865af0d9f8d7d19a0b4ffb5ae899dc Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 7 Oct 2014 19:44:44 +0200
Subject: [PATCH 06/19] SBUS: Allow connections from other UIDs

Unless dbus_connection_set_unix_user_function() is used, D-Bus only
allows connections from UID 0. This patch adds a custom checker function
that allows either UID 0 or the pre-configured SSSD user ID.
---
 src/monitor/monitor.c           |  3 +++
 src/sbus/sssd_dbus.h            |  4 ++++
 src/sbus/sssd_dbus_connection.c | 20 ++++++++++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 6d51119b4ac6bcfb29a7f00bf0de766ece5a67d7..5e0680c82dca785a073b3b4758d6fcfb471de727 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -2392,6 +2392,9 @@ static int monitor_service_init(struct sbus_connection *conn, void *data)
     mini->ctx = ctx;
     mini->conn = conn;
 
+    /* Allow access from the SSSD user */
+    sbus_allow_uid(conn, &ctx->uid);
+
     /* 10 seconds should be plenty */
     tv = tevent_timeval_current_ofs(10, 0);
 
diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h
index d01926368ce0ae5312d8ea0057a89d9a7176836b..5b128eaedb320cb745c1b635867e1b53ca556ec9 100644
--- a/src/sbus/sssd_dbus.h
+++ b/src/sbus/sssd_dbus.h
@@ -209,6 +209,10 @@ int sbus_conn_send(struct sbus_connection *conn,
 void sbus_conn_send_reply(struct sbus_connection *conn,
                           DBusMessage *reply);
 
+/* Set up D-BUS access control. If there is a SSSD user, we must allow
+ * him to connect. root is always allowed */
+void sbus_allow_uid(struct sbus_connection *conn, uid_t *uid);
+
 /*
  * This structure is passed to all dbus method and property
  * handlers. It is a talloc context which will be valid until
diff --git a/src/sbus/sssd_dbus_connection.c b/src/sbus/sssd_dbus_connection.c
index 06256a85b5e81b39d50923db6d41b64015114ce1..6102ef9ae4715d36a623b802b9095ec1c99c1a39 100644
--- a/src/sbus/sssd_dbus_connection.c
+++ b/src/sbus/sssd_dbus_connection.c
@@ -922,3 +922,23 @@ void sbus_conn_send_reply(struct sbus_connection *conn, DBusMessage *reply)
 {
     dbus_connection_send(conn->dbus.conn, reply, NULL);
 }
+
+dbus_bool_t is_uid_sssd_user(DBusConnection *connection,
+                             unsigned long   uid,
+                             void           *data)
+{
+    uid_t sssd_user = * (uid_t *) data;
+
+    if (uid == 0 || uid == sssd_user) {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+void sbus_allow_uid(struct sbus_connection *conn, uid_t *uid)
+{
+    dbus_connection_set_unix_user_function(sbus_get_connection(conn),
+                                           is_uid_sssd_user,
+                                           uid, NULL);
+}
-- 
1.9.3

-------------- next part --------------
>From ae7c67ba9d41766090472851be967bf52d3a1aec Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 15 Oct 2014 15:58:58 +0200
Subject: [PATCH 07/19] BE: Own the sbus socket as the SSSD user

In some cases, the back end might still be running as root, but the
responder would be running unprivileged. In this case, we need to allow
connecting from the SSSD user ID.
---
 src/monitor/monitor.c            |  8 ++++++++
 src/providers/data_provider_be.c | 16 ++++++++++++----
 src/providers/dp_backend.h       |  2 ++
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 5e0680c82dca785a073b3b4758d6fcfb471de727..5445623c8b983ac83b059f0be0f709c723fd8a94 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1306,6 +1306,14 @@ static int get_provider_config(struct mt_ctx *ctx, const char *name,
             return ENOMEM;
         }
 
+        svc->command = talloc_asprintf_append(svc->command,
+                " --uid %"SPRIuid" --gid %"SPRIgid,
+                ctx->uid, ctx->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
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 122c5b091751b641f815ddff5c56ac99ace69939..2716e4a8b38f3ff9a5b48a861ecc31f18f9fcbce 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -2226,6 +2226,9 @@ static int be_client_init(struct sbus_connection *conn, void *data)
     becli->conn = conn;
     becli->initialized = false;
 
+    /* Allow access from the SSSD user */
+    sbus_allow_uid(conn, &bectx->uid);
+
     /* 5 seconds should be plenty */
     tv = tevent_timeval_current_ofs(5, 0);
 
@@ -2251,7 +2254,8 @@ static int be_client_init(struct sbus_connection *conn, void *data)
 
 /* be_srv_init
  * set up per-domain sbus channel */
-static int be_srv_init(struct be_ctx *ctx)
+static int be_srv_init(struct be_ctx *ctx,
+                       uid_t uid, gid_t gid)
 {
     char *sbus_address;
     int ret;
@@ -2263,7 +2267,10 @@ static int be_srv_init(struct be_ctx *ctx)
         return ret;
     }
 
-    ret = sbus_new_server(ctx, ctx->ev, sbus_address, 0, 0,
+    ctx->uid = uid;
+    ctx->gid = gid;
+
+    ret = sbus_new_server(ctx, ctx->ev, sbus_address, uid, gid,
                           true, &ctx->sbus_srv, be_client_init, ctx);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up sbus server.\n");
@@ -2554,6 +2561,7 @@ done:
 
 int be_process_init(TALLOC_CTX *mem_ctx,
                     const char *be_domain,
+                    uid_t uid, gid_t gid,
                     struct tevent_context *ev,
                     struct confdb_ctx *cdb)
 {
@@ -2609,7 +2617,7 @@ int be_process_init(TALLOC_CTX *mem_ctx,
         goto fail;
     }
 
-    ret = be_srv_init(ctx);
+    ret = be_srv_init(ctx, uid, gid);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE, "fatal error setting up server bus\n");
         goto fail;
@@ -2870,7 +2878,7 @@ int main(int argc, const char *argv[])
     }
 
     ret = be_process_init(main_ctx,
-                          be_domain,
+                          be_domain, uid, gid,
                           main_ctx->event_ctx,
                           main_ctx->confdb_ctx);
     if (ret != EOK) {
diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
index 075681ff9dd641daf56929c05cb94170cd1b292a..e4213b44b32e8b9cb942dfcfef4998aa732d113c 100644
--- a/src/providers/dp_backend.h
+++ b/src/providers/dp_backend.h
@@ -116,6 +116,8 @@ struct be_ctx {
     struct sss_domain_info *domain;
     const char *identity;
     const char *conf_path;
+    uid_t uid;
+    gid_t gid;
     struct be_failover_ctx *be_fo;
     struct be_resolv_ctx *be_res;
 
-- 
1.9.3

-------------- next part --------------
>From aee761712bf9b2b9b6aa6b62f442067896ba60c9 Mon Sep 17 00:00:00 2001
From: Michal Zidek <mzidek at redhat.com>
Date: Thu, 9 Oct 2014 17:15:56 +0200
Subject: [PATCH 08/19] MONITOR: Allow confdb to be accessed by nonroot user

---
 src/monitor/monitor.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 5445623c8b983ac83b059f0be0f709c723fd8a94..1567d5d241077f7e0a9f9968d280e6ceaaeb7ac1 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -927,7 +927,7 @@ static int get_service_user(struct mt_ctx *ctx)
                             CONFDB_MONITOR_USER_RUNAS,
                             NULL, &user_str);
     if (ret != EOK) {
-        DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get the user to run as");
+        DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get the user to run as\n");
         return ret;
     }
 
@@ -1696,7 +1696,6 @@ static errno_t load_configuration(TALLOC_CTX *mem_ctx,
         DEBUG(SSSDBG_FATAL_FAILURE, "Fatal error initializing confdb\n");
         goto done;
     }
-    talloc_zfree(cdb_file);
 
     ret = confdb_init_db(config_file, ctx->cdb);
     if (ret != EOK) {
@@ -1712,6 +1711,17 @@ static errno_t load_configuration(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
+    /* Allow configuration database to be accessible
+     * when SSSD runs as nonroot */
+    ret = chown(cdb_file, ctx->uid, ctx->gid);
+    if (ret != 0) {
+        ret = errno;
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              "chown failed for [%s]: [%d][%s].\n",
+              cdb_file, ret, sss_strerror(ret));
+        goto done;
+    }
+
     *monitor = ctx;
 
     ret = EOK;
-- 
1.9.3

-------------- next part --------------
>From 305f876bbd9ba1bcaf15027199b81da1522a8b52 Mon Sep 17 00:00:00 2001
From: Michal Zidek <mzidek at redhat.com>
Date: Thu, 9 Oct 2014 17:21:30 +0200
Subject: [PATCH 09/19] SYSDB: Allow calling chown on the sysdb file from
 monitor

Sysdb must be accessible for the nonroot sssd
processes.
---
 src/db/sysdb.c        | 21 +++++++++++++++++++++
 src/db/sysdb.h        |  9 +++++++++
 src/monitor/monitor.c |  3 ++-
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index 8d6f00b52976228bfc9dfdc93503148837677346..1f02585e747dda6aadde772f76f30d3d69c4cfc0 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -1322,6 +1322,16 @@ int sysdb_init(TALLOC_CTX *mem_ctx,
                struct sss_domain_info *domains,
                bool allow_upgrade)
 {
+    return sysdb_init_ext(mem_ctx, domains, allow_upgrade, false, 0, 0);
+}
+
+int sysdb_init_ext(TALLOC_CTX *mem_ctx,
+                   struct sss_domain_info *domains,
+                   bool allow_upgrade,
+                   bool chown_dbfile,
+                   uid_t uid,
+                   gid_t gid)
+{
     struct sss_domain_info *dom;
     struct sysdb_ctx *sysdb;
     int ret;
@@ -1343,6 +1353,17 @@ int sysdb_init(TALLOC_CTX *mem_ctx,
             return ret;
         }
 
+        if (chown_dbfile) {
+            ret = chown(sysdb->ldb_file, uid, gid);
+            if (ret != 0) {
+                ret = errno;
+                DEBUG(SSSDBG_CRIT_FAILURE,
+                      "Cannot set sysdb ownership to %"SPRIuid":%"SPRIgid"\n",
+                      uid, gid);
+                return ret;
+            }
+        }
+
         dom->sysdb = talloc_move(dom, &sysdb);
     }
 
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 6bb25de149818ccd0996e06f1fdb423c1e6f1767..67d4f1e5b30f787423dfec5d2a4b60ddeb45a359 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -444,6 +444,15 @@ errno_t sysdb_apply_default_override(struct sss_domain_info *domain,
 int sysdb_init(TALLOC_CTX *mem_ctx,
                struct sss_domain_info *domains,
                bool allow_upgrade);
+
+/* Same as sysdb_init, but additionally allows to change
+ * file ownership of the sysdb databases. */
+int sysdb_init_ext(TALLOC_CTX *mem_ctx,
+                   struct sss_domain_info *domains,
+                   bool allow_upgrade,
+                   bool chown_dbfile,
+                   uid_t uid, gid_t gid);
+
 /* used to initialize only one domain database.
  * Do NOT use if sysdb_init has already been called */
 int sysdb_domain_init(TALLOC_CTX *mem_ctx,
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 1567d5d241077f7e0a9f9968d280e6ceaaeb7ac1..210fecadf532fb8e6be97b6970e1b0615229ea29 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -2311,7 +2311,8 @@ static int monitor_process_init(struct mt_ctx *ctx,
     if (!tmp_ctx) {
         return ENOMEM;
     }
-    ret = sysdb_init(tmp_ctx, ctx->domains, true);
+    ret = sysdb_init_ext(tmp_ctx, ctx->domains, true,
+                         true, ctx->uid, ctx->gid);
     if (ret != EOK) {
         SYSDB_VERSION_ERROR_DAEMON(ret);
         return ret;
-- 
1.9.3

-------------- next part --------------
>From 61defc1239a2bbe5c8c4b50e6ba86c8b18fd8abb Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Sun, 21 Sep 2014 13:52:05 +0200
Subject: [PATCH 10/19] NSS: Run as a user specified by monitor

Adds the NSS responder to the list of services known to work as a
non-root user and becomes the specified user after starting the NSS
responder.
---
 src/monitor/monitor.c      | 3 +++
 src/responder/nss/nsssrv.c | 3 ++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 210fecadf532fb8e6be97b6970e1b0615229ea29..a7d411ad59950dc845ad72533f45986d0d5171f2 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1062,6 +1062,9 @@ static errno_t get_ping_config(struct mt_ctx *ctx, const char *path,
  */
 static bool svc_supported_as_nonroot(const char *svc_name)
 {
+    if (strcmp(svc_name, "nss") == 0) {
+        return true;
+    }
     return false;
 }
 
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 420fd3d316959a67737f23e9a8b3d1c797583ea3..dbbdb4f844410eabe01f184ccdf8d9deb41833f4 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -568,7 +568,8 @@ int main(int argc, const char *argv[])
     /* set up things like debug, signals, daemonization, etc... */
     debug_log_file = "sssd_nss";
 
-    ret = server_setup("sssd[nss]", 0, 0, 0, CONFDB_NSS_CONF_ENTRY, &main_ctx);
+    ret = server_setup("sssd[nss]", 0, uid, gid, CONFDB_NSS_CONF_ENTRY,
+                       &main_ctx);
     if (ret != EOK) return 2;
 
     ret = die_if_parent_died();
-- 
1.9.3

-------------- next part --------------
>From 1a2d3bf47c0da1bb32be138fa8b2b33260f68a37 Mon Sep 17 00:00:00 2001
From: Michal Zidek <mzidek at redhat.com>
Date: Wed, 15 Oct 2014 17:35:12 +0200
Subject: [PATCH 11/19] responder_common: Create fd for pipe in helper

Move creating of file descriptor for pipes into
helper function and make this function public.
---
 src/responder/common/responder.h        |   2 +
 src/responder/common/responder_common.c | 129 ++++++++++++++------------------
 2 files changed, 59 insertions(+), 72 deletions(-)

diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index 97552ec472c5baa285b41cc48b51149f3ef6adb5..d233710782fe7df1bbcc338e3815d1701557519e 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -176,6 +176,8 @@ responder_get_domain(struct resp_ctx *rctx, const char *domain);
 errno_t responder_get_domain_by_id(struct resp_ctx *rctx, const char *id,
                                    struct sss_domain_info **_ret_dom);
 
+int create_pipe_fd(const char *sock_name, int *fd, mode_t umaskval);
+
 /* responder_cmd.c */
 int sss_cmd_empty_packet(struct sss_packet *packet);
 int sss_cmd_send_empty(struct cli_ctx *cctx, TALLOC_CTX *freectx);
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 0ec2372e8d08f1002b303b5edc6897f17cee9699..3b880647e45cf4d4191ff7a9166e82b11288204d 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -584,10 +584,63 @@ static int sss_dp_init(struct resp_ctx *rctx,
     return EOK;
 }
 
+int create_pipe_fd(const char *sock_name, int *fd, mode_t umaskval)
+{
+    struct sockaddr_un addr;
+    errno_t ret;
+
+    *fd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (*fd == -1) {
+        return EIO;
+    }
+
+    umask(umaskval);
+
+    ret = set_nonblocking(*fd);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    ret = set_close_on_exec(*fd);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strncpy(addr.sun_path, sock_name, sizeof(addr.sun_path)-1);
+    addr.sun_path[sizeof(addr.sun_path)-1] = '\0';
+
+    /* make sure we have no old sockets around */
+    unlink(sock_name);
+
+    if (bind(*fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              "Unable to bind on socket '%s'\n", sock_name);
+        ret = EIO;
+        goto done;
+    }
+    if (listen(*fd, 10) != 0) {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              "Unable to listen on socket '%s'\n", sock_name);
+        ret = EIO;
+        goto done;
+    }
+
+    ret = EOK;
+done:
+    /* we want default permissions on created files to be very strict,
+       so set our umask to 0177 */
+    umask(0177);
+    if (ret != EOK) {
+        close(*fd);
+    }
+    return ret;
+}
+
 /* create a unix socket and listen to it */
 static int set_unix_socket(struct resp_ctx *rctx)
 {
-    struct sockaddr_un addr;
     errno_t ret;
     struct accept_fd_ctx *accept_ctx;
 
@@ -628,42 +681,11 @@ static int set_unix_socket(struct resp_ctx *rctx)
 #endif
 
     if (rctx->sock_name != NULL ) {
-        rctx->lfd = socket(AF_UNIX, SOCK_STREAM, 0);
-        if (rctx->lfd == -1) {
-            return EIO;
-        }
-
         /* Set the umask so that permissions are set right on the socket.
          * It must be readable and writable by anybody on the system. */
-        umask(0111);
-
-        ret = set_nonblocking(rctx->lfd);
+        ret = create_pipe_fd(rctx->sock_name, &rctx->lfd, 0111);
         if (ret != EOK) {
-            goto failed;
-        }
-
-        ret = set_close_on_exec(rctx->lfd);
-        if (ret != EOK) {
-            goto failed;
-        }
-
-        memset(&addr, 0, sizeof(addr));
-        addr.sun_family = AF_UNIX;
-        strncpy(addr.sun_path, rctx->sock_name, sizeof(addr.sun_path)-1);
-        addr.sun_path[sizeof(addr.sun_path)-1] = '\0';
-
-        /* make sure we have no old sockets around */
-        unlink(rctx->sock_name);
-
-        if (bind(rctx->lfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-            DEBUG(SSSDBG_FATAL_FAILURE,
-                  "Unable to bind on socket '%s'\n", rctx->sock_name);
-            goto failed;
-        }
-        if (listen(rctx->lfd, 10) != 0) {
-            DEBUG(SSSDBG_FATAL_FAILURE,
-                  "Unable to listen on socket '%s'\n", rctx->sock_name);
-            goto failed;
+            return ret;
         }
 
         accept_ctx = talloc_zero(rctx, struct accept_fd_ctx);
@@ -682,42 +704,11 @@ static int set_unix_socket(struct resp_ctx *rctx)
 
     if (rctx->priv_sock_name != NULL ) {
         /* create privileged pipe */
-        rctx->priv_lfd = socket(AF_UNIX, SOCK_STREAM, 0);
-        if (rctx->priv_lfd == -1) {
-            close(rctx->lfd);
-            return EIO;
-        }
-
-        umask(0177);
-
-        ret = set_nonblocking(rctx->priv_lfd);
+        ret = create_pipe_fd(rctx->priv_sock_name, &rctx->priv_lfd, 0177);
         if (ret != EOK) {
             goto failed;
         }
 
-        ret = set_close_on_exec(rctx->priv_lfd);
-        if (ret != EOK) {
-            goto failed;
-        }
-
-        memset(&addr, 0, sizeof(addr));
-        addr.sun_family = AF_UNIX;
-        strncpy(addr.sun_path, rctx->priv_sock_name, sizeof(addr.sun_path)-1);
-        addr.sun_path[sizeof(addr.sun_path)-1] = '\0';
-
-        unlink(rctx->priv_sock_name);
-
-        if (bind(rctx->priv_lfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-            DEBUG(SSSDBG_FATAL_FAILURE,
-                  "Unable to bind on socket '%s'\n", rctx->priv_sock_name);
-            goto failed;
-        }
-        if (listen(rctx->priv_lfd, 10) != 0) {
-            DEBUG(SSSDBG_FATAL_FAILURE,
-                  "Unable to listen on socket '%s'\n", rctx->priv_sock_name);
-            goto failed;
-        }
-
         accept_ctx = talloc_zero(rctx, struct accept_fd_ctx);
         if(!accept_ctx) goto failed;
         accept_ctx->rctx = rctx;
@@ -733,15 +724,9 @@ static int set_unix_socket(struct resp_ctx *rctx)
         }
     }
 
-    /* we want default permissions on created files to be very strict,
-       so set our umask to 0177 */
-    umask(0177);
     return EOK;
 
 failed:
-    /* we want default permissions on created files to be very strict,
-       so set our umask to 0177 */
-    umask(0177);
     close(rctx->lfd);
     close(rctx->priv_lfd);
     return EIO;
-- 
1.9.3

-------------- next part --------------
>From bcb390c8ad25b9a977c0d008b11fa2235d1c66c8 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Fri, 17 Oct 2014 16:44:05 +0200
Subject: [PATCH 12/19] TEST: Unit test for create_pipe_fd

---
 src/tests/cwrap/test_responder_common.c | 91 +++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/src/tests/cwrap/test_responder_common.c b/src/tests/cwrap/test_responder_common.c
index 23dcf753f184cdecaf39c73c6e9be0e23e6df968..7e3f2e025a0dce15cc93e560a42bb566eff9fb30 100644
--- a/src/tests/cwrap/test_responder_common.c
+++ b/src/tests/cwrap/test_responder_common.c
@@ -23,6 +23,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <talloc.h>
 
 #include <popt.h>
 #include "util/util.h"
@@ -105,6 +106,93 @@ void test_csv_to_uid_list_neg(void **state)
     talloc_free(tmp_ctx);
 }
 
+struct create_pipe_ctx {
+    int fd;
+    const char *sock_name;
+};
+
+void test_create_pipe_fd_setup(void **state)
+{
+    struct create_pipe_ctx *ctx;
+
+    ctx = talloc(global_talloc_context, struct create_pipe_ctx);
+    assert_non_null(ctx);
+    ctx->fd = -1;
+
+    *state = ctx;
+}
+
+void check_sock_properties(struct create_pipe_ctx *ctx, mode_t mode)
+{
+    int ret;
+    int optval;
+    socklen_t optlen;
+    struct stat sbuf;
+
+    /* Check existence of the file and the permissions */
+    ret = stat(ctx->sock_name, &sbuf);
+    assert_int_equal(ret, 0);
+    assert_true(S_ISSOCK(sbuf.st_mode));
+    assert_true((sbuf.st_mode & ~S_IFMT) == mode);
+
+    /* Check it's a UNIX socket */
+    optlen = sizeof(optval);
+    ret = getsockopt(ctx->fd, SOL_SOCKET, SO_DOMAIN, &optval, &optlen);
+    assert_int_equal(ret, 0);
+    assert_int_equal(optval, AF_UNIX);
+
+    optlen = sizeof(optval);
+    ret = getsockopt(ctx->fd, SOL_SOCKET, SO_TYPE, &optval, &optlen);
+    assert_int_equal(ret, 0);
+    assert_int_equal(optval, SOCK_STREAM);
+
+    /* Make sure this is a listening socket */
+    optlen = sizeof(optval);
+    ret = getsockopt(ctx->fd, SOL_SOCKET, SO_ACCEPTCONN, &optval, &optlen);
+    assert_int_equal(ret, 0);
+    assert_int_equal(optval, 1);
+
+    /* Check the right protocol */
+    optlen = sizeof(optval);
+    ret = getsockopt(ctx->fd, SOL_SOCKET, SO_PROTOCOL, &optval, &optlen);
+    assert_int_equal(ret, 0);
+    assert_int_equal(optval, 0);
+
+}
+
+void test_create_pipe_fd(void **state)
+{
+    int ret;
+    struct create_pipe_ctx *ctx;
+
+    ctx = talloc_get_type(*state, struct create_pipe_ctx);
+
+    ctx->sock_name = __FUNCTION__;
+
+    ret = create_pipe_fd(ctx->sock_name, &ctx->fd, 0111);
+    assert_int_equal(ret, EOK);
+    assert_int_not_equal(ctx->fd, -1);
+    check_sock_properties(ctx, 0666);
+
+    /* Make sure we can overwrite an existing socket */
+    ret = create_pipe_fd(ctx->sock_name, &ctx->fd, 0000);
+    assert_int_equal(ret, EOK);
+    assert_int_not_equal(ctx->fd, -1);
+    check_sock_properties(ctx, 0777);
+}
+
+void test_create_pipe_fd_teardown(void **state)
+{
+    struct create_pipe_ctx *ctx;
+
+    ctx = talloc_get_type(*state, struct create_pipe_ctx);
+
+    if (ctx->fd != -1) {
+        unlink(ctx->sock_name);
+        close(ctx->fd);
+    }
+}
+
 int main(int argc, const char *argv[])
 {
     poptContext pc;
@@ -119,6 +207,9 @@ int main(int argc, const char *argv[])
         unit_test(test_uid_csv_to_uid_list),
         unit_test(test_name_csv_to_uid_list),
         unit_test(test_csv_to_uid_list_neg),
+        unit_test_setup_teardown(test_create_pipe_fd,
+                                 test_create_pipe_fd_setup,
+                                 test_create_pipe_fd_teardown)
     };
 
     /* Set debug level to invalid value so we can deside if -d 0 was used. */
-- 
1.9.3

-------------- next part --------------
>From 5854febb08114e907c4fb847c11f16280c19624d Mon Sep 17 00:00:00 2001
From: Michal Zidek <mzidek at redhat.com>
Date: Wed, 15 Oct 2014 18:01:55 +0200
Subject: [PATCH 13/19] responders: Do not initialize pipe fd if already
 present

Allow to skip initialization of pipe file descriptor
if the responder context already has one.
---
 src/responder/autofs/autofssrv.c        |  2 +-
 src/responder/common/responder.h        |  2 ++
 src/responder/common/responder_common.c | 20 ++++++++++++++------
 src/responder/ifp/ifpsrv.c              |  2 +-
 src/responder/nss/nsssrv.c              |  2 +-
 src/responder/pac/pacsrv.c              |  2 +-
 src/responder/pam/pamsrv.c              |  4 ++--
 src/responder/ssh/sshsrv.c              |  2 +-
 src/responder/sudo/sudosrv.c            |  2 +-
 9 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/src/responder/autofs/autofssrv.c b/src/responder/autofs/autofssrv.c
index 931cf018bfe15b37bf8e5f93a21c7ab61d238c18..12a7a777e214fa4c3821eb58ff602b3f3efb987a 100644
--- a/src/responder/autofs/autofssrv.c
+++ b/src/responder/autofs/autofssrv.c
@@ -132,7 +132,7 @@ autofs_process_init(TALLOC_CTX *mem_ctx,
     autofs_cmds = get_autofs_cmds();
     ret = sss_process_init(mem_ctx, ev, cdb,
                            autofs_cmds,
-                           SSS_AUTOFS_SOCKET_NAME, NULL,
+                           SSS_AUTOFS_SOCKET_NAME, -1, NULL, -1,
                            CONFDB_AUTOFS_CONF_ENTRY,
                            SSS_AUTOFS_SBUS_SERVICE_NAME,
                            SSS_AUTOFS_SBUS_SERVICE_VERSION,
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index d233710782fe7df1bbcc338e3815d1701557519e..8837e11425be36c67da038287de48c069ae335cd 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -159,7 +159,9 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
                      struct confdb_ctx *cdb,
                      struct sss_cmd_table sss_cmds[],
                      const char *sss_pipe_name,
+                     int pipe_fd,
                      const char *sss_priv_pipe_name,
+                     int priv_pipe_fd,
                      const char *confdb_service_path,
                      const char *svc_name,
                      uint16_t svc_version,
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 3b880647e45cf4d4191ff7a9166e82b11288204d..05e7ee554c7fc13cd799c381e1cf8a869aeee0a6 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -683,9 +683,11 @@ static int set_unix_socket(struct resp_ctx *rctx)
     if (rctx->sock_name != NULL ) {
         /* Set the umask so that permissions are set right on the socket.
          * It must be readable and writable by anybody on the system. */
-        ret = create_pipe_fd(rctx->sock_name, &rctx->lfd, 0111);
-        if (ret != EOK) {
-            return ret;
+        if (rctx->lfd == -1) {
+            ret = create_pipe_fd(rctx->sock_name, &rctx->lfd, 0111);
+            if (ret != EOK) {
+                return ret;
+            }
         }
 
         accept_ctx = talloc_zero(rctx, struct accept_fd_ctx);
@@ -704,9 +706,11 @@ static int set_unix_socket(struct resp_ctx *rctx)
 
     if (rctx->priv_sock_name != NULL ) {
         /* create privileged pipe */
-        ret = create_pipe_fd(rctx->priv_sock_name, &rctx->priv_lfd, 0177);
-        if (ret != EOK) {
-            goto failed;
+        if (rctx->priv_lfd == -1) {
+            ret = create_pipe_fd(rctx->priv_sock_name, &rctx->priv_lfd, 0177);
+            if (ret != EOK) {
+                goto failed;
+            }
         }
 
         accept_ctx = talloc_zero(rctx, struct accept_fd_ctx);
@@ -749,7 +753,9 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
                      struct confdb_ctx *cdb,
                      struct sss_cmd_table sss_cmds[],
                      const char *sss_pipe_name,
+                     int pipe_fd,
                      const char *sss_priv_pipe_name,
+                     int priv_pipe_fd,
                      const char *confdb_service_path,
                      const char *svc_name,
                      uint16_t svc_version,
@@ -773,6 +779,8 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
     rctx->sss_cmds = sss_cmds;
     rctx->sock_name = sss_pipe_name;
     rctx->priv_sock_name = sss_priv_pipe_name;
+    rctx->lfd = pipe_fd;
+    rctx->priv_lfd = priv_pipe_fd;
     rctx->confdb_service_path = confdb_service_path;
     rctx->shutting_down = false;
 
diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c
index 6413c18c8943f1d8bb213605073acc50996210ca..90f45c432450a6883a26ff18a955822bfb699b62 100644
--- a/src/responder/ifp/ifpsrv.c
+++ b/src/responder/ifp/ifpsrv.c
@@ -310,7 +310,7 @@ int ifp_process_init(TALLOC_CTX *mem_ctx,
     ifp_cmds = get_ifp_cmds();
     ret = sss_process_init(mem_ctx, ev, cdb,
                            ifp_cmds,
-                           NULL, NULL,
+                           NULL, -1, NULL, -1,
                            CONFDB_IFP_CONF_ENTRY,
                            SSS_IFP_SBUS_SERVICE_NAME,
                            SSS_IFP_SBUS_SERVICE_VERSION,
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index dbbdb4f844410eabe01f184ccdf8d9deb41833f4..cfb146464d224cdb8b517d23a86421da7eaccd1f 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -392,7 +392,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
 
     ret = sss_process_init(mem_ctx, ev, cdb,
                            nss_cmds,
-                           SSS_NSS_SOCKET_NAME, NULL,
+                           SSS_NSS_SOCKET_NAME, -1, NULL, -1,
                            CONFDB_NSS_CONF_ENTRY,
                            NSS_SBUS_SERVICE_NAME,
                            NSS_SBUS_SERVICE_VERSION,
diff --git a/src/responder/pac/pacsrv.c b/src/responder/pac/pacsrv.c
index b76691de829b4f40937a07ea83825a606950aa1e..e427cd756f4031218a8fb99c30bf709e21680039 100644
--- a/src/responder/pac/pacsrv.c
+++ b/src/responder/pac/pacsrv.c
@@ -119,7 +119,7 @@ int pac_process_init(TALLOC_CTX *mem_ctx,
 
     ret = sss_process_init(mem_ctx, ev, cdb,
                            pac_cmds,
-                           SSS_PAC_SOCKET_NAME, NULL,
+                           SSS_PAC_SOCKET_NAME, -1, NULL, -1,
                            CONFDB_PAC_CONF_ENTRY,
                            PAC_SBUS_SERVICE_NAME,
                            PAC_SBUS_SERVICE_VERSION,
diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
index 91b395080820b27f5d57341e59dd739e674be31a..a3f8662738c26a537bc21d8d419e65e49c4828c9 100644
--- a/src/responder/pam/pamsrv.c
+++ b/src/responder/pam/pamsrv.c
@@ -194,8 +194,8 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
     pam_cmds = get_pam_cmds();
     ret = sss_process_init(mem_ctx, ev, cdb,
                            pam_cmds,
-                           SSS_PAM_SOCKET_NAME,
-                           SSS_PAM_PRIV_SOCKET_NAME,
+                           SSS_PAM_SOCKET_NAME, -1,
+                           SSS_PAM_PRIV_SOCKET_NAME, -1,
                            CONFDB_PAM_CONF_ENTRY,
                            SSS_PAM_SBUS_SERVICE_NAME,
                            SSS_PAM_SBUS_SERVICE_VERSION,
diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c
index 1328d1746b9e2d6474d6c2f8ce2825be463ca3e7..b154ee1baa16de68f642d2e967b8e7c873c8d4e7 100644
--- a/src/responder/ssh/sshsrv.c
+++ b/src/responder/ssh/sshsrv.c
@@ -92,7 +92,7 @@ int ssh_process_init(TALLOC_CTX *mem_ctx,
     ssh_cmds = get_ssh_cmds();
     ret = sss_process_init(mem_ctx, ev, cdb,
                            ssh_cmds,
-                           SSS_SSH_SOCKET_NAME, NULL,
+                           SSS_SSH_SOCKET_NAME, -1, NULL, -1,
                            CONFDB_SSH_CONF_ENTRY,
                            SSS_SSH_SBUS_SERVICE_NAME,
                            SSS_SSH_SBUS_SERVICE_VERSION,
diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c
index 30752c9dacdc390b24fe837c0630333b5e171448..038e3fd7da0829ce554a31694725c3dddaf5c038 100644
--- a/src/responder/sudo/sudosrv.c
+++ b/src/responder/sudo/sudosrv.c
@@ -93,7 +93,7 @@ int sudo_process_init(TALLOC_CTX *mem_ctx,
     sudo_cmds = get_sudo_cmds();
     ret = sss_process_init(mem_ctx, ev, cdb,
                            sudo_cmds,
-                           SSS_SUDO_SOCKET_NAME, NULL,
+                           SSS_SUDO_SOCKET_NAME, -1, NULL, -1,
                            CONFDB_SUDO_CONF_ENTRY,
                            SSS_SUDO_SBUS_SERVICE_NAME,
                            SSS_SUDO_SBUS_SERVICE_VERSION,
-- 
1.9.3

-------------- next part --------------
>From 8a50b5eec088332579c6957b66de4aa727a26561 Mon Sep 17 00:00:00 2001
From: Michal Zidek <mzidek at redhat.com>
Date: Wed, 15 Oct 2014 18:15:53 +0200
Subject: [PATCH 14/19] PAM: Create pipe file descriptors before priviledges
 are dropped

---
 src/responder/pam/pamsrv.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
index a3f8662738c26a537bc21d8d419e65e49c4828c9..8e0dc6cdf2cee1e31b435fbed461184e275fedbb 100644
--- a/src/responder/pam/pamsrv.c
+++ b/src/responder/pam/pamsrv.c
@@ -181,7 +181,8 @@ done:
 
 static int pam_process_init(TALLOC_CTX *mem_ctx,
                             struct tevent_context *ev,
-                            struct confdb_ctx *cdb)
+                            struct confdb_ctx *cdb,
+                            int pipe_fd, int priv_pipe_fd)
 {
     struct resp_ctx *rctx;
     struct sss_cmd_table *pam_cmds;
@@ -194,8 +195,8 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
     pam_cmds = get_pam_cmds();
     ret = sss_process_init(mem_ctx, ev, cdb,
                            pam_cmds,
-                           SSS_PAM_SOCKET_NAME, -1,
-                           SSS_PAM_PRIV_SOCKET_NAME, -1,
+                           SSS_PAM_SOCKET_NAME, pipe_fd,
+                           SSS_PAM_PRIV_SOCKET_NAME, priv_pipe_fd,
                            CONFDB_PAM_CONF_ENTRY,
                            SSS_PAM_SBUS_SERVICE_NAME,
                            SSS_PAM_SBUS_SERVICE_VERSION,
@@ -318,6 +319,8 @@ int main(int argc, const char *argv[])
     int ret;
     uid_t uid;
     gid_t gid;
+    int pipe_fd;
+    int priv_pipe_fd;
 
     struct poptOption long_options[] = {
         POPT_AUTOHELP
@@ -347,6 +350,24 @@ int main(int argc, const char *argv[])
     /* set up things like debug, signals, daemonization, etc... */
     debug_log_file = "sssd_pam";
 
+    /* Crate pipe file descriptors here before priviledges are dropped
+     * in server_setup() */
+    ret = create_pipe_fd(SSS_PAM_SOCKET_NAME, &pipe_fd, 0111);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              "create_pipe_fd failed [%d]: %s.\n",
+              ret, sss_strerror(ret));
+        return 2;
+    }
+
+    ret = create_pipe_fd(SSS_PAM_PRIV_SOCKET_NAME, &priv_pipe_fd, 0177);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              "create_pipe_fd failed (priviledged pipe) [%d]: %s.\n",
+              ret, sss_strerror(ret));
+        return 2;
+    }
+
     ret = server_setup("sssd[pam]", 0, 0, 0, CONFDB_PAM_CONF_ENTRY, &main_ctx);
     if (ret != EOK) return 2;
 
@@ -359,7 +380,8 @@ int main(int argc, const char *argv[])
 
     ret = pam_process_init(main_ctx,
                            main_ctx->event_ctx,
-                           main_ctx->confdb_ctx);
+                           main_ctx->confdb_ctx,
+                           pipe_fd, priv_pipe_fd);
     if (ret != EOK) return 3;
 
     /* loop on main */
-- 
1.9.3

-------------- next part --------------
>From e8411c1ec7296a2951b6bef7a5c37908afe214ee Mon Sep 17 00:00:00 2001
From: Michal Zidek <mzidek at redhat.com>
Date: Thu, 9 Oct 2014 17:25:34 +0200
Subject: [PATCH 15/19] PAM: Run pam responder as nonroot

---
 src/monitor/monitor.c      | 3 ++-
 src/responder/pam/pamsrv.c | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index a7d411ad59950dc845ad72533f45986d0d5171f2..297dc6b1413e694fef253a0a3d0133a513747f37 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1062,7 +1062,8 @@ static errno_t get_ping_config(struct mt_ctx *ctx, const char *path,
  */
 static bool svc_supported_as_nonroot(const char *svc_name)
 {
-    if (strcmp(svc_name, "nss") == 0) {
+    if ((strcmp(svc_name, "nss") == 0)
+        || (strcmp(svc_name, "pam") == 0)) {
         return true;
     }
     return false;
diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
index 8e0dc6cdf2cee1e31b435fbed461184e275fedbb..1f36c7dd2ca27e001e6ebddee1db29512e093667 100644
--- a/src/responder/pam/pamsrv.c
+++ b/src/responder/pam/pamsrv.c
@@ -368,7 +368,7 @@ int main(int argc, const char *argv[])
         return 2;
     }
 
-    ret = server_setup("sssd[pam]", 0, 0, 0, CONFDB_PAM_CONF_ENTRY, &main_ctx);
+    ret = server_setup("sssd[pam]", 0, uid, gid, CONFDB_PAM_CONF_ENTRY, &main_ctx);
     if (ret != EOK) return 2;
 
     ret = die_if_parent_died();
-- 
1.9.3

-------------- next part --------------
>From 682661af34c25e267346123815659883a7095c0a Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Fri, 17 Oct 2014 17:30:07 +0200
Subject: [PATCH 16/19] AUTOFS: Run the autofs responder as the SSSD user

---
 src/monitor/monitor.c            | 3 ++-
 src/responder/autofs/autofssrv.c | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 297dc6b1413e694fef253a0a3d0133a513747f37..d83571c7fe875ef6e6e439b27ff4f42b294d2e90 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1063,7 +1063,8 @@ static errno_t get_ping_config(struct mt_ctx *ctx, const char *path,
 static bool svc_supported_as_nonroot(const char *svc_name)
 {
     if ((strcmp(svc_name, "nss") == 0)
-        || (strcmp(svc_name, "pam") == 0)) {
+        || (strcmp(svc_name, "pam") == 0)
+        || (strcmp(svc_name, "autofs") == 0)) {
         return true;
     }
     return false;
diff --git a/src/responder/autofs/autofssrv.c b/src/responder/autofs/autofssrv.c
index 12a7a777e214fa4c3821eb58ff602b3f3efb987a..44474ee0858d92fb5965de07773e3ad1e020ebfd 100644
--- a/src/responder/autofs/autofssrv.c
+++ b/src/responder/autofs/autofssrv.c
@@ -238,7 +238,7 @@ int main(int argc, const char *argv[])
     /* set up things like debug, signals, daemonization, etc... */
     debug_log_file = "sssd_autofs";
 
-    ret = server_setup("sssd[autofs]", 0, 0, 0,
+    ret = server_setup("sssd[autofs]", 0, uid, gid,
                        CONFDB_AUTOFS_CONF_ENTRY, &main_ctx);
     if (ret != EOK) {
         return 2;
-- 
1.9.3

-------------- next part --------------
>From 215efb89043cb1becb472585602aa723fca17c43 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Fri, 17 Oct 2014 17:31:31 +0200
Subject: [PATCH 17/19] PAC: Run the pac responder as the SSSD user

---
 src/monitor/monitor.c      | 3 ++-
 src/responder/pac/pacsrv.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index d83571c7fe875ef6e6e439b27ff4f42b294d2e90..71b4461ca0b3d3db029d0f3f6cf0dbb0566acd0d 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1064,7 +1064,8 @@ static bool svc_supported_as_nonroot(const char *svc_name)
 {
     if ((strcmp(svc_name, "nss") == 0)
         || (strcmp(svc_name, "pam") == 0)
-        || (strcmp(svc_name, "autofs") == 0)) {
+        || (strcmp(svc_name, "autofs") == 0)
+        || (strcmp(svc_name, "pac") == 0)) {
         return true;
     }
     return false;
diff --git a/src/responder/pac/pacsrv.c b/src/responder/pac/pacsrv.c
index e427cd756f4031218a8fb99c30bf709e21680039..3eb21c8fff85343249494bcc06d97cda4b738034 100644
--- a/src/responder/pac/pacsrv.c
+++ b/src/responder/pac/pacsrv.c
@@ -247,7 +247,8 @@ int main(int argc, const char *argv[])
     /* set up things like debug, signals, daemonization, etc... */
     debug_log_file = "sssd_pac";
 
-    ret = server_setup("sssd[pac]", 0, 0, 0, CONFDB_PAC_CONF_ENTRY, &main_ctx);
+    ret = server_setup("sssd[pac]", 0, uid, gid,
+                       CONFDB_PAC_CONF_ENTRY, &main_ctx);
     if (ret != EOK) return 2;
 
     ret = die_if_parent_died();
-- 
1.9.3

-------------- next part --------------
>From 96cabca60951e8337443ba382b2cd944d969fcac Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Fri, 17 Oct 2014 18:14:45 +0200
Subject: [PATCH 18/19] SUDO: Run the sudo responder as the SSSD user

---
 src/monitor/monitor.c        | 3 ++-
 src/responder/sudo/sudosrv.c | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 71b4461ca0b3d3db029d0f3f6cf0dbb0566acd0d..266d1299ac2cb3b955af90b9d52db4aa0ecd8cef 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1065,7 +1065,8 @@ static bool svc_supported_as_nonroot(const char *svc_name)
     if ((strcmp(svc_name, "nss") == 0)
         || (strcmp(svc_name, "pam") == 0)
         || (strcmp(svc_name, "autofs") == 0)
-        || (strcmp(svc_name, "pac") == 0)) {
+        || (strcmp(svc_name, "pac") == 0)
+        || (strcmp(svc_name, "sudo") == 0)) {
         return true;
     }
     return false;
diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c
index 038e3fd7da0829ce554a31694725c3dddaf5c038..a25f98ecabaa952a7cd87c54cd302903cb563faf 100644
--- a/src/responder/sudo/sudosrv.c
+++ b/src/responder/sudo/sudosrv.c
@@ -195,7 +195,7 @@ int main(int argc, const char *argv[])
     /* set up things like debug, signals, daemonization, etc... */
     debug_log_file = "sssd_sudo";
 
-    ret = server_setup("sssd[sudo]", 0, 0, 0, CONFDB_SUDO_CONF_ENTRY,
+    ret = server_setup("sssd[sudo]", 0, uid, gid, CONFDB_SUDO_CONF_ENTRY,
                        &main_ctx);
     if (ret != EOK) {
         return 2;
-- 
1.9.3

-------------- next part --------------
>From fd7b47c50bc232eb2fd45e91dbbe5aa9cf0154ad Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Fri, 17 Oct 2014 18:14:53 +0200
Subject: [PATCH 19/19] SSH: Run the ssh responder as the SSSD user

---
 src/monitor/monitor.c      | 3 ++-
 src/responder/ssh/sshsrv.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 266d1299ac2cb3b955af90b9d52db4aa0ecd8cef..50dacd78ee97ed1683302534468de3dfc0456074 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1066,7 +1066,8 @@ static bool svc_supported_as_nonroot(const char *svc_name)
         || (strcmp(svc_name, "pam") == 0)
         || (strcmp(svc_name, "autofs") == 0)
         || (strcmp(svc_name, "pac") == 0)
-        || (strcmp(svc_name, "sudo") == 0)) {
+        || (strcmp(svc_name, "sudo") == 0)
+        || (strcmp(svc_name, "ssh") == 0)) {
         return true;
     }
     return false;
diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c
index b154ee1baa16de68f642d2e967b8e7c873c8d4e7..b1969b49de8579f0136c3afa78eb16d68c81ee4e 100644
--- a/src/responder/ssh/sshsrv.c
+++ b/src/responder/ssh/sshsrv.c
@@ -215,7 +215,8 @@ int main(int argc, const char *argv[])
     /* set up things like debug, signals, daemonization, etc... */
     debug_log_file = "sssd_ssh";
 
-    ret = server_setup("sssd[ssh]", 0, 0, 0, CONFDB_SSH_CONF_ENTRY, &main_ctx);
+    ret = server_setup("sssd[ssh]", 0, uid, gid,
+                       CONFDB_SSH_CONF_ENTRY, &main_ctx);
     if (ret != EOK) {
         return 2;
     }
-- 
1.9.3



More information about the sssd-devel mailing list