URL: https://github.com/SSSD/sssd/pull/183
Author: fidencio
 Title: #183: More socket-activation fixes
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/183/head:pr183
git checkout pr183
From f1683d696fe257bebd7f69393b97140287d8832a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fiden...@redhat.com>
Date: Tue, 7 Mar 2017 16:55:41 +0100
Subject: [PATCH 1/2] SYSTEMD: Ensure the service is shutdown in case the
 socket is stopped
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Avoid leaving the service running in case the admin calls `systemctl
stop sssd-@responder@.socket`.

Resolves:
https://pagure.io/SSSD/sssd/issue/3323

Signed-off-by: Fabiano FidĂȘncio <fiden...@redhat.com>
---
 src/sysv/systemd/sssd-autofs.service.in | 2 ++
 src/sysv/systemd/sssd-nss.service.in    | 2 ++
 src/sysv/systemd/sssd-pac.service.in    | 2 ++
 src/sysv/systemd/sssd-pam.service.in    | 2 ++
 src/sysv/systemd/sssd-ssh.service.in    | 2 ++
 src/sysv/systemd/sssd-sudo.service.in   | 2 ++
 6 files changed, 12 insertions(+)

diff --git a/src/sysv/systemd/sssd-autofs.service.in b/src/sysv/systemd/sssd-autofs.service.in
index 32ea6e1..2f4196b 100644
--- a/src/sysv/systemd/sssd-autofs.service.in
+++ b/src/sysv/systemd/sssd-autofs.service.in
@@ -3,6 +3,8 @@ Description=SSSD AutoFS Service responder
 Documentation=man:sssd.conf(5)
 After=sssd.service
 BindsTo=sssd.service
+After=sssd-autofs.socket
+BindsTo=sssd-autofs.socket
 RefuseManualStart=true
 
 [Install]
diff --git a/src/sysv/systemd/sssd-nss.service.in b/src/sysv/systemd/sssd-nss.service.in
index e2f68bc..6b8bfcf 100644
--- a/src/sysv/systemd/sssd-nss.service.in
+++ b/src/sysv/systemd/sssd-nss.service.in
@@ -3,6 +3,8 @@ Description=SSSD NSS Service responder
 Documentation=man:sssd.conf(5)
 After=sssd.service
 BindsTo=sssd.service
+After=sssd-nss.socket
+BindsTo=sssd-nss.socket
 RefuseManualStart=true
 
 [Install]
diff --git a/src/sysv/systemd/sssd-pac.service.in b/src/sysv/systemd/sssd-pac.service.in
index ffbfdec..841f48a 100644
--- a/src/sysv/systemd/sssd-pac.service.in
+++ b/src/sysv/systemd/sssd-pac.service.in
@@ -3,6 +3,8 @@ Description=SSSD PAC Service responder
 Documentation=man:sssd.conf(5)
 After=sssd.service
 BindsTo=sssd.service
+After=sssd-pac.socket
+BindsTo=sssd-pac.socket
 RefuseManualStart=true
 
 [Install]
diff --git a/src/sysv/systemd/sssd-pam.service.in b/src/sysv/systemd/sssd-pam.service.in
index 6dec46f..aa413d2 100644
--- a/src/sysv/systemd/sssd-pam.service.in
+++ b/src/sysv/systemd/sssd-pam.service.in
@@ -3,6 +3,8 @@ Description=SSSD PAM Service responder
 Documentation=man:sssd.conf(5)
 After=sssd.service
 BindsTo=sssd.service
+After=sssd-pam.socket
+BindsTo=sssd-pam.socket
 RefuseManualStart=true
 
 [Install]
diff --git a/src/sysv/systemd/sssd-ssh.service.in b/src/sysv/systemd/sssd-ssh.service.in
index 6f233b4..d35b85e 100644
--- a/src/sysv/systemd/sssd-ssh.service.in
+++ b/src/sysv/systemd/sssd-ssh.service.in
@@ -3,6 +3,8 @@ Description=SSSD SSH Service responder
 Documentation=man:sssd.conf(5)
 After=sssd.service
 BindsTo=sssd.service
+After=sssd-ssh.socket
+BindsTo=sssd-ssh.socket
 RefuseManualStart=true
 
 [Install]
diff --git a/src/sysv/systemd/sssd-sudo.service.in b/src/sysv/systemd/sssd-sudo.service.in
index b59bcbc..9b0da3b 100644
--- a/src/sysv/systemd/sssd-sudo.service.in
+++ b/src/sysv/systemd/sssd-sudo.service.in
@@ -3,6 +3,8 @@ Description=SSSD Sudo Service responder
 Documentation=man:sssd.conf(5) man:sssd-sudo(5)
 After=sssd.service
 BindsTo=sssd.service
