chiark / gitweb /
bus: properly unmap mapped area
[elogind.git] / src / login / pam-module.c
index 08a9328b651e1a4f6d8b72dfd89d0a14081fa42a..13290fd8ea6de3fcbb621e99dc7d92e7be50a030 100644 (file)
@@ -32,8 +32,6 @@
 #include <security/pam_ext.h>
 #include <security/pam_misc.h>
 
-#include <systemd/sd-daemon.h>
-
 #include "util.h"
 #include "audit.h"
 #include "macro.h"
@@ -41,6 +39,7 @@
 #include "dbus-common.h"
 #include "def.h"
 #include "socket-util.h"
+#include "fileio.h"
 
 static int parse_argv(pam_handle_t *handle,
                       int argc, const char **argv,
@@ -49,6 +48,7 @@ static int parse_argv(pam_handle_t *handle,
                       bool *kill_processes,
                       char ***kill_only_users,
                       char ***kill_exclude_users,
+                      const char **class,
                       bool *debug) {
 
         unsigned i;
@@ -135,6 +135,11 @@ static int parse_argv(pam_handle_t *handle,
                                 *kill_exclude_users = l;
                         }
 
+                } else if (startswith(argv[i], "class=")) {
+
+                        if (class)
+                                *class = argv[i] + 6;
+
                 } else if (startswith(argv[i], "debug=")) {
                         if ((k = parse_boolean(argv[i] + 6)) < 0) {
                                 pam_syslog(handle, LOG_ERR, "Failed to parse debug= argument.");
@@ -251,13 +256,15 @@ static bool check_user_lists(
 }
 
 static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) {
-        char *p = NULL;
+        _cleanup_free_ char *p = NULL;
         int r;
-        int fd;
-        union sockaddr_union sa;
+        _cleanup_close_ int fd = -1;
+        union sockaddr_union sa = {
+                .un.sun_family = AF_UNIX,
+        };
         struct ucred ucred;
         socklen_t l;
-        char *tty;
+        _cleanup_free_ char *tty = NULL;
         int v;
 
         assert(display);
@@ -272,27 +279,17 @@ static int get_seat_from_display(const char *display, const char **seat, uint32_
         r = socket_from_display(display, &p);
         if (r < 0)
                 return r;
+        strncpy(sa.un.sun_path, p, sizeof(sa.un.sun_path)-1);
 
         fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
-        if (fd < 0) {
-                free(p);
+        if (fd < 0)
                 return -errno;
-        }
 
-        zero(sa);
-        sa.un.sun_family = AF_UNIX;
-        strncpy(sa.un.sun_path, p, sizeof(sa.un.sun_path)-1);
-        free(p);
-
-        if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
-                close_nointr_nofail(fd);
+        if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0)
                 return -errno;
-        }
 
         l = sizeof(ucred);
         r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l);
-        close_nointr_nofail(fd);
-
         if (r < 0)
                 return -errno;
 
@@ -301,8 +298,6 @@ static int get_seat_from_display(const char *display, const char **seat, uint32_
                 return r;
 
         v = vtnr_from_tty(tty);
-        free(tty);
-
         if (v < 0)
                 return v;
         else if (v == 0)
@@ -322,7 +317,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
 
         struct passwd *pw;
         bool kill_processes = false, debug = false;
-        const char *username, *id, *object_path, *runtime_path, *service = NULL, *tty = NULL, *display = NULL, *remote_user = NULL, *remote_host = NULL, *seat = NULL, *type, *class, *cvtnr = NULL;
+        const char *username, *id, *object_path, *runtime_path, *service = NULL, *tty = NULL, *display = NULL, *remote_user = NULL, *remote_host = NULL, *seat = NULL, *type = NULL, *class = NULL, *class_pam = NULL, *cvtnr = NULL;
         char **controllers = NULL, **reset_controllers = NULL, **kill_only_users = NULL, **kill_exclude_users = NULL;
         DBusError error;
         uint32_t uid, pid;
@@ -341,15 +336,15 @@ _public_ PAM_EXTERN int pam_sm_open_session(
 
         /* pam_syslog(handle, LOG_INFO, "pam-systemd initializing"); */
 
-        /* Make this a NOP on non-systemd systems */
-        if (sd_booted() <= 0)
+        /* Make this a NOP on non-logind systems */
+        if (!logind_running())
                 return PAM_SUCCESS;
 
         if (parse_argv(handle,
                        argc, argv,
                        &controllers, &reset_controllers,
                        &kill_processes, &kill_only_users, &kill_exclude_users,
-                       &debug) < 0) {
+                       &class_pam, &debug) < 0) {
                 r = PAM_SESSION_ERR;
                 goto finish;
         }
@@ -445,17 +440,26 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         seat = strempty(seat);
 
         if (strchr(tty, ':')) {
-                /* A tty with a colon is usually an X11 display, place
-                 * there to show up in utmp. We rearrange things and
-                 * don't pretend that an X display was a tty */
+                /* A tty with a colon is usually an X11 display,
+                 * placed there to show up in utmp. We rearrange
+                 * things and don't pretend that an X display was a
+                 * tty. */
 
                 if (isempty(display))
                         display = tty;
                 tty = "";
         } else if (streq(tty, "cron")) {
-                /* cron has been setting PAM_TTY to "cron" for a very long time
-                 * and it cannot stop doing that for compatibility reasons. */
+                /* cron has been setting PAM_TTY to "cron" for a very
+                 * long time and it probably shouldn't stop doing that
+                 * for compatibility reasons. */
+                tty = "";
+                type = "unspecified";
+        } else if (streq(tty, "ssh")) {
+                /* ssh has been setting PAM_TTY to "ssh" for a very
+                 * long time and probably shouldn't stop doing that
+                 * for compatibility reasons. */
                 tty = "";
+                type ="tty";
         }
 
         /* If this fails vtnr will be 0, that's intended */
@@ -469,14 +473,17 @@ _public_ PAM_EXTERN int pam_sm_open_session(
                         get_seat_from_display(display, NULL, &vtnr);
         }
 
-        type = !isempty(display) ? "x11" :
-                   !isempty(tty) ? "tty" : "unspecified";
+        if (!type)
+                type = !isempty(display) ? "x11" :
+                        !isempty(tty) ? "tty" : "unspecified";
 
         class = pam_getenv(handle, "XDG_SESSION_CLASS");
         if (isempty(class))
                 class = getenv("XDG_SESSION_CLASS");
         if (isempty(class))
-                class = "user";
+                class = class_pam;
+        if (isempty(class))
+                class = streq(type, "unspecified") ? "background" : "user";
 
         remote = !isempty(remote_host) &&
                 !streq(remote_host, "localhost") &&