summaryrefslogtreecommitdiff
path: root/consolekit.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2012-10-31 10:35:38 +0000
committerColin Watson <cjwatson@debian.org>2012-10-31 10:35:38 +0000
commit301aad188299b268452af6b67261336c88f44ab1 (patch)
tree5ec34d429196f17ea6eb2205ca8f96da32b09dd1 /consolekit.c
parent5cb249b209c170d817471b575b6d105094f137bc (diff)
* Merge from Ubuntu:
- Add support for registering ConsoleKit sessions on login. (This is currently enabled only when building for Ubuntu.)
Diffstat (limited to 'consolekit.c')
-rw-r--r--consolekit.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/consolekit.c b/consolekit.c
new file mode 100644
index 000000000..2da3b10f6
--- /dev/null
+++ b/consolekit.c
@@ -0,0 +1,239 @@
1/*
2 * Copyright (c) 2008 Colin Watson. All rights reserved.
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/*
17 * Loosely based on pam-ck-connector, which is:
18 *
19 * Copyright (c) 2007 David Zeuthen <davidz@redhat.com>
20 *
21 * Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or sell
26 * copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#include "includes.h"
44
45#ifdef USE_CONSOLEKIT
46
47#include <ck-connector.h>
48
49#include "xmalloc.h"
50#include "channels.h"
51#include "key.h"
52#include "hostfile.h"
53#include "auth.h"
54#include "log.h"
55#include "servconf.h"
56#include "canohost.h"
57#include "session.h"
58#include "consolekit.h"
59
60extern ServerOptions options;
61extern u_int utmp_len;
62
63void
64set_active(const char *cookie)
65{
66 DBusError err;
67 DBusConnection *connection;
68 DBusMessage *message = NULL, *reply = NULL;
69 char *sid;
70 DBusMessageIter iter, subiter;
71 const char *interface, *property;
72 dbus_bool_t active;
73
74 dbus_error_init(&err);
75 connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
76 if (!connection) {
77 if (dbus_error_is_set(&err)) {
78 error("unable to open DBus connection: %s",
79 err.message);
80 dbus_error_free(&err);
81 }
82 goto out;
83 }
84 dbus_connection_set_exit_on_disconnect(connection, FALSE);
85
86 message = dbus_message_new_method_call("org.freedesktop.ConsoleKit",
87 "/org/freedesktop/ConsoleKit/Manager",
88 "org.freedesktop.ConsoleKit.Manager",
89 "GetSessionForCookie");
90 if (!message)
91 goto out;
92 if (!dbus_message_append_args(message, DBUS_TYPE_STRING, &cookie,
93 DBUS_TYPE_INVALID)) {
94 if (dbus_error_is_set(&err)) {
95 error("unable to get current session: %s",
96 err.message);
97 dbus_error_free(&err);
98 }
99 goto out;
100 }
101
102 dbus_error_init(&err);
103 reply = dbus_connection_send_with_reply_and_block(connection, message,
104 -1, &err);
105 if (!reply) {
106 if (dbus_error_is_set(&err)) {
107 error("unable to get current session: %s",
108 err.message);
109 dbus_error_free(&err);
110 }
111 goto out;
112 }
113
114 dbus_error_init(&err);
115 if (!dbus_message_get_args(reply, &err,
116 DBUS_TYPE_OBJECT_PATH, &sid,
117 DBUS_TYPE_INVALID)) {
118 if (dbus_error_is_set(&err)) {
119 error("unable to get current session: %s",
120 err.message);
121 dbus_error_free(&err);
122 }
123 goto out;
124 }
125 dbus_message_unref(reply);
126 dbus_message_unref(message);
127 message = reply = NULL;
128
129 message = dbus_message_new_method_call("org.freedesktop.ConsoleKit",
130 sid, "org.freedesktop.DBus.Properties", "Set");
131 if (!message)
132 goto out;
133 interface = "org.freedesktop.ConsoleKit.Session";
134 property = "active";
135 if (!dbus_message_append_args(message,
136 DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property,
137 DBUS_TYPE_INVALID))
138 goto out;
139 dbus_message_iter_init_append(message, &iter);
140 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
141 DBUS_TYPE_BOOLEAN_AS_STRING, &subiter))
142 goto out;
143 active = TRUE;
144 if (!dbus_message_iter_append_basic(&subiter, DBUS_TYPE_BOOLEAN,
145 &active))
146 goto out;
147 if (!dbus_message_iter_close_container(&iter, &subiter))
148 goto out;
149
150 dbus_error_init(&err);
151 reply = dbus_connection_send_with_reply_and_block(connection, message,
152 -1, &err);
153 if (!reply) {
154 if (dbus_error_is_set(&err)) {
155 error("unable to make current session active: %s",
156 err.message);
157 dbus_error_free(&err);
158 }
159 goto out;
160 }
161
162out:
163 if (reply)
164 dbus_message_unref(reply);
165 if (message)
166 dbus_message_unref(message);
167}
168
169/*
170 * We pass display separately rather than using s->display because the
171 * latter is not available in the monitor when using privsep.
172 */
173
174char *
175consolekit_register(Session *s, const char *display)
176{
177 DBusError err;
178 const char *tty = s->tty;
179 const char *remote_host_name;
180 dbus_bool_t is_local = FALSE;
181 const char *cookie = NULL;
182
183 if (s->ckc) {
184 debug("already registered with ConsoleKit");
185 return xstrdup(ck_connector_get_cookie(s->ckc));
186 }
187
188 s->ckc = ck_connector_new();
189 if (!s->ckc) {
190 error("ck_connector_new failed");
191 return NULL;
192 }
193
194 if (!tty)
195 tty = "";
196 if (!display)
197 display = "";
198 remote_host_name = get_remote_name_or_ip(utmp_len, options.use_dns);
199 if (!remote_host_name)
200 remote_host_name = "";
201
202 dbus_error_init(&err);
203 if (!ck_connector_open_session_with_parameters(s->ckc, &err,
204 "unix-user", &s->pw->pw_uid,
205 "display-device", &tty,
206 "x11-display", &display,
207 "remote-host-name", &remote_host_name,
208 "is-local", &is_local,
209 NULL)) {
210 if (dbus_error_is_set(&err)) {
211 debug("%s", err.message);
212 dbus_error_free(&err);
213 } else {
214 debug("insufficient privileges or D-Bus / ConsoleKit "
215 "not available");
216 }
217 return NULL;
218 }
219
220 debug("registered uid=%d on tty='%s' with ConsoleKit",
221 s->pw->pw_uid, s->tty);
222
223 cookie = ck_connector_get_cookie(s->ckc);
224 set_active(cookie);
225 return xstrdup(cookie);
226}
227
228void
229consolekit_unregister(Session *s)
230{
231 if (s->ckc) {
232 debug("unregistering ConsoleKit session %s",
233 ck_connector_get_cookie(s->ckc));
234 ck_connector_unref(s->ckc);
235 s->ckc = NULL;
236 }
237}
238
239#endif /* USE_CONSOLEKIT */