+After=sssd-sudo.socket
+BindsTo=sssd-sudo.socket
 RefuseManualStart=true
 
 [Install]

From b5c9321b2d13e40ee7d9a63c5b9c8eb534a53a18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fiden...@redhat.com>
Date: Tue, 7 Mar 2017 23:15:30 +0100
Subject: [PATCH 2/2] Avoid TOCTOU vulnerability with the log files
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The time-of-check time-of-use bug can occur on SSSD as the ownership of
the log files is changed during the ExecStartPre but the file itself is
only opened during the server_setup().

This issue was brough up while working on a fix for 3322[0].

A few conversations happened around this very same issue and some of the
solutions are:

- Pass two new arguments to the responders when initializing the
processes. These arguments would be "user" and "group" and would take
the user and group names. The problem with this solution is that SSSD
would end up calling getpwnam() in order to get the uid and gid and it
would be a circular dependency, which we really want to avoid during the
service startup (as pointed by Stephen Gallagher).

- Considering the sssd user has a static id, pass its uid and gid using
the "uid" and "gid" arguments. This one would probably work well, but we
cannot ensure that we're in sync with another distros which take
advantage of the non-privileged user.

- Provide our own binary for doing chown() without calling getpwnam()
and use it instead of /usr/bin/chown. In my particular opinion we should
avoiding taking this path, avoid keeping/maintaining our own
implementation of chown.

- Always run the socket-activated services as root. This is a really
strong thing to do, but ensures that we won't have the TUCTOU issue and
we're not going to call getpwnam() during the service initialization.
The downside of this solution is that downstream distros would have to
patch SSSD in case they want to support running the socket-activated
services as unprivileged user.

The path I've chosen is a mix of the second and the last options. We
start passing the uid and gid arguments to the socket-activated services
and also drop support to run them as unprivileged user (at least for
now).

As part of this patch open_and_fchown_debug_file() has also been added
in order to ensure we open the file, with the file opened we change its
ownership and keep the file opened while it's being used, avoiding then
the TOCTOU vulnerability.

This patch indirectly solves 3322[0].

[0]: https://pagure.io/SSSD/sssd/issue/3322

Signed-off-by: Fabiano FidĂȘncio <fiden...@redhat.com>
---
 Makefile.am                              |  4 +-
 src/sysv/systemd/sssd-autofs.service.in  |  6 +--
 src/sysv/systemd/sssd-autofs.socket.in   |  2 -
 src/sysv/systemd/sssd-nss.service.in     |  3 +-
 src/sysv/systemd/sssd-nss.socket.in      |  2 -
 src/sysv/systemd/sssd-pac.service.in     |  6 +--
 src/sysv/systemd/sssd-pac.socket.in      |  2 -
 src/sysv/systemd/sssd-pam-priv.socket.in |  2 -
 src/sysv/systemd/sssd-pam.service.in     |  6 +--
 src/sysv/systemd/sssd-pam.socket.in      |  2 -
 src/sysv/systemd/sssd-ssh.service.in     |  6 +--
 src/sysv/systemd/sssd-ssh.socket.in      |  2 -
 src/sysv/systemd/sssd-sudo.service.in    |  6 +--
 src/sysv/systemd/sssd-sudo.socket.in     |  2 -
 src/util/debug.c                         | 78 ++++++++++++++++++++++++++++----
 src/util/server.c                        | 24 +++++-----
 src/util/util.h                          |  2 +
 17 files changed, 89 insertions(+), 66 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 34da1f0..1265f61 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4150,11 +4150,9 @@ edit_cmd = $(SED) \
         -e 's|@sbindir[@]|$(sbindir)|g' \
         -e 's|@environment_file[@]|$(environment_file)|g' \
         -e 's|@localstatedir[@]|$(localstatedir)|g' \
-        -e 's|@logpath[@]|$(logpath)|g' \
         -e 's|@libexecdir[@]|$(libexecdir)|g' \
         -e 's|@pipepath[@]|$(pipepath)|g' \
-        -e 's|@prefix[@]|$(prefix)|g' \
-        -e 's|@SSSD_USER[@]|$(SSSD_USER)|g'
+        -e 's|@prefix[@]|$(prefix)|g'
 
 replace_script = \
     @rm -f $@ $@.tmp; \
