diff options
-rw-r--r-- | src/login/logind-dbus.c | 8 | ||||
-rw-r--r-- | src/login/pam-module.c | 17 |
2 files changed, 21 insertions, 4 deletions
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index b95cc9bfbb..a7647e3c80 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -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); diff --git a/src/login/pam-module.c b/src/login/pam-module.c index af108c46d5..08a9328b65 100644 --- a/src/login/pam-module.c +++ b/src/login/pam-module.c @@ -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 |