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_WITH_PRIVATE (TlmDbusLoginAdapter, tlm_dbus_login_adapter, G_TYPE_OBJECT)
61 static guint signals[SIG_MAX];
65 TlmDbusLoginAdapter *self,
66 GDBusMethodInvocation *invocation,
68 const gchar *username,
69 const gchar *password,
70 const GVariant *environ,
75 TlmDbusLoginAdapter *self,
76 GDBusMethodInvocation *invocation,
78 const gchar *username,
79 const gchar *password,
80 const GVariant *environ,
85 TlmDbusLoginAdapter *self,
86 GDBusMethodInvocation *invocation,
97 TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
99 switch (property_id) {
100 case PROP_CONNECTION:
101 self->priv->connection = g_value_dup_object (value);
104 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
115 TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
117 switch (property_id) {
118 case PROP_CONNECTION:
119 g_value_set_object (value, self->priv->connection);
122 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
130 TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
132 DBG("- unregistering dbus login adaptor %p.", self);
134 if (self->priv->dbus_obj) {
135 g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (
136 self->priv->dbus_obj));
137 g_object_unref (self->priv->dbus_obj);
138 self->priv->dbus_obj = NULL;
141 if (self->priv->connection) {
142 /* NOTE: There seems to be some bug in glib's dbus connection's
143 * worker thread such that it does not closes the stream. The problem
144 * is hard to be tracked exactly as it is more of timing issue.
145 * Following code snippet at least closes the stream to avoid any
148 GIOStream *stream = g_dbus_connection_get_stream (
149 self->priv->connection);
150 if (stream) g_io_stream_close (stream, NULL, NULL);
151 g_object_unref (self->priv->connection);
152 self->priv->connection = NULL;
155 G_OBJECT_CLASS (tlm_dbus_login_adapter_parent_class)->dispose (
164 G_OBJECT_CLASS (tlm_dbus_login_adapter_parent_class)->finalize (
169 tlm_dbus_login_adapter_class_init (
170 TlmDbusLoginAdapterClass *klass)
172 GObjectClass* object_class = G_OBJECT_CLASS (klass);
174 object_class->get_property = _get_property;
175 object_class->set_property = _set_property;
176 object_class->dispose = _dispose;
177 object_class->finalize = _finalize;
179 properties[PROP_CONNECTION] = g_param_spec_object (
182 "DBus connection used",
183 G_TYPE_DBUS_CONNECTION,
184 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
186 g_object_class_install_properties (object_class, N_PROPERTIES, properties);
188 signals[SIG_LOGIN_USER] = g_signal_new ("login-user",
189 TLM_TYPE_LOGIN_ADAPTER,
201 G_TYPE_DBUS_METHOD_INVOCATION);
203 signals[SIG_LOGOUT_USER] = g_signal_new ("logout-user",
204 TLM_TYPE_LOGIN_ADAPTER,
213 G_TYPE_DBUS_METHOD_INVOCATION);
215 signals[SIG_SWITCH_USER] = g_signal_new ("switch-user",
216 TLM_TYPE_LOGIN_ADAPTER,
228 G_TYPE_DBUS_METHOD_INVOCATION);
232 tlm_dbus_login_adapter_init (TlmDbusLoginAdapter *self)
234 self->priv = tlm_dbus_login_adapter_get_instance_private (self);
236 self->priv->connection = 0;
237 self->priv->dbus_obj = tlm_dbus_login_skeleton_new ();
242 TlmDbusLoginAdapter *self,
243 GDBusMethodInvocation *invocation,
244 const gchar *seat_id,
245 const gchar *username,
246 const gchar *password,
247 const GVariant *environment,
250 GError *error = NULL;
252 g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self), FALSE);
254 if (!seat_id || !username || !password) {
255 error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
257 g_dbus_method_invocation_return_gerror (invocation, error);
258 g_error_free (error);
261 DBG ("Emit login-user signal: seat_id=%s, username=%s", seat_id, username);
263 g_signal_emit (self, signals[SIG_LOGIN_USER], 0, seat_id, username,
264 password, environment, invocation);
270 _handle_logout_user (
271 TlmDbusLoginAdapter *self,
272 GDBusMethodInvocation *invocation,
273 const gchar *seat_id,
276 GError *error = NULL;
278 g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self),
282 error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
284 g_dbus_method_invocation_return_gerror (invocation, error);
285 g_error_free (error);
288 DBG ("Emit logout-user signal: seat_id=%s", seat_id);
290 g_signal_emit (self, signals[SIG_LOGOUT_USER], 0, seat_id, invocation);
296 _handle_switch_user (
297 TlmDbusLoginAdapter *self,
298 GDBusMethodInvocation *invocation,
299 const gchar *seat_id,
300 const gchar *username,
301 const gchar *password,
302 const GVariant *environment,
305 GError *error = NULL;
307 g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self),
310 if (!seat_id || !username || !password) {
311 error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
313 g_dbus_method_invocation_return_gerror (invocation, error);
314 g_error_free (error);
317 DBG ("Emit switch-user signal: seat_id=%s, username=%s", seat_id, username);
319 g_signal_emit (self, signals[SIG_SWITCH_USER], 0, seat_id, username,
320 password, environment, invocation);
325 TlmDbusLoginAdapter *
326 tlm_dbus_login_adapter_new_with_connection (
327 GDBusConnection *bus_connection)
330 TlmDbusLoginAdapter *adapter = TLM_DBUS_LOGIN_ADAPTER (g_object_new (
331 TLM_TYPE_LOGIN_ADAPTER, "connection", bus_connection, NULL));
333 if (!g_dbus_interface_skeleton_export (
334 G_DBUS_INTERFACE_SKELETON(adapter->priv->dbus_obj),
335 adapter->priv->connection, TLM_LOGIN_OBJECTPATH, &err)) {
336 WARN ("failed to register object: %s", err->message);
338 g_object_unref (adapter);
342 DBG("(+) started login interface '%p' at path '%s' on connection"
343 " '%p'", adapter, TLM_LOGIN_OBJECTPATH, bus_connection);
345 g_signal_connect_swapped (adapter->priv->dbus_obj,
346 "handle-login-user", G_CALLBACK (_handle_login_user), adapter);
347 g_signal_connect_swapped (adapter->priv->dbus_obj,
348 "handle-logout-user", G_CALLBACK(_handle_logout_user), adapter);
349 g_signal_connect_swapped (adapter->priv->dbus_obj,
350 "handle-switch-user", G_CALLBACK(_handle_switch_user), adapter);
356 tlm_dbus_login_adapter_request_completed (
357 TlmDbusRequest *request,
360 g_return_if_fail (request && request->dbus_adapter &&
361 TLM_IS_DBUS_LOGIN_ADAPTER(request->dbus_adapter));
363 TlmDbusLoginAdapter *adapter = TLM_DBUS_LOGIN_ADAPTER (
364 request->dbus_adapter);
366 g_dbus_method_invocation_return_gerror (request->invocation, error);
370 switch (request->type) {
371 case TLM_DBUS_REQUEST_TYPE_LOGIN_USER:
372 tlm_dbus_login_complete_login_user (adapter->priv->dbus_obj,
373 request->invocation);
375 case TLM_DBUS_REQUEST_TYPE_LOGOUT_USER:
376 tlm_dbus_login_complete_logout_user (adapter->priv->dbus_obj,
377 request->invocation);
379 case TLM_DBUS_REQUEST_TYPE_SWITCH_USER:
380 tlm_dbus_login_complete_switch_user (adapter->priv->dbus_obj,
381 request->invocation);