diff --git a/src/sysv/systemd/sssd-autofs.service.in b/src/sysv/systemd/sssd-autofs.service.in
index 2f4196b..2aaf5d6 100644
--- a/src/sysv/systemd/sssd-autofs.service.in
+++ b/src/sysv/systemd/sssd-autofs.service.in
@@ -11,9 +11,5 @@ RefuseManualStart=true
 Also=sssd-autofs.socket
 
 [Service]
-ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_autofs.log
-ExecStart=@libexecdir@/sssd/sssd_autofs --debug-to-files --socket-activated
+ExecStart=@libexecdir@/sssd/sssd_autofs --uid 0 --gid 0 --debug-to-files --socket-activated
 Restart=on-failure
-User=@SSSD_USER@
-Group=@SSSD_USER@
-PermissionsStartOnly=true
diff --git a/src/sysv/systemd/sssd-autofs.socket.in b/src/sysv/systemd/sssd-autofs.socket.in
index 201b33d..1cd1392 100644
--- a/src/sysv/systemd/sssd-autofs.socket.in
+++ b/src/sysv/systemd/sssd-autofs.socket.in
@@ -9,8 +9,6 @@ Conflicts=shutdown.target
 [Socket]
 ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r autofs
 ListenStream=@pipepath@/autofs
-SocketUser=@SSSD_USER@
-SocketGroup=@SSSD_USER@
 
 [Install]
 WantedBy=sssd.service
diff --git a/src/sysv/systemd/sssd-nss.service.in b/src/sysv/systemd/sssd-nss.service.in
index 6b8bfcf..448725a 100644
--- a/src/sysv/systemd/sssd-nss.service.in
+++ b/src/sysv/systemd/sssd-nss.service.in
@@ -11,6 +11,5 @@ RefuseManualStart=true
 Also=sssd-nss.socket
 
 [Service]
-ExecStartPre=-/bin/chown root:root @logpath@/sssd_nss.log
-ExecStart=@libexecdir@/sssd/sssd_nss --debug-to-files --socket-activated
+ExecStart=@libexecdir@/sssd/sssd_nss --uid 0 --gid 0 --debug-to-files --socket-activated
 Restart=on-failure
diff --git a/src/sysv/systemd/sssd-nss.socket.in b/src/sysv/systemd/sssd-nss.socket.in
index 39d30e8..83c1285 100644
--- a/src/sysv/systemd/sssd-nss.socket.in
+++ b/src/sysv/systemd/sssd-nss.socket.in
@@ -9,8 +9,6 @@ Conflicts=shutdown.target
 [Socket]
 ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r nss
 ListenStream=@pipepath@/nss
-SocketUser=@SSSD_USER@
-SocketGroup=@SSSD_USER@
 
 [Install]
 WantedBy=sssd.service
diff --git a/src/sysv/systemd/sssd-pac.service.in b/src/sysv/systemd/sssd-pac.service.in
index 841f48a..d6cde93 100644
--- a/src/sysv/systemd/sssd-pac.service.in
+++ b/src/sysv/systemd/sssd-pac.service.in
@@ -11,9 +11,5 @@ RefuseManualStart=true
 Also=sssd-pac.socket
 
 [Service]
-ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_pac.log
-ExecStart=@libexecdir@/sssd/sssd_pac --debug-to-files --socket-activated
+ExecStart=@libexecdir@/sssd/sssd_pac --uid 0 --gid 0 --debug-to-files --socket-activated
 Restart=on-failure
-User=@SSSD_USER@
-Group=@SSSD_USER@
-PermissionsStartOnly=true
diff --git a/src/sysv/systemd/sssd-pac.socket.in b/src/sysv/systemd/sssd-pac.socket.in
index 40dec44..4388e9f 100644
--- a/src/sysv/systemd/sssd-pac.socket.in
+++ b/src/sysv/systemd/sssd-pac.socket.in
@@ -9,8 +9,6 @@ Conflicts=shutdown.target
 [Socket]
 ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r pac
 ListenStream=@pipepath@/pac
-SocketUser=@SSSD_USER@
-SocketGroup=@SSSD_USER@
 
 [Install]
 WantedBy=sssd.service
diff --git a/src/sysv/systemd/sssd-pam-priv.socket.in b/src/sysv/systemd/sssd-pam-priv.socket.in
index 27f2cf7..bfaf5b0 100644
--- a/src/sysv/systemd/sssd-pam-priv.socket.in
+++ b/src/sysv/systemd/sssd-pam-priv.socket.in
@@ -11,8 +11,6 @@ Conflicts=shutdown.target
 ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r pam
 Service=sssd-pam.service
 ListenStream=@pipepath@/private/pam
-SocketUser=root
-SocketGroup=root
 SocketMode=0600
 
 [Install]
