1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of tlm
6 * Copyright (C) 2014 Intel Corporation.
8 * Contact: Imran Zaman <imran.zaman@intel.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 #include "common/tlm-log.h"
29 #include "common/tlm-error.h"
30 #include "common/dbus/tlm-dbus.h"
32 #include "tlm-dbus-login-adapter.h"
43 static GParamSpec *properties[N_PROPERTIES];
45 struct _TlmDbusLoginAdapterPrivate
47 GDBusConnection *connection;
48 TlmDbusLogin *dbus_obj;
51 G_DEFINE_TYPE (TlmDbusLoginAdapter, tlm_dbus_login_adapter, G_TYPE_OBJECT)
53 #define TLM_DBUS_LOGIN_ADAPTER_GET_PRIV(obj) \
54 G_TYPE_INSTANCE_GET_PRIVATE ((obj), TLM_TYPE_LOGIN_ADAPTER, \
55 TlmDbusLoginAdapterPrivate)
65 static guint signals[SIG_MAX];
69 TlmDbusLoginAdapter *self,
70 GDBusMethodInvocation *invocation,
72 const gchar *username,
73 const gchar *password,
74 const GVariant *environ,
79 TlmDbusLoginAdapter *self,
80 GDBusMethodInvocation *invocation,
82 const gchar *username,
83 const gchar *password,
84 const GVariant *environ,
89 TlmDbusLoginAdapter *self,
90 GDBusMethodInvocation *invocation,
101 TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
103 switch (property_id) {
104 case PROP_CONNECTION:
105 self->priv->connection = g_value_dup_object (value);
108 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
119 TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
121 switch (property_id) {
122 case PROP_CONNECTION:
123 g_value_set_object (value, self->priv->connection);
126 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
134 TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
136 DBG("- unregistering dbus login adaptor %p.", self);
138 if (self->priv->dbus_obj) {
139 g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (
140 self->priv->dbus_obj));
141 g_object_unref (self->priv->dbus_obj);
142 self->priv->dbus_obj = NULL;
145 if (self->priv->connection) {
146 /* NOTE: There seems to be some bug in glib's dbus connection's
147 * worker thread such that it does not closes the stream. The problem
148 * is hard to be tracked exactly as it is more of timing issue.
149 * Following code snippet at least closes the stream to avoid any
152 GIOStream *stream = g_dbus_connection_get_stream (
153 self->priv->connection);
154 if (stream) g_io_stream_close (stream, NULL, NULL);
155 g_object_unref (self->priv->connection);
156 self->priv->connection = NULL;
159 G_OBJECT_CLASS (tlm_dbus_login_adapter_parent_class)->dispose (
168 G_OBJECT_CLASS (tlm_dbus_login_adapter_parent_class)->finalize (
173 tlm_dbus_login_adapter_class_init (
174 TlmDbusLoginAdapterClass *klass)
176 GObjectClass* object_class = G_OBJECT_CLASS (klass);
178 g_type_class_add_private (object_class,
179 sizeof (TlmDbusLoginAdapterPrivate));
181 object_class->get_property = _get_property;
182 object_class->set_property = _set_property;
183 object_class->dispose = _dispose;
184 object_class->finalize = _finalize;
186 properties[PROP_CONNECTION] = g_param_spec_object (
189 "DBus connection used",
190 G_TYPE_DBUS_CONNECTION,
191 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
193 g_object_class_install_properties (object_class, N_PROPERTIES, properties);
195 signals[SIG_LOGIN_USER] = g_signal_new ("login-user",
196 TLM_TYPE_LOGIN_ADAPTER,
208 G_TYPE_DBUS_METHOD_INVOCATION);
210 signals[SIG_LOGOUT_USER] = g_signal_new ("logout-user",
211 TLM_TYPE_LOGIN_ADAPTER,
220 G_TYPE_DBUS_METHOD_INVOCATION);
222 signals[SIG_SWITCH_USER] = g_signal_new ("switch-user",
223 TLM_TYPE_LOGIN_ADAPTER,
235 G_TYPE_DBUS_METHOD_INVOCATION);
239 tlm_dbus_login_adapter_init (TlmDbusLoginAdapter *self)
241 self->priv = TLM_DBUS_LOGIN_ADAPTER_GET_PRIV(self);
243 self->priv->connection = 0;
244 self->priv->dbus_obj = tlm_dbus_login_skeleton_new ();
249 TlmDbusLoginAdapter *self,
250 GDBusMethodInvocation *invocation,
251 const gchar *seat_id,
252 const gchar *username,
253 const gchar *password,
254 const GVariant *environment,
257 GError *error = NULL;
259 g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self), FALSE);
261 if (!seat_id || !username || !password) {
262 error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
264 g_dbus_method_invocation_return_gerror (invocation, error);
265 g_error_free (error);
268 DBG ("Emit login-user signal: seat_id=%s, username=%s", seat_id, username);
270 g_signal_emit (self, signals[SIG_LOGIN_USER], 0, seat_id, username,
271 password, environment, invocation);
277 _handle_logout_user (
278 TlmDbusLoginAdapter *self,
279 GDBusMethodInvocation *invocation,
280 const gchar *seat_id,
283 GError *error = NULL;
285 g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self),
289 error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
291 g_dbus_method_invocation_return_gerror (invocation, error);
292 g_error_free (error);
295 DBG ("Emit logout-user signal: seat_id=%s", seat_id);
297 g_signal_emit (self, signals[SIG_LOGOUT_USER], 0, seat_id, invocation);
303 _handle_switch_user (
304 TlmDbusLoginAdapter *self,
305 GDBusMethodInvocation *invocation,
306 const gchar *seat_id,
307 const gchar *username,
308 const gchar *password,
309 const GVariant *environment,
312 GError *error = NULL;
314 g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self),
317 if (!seat_id || !username || !password) {
318 error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
320 g_dbus_method_invocation_return_gerror (invocation, error);
321 g_error_free (error);
324 DBG ("Emit switch-user signal: seat_id=%s, username=%s", seat_id, username);
326 g_signal_emit (self, signals[SIG_SWITCH_USER], 0, seat_id, username,
327 password, environment, invocation);
332 TlmDbusLoginAdapter *
333 tlm_dbus_login_adapter_new_with_connection (
334 GDBusConnection *bus_connection)
337 TlmDbusLoginAdapter *adapter = TLM_DBUS_LOGIN_ADAPTER (g_object_new (
338 TLM_TYPE_LOGIN_ADAPTER, "connection", bus_connection, NULL));
340 if (!g_dbus_interface_skeleton_export (
341 G_DBUS_INTERFACE_SKELETON(adapter->priv->dbus_obj),
342 adapter->priv->connection, TLM_LOGIN_OBJECTPATH, &err)) {
343 WARN ("failed to register object: %s", err->message);
345 g_object_unref (adapter);
349 DBG("(+) started login interface '%p' at path '%s' on connection"
350 " '%p'", adapter, TLM_LOGIN_OBJECTPATH, bus_connection);
352 g_signal_connect_swapped (adapter->priv->dbus_obj,
353 "handle-login-user", G_CALLBACK (_handle_login_user), adapter);
354 g_signal_connect_swapped (adapter->priv->dbus_obj,
355 "handle-logout-user", G_CALLBACK(_handle_logout_user), adapter);
356 g_signal_connect_swapped (adapter->priv->dbus_obj,
357 "handle-switch-user", G_CALLBACK(_handle_switch_user), adapter);
363 tlm_dbus_login_adapter_request_completed (
364 TlmDbusRequest *request,
367 g_return_if_fail (request && request->dbus_adapter &&
368 TLM_IS_DBUS_LOGIN_ADAPTER(request->dbus_adapter));
370 TlmDbusLoginAdapter *adapter = TLM_DBUS_LOGIN_ADAPTER (
371 request->dbus_adapter);
373 g_dbus_method_invocation_return_gerror (request->invocation, error);
377 switch (request->type) {
378 case TLM_DBUS_REQUEST_TYPE_LOGIN_USER:
379 tlm_dbus_login_complete_login_user (adapter->priv->dbus_obj,
380 request->invocation);
382 case TLM_DBUS_REQUEST_TYPE_LOGOUT_USER:
383 tlm_dbus_login_complete_logout_user (adapter->priv->dbus_obj,
384 request->invocation);
386 case TLM_DBUS_REQUEST_TYPE_SWITCH_USER:
387 tlm_dbus_login_complete_switch_user (adapter->priv->dbus_obj,
388 request->invocation);