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

Jakub Hrozek jhrozek at redhat.com
Tue Oct 21 14:40:46 UTC 2014


On Tue, Oct 21, 2014 at 01:59:31PM +0200, Pavel Reichl wrote:
> Just last nitpicks before I dive into testing:

I hope I managed to fix them all, see the attached patches..
-------------- next part --------------
>From af232cfbd8865f689521e9f958b490cb7d890350 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             |  54 ++++++++++++
 src/tests/cwrap/passwd                  |   3 +-
 src/tests/cwrap/test_responder_common.c | 144 ++++++++++++++++++++++++++++++++
 src/tests/cwrap/test_usertools.c        | 106 +++++++++++++++++++++++
 src/util/usertools.c                    |  44 ++++++++++
 src/util/util.c                         |   1 +
 src/util/util.h                         |   2 +
 9 files changed, 360 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 28d60e7f5bc346543f51740ec4b2781a99a48909..d9eb5a8a6f6d5e71d6efb5cef83af8185adc8191 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
@@ -106,4 +108,56 @@ 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 \
+    ../../../src/db/sysdb_views.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..6423059456a06f0c8f8ebdd803641b7207e862fd
--- /dev/null
+++ b/src/tests/cwrap/test_usertools.c
@@ -0,0 +1,106 @@
+/*
+    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, 456);
+}
+
+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;
+    gid_t gid;
+    errno_t ret;
+
+    ret = sss_user_by_name_or_uid("sssd", &uid, NULL);
+    assert_int_equal(ret, EOK);
+    assert_int_equal(uid, 123);
+
+    ret = sss_user_by_name_or_uid("sssd", NULL, &gid);
+    assert_int_equal(ret, EOK);
+    assert_int_equal(gid, 456);
+}
+
+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..a0b914e2fe8f65a71015944e63cb2d2813345d84 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,44 @@ 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;
+    errno_t ret;
+    char *endptr;
+    struct passwd *pwd;
+
+    /* Try if it's an ID first */
+    errno = 0;
+    uid = strtouint32(input, &endptr, 10);
+    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);
+    } else {
+        pwd = getpwuid(uid);
+    }
+
+    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;
+    }
+
+    if (_uid) {
+        *_uid = pwd->pw_uid;
+    }
+
+    if (_gid) {
+        *_gid = pwd->pw_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 df83aac7d53ccadb806e8a1be90f0e45abb829ae..69074c93c1640a1e4a7e590b7f9feb6cc04804a4 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -404,6 +404,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 21fff28f30eb0b40962683dd4ceb933b08333909 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 a new configure-time option that lets you select the user to run
SSSD as. The default is 'root' for backwards compatibility.

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 b949c9c24070026570de970b545918a7eb279c6d..61bf5cf957d4024b67f48cf42f5735b5fa368945 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
@@ -2740,24 +2748,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 c66d1b24cb56d57d4609cfb79d959ccf008570d0 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 ownership 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 74f7e950518841ec3cbd6e3fb4edf2eb873c7704..988174b5e2a64dc6ce90e14e6c69dde3a685e15d 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -604,17 +604,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
@@ -803,6 +803,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 104450e12d366cb41930e67b8bf44eac38e8d461 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

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.
---
 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 34d4610654c24017bcad8608332c71232d665d40..159aa9f2c44ed91c94a40c98d5a7710793f0aa85 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..df1cd5ca14c759f7aab98094a2b8ad35731c35e6 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
-- 
1.9.3

-------------- next part --------------
>From 027cdd9f2d657198229676635a6833a19183aec2 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      | 18 ++++++++++++++++--
 src/tests/common_dbus.c          |  4 ++--
 7 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index df1cd5ca14c759f7aab98094a2b8ad35731c35e6..b6777784cd289e85c865fc16490d0287a63192a5 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..18fb98df61f1740898f725cb0ae9924f5e2f7716 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,
@@ -260,9 +261,22 @@ int sbus_new_server(TALLOC_CTX *mem_ctx,
     if ((stat_buf.st_mode & ~S_IFMT) != (S_IRUSR|S_IWUSR)) {
         ret = chmod(filename, (S_IRUSR|S_IWUSR));
         if (ret != EOK) {
+            ret = errno;
             DEBUG(SSSDBG_CRIT_FAILURE,
-                  "chmod failed for [%s]: [%d][%s].\n", filename, errno,
-                                                         strerror(errno));
+                  "chmod failed for [%s]: [%d][%s].\n", filename, ret,
+                                                        sss_strerror(ret));
+            ret = EIO;
+            goto done;
+        }
+    }
+
+    if (stat_buf.st_uid != uid || stat_buf.st_gid != gid) {
+        ret = chown(filename, uid, gid);
+        if (ret != EOK) {
+            ret = errno;
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "chown failed for [%s]: [%d][%s].\n", filename, ret,
+                                                        sss_strerror(ret));
             ret = EIO;
             goto done;
         }
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 c09037401e839d2424ac5ac08148422c1cbc1dba 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 b6777784cd289e85c865fc16490d0287a63192a5..fc6b2963fff41a2a2aefdaf502817f6764e95b1e 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 d2db5636e268866809b46a3566bc36b61c79621f 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 fc6b2963fff41a2a2aefdaf502817f6764e95b1e..905e66f25601d155557487ae9c7eb6d3145d3a83 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 35a605555eb17db77adcdc75eda99c20ee7794e7 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 | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 905e66f25601d155557487ae9c7eb6d3145d3a83..37f6e928be3508762e1c3afadbb67762f5cc1d38 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -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,11 +1711,23 @@ 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;
 
 done:
+    talloc_free(cdb_file);
     if (ret != EOK) {
         talloc_free(ctx);
     }
-- 
1.9.3

-------------- next part --------------
>From 0512790dff2c5a20151afedd574c52049ee91244 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 0d0971d98dd684e47ae8ec067447169f41ebba67..ebb1bbedaf2df3030a012f1f0be8c5a069399cc3 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -533,6 +533,15 @@ uint64_t sss_view_ldb_msg_find_attr_as_uint64(struct sss_domain_info *dom,
 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 37f6e928be3508762e1c3afadbb67762f5cc1d38..04702428c4ed7fd1d77c6f18e491fa69b3700f4f 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -2312,7 +2312,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 3fd4d72f040d88b81b22180269974349e477a98b 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 04702428c4ed7fd1d77c6f18e491fa69b3700f4f..297648a60836cec1bd95c0a2972c8d14be32675a 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 c1e3e88c776ae2623e5662d7e9396410c71515f7 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 | 135 +++++++++++++++-----------------
 2 files changed, 65 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..a262a2c1487c786404b6d0d4c720edd1679279d0 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -584,10 +584,69 @@ 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 */
+    ret = unlink(sock_name);
+    if (ret != 0 && errno != ENOENT) {
+        ret = errno;
+        DEBUG(SSSDBG_MINOR_FAILURE,
+              "Cannot remove old socket (errno=%d), bind might fail!\n", ret);
+    }
+
+    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 +687,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 +710,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 +730,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 61e3c98f950d3e62762cde24ceaf78ce73ed750b 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 d76ec6c748010723f9c1c39f925648e9cecf1549 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 a262a2c1487c786404b6d0d4c720edd1679279d0..85aa04335b72c38fb7a128f04315e3c4189c5d56 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -689,9 +689,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);
@@ -710,9 +712,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);
@@ -755,7 +759,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,
@@ -779,6 +785,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 8d8fe885abb8ef53ee7f49e763ba78c4dda9a983..eddeec9812bdd650bfbfb78ede91bf3704113504 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 ad1d070a1750729e735fc5b140f754135ab7ae1c 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 ded9182b541ff2fd97688697ba2feef0968c2bf8 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 297648a60836cec1bd95c0a2972c8d14be32675a..2f622e571478b2a71ef29ed518ca3b80c077b766 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 b72023713628a62c450ae0f57fbabaf223555b67 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 2f622e571478b2a71ef29ed518ca3b80c077b766..4e461aa78e47ec6cedb77dd030f72c273a00a495 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 acce0bdfdaf691765eeba6ad9e2384fedc900b39 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 4e461aa78e47ec6cedb77dd030f72c273a00a495..61a9f0b849a460da88b393b4f08795fb7a571886 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 81a83f1045f450e642e402eb57ff132473193d8e 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 61a9f0b849a460da88b393b4f08795fb7a571886..d09aeba9033ff1460f9d4a6c51f35edbf2e67fa6 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 31315a73c0d1c35961a64e2ee8dab0f5a203fb1a 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 d09aeba9033ff1460f9d4a6c51f35edbf2e67fa6..0dea327213a1ad04b6f69c0ffb0fb87254420796 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