]>
Commit | Line | Data |
---|---|---|
8aa6e482 JR |
1 | From 75c8e3cffd7da8eede614cf61384957af2c82a29 Mon Sep 17 00:00:00 2001 |
2 | From: Lennart Poettering <lennart@poettering.net> | |
3 | Date: Thu, 22 Mar 2012 01:06:40 +0000 | |
4 | Subject: logind: close FIFO before ending sessions cleanly | |
5 | ||
6 | For clean session endings ask logind explicitly to get rid of the FIFO | |
7 | before closing it so that the FIFO logic doesn't result in su/sudo to be | |
8 | terminated immediately. | |
9 | --- | |
10 | diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c | |
11 | index d8f4d89..ea6b89f 100644 | |
12 | --- a/src/login/logind-dbus.c | |
13 | +++ b/src/login/logind-dbus.c | |
14 | @@ -80,6 +80,9 @@ | |
15 | " <arg name=\"seat\" type=\"s\" direction=\"out\"/>\n" \ | |
16 | " <arg name=\"vtnr\" type=\"u\" direction=\"out\"/>\n" \ | |
17 | " </method>\n" \ | |
18 | + " <method name=\"ReleaseSession\">\n" \ | |
19 | + " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \ | |
20 | + " </method>\n" \ | |
21 | " <method name=\"ActivateSession\">\n" \ | |
22 | " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \ | |
23 | " </method>\n" \ | |
24 | @@ -1075,6 +1078,33 @@ static DBusHandlerResult manager_message_handler( | |
25 | if (r < 0) | |
26 | return bus_send_error_reply(connection, message, &error, r); | |
27 | ||
28 | + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ReleaseSession")) { | |
29 | + const char *name; | |
30 | + Session *session; | |
31 | + | |
32 | + if (!dbus_message_get_args( | |
33 | + message, | |
34 | + &error, | |
35 | + DBUS_TYPE_STRING, &name, | |
36 | + DBUS_TYPE_INVALID)) | |
37 | + return bus_send_error_reply(connection, message, &error, -EINVAL); | |
38 | + | |
39 | + session = hashmap_get(m->sessions, name); | |
40 | + if (!session) | |
41 | + return bus_send_error_reply(connection, message, &error, -ENOENT); | |
42 | + | |
43 | + /* We use the FIFO to detect stray sessions where the | |
44 | + process invoking PAM dies abnormally. We need to make | |
45 | + sure that that process is not killed if at the clean | |
46 | + end of the session it closes the FIFO. Hence, with | |
47 | + this call explicitly turn off the FIFO logic, so that | |
48 | + the PAM code can finish clean up on its own */ | |
49 | + session_remove_fifo(session); | |
50 | + | |
51 | + reply = dbus_message_new_method_return(message); | |
52 | + if (!reply) | |
53 | + goto oom; | |
54 | + | |
55 | } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ActivateSession")) { | |
56 | const char *name; | |
57 | Session *session; | |
58 | diff --git a/src/login/pam-module.c b/src/login/pam-module.c | |
59 | index 8544413..4106d2b 100644 | |
60 | --- a/src/login/pam-module.c | |
61 | +++ b/src/login/pam-module.c | |
62 | @@ -414,7 +414,6 @@ _public_ PAM_EXTERN int pam_sm_open_session( | |
63 | "/org/freedesktop/login1", | |
64 | "org.freedesktop.login1.Manager", | |
65 | "CreateSession"); | |
66 | - | |
67 | if (!m) { | |
68 | pam_syslog(handle, LOG_ERR, "Could not allocate create session message."); | |
69 | r = PAM_BUF_ERR; | |
70 | @@ -620,11 +619,77 @@ _public_ PAM_EXTERN int pam_sm_close_session( | |
71 | int argc, const char **argv) { | |
72 | ||
73 | const void *p = NULL; | |
74 | + const char *id; | |
75 | + DBusConnection *bus = NULL; | |
76 | + DBusMessage *m = NULL, *reply = NULL; | |
77 | + DBusError error; | |
78 | + int r; | |
79 | ||
80 | - pam_get_data(handle, "systemd.session-fd", &p); | |
81 | + assert(handle); | |
82 | + | |
83 | + dbus_error_init(&error); | |
84 | + | |
85 | + id = pam_getenv(handle, "XDG_SESSION_ID"); | |
86 | + if (id) { | |
87 | + | |
88 | + /* Before we go and close the FIFO we need to tell | |
89 | + * logind that this is a clean session shutdown, so | |
90 | + * that it doesn't just go and slaughter us | |
91 | + * immediately after closing the fd */ | |
92 | + | |
93 | + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); | |
94 | + if (!bus) { | |
95 | + pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", bus_error_message(&error)); | |
96 | + r = PAM_SESSION_ERR; | |
97 | + goto finish; | |
98 | + } | |
99 | + | |
100 | + m = dbus_message_new_method_call( | |
101 | + "org.freedesktop.login1", | |
102 | + "/org/freedesktop/login1", | |
103 | + "org.freedesktop.login1.Manager", | |
104 | + "ReleaseSession"); | |
105 | + if (!m) { | |
106 | + pam_syslog(handle, LOG_ERR, "Could not allocate release session message."); | |
107 | + r = PAM_BUF_ERR; | |
108 | + goto finish; | |
109 | + } | |
110 | + | |
111 | + if (!dbus_message_append_args(m, | |
112 | + DBUS_TYPE_STRING, &id, | |
113 | + DBUS_TYPE_INVALID)) { | |
114 | + pam_syslog(handle, LOG_ERR, "Could not attach parameters to message."); | |
115 | + r = PAM_BUF_ERR; | |
116 | + goto finish; | |
117 | + } | |
118 | ||
119 | + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); | |
120 | + if (!reply) { | |
121 | + pam_syslog(handle, LOG_ERR, "Failed to release session: %s", bus_error_message(&error)); | |
122 | + r = PAM_SESSION_ERR; | |
123 | + goto finish; | |
124 | + } | |
125 | + } | |
126 | + | |
127 | + r = PAM_SUCCESS; | |
128 | + | |
129 | +finish: | |
130 | + pam_get_data(handle, "systemd.session-fd", &p); | |
131 | if (p) | |
132 | close_nointr(PTR_TO_INT(p) - 1); | |
133 | ||
134 | - return PAM_SUCCESS; | |
135 | + dbus_error_free(&error); | |
136 | + | |
137 | + if (bus) { | |
138 | + dbus_connection_close(bus); | |
139 | + dbus_connection_unref(bus); | |
140 | + } | |
141 | + | |
142 | + if (m) | |
143 | + dbus_message_unref(m); | |
144 | + | |
145 | + if (reply) | |
146 | + dbus_message_unref(reply); | |
147 | + | |
148 | + return r; | |
149 | } | |
150 | -- | |
151 | cgit v0.9.0.2-2-gbebe |