diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-03-22 02:06:40 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-03-22 02:06:40 +0100 |
commit | 75c8e3cffd7da8eede614cf61384957af2c82a29 (patch) | |
tree | 5ce60ed8c277ea27648206c662159671d5b64526 /src/login/pam-module.c | |
parent | c9d8629baa09f853fbcc44972c9748e70562270c (diff) |
logind: close FIFO before ending sessions cleanly
For clean session endings ask logind explicitly to get rid of the FIFO
before closing it so that the FIFO logic doesn't result in su/sudo to be
terminated immediately.
Diffstat (limited to 'src/login/pam-module.c')
-rw-r--r-- | src/login/pam-module.c | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/src/login/pam-module.c b/src/login/pam-module.c index 8544413a08..4106d2ba4b 100644 --- a/src/login/pam-module.c +++ b/src/login/pam-module.c @@ -414,7 +414,6 @@ _public_ PAM_EXTERN int pam_sm_open_session( "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "CreateSession"); - if (!m) { pam_syslog(handle, LOG_ERR, "Could not allocate create session message."); r = PAM_BUF_ERR; @@ -620,11 +619,77 @@ _public_ PAM_EXTERN int pam_sm_close_session( int argc, const char **argv) { const void *p = NULL; + const char *id; + DBusConnection *bus = NULL; + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; - pam_get_data(handle, "systemd.session-fd", &p); + assert(handle); + + dbus_error_init(&error); + + id = pam_getenv(handle, "XDG_SESSION_ID"); + if (id) { + + /* Before we go and close the FIFO we need to tell + * logind that this is a clean session shutdown, so + * that it doesn't just go and slaughter us + * immediately after closing the fd */ + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", bus_error_message(&error)); + r = PAM_SESSION_ERR; + goto finish; + } + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ReleaseSession"); + if (!m) { + pam_syslog(handle, LOG_ERR, "Could not allocate release session message."); + r = PAM_BUF_ERR; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &id, + DBUS_TYPE_INVALID)) { + pam_syslog(handle, LOG_ERR, "Could not attach parameters to message."); + r = PAM_BUF_ERR; + goto finish; + } + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + pam_syslog(handle, LOG_ERR, "Failed to release session: %s", bus_error_message(&error)); + r = PAM_SESSION_ERR; + goto finish; + } + } + + r = PAM_SUCCESS; + +finish: + pam_get_data(handle, "systemd.session-fd", &p); if (p) close_nointr(PTR_TO_INT(p) - 1); - return PAM_SUCCESS; + dbus_error_free(&error); + + if (bus) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + return r; } |