]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pam_systemd: resolve the tty of display via /sys instead of /dev
authorTopi Miettinen <toiwoton@gmail.com>
Sun, 26 Jan 2020 09:58:34 +0000 (11:58 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 29 Jan 2020 15:06:48 +0000 (16:06 +0100)
Rely on information provided by /proc/*/stat and /sys/dev/char for resolving
the controlling tty for the display server, instead of trying to access the
tty device in /dev (which may not be accessible for example due to
PrivateDevices=yes).

src/login/pam_systemd.c

index c7fe858b921df59f6b47ee6865eb8ec063a9e990..8447e1c555f9a2a54d3dda4fe45b9a625fbb9522 100644 (file)
@@ -11,6 +11,7 @@
 #include <security/pam_modutil.h>
 #include <sys/file.h>
 #include <sys/stat.h>
+#include <sys/sysmacros.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -219,10 +220,11 @@ static int socket_from_display(const char *display, char **path) {
 
 static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) {
         union sockaddr_union sa = {};
-        _cleanup_free_ char *p = NULL, *tty = NULL;
+        _cleanup_free_ char *p = NULL, *sys_path = NULL, *tty = NULL;
         _cleanup_close_ int fd = -1;
         struct ucred ucred;
         int v, r, salen;
+        dev_t display_ctty;
 
         assert(display);
         assert(vtnr);
@@ -251,7 +253,13 @@ static int get_seat_from_display(const char *display, const char **seat, uint32_
         if (r < 0)
                 return r;
 
-        r = get_ctty(ucred.pid, NULL, &tty);
+        r = get_ctty_devnr(ucred.pid, &display_ctty);
+        if (r < 0)
+                return r;
+
+        if (asprintf(&sys_path, "/sys/dev/char/%d:%d", major(display_ctty), minor(display_ctty)) < 0)
+                return -ENOMEM;
+        r = readlink_value(sys_path, &tty);
         if (r < 0)
                 return r;