diff --git a/src/sysv/systemd/sssd-pam.service.in b/src/sysv/systemd/sssd-pam.service.in
index aa413d2..dca3345 100644
--- a/src/sysv/systemd/sssd-pam.service.in
+++ b/src/sysv/systemd/sssd-pam.service.in
@@ -11,9 +11,5 @@ RefuseManualStart=true
 Also=sssd-pam.socket sssd-pam-priv.socket
 
 [Service]
-ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_pam.log
-ExecStart=@libexecdir@/sssd/sssd_pam --debug-to-files --socket-activated
+ExecStart=@libexecdir@/sssd/sssd_pam --uid 0 --gid 0 --debug-to-files --socket-activated
 Restart=on-failure
-User=@SSSD_USER@
-Group=@SSSD_USER@
-PermissionsStartOnly=true
diff --git a/src/sysv/systemd/sssd-pam.socket.in b/src/sysv/systemd/sssd-pam.socket.in
index cbbb762..d8b5faa 100644
--- a/src/sysv/systemd/sssd-pam.socket.in
+++ b/src/sysv/systemd/sssd-pam.socket.in
@@ -10,8 +10,6 @@ Conflicts=shutdown.target
 [Socket]
 ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r pam
 ListenStream=@pipepath@/pam
-SocketUser=root
-SocketGroup=root
 
 [Install]
 WantedBy=sssd.service
diff --git a/src/sysv/systemd/sssd-ssh.service.in b/src/sysv/systemd/sssd-ssh.service.in
index d35b85e..a2c1902 100644
--- a/src/sysv/systemd/sssd-ssh.service.in
+++ b/src/sysv/systemd/sssd-ssh.service.in
@@ -11,9 +11,5 @@ RefuseManualStart=true
 Also=sssd-ssh.socket
 
 [Service]
-ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_ssh.log
-ExecStart=@libexecdir@/sssd/sssd_ssh --debug-to-files --socket-activated
+ExecStart=@libexecdir@/sssd/sssd_ssh --uid 0 --gid 0 --debug-to-files --socket-activated
 Restart=on-failure
-User=@SSSD_USER@
-Group=@SSSD_USER@
-PermissionsStartOnly=true
diff --git a/src/sysv/systemd/sssd-ssh.socket.in b/src/sysv/systemd/sssd-ssh.socket.in
index 4772ef3..97c3d62 100644
--- a/src/sysv/systemd/sssd-ssh.socket.in
+++ b/src/sysv/systemd/sssd-ssh.socket.in
@@ -9,8 +9,6 @@ Conflicts=shutdown.target
 [Socket]
 ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r ssh
 ListenStream=@pipepath@/ssh
-SocketUser=@SSSD_USER@
-SocketGroup=@SSSD_USER@
 
 [Install]
 WantedBy=sssd.service
diff --git a/src/sysv/systemd/sssd-sudo.service.in b/src/sysv/systemd/sssd-sudo.service.in
index 9b0da3b..2923a03 100644
--- a/src/sysv/systemd/sssd-sudo.service.in
+++ b/src/sysv/systemd/sssd-sudo.service.in
@@ -11,9 +11,5 @@ RefuseManualStart=true
 Also=sssd-sudo.socket
 
 [Service]
-ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_sudo.log
-ExecStart=@libexecdir@/sssd/sssd_sudo --debug-to-files --socket-activated
+ExecStart=@libexecdir@/sssd/sssd_sudo --uid 0 --gid 0 --debug-to-files --socket-activated
 Restart=on-failure
-User=@SSSD_USER@
-Group=@SSSD_USER@
-PermissionsStartOnly=true
diff --git a/src/sysv/systemd/sssd-sudo.socket.in b/src/sysv/systemd/sssd-sudo.socket.in
index c9abb87..e83bed5 100644
--- a/src/sysv/systemd/sssd-sudo.socket.in
+++ b/src/sysv/systemd/sssd-sudo.socket.in
@@ -9,8 +9,6 @@ Conflicts=shutdown.target
 [Socket]
 ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r sudo
 ListenStream=@pipepath@/sudo
-SocketUser=@SSSD_USER@
-SocketGroup=@SSSD_USER@
 
 [Install]
 WantedBy=sssd.service
diff --git a/src/util/debug.c b/src/util/debug.c
index ca4fa4c..2e6fe46 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -406,6 +406,45 @@ int open_debug_file_ex(const char *filename, FILE **filep, bool want_cloexec)
     return EOK;
 }
 
