chiark / gitweb /
logind: only release logind session from the PAM module if the same module instance...
[elogind.git] / src / login / pam-module.c
index 0d387918c7eac328a63fa6d932ca6c82728f399f..08a9328b651e1a4f6d8b72dfd89d0a14081fa42a 100644 (file)
@@ -331,7 +331,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         int session_fd = -1;
         DBusConnection *bus = NULL;
         DBusMessage *m = NULL, *reply = NULL;
-        dbus_bool_t remote;
+        dbus_bool_t remote, existing;
         int r;
         uint32_t vtnr = 0;
 
@@ -428,8 +428,14 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         pam_get_item(handle, PAM_TTY, (const void**) &tty);
         pam_get_item(handle, PAM_RUSER, (const void**) &remote_user);
         pam_get_item(handle, PAM_RHOST, (const void**) &remote_host);
+
         seat = pam_getenv(handle, "XDG_SEAT");
+        if (isempty(seat))
+                seat = getenv("XDG_SEAT");
+
         cvtnr = pam_getenv(handle, "XDG_VTNR");
+        if (isempty(cvtnr))
+                cvtnr = getenv("XDG_VTNR");
 
         service = strempty(service);
         tty = strempty(tty);
@@ -467,6 +473,8 @@ _public_ PAM_EXTERN int pam_sm_open_session(
                    !isempty(tty) ? "tty" : "unspecified";
 
         class = pam_getenv(handle, "XDG_SESSION_CLASS");
+        if (isempty(class))
+                class = getenv("XDG_SESSION_CLASS");
         if (isempty(class))
                 class = "user";
 
@@ -535,6 +543,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
                                    DBUS_TYPE_UNIX_FD, &session_fd,
                                    DBUS_TYPE_STRING, &seat,
                                    DBUS_TYPE_UINT32, &vtnr,
+                                   DBUS_TYPE_BOOLEAN, &existing,
                                    DBUS_TYPE_INVALID)) {
                 pam_syslog(handle, LOG_ERR, "Failed to parse message: %s", bus_error_message(&error));
                 r = PAM_SESSION_ERR;
@@ -578,6 +587,12 @@ _public_ PAM_EXTERN int pam_sm_open_session(
                 }
         }
 
+        r = pam_set_data(handle, "systemd.existing", INT_TO_PTR(!!existing), NULL);
+        if (r != PAM_SUCCESS) {
+                pam_syslog(handle, LOG_ERR, "Failed to install existing flag.");
+                return r;
+        }
+
         if (session_fd >= 0) {
                 r = pam_set_data(handle, "systemd.session-fd", INT_TO_PTR(session_fd+1), NULL);
                 if (r != PAM_SUCCESS) {
@@ -620,7 +635,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
                 int flags,
                 int argc, const char **argv) {
 
-        const void *p = NULL;
+        const void *p = NULL, *existing = NULL;
         const char *id;
         DBusConnection *bus = NULL;
         DBusMessage *m = NULL, *reply = NULL;
@@ -631,8 +646,12 @@ _public_ PAM_EXTERN int pam_sm_close_session(
 
         dbus_error_init(&error);
 
+        /* Only release session if it wasn't pre-existing when we
+         * tried to create it */
+        pam_get_data(handle, "systemd.existing", &existing);
+
         id = pam_getenv(handle, "XDG_SESSION_ID");
-        if (id) {
+        if (id && !existing) {
 
                 /* Before we go and close the FIFO we need to tell
                  * logind that this is a clean session shutdown, so