chiark / gitweb /
logind: only release logind session from the PAM module if the same module instance...
authorLennart Poettering <lennart@poettering.net>
Tue, 16 Oct 2012 17:21:21 +0000 (19:21 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 16 Oct 2012 17:21:21 +0000 (19:21 +0200)
src/login/logind-dbus.c
src/login/pam-module.c

index b95cc9bfbba8f45055d722252346e5d119ddd5f5..a7647e3c80a971c9482e1d74b274ecf7a7460376 100644 (file)
@@ -83,6 +83,7 @@
         "   <arg name=\"fd\" type=\"h\" direction=\"out\"/>\n"          \
         "   <arg name=\"seat\" type=\"s\" direction=\"out\"/>\n"        \
         "   <arg name=\"vtnr\" type=\"u\" direction=\"out\"/>\n"        \
+        "   <arg name=\"existing\" type=\"b\" direction=\"out\"/>\n"    \
         "  </method>\n"                                                 \
         "  <method name=\"ReleaseSession\">\n"                          \
         "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
@@ -300,7 +301,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
         User *user = NULL;
         const char *type, *class, *seat, *tty, *display, *remote_user, *remote_host, *service;
         uint32_t uid, leader, audit_id = 0;
-        dbus_bool_t remote, kill_processes;
+        dbus_bool_t remote, kill_processes, exists;
         char **controllers = NULL, **reset_controllers = NULL;
         SessionType t;
         SessionClass c;
@@ -518,6 +519,8 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
 
                         seat = session->seat ? session->seat->id : "";
                         vtnr = session->vtnr;
+                        exists = true;
+
                         b = dbus_message_append_args(
                                         reply,
                                         DBUS_TYPE_STRING, &session->id,
@@ -526,6 +529,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
                                         DBUS_TYPE_UNIX_FD, &fifo_fd,
                                         DBUS_TYPE_STRING, &seat,
                                         DBUS_TYPE_UINT32, &vtnr,
+                                        DBUS_TYPE_BOOLEAN, &exists,
                                         DBUS_TYPE_INVALID);
                         free(p);
 
@@ -642,6 +646,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
         }
 
         seat = s ? s->id : "";
+        exists = false;
         b = dbus_message_append_args(
                         reply,
                         DBUS_TYPE_STRING, &session->id,
@@ -650,6 +655,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
                         DBUS_TYPE_UNIX_FD, &fifo_fd,
                         DBUS_TYPE_STRING, &seat,
                         DBUS_TYPE_UINT32, &vtnr,
+                        DBUS_TYPE_BOOLEAN, &exists,
                         DBUS_TYPE_INVALID);
         free(p);
 
index af108c46d59aa4f9babf61b96f0efa7596610aea..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;
 
@@ -543,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;
@@ -586,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) {
@@ -628,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;
@@ -639,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