+int open_and_fchown_debug_file(uid_t uid, gid_t gid)
+{
+    char *logpath;
+    int fd = -1;
+    int ret;
+
+    ret = asprintf(&logpath, "%s/%s.log", LOG_PATH, debug_log_file);
+    if (ret == -1) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    errno = 0;
+    fd = open(logpath, FD_CLOEXEC, O_WRONLY);
+    if (fd == -1) {
+        ret = errno;
+        goto done;
+    }
+
+    ret = fchown(fd, uid, gid);
+    if (ret == -1) {
+        ret = errno;
+        close(fd);
+        goto done;
+    }
+
+    ret = set_debug_file_from_fd(fd);
+    if (ret != EOK) {
+        close(fd);
+        goto done;
+    }
+
+    ret = EOK;
+
+done:
+    free(logpath);
+    return ret;
+}
+
 int open_debug_file(void)
 {
     return open_debug_file_ex(NULL, NULL, true);
@@ -414,10 +453,32 @@ int open_debug_file(void)
 int rotate_debug_files(void)
 {
     int ret;
-    errno_t error;
 
     if (!debug_to_file) return EOK;
 
+    ret = close_debug_files();
+    if (ret != 0) {
+       sss_log(SSS_LOG_ALERT, "Attempting to open new file anyway. "
+                               "Be aware that this is a resource leak\n");
+    }
+
+    return open_debug_file();
+}
+
+void talloc_log_fn(const char *message)
+{
+    DEBUG(SSSDBG_FATAL_FAILURE, "%s\n", message);
+}
+
+int close_debug_files(void)
+{
+    int ret;
+    errno_t error;
+
+    if (debug_file == NULL) {
+        return EOK;
+    }
+
     do {
         error = 0;
         ret = fclose(debug_file);
@@ -441,16 +502,13 @@ int rotate_debug_files(void)
          */
         sss_log(SSS_LOG_ALERT, "Could not close debug file [%s]. [%d][%s]\n",
                                debug_log_file, error, strerror(error));
-        sss_log(SSS_LOG_ALERT, "Attempting to open new file anyway. "
-                               "Be aware that this is a resource leak\n");
+        ret = error;
+        goto done;
     }
 
-    debug_file = NULL;
+    ret = EOK;
 
-    return open_debug_file();
-}
-
-void talloc_log_fn(const char *message)
-{
-    DEBUG(SSSDBG_FATAL_FAILURE, "%s\n", message);
+done:
+    debug_file = NULL;
+    return ret;
 }
diff --git a/src/util/server.c b/src/util/server.c
index 9c94418..f0fc336 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -472,13 +472,13 @@ int server_setup(const char *name, int flags,
               sss_strerror(ret), ret);
     }
 
-    if (!is_socket_activated()) {
-        ret = chown_debug_file(NULL, uid, gid);
-        if (ret != EOK) {
-            DEBUG(SSSDBG_MINOR_FAILURE,
-                  "Cannot chown the debug files, debugging might not work!\n");
-        }
+    ret = open_and_fchown_debug_file(uid, gid);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_MINOR_FAILURE,
+              "Cannot chown the debug files, debugging might not work!\n");
+    }
 
+    if (!is_socket_activated()) {
         ret = become_user(uid, gid);
         if (ret != EOK) {
             DEBUG(SSSDBG_FUNC_DATA,
@@ -660,13 +660,13 @@ int server_setup(const char *name, int flags,
         return EIO;
     }
 
-    /* open log file if told so */
-    if (debug_to_file) {
-        ret = open_debug_file();
+    if (debug_to_file == 0) {
+        ret = close_debug_files();
         if (ret != EOK) {
-            DEBUG(SSSDBG_FATAL_FAILURE, "Error setting up logging (%d) "
-                                         "[%s]\n", ret, strerror(ret));
-            return ret;
+            DEBUG(SSSDBG_MINOR_FAILURE,
+                  "Cannot close the debug file, even if it's explicitly set "
+                  "to not debug to file: [%d] [%s]\n",
+                  ret, sss_strerror(ret));
         }
     }
 
diff --git a/src/util/util.h b/src/util/util.h
index a2dc89b..f44a076 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -158,6 +158,8 @@ int chown_debug_file(const char *filename, uid_t uid, gid_t gid);
 int open_debug_file_ex(const char *filename, FILE **filep, bool want_cloexec);
 int open_debug_file(void);
 int rotate_debug_files(void);
+int open_and_fchown_debug_file(uid_t uid, gid_t gid);
+int close_debug_files(void);
 void talloc_log_fn(const char *msg);
 
 /* From sss_log.c */
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org

Reply via email to