diff options
Diffstat (limited to 'src/users-service-dbus.c')
-rw-r--r-- | src/users-service-dbus.c | 1417 |
1 files changed, 705 insertions, 712 deletions
diff --git a/src/users-service-dbus.c b/src/users-service-dbus.c index e6d094c..382c2dc 100644 --- a/src/users-service-dbus.c +++ b/src/users-service-dbus.c @@ -4,6 +4,7 @@ * * Authors: * Cody Russell <crussell@canonical.com> + * Charles Kerr <charles.kerr@canonical.com> * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published @@ -19,946 +20,938 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <string.h> +#include <glib.h> + #include <errno.h> -#include <pwd.h> +#include <string.h> -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-lowlevel.h> +#include <pwd.h> /* getpwuid() */ #include "dbus-shared-names.h" -#include "display-manager-client.h" +#include "dbus-accounts.h" +#include "dbus-consolekit-manager.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-display-manager.h" +#include "dbus-user.h" #include "users-service-dbus.h" -#include "accounts-service-client.h" -#include "consolekit-manager-client.h" -#include "consolekit-session-client.h" -#include "consolekit-seat-client.h" #define CK_ADDR "org.freedesktop.ConsoleKit" #define CK_SESSION_IFACE "org.freedesktop.ConsoleKit.Session" +/** +*** +**/ -static void users_service_dbus_class_init (UsersServiceDbusClass *klass); -static void users_service_dbus_init (UsersServiceDbus *self); -static void users_service_dbus_dispose (GObject *object); -static void users_service_dbus_finalize (GObject *object); -static void create_display_manager_proxy (UsersServiceDbus *self); -static void create_accounts_service_proxy (UsersServiceDbus *self); -static void create_seat_proxy (UsersServiceDbus *self); -static void create_ck_proxy (UsersServiceDbus *self); -static void create_cksession_proxy (UsersServiceDbus *self); -static gchar *get_seat (UsersServiceDbus *service); -static void user_added (DBusGProxy *proxy, - const gchar *user_id, - gpointer user_data); -static void user_deleted (DBusGProxy *proxy, - const gchar *user_id, - gpointer user_data); -static void user_changed (DBusGProxy *proxy, - gpointer user_data); -static void seat_proxy_session_added (DBusGProxy *seat_proxy, - const gchar *session_id, - UsersServiceDbus *service); -static void seat_proxy_session_removed (DBusGProxy *seat_proxy, - const gchar *session_id, - UsersServiceDbus *service); -static void sync_users (UsersServiceDbus *self); -static gboolean do_add_session (UsersServiceDbus *service, - UserData *user, - const gchar *ssid); -static gchar * get_seat_internal (DBusGProxy *proxy); - -/* Private */ -typedef struct _UsersServiceDbusPrivate UsersServiceDbusPrivate; +static void init_users (UsersServiceDbus * self); -struct _UsersServiceDbusPrivate -{ - GHashTable *users; - gint count; - gchar *seat; - gchar *ssid; +static gchar* get_seat (UsersServiceDbus * service); - DBusGConnection *system_bus; +static void on_user_added (Accounts * o, + const gchar * user_object_path, + UsersServiceDbus * service); - DBusGProxy *accounts_service_proxy; - DBusGProxy *display_manager_proxy; - DBusGProxy *display_manager_props_proxy; - DBusGProxy *ck_proxy; - DBusGProxy *seat_proxy; - DBusGProxy *session_proxy; +static void on_user_deleted (Accounts * o, + const gchar * user_object_path, + UsersServiceDbus * service); - GHashTable *exclusions; - GHashTable *sessions; +static void on_session_added (ConsoleKitSeat * seat, + const gchar * ssid, + UsersServiceDbus * service); - DbusmenuMenuitem * guest_item; - gchar * guest_session_id; - gboolean guest_session_enabled; -}; - -#define USERS_SERVICE_DBUS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), USERS_SERVICE_DBUS_TYPE, UsersServiceDbusPrivate)) - -/* Signals */ -enum { - USER_ADDED, - USER_DELETED, - LAST_SIGNAL -}; +static void on_session_removed (ConsoleKitSeat * seat, + const gchar * ssid, + UsersServiceDbus * service); -static guint signals[LAST_SIGNAL] = { 0 }; +static void on_session_list (ConsoleKitSeat * seat, + GAsyncResult * result, + UsersServiceDbus * service); -/* GObject Boilerplate */ -G_DEFINE_TYPE (UsersServiceDbus, users_service_dbus, G_TYPE_OBJECT); +/*** +**** Priv Struct +***/ -static void -users_service_dbus_class_init (UsersServiceDbusClass *klass) +struct _UsersServiceDbusPrivate { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + gchar * seat; + gchar * guest_ssid; - g_type_class_add_private (object_class, sizeof (UsersServiceDbusPrivate)); + /* ssid -> AccountsUser lookup */ + GHashTable * sessions; - object_class->dispose = users_service_dbus_dispose; - object_class->finalize = users_service_dbus_finalize; + /* user object path -> AccountsUser lookup */ + GHashTable * users; - signals[USER_ADDED] = g_signal_new ("user-added", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (UsersServiceDbusClass, user_added), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); + GCancellable * cancellable; + ConsoleKitSeat * seat_proxy; + ConsoleKitManager * ck_manager_proxy; + Accounts * accounts_proxy; + DisplayManagerSeat * display_proxy; +}; - signals[USER_DELETED] = g_signal_new ("user-deleted", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (UsersServiceDbusClass, user_deleted), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); -} +/*** +**** GObject +***/ -static void -users_service_dbus_init (UsersServiceDbus *self) +enum { - GError *error = NULL; - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - - priv->users = NULL; - priv->count = 0; - priv->guest_item = NULL; - priv->guest_session_id = NULL; - - priv->guest_session_enabled = FALSE; - - /* Get the system bus */ - priv->system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (error != NULL) - { - g_error ("Unable to get system bus"); - g_error_free(error); - - return; - } - - priv->sessions = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_free); + USER_ADDED, + USER_DELETED, + USER_LOGGED_IN_CHANGED, + GUEST_LOGGED_IN_CHANGED, + N_SIGNALS +}; - priv->users = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - NULL); +static guint signals[N_SIGNALS] = { 0 }; - create_ck_proxy (self); - create_seat_proxy (self); - create_display_manager_proxy (self); - create_accounts_service_proxy (self); -} +G_DEFINE_TYPE (UsersServiceDbus, users_service_dbus, G_TYPE_OBJECT); static void users_service_dbus_dispose (GObject *object) { - G_OBJECT_CLASS (users_service_dbus_parent_class)->dispose (object); -} - -static void -users_service_dbus_finalize (GObject *object) -{ - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (object); - - if (priv->guest_session_id != NULL) { - g_free(priv->guest_session_id); - priv->guest_session_id = NULL; - } - - G_OBJECT_CLASS (users_service_dbus_parent_class)->finalize (object); -} + UsersServiceDbusPrivate * priv = USERS_SERVICE_DBUS(object)->priv; + g_clear_object (&priv->accounts_proxy); + g_clear_object (&priv->display_proxy); + g_clear_object (&priv->seat_proxy); + g_clear_object (&priv->ck_manager_proxy); -static void -create_display_manager_proxy (UsersServiceDbus *self) -{ - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - GError *error = NULL; - const gchar *seat = NULL; - - seat = g_getenv ("XDG_SEAT_PATH"); - g_debug ("CREATING DM PROXIES WITH %s", seat); - priv->display_manager_proxy = dbus_g_proxy_new_for_name (priv->system_bus, - "org.freedesktop.DisplayManager", - seat, - "org.freedesktop.DisplayManager.Seat"); - - priv->display_manager_props_proxy = dbus_g_proxy_new_for_name (priv->system_bus, - "org.freedesktop.DisplayManager", - seat, - "org.freedesktop.DBus.Properties"); - - - if (!priv->display_manager_proxy) + if (priv->cancellable != NULL) { - g_warning ("Failed to get DisplayManager seat proxy."); - return; + g_cancellable_cancel (priv->cancellable); + g_clear_object (&priv->cancellable); } - if (!priv->display_manager_props_proxy) - { - g_warning ("Failed to get DisplayManager Properties seat proxy."); - return; - } - - GValue has_guest_session = {0}; - g_value_init (&has_guest_session, G_TYPE_BOOLEAN); - if (!dbus_g_proxy_call (priv->display_manager_props_proxy, - "Get", - &error, - G_TYPE_STRING, - "org.freedesktop.DisplayManager.Seat", - G_TYPE_STRING, - "HasGuestAccount", - G_TYPE_INVALID, - G_TYPE_VALUE, - &has_guest_session, - G_TYPE_INVALID)) + + if (priv->users != NULL) { - g_warning ("Failed to get the HasGuestSession property from the DisplayManager Properties seat proxy. error: %s", error->message); - g_error_free (error); - return; + g_hash_table_destroy (priv->users); + priv->users = NULL; } - g_debug ("Does seat have a guest account = %i", g_value_get_boolean (&has_guest_session)); - priv->guest_session_enabled = g_value_get_boolean (&has_guest_session); -} -static void -create_accounts_service_proxy (UsersServiceDbus *self) -{ - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - GPtrArray *users = g_ptr_array_new (); - GError *error = NULL; - - priv->accounts_service_proxy = dbus_g_proxy_new_for_name (priv->system_bus, - "org.freedesktop.Accounts", - "/org/freedesktop/Accounts", - "org.freedesktop.Accounts"); - - dbus_g_proxy_add_signal (priv->accounts_service_proxy, - "UserAdded", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - - dbus_g_proxy_add_signal (priv->accounts_service_proxy, - "UserChanged", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - - dbus_g_proxy_add_signal (priv->accounts_service_proxy, - "UserDeleted", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (priv->accounts_service_proxy, - "UserAdded", - G_CALLBACK (user_added), - self, - NULL); - - dbus_g_proxy_connect_signal (priv->accounts_service_proxy, - "UserDeleted", - G_CALLBACK (user_deleted), - self, - NULL); - - if (!org_freedesktop_Accounts_list_cached_users (priv->accounts_service_proxy, - &users, - &error)) + if (priv->sessions != NULL) { - g_warning ("failed to retrieve user count: %s", error->message); - g_error_free (error); - - return; + g_hash_table_destroy (priv->sessions); + priv->sessions = NULL; } - priv->count = users->len; - g_ptr_array_free (users, TRUE); - sync_users (self); + G_OBJECT_CLASS (users_service_dbus_parent_class)->dispose (object); } static void -create_ck_proxy (UsersServiceDbus *self) +users_service_dbus_finalize (GObject *object) { - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); + UsersServiceDbusPrivate * priv = USERS_SERVICE_DBUS(object)->priv; - priv->ck_proxy = dbus_g_proxy_new_for_name (priv->system_bus, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager"); + g_free (priv->guest_ssid); + g_free (priv->seat); - if (!priv->ck_proxy) - { - g_warning ("Failed to get ConsoleKit proxy."); - return; - } + G_OBJECT_CLASS (users_service_dbus_parent_class)->finalize (object); } -/* Get the initial sessions when starting up */ -static void -get_cksessions_cb (DBusGProxy *proxy, GPtrArray * sessions, GError * error, gpointer userdata) +static void +users_service_dbus_class_init (UsersServiceDbusClass *klass) { - if (error != NULL) { - g_warning("Unable to get initial sessions: %s", error->message); - return; - } + GObjectClass *object_class = G_OBJECT_CLASS (klass); - /* If there's no error we should at least get an - array of zero entries */ - g_return_if_fail(sessions != NULL); - g_debug("Got %d initial sessions", sessions->len); + g_type_class_add_private (object_class, sizeof (UsersServiceDbusPrivate)); - int i; - for (i = 0; i < sessions->len; i++) { - seat_proxy_session_added(proxy, g_ptr_array_index(sessions, i), USERS_SERVICE_DBUS(userdata)); - } + object_class->dispose = users_service_dbus_dispose; + object_class->finalize = users_service_dbus_finalize; - return; + signals[USER_ADDED] = g_signal_new ( + "user-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (UsersServiceDbusClass, user_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[USER_DELETED] = g_signal_new ( + "user-deleted", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (UsersServiceDbusClass, user_deleted), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[USER_LOGGED_IN_CHANGED] = g_signal_new ( + "user-logged-in-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (UsersServiceDbusClass, user_logged_in_changed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[GUEST_LOGGED_IN_CHANGED] = g_signal_new ( + "guest-logged-in-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (UsersServiceDbusClass, guest_logged_in_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void -create_seat_proxy (UsersServiceDbus *self) +users_service_dbus_init (UsersServiceDbus *self) { - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - GError *error = NULL; + GError * error = NULL; + + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + USERS_SERVICE_DBUS_TYPE, + UsersServiceDbusPrivate); + + UsersServiceDbusPrivate * p = self->priv; - priv->seat = get_seat (self); - if (priv->seat == NULL) + p->cancellable = g_cancellable_new (); + + /* ssid -> AccountsUser */ + p->sessions = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_object_unref); + + /* user object path -> AccountsUser */ + p->users = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_object_unref); + + /** + *** create the consolekit manager proxy... + **/ + + p->ck_manager_proxy = console_kit_manager_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + NULL, + &error); + if (error != NULL) { - return; + g_warning ("%s: %s", G_STRLOC, error->message); + g_clear_error (&error); } - priv->seat_proxy = dbus_g_proxy_new_for_name_owner (priv->system_bus, - "org.freedesktop.ConsoleKit", - priv->seat, - "org.freedesktop.ConsoleKit.Seat", - &error); + p->seat = get_seat (self); - if (!priv->seat_proxy) + /** + *** create the consolekit seat proxy... + **/ + + if (p->seat != NULL) { + ConsoleKitSeat * proxy = console_kit_seat_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.ConsoleKit", + p->seat, + NULL, + &error); + if (error != NULL) { g_warning ("Failed to connect to the ConsoleKit seat: %s", error->message); - g_error_free (error); + g_clear_error (&error); } + else + { + g_signal_connect (proxy, "session-added", + G_CALLBACK (on_session_added), self); + g_signal_connect (proxy, "session-removed", + G_CALLBACK (on_session_removed), self); + console_kit_seat_call_get_sessions (proxy, p->cancellable, + (GAsyncReadyCallback)on_session_list, self); + p->seat_proxy = proxy; + } + } - return; + /** + *** create the accounts manager proxy... + **/ + + Accounts * proxy = accounts_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.Accounts", + "/org/freedesktop/Accounts", + NULL, + &error); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); } + else + { + g_signal_connect (proxy, "user-added", G_CALLBACK(on_user_added), self); + g_signal_connect (proxy, "user-deleted", G_CALLBACK(on_user_deleted), self); + p->accounts_proxy = proxy; + init_users (self); + } +} - dbus_g_proxy_add_signal (priv->seat_proxy, - "SessionAdded", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->seat_proxy, - "SessionRemoved", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); +/*** +**** +***/ - dbus_g_proxy_connect_signal (priv->seat_proxy, - "SessionAdded", - G_CALLBACK (seat_proxy_session_added), - self, - NULL); - dbus_g_proxy_connect_signal (priv->seat_proxy, - "SessionRemoved", - G_CALLBACK (seat_proxy_session_removed), - self, - NULL); +static void +emit_user_added (UsersServiceDbus * self, AccountsUser * user) +{ + g_signal_emit (self, signals[USER_ADDED], 0, user); +} - org_freedesktop_ConsoleKit_Seat_get_sessions_async (priv->seat_proxy, get_cksessions_cb, self); +static void +emit_user_deleted (UsersServiceDbus * self, AccountsUser * user) +{ + g_signal_emit (self, signals[USER_DELETED], 0, user); +} - return; +static void +emit_user_login_changed (UsersServiceDbus * self, AccountsUser * user) +{ + g_signal_emit (self, signals[USER_LOGGED_IN_CHANGED], 0, user); } static void -create_cksession_proxy (UsersServiceDbus *service) +emit_guest_login_changed (UsersServiceDbus * self) { - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); + g_signal_emit (self, signals[GUEST_LOGGED_IN_CHANGED], 0); +} - priv->session_proxy = dbus_g_proxy_new_for_name (priv->system_bus, - CK_ADDR, - priv->ssid, - CK_SESSION_IFACE); +/*** +**** +***/ - if (!priv->session_proxy) +static ConsoleKitSession* +create_consolekit_session_proxy (const char * ssid) +{ + GError * error = NULL; + + ConsoleKitSession * p = console_kit_session_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + CK_ADDR, + ssid, + NULL, + &error); + + if (error != NULL) { - g_warning ("Failed to get ConsoleKit session proxy"); - return; + g_warning ("%s: %s", G_STRLOC, error->message); + g_error_free (error); } + + return p; } static gchar * -get_seat (UsersServiceDbus *service) +get_seat_from_session_proxy (ConsoleKitSession * session_proxy) { - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - GError *error = NULL; - gchar *ssid = NULL; - gchar *seat; - - if (!dbus_g_proxy_call (priv->ck_proxy, - "GetCurrentSession", - &error, - G_TYPE_INVALID, - DBUS_TYPE_G_OBJECT_PATH, - &ssid, - G_TYPE_INVALID)) - { - if (error) - { - g_debug ("Failed to call GetCurrentSession: %s", error->message); - g_error_free (error); - } - - if (ssid) - g_free (ssid); + gchar * seat = NULL; - return NULL; + GError * error = NULL; + console_kit_session_call_get_seat_id_sync (session_proxy, + &seat, + NULL, + &error); + if (error != NULL) + { + g_debug ("%s: %s", G_STRLOC, error->message); + g_error_free (error); } - priv->ssid = ssid; - create_cksession_proxy (service); - - seat = get_seat_internal (priv->session_proxy); - return seat; } static gchar * -get_seat_internal (DBusGProxy *proxy) +get_seat (UsersServiceDbus *service) { - GError *error = NULL; - gchar *seat = NULL; + gchar * seat = NULL; + gchar * ssid = NULL; + GError * error = NULL; + UsersServiceDbusPrivate * priv = service->priv; + + console_kit_manager_call_get_current_session_sync (priv->ck_manager_proxy, + &ssid, + NULL, + &error); - if (!org_freedesktop_ConsoleKit_Session_get_seat_id (proxy, &seat, &error)) + if (error != NULL) { - if (error) - { - g_debug ("Failed to call GetSeatId: %s", error->message); + g_debug ("%s: %s", G_STRLOC, error->message); + g_error_free (error); + } + else + { + ConsoleKitSession * session = create_consolekit_session_proxy (ssid); - return NULL; + if (session != NULL) + { + seat = get_seat_from_session_proxy (session); + g_object_unref (session); } } return seat; } -static gboolean -get_unix_user (UsersServiceDbus *service, - const gchar *session_id, - uid_t *uidp) -{ - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - GError *error = NULL; - guint uid; - DBusGProxy *session_proxy; - - g_debug("Building session proxy for: %s", session_id); - session_proxy = dbus_g_proxy_new_for_name_owner(priv->system_bus, - CK_ADDR, - session_id, - CK_SESSION_IFACE, - &error); - - if (error != NULL) { - g_warning("Unable to get CK Session proxy: %s", error->message); - g_error_free(error); - return FALSE; - } - - if (!org_freedesktop_ConsoleKit_Session_get_unix_user(session_proxy, &uid, &error)) +/* lazy-create the display manager proxy */ +static DisplayManagerSeat * +get_display_proxy (UsersServiceDbus * self) +{ + UsersServiceDbusPrivate * priv = self->priv; + + if (priv->display_proxy == NULL) { - if (error) + const gchar * const seat = g_getenv ("XDG_SEAT_PATH"); + g_debug ("%s lazy-creating the DisplayManager proxy for seat %s", G_STRLOC, seat); + + GError * error = NULL; + DisplayManagerSeat * p = display_manager_seat_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.DisplayManager", + seat, + NULL, + &error); + + if (error == NULL) + { + priv->display_proxy = p; + } + else { - g_warning ("Failed to call GetUnixUser: %s", error->message); + g_warning ("%s: %s", G_STRLOC, error->message); g_error_free (error); } + } + + return priv->display_proxy; +} - g_object_unref(session_proxy); - return FALSE; +/*** +**** AccountsUser add-ons for tracking sessions +***/ + +static GHashTable* +user_get_sessions_hashset (AccountsUser * user) +{ + static GQuark q = 0; + + if (G_UNLIKELY(!q)) + { + q = g_quark_from_static_string ("sessions"); } - if (uidp != NULL) + GObject * o = G_OBJECT (user); + GHashTable * h = g_object_get_qdata (o, q); + if (h == NULL) { - *uidp = (uid_t)uid; + h = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_object_set_qdata_full (o, q, h, (GDestroyNotify)g_hash_table_destroy); } - g_object_unref(session_proxy); - return TRUE; + return h; } -static gboolean -do_add_session (UsersServiceDbus *service, - UserData *user, - const gchar *ssid) -{ - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - GError *error = NULL; - gchar *seat = NULL; - gchar *xdisplay = NULL; - DBusGProxy * session_proxy; - GList *l; - - session_proxy = dbus_g_proxy_new_for_name_owner(priv->system_bus, - CK_ADDR, - ssid, - CK_SESSION_IFACE, - &error); - - if (error != NULL) { - g_warning("Unable to get CK Session proxy: %s", error->message); - g_error_free(error); - return FALSE; - } - - seat = get_seat_internal (session_proxy); - - if (!seat || !priv->seat || strcmp (seat, priv->seat) != 0) { - g_object_unref(session_proxy); - return FALSE; - } - - if (!org_freedesktop_ConsoleKit_Session_get_x11_display (session_proxy, &xdisplay, &error)) +static void +user_add_session (AccountsUser * user, const char * ssid) +{ + g_hash_table_add (user_get_sessions_hashset(user), g_strdup(ssid)); +} + +static void +user_remove_session (AccountsUser * user, const char * ssid) +{ + g_hash_table_remove (user_get_sessions_hashset(user), ssid); +} + +static guint +user_count_sessions (AccountsUser * user) +{ + return g_hash_table_size (user_get_sessions_hashset(user)); +} + +/*** +**** Users +***/ + +/* adds this user session to the user's and service's session tables */ +static void +add_user_session (UsersServiceDbus * service, + AccountsUser * user, + const gchar * ssid) +{ + ConsoleKitSession * session_proxy = create_consolekit_session_proxy (ssid); + if (session_proxy != NULL) { - if (error) + UsersServiceDbusPrivate * priv = service->priv; + gchar * seat = get_seat_from_session_proxy (session_proxy); + + /* is this session in our seat? */ + if (seat && priv->seat && !g_strcmp0 (seat, priv->seat)) { - g_debug ("Failed to call GetX11Display: %s", error->message); - g_error_free (error); + /* does this session have a display? */ + gchar * display = NULL; + console_kit_session_call_get_x11_display_sync (session_proxy, + &display, + NULL, NULL); + const gboolean has_display = display && *display; + g_free (display); + + if (has_display) + { + const gchar * username = accounts_user_get_user_name (user); + g_debug ("%s adding %s's session '%s' to our tables", + G_STRLOC, username, ssid); + + g_hash_table_insert (priv->sessions, + g_strdup (ssid), + g_object_ref (user)); + + user_add_session (user, ssid); + } } - g_object_unref(session_proxy); - return FALSE; + g_free (seat); + g_object_unref (session_proxy); } +} - g_object_unref(session_proxy); +/* calls add_user_session() for each of this user's sessions */ +static void +add_user (UsersServiceDbus *self, AccountsUser * user) +{ + const guint64 uid = accounts_user_get_uid (user); + const char * username = accounts_user_get_user_name (user); + g_debug ("%s adding %s (%i)", G_STRLOC, username, (int)uid); + + GError * error = NULL; + gchar ** sessions = NULL; + console_kit_manager_call_get_sessions_for_unix_user_sync ( + self->priv->ck_manager_proxy, + uid, + &sessions, + NULL, + &error); - if (!xdisplay || xdisplay[0] == '\0') - return FALSE; + if (error != NULL) + { + g_debug ("%s: %s", G_STRLOC, error->message); + g_error_free (error); + } + else if (sessions != NULL) + { + int i; - g_hash_table_insert (priv->sessions, - g_strdup (ssid), - g_strdup (user->user_name)); + for (i=0; sessions[i]; i++) + { + const char * const ssid = sessions[i]; + g_debug ("%s adding %s's session %s", G_STRLOC, username, ssid); + add_user_session (self, user, ssid); + } - l = g_list_find_custom (user->sessions, ssid, (GCompareFunc)g_strcmp0); - if (l == NULL) - { - g_debug ("Adding session %s", ssid); + g_strfreev (sessions); + } +} - user->sessions = g_list_prepend (user->sessions, g_strdup (ssid)); +static void +add_user_from_object_path (UsersServiceDbus * self, + const char * user_object_path) +{ + GError * error = NULL; + AccountsUser * user = accounts_user_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.Accounts", + user_object_path, + NULL, + &error); - if (user->menuitem != NULL) { - dbusmenu_menuitem_property_set_bool(user->menuitem, USER_ITEM_PROP_LOGGED_IN, TRUE); - } + if (error != NULL) + { + g_warning ("%s: %s", G_STRLOC, error->message); + g_clear_error (&error); } else { - g_debug ("User %s already has session %s", user->user_name, ssid); + g_debug ("%s adding user %s from object path %s", G_STRLOC, + accounts_user_get_user_name(user), + user_object_path); + g_hash_table_insert (self->priv->users, g_strdup(user_object_path), user); + add_user (self, user); } - - return TRUE; } + +/* calls add_user_from_object_path() on a list of user object paths */ static void -add_sessions_for_user (UsersServiceDbus *self, - UserData *user) +init_users (UsersServiceDbus *self) { - g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); + g_return_if_fail(IS_USERS_SERVICE_DBUS(self)); - g_debug ("!!!!!!!!!! - add_sessions_for_user %i %s", - (int)user->uid, user->user_name); + GError * error = NULL; + char ** object_paths = NULL; + UsersServiceDbusPrivate * priv = self->priv; + g_debug ("%s bootstrapping the user list", G_STRLOC); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - GError *error; - GPtrArray *sessions; - int i; + accounts_call_list_cached_users_sync (priv->accounts_proxy, + &object_paths, + NULL, + &error); - error = NULL; - if (!org_freedesktop_ConsoleKit_Manager_get_sessions_for_unix_user(priv->ck_proxy, user->uid, &sessions, &error)) + if (error != NULL) { - g_debug ("Failed to call GetSessionsForUnixUser: %s", error->message); - g_error_free (error); - - return; + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); } - - for (i = 0; i < sessions->len; i++) + else if (object_paths != NULL) { - char *ssid; + gint i; - ssid = g_ptr_array_index (sessions, i); - do_add_session (self, user, ssid); + for (i=0; object_paths[i] != NULL; ++i) + { + add_user_from_object_path (self, object_paths[i]); + } + + g_strfreev (object_paths); } - g_ptr_array_foreach (sessions, (GFunc)g_free, NULL); - g_ptr_array_free (sessions, TRUE); + g_debug ("%s finished bootstrapping the user list", G_STRLOC); } +static void +on_user_added (Accounts * o G_GNUC_UNUSED, + const gchar * user_path, + UsersServiceDbus * service) +{ + add_user_from_object_path (service, user_path); + + AccountsUser * user = g_hash_table_lookup (service->priv->users, user_path); + emit_user_added (service, user); +} static void -seat_proxy_session_added (DBusGProxy *seat_proxy, - const gchar *session_id, - UsersServiceDbus *service) +on_user_deleted (Accounts * o G_GNUC_UNUSED, + const gchar * user_path, + UsersServiceDbus * service) { - g_return_if_fail(IS_USERS_SERVICE_DBUS(service)); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - uid_t uid; - struct passwd *pwent; - UserData *user; + AccountsUser * user = g_hash_table_lookup (service->priv->users, user_path); - if (!get_unix_user (service, session_id, &uid)) + if (user != NULL) { - g_warning ("Failed to lookup user for session"); - return; + GObject * o = g_object_ref (G_OBJECT(user)); + g_hash_table_remove (service->priv->users, user_path); + emit_user_deleted (service, user); + g_object_unref (o); } +} - errno = 0; - pwent = getpwuid (uid); - if (!pwent) - { - g_warning ("Failed to lookup user id %d: %s", (int)uid, g_strerror (errno)); - return; - } +static AccountsUser * +find_user_from_username (UsersServiceDbus * self, + const gchar * username) +{ + AccountsUser * match = NULL; - /* We need to special case guest here because it doesn't - show up in the GDM user tables. */ - if (g_strcmp0("guest", pwent->pw_name) == 0) { - if (priv->guest_item != NULL) { - dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, TRUE); - } - priv->guest_session_id = g_strdup(session_id); - g_debug("Found guest session: %s", priv->guest_session_id); - return; - } + g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), match); - user = users_service_dbus_get_user_by_username (service, pwent->pw_name); - if (!user) - return; + gpointer user; + GHashTableIter iter; + g_hash_table_iter_init (&iter, self->priv->users); + while (!match && g_hash_table_iter_next (&iter, NULL, &user)) + { + if (!g_strcmp0 (username, accounts_user_get_user_name (user))) + { + match = user; + } + } - do_add_session (service, user, session_id); + return match; } +/*** +**** Sessions +***/ + static void -seat_proxy_session_removed (DBusGProxy *seat_proxy, - const gchar *session_id, - UsersServiceDbus *service) -{ - g_return_if_fail(IS_USERS_SERVICE_DBUS(service)); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - UserData *user; - gchar *username; - GList *l; - - username = g_hash_table_lookup (priv->sessions, session_id); - if (!username) { - if (g_strcmp0(session_id, priv->guest_session_id) == 0) { - g_debug("Removing guest session: %s", priv->guest_session_id); - if (priv->guest_item != NULL) { - dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, FALSE); - } - g_free(priv->guest_session_id); - priv->guest_session_id = NULL; - } - return; - } +on_session_removed (ConsoleKitSeat * seat_proxy, + const gchar * ssid, + UsersServiceDbus * service) +{ + g_return_if_fail (IS_USERS_SERVICE_DBUS (service)); - user = users_service_dbus_get_user_by_username (service, username); - if (!user) - return; + UsersServiceDbusPrivate * priv = service->priv; + g_debug ("%s %s() session removed %s", G_STRLOC, G_STRFUNC, ssid); - l = g_list_find_custom (user->sessions, - session_id, - (GCompareFunc)g_strcmp0); - if (l) + if (!g_strcmp0 (ssid, priv->guest_ssid)) { - g_debug ("Removing session %s", session_id); - - g_free (l->data); - user->sessions = g_list_delete_link (user->sessions, l); - if (user->menuitem != NULL && user->sessions == NULL) { - dbusmenu_menuitem_property_set_bool(user->menuitem, USER_ITEM_PROP_LOGGED_IN, FALSE); - } + g_debug ("%s removing guest session %s", G_STRLOC, ssid); + g_clear_pointer (&priv->guest_ssid, g_free); + emit_guest_login_changed (service); } else { - g_debug ("Session not found: %s", session_id); + AccountsUser * user = g_hash_table_lookup (priv->sessions, ssid); + if (user == NULL) + { + g_debug ("%s we're not tracking ssid %s", G_STRLOC, ssid); + } + else + { + GObject * o = g_object_ref (G_OBJECT(user)); + g_hash_table_remove (service->priv->users, ssid); + user_remove_session (user, ssid); + emit_user_login_changed (service, user); + g_object_unref (o); + } } } -static void -sync_users (UsersServiceDbus *self) +static gchar* +get_unix_username_from_ssid (UsersServiceDbus * self, + const gchar * ssid) { - g_return_if_fail(IS_USERS_SERVICE_DBUS(self)); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - - GPtrArray *users = NULL; - GError *error = NULL; - gint i; - - users = g_ptr_array_new (); - - if (!org_freedesktop_Accounts_list_cached_users (priv->accounts_service_proxy, - &users, - &error)) - { - g_warning ("failed to retrieve user list: %s", error->message); - g_error_free (error); + gchar * username = NULL; - return; - } - - for (i = 0; i < users->len; i++) + ConsoleKitSession * session_proxy = create_consolekit_session_proxy (ssid); + if (session_proxy != NULL) { - gchar *id; - DBusGProxy *proxy; - UserData *user; - GError *error = NULL; - - id = g_ptr_array_index (users, i); - - proxy = dbus_g_proxy_new_for_name (priv->system_bus, - "org.freedesktop.Accounts", - id, - "org.freedesktop.DBus.Properties"); - - GHashTable *properties; - if (!dbus_g_proxy_call (proxy, "GetAll", &error, - G_TYPE_STRING, "org.freedesktop.Accounts.User", G_TYPE_INVALID, - dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &properties, G_TYPE_INVALID)) - { - g_warning ("unable to retrieve user info: %s", error->message); - g_error_free (error); - - continue; - } - - user = g_hash_table_lookup (priv->users, id); - // Double check we havent processed this user already - if (user != NULL) + guint uid = 0; + GError * error = NULL; + console_kit_session_call_get_unix_user_sync (session_proxy, + &uid, + NULL, &error); + if (error != NULL) { - g_free(user->user_name); - g_free(user->real_name); - g_free(user->icon_file); - user->real_name_conflict = FALSE; - //continue; + g_warning ("%s: %s", G_STRLOC, error->message); + g_clear_error (&error); } else - { - user = g_new0 (UserData, 1); + { + errno = 0; + const struct passwd * pwent = getpwuid (uid); + if (pwent == NULL) + { + g_warning ("Failed to lookup user id %d: %s", (int)uid, g_strerror(errno)); + } + else + { + username = g_strdup (pwent->pw_name); + } } - // Can't subscribe to the Changed signal on each individual user path - // for some reason. - dbus_g_proxy_add_signal (proxy, - "Changed", - G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (proxy, "Changed", - G_CALLBACK(user_changed), - self, - NULL); - user->uid = g_value_get_uint64 (g_hash_table_lookup (properties, "Uid")); - user->user_name = g_strdup (g_value_get_string (g_hash_table_lookup (properties, "UserName"))); - user->real_name = g_strdup (g_value_get_string (g_hash_table_lookup (properties, "RealName"))); - user->icon_file = g_strdup (g_value_get_string (g_hash_table_lookup (properties, "IconFile"))); - user->real_name_conflict = FALSE; - user->menuitem = NULL; - - g_hash_table_unref (properties); - - g_hash_table_insert (priv->users, - g_strdup (id), - user); - - add_sessions_for_user (self, user); + + g_object_unref (session_proxy); } - g_ptr_array_free (users, TRUE); + return username; } -static void -user_changed (DBusGProxy *proxy, - gpointer user_data) +static gboolean +is_guest_username (const char * username) { - g_debug ("JUST RESYNCED THE USERS FROM A USER CHANGE"); - UsersServiceDbus *service = (UsersServiceDbus *)user_data; - sync_users (service); + if (!g_strcmp0 (username, "guest")) + return TRUE; + + if ((strlen(username)==12) && !memcmp(username,"guest-",6)) + return TRUE; + + return FALSE; } +/* If the new session belongs to 'guest', update our guest_ssid. + Otherwise, call add_user_session() to update our session tables */ static void -user_added (DBusGProxy *proxy, - const gchar *user_id, - gpointer user_data) +on_session_added (ConsoleKitSeat * seat_proxy G_GNUC_UNUSED, + const gchar * ssid, + UsersServiceDbus * service) { - UsersServiceDbus *service = (UsersServiceDbus *)user_data; - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - priv->count++; - sync_users (service); - g_signal_emit (service, - signals[USER_ADDED], - 0, - user_id); -} + g_return_if_fail (IS_USERS_SERVICE_DBUS(service)); -static void -user_deleted (DBusGProxy *proxy, - const gchar *user_id, - gpointer user_data) -{ - UsersServiceDbus *service = (UsersServiceDbus *)user_data; - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); + gchar * username = get_unix_username_from_ssid (service, ssid); + g_debug ("%s %s() username %s has new session %s", G_STRLOC, G_STRFUNC, username, ssid); - priv->count--; - g_hash_table_remove (priv->users, user_id); + if (is_guest_username (username)) + { + /* handle guest as a special case -- it's not in the GDM + user tables and there isn't be an AccountsUser for it */ + g_debug("Found guest session: %s", ssid); + g_free (service->priv->guest_ssid); + service->priv->guest_ssid = g_strdup (ssid); + emit_guest_login_changed (service); + } + else + { + AccountsUser * user = find_user_from_username (service, username); + + if (user != NULL) + { + add_user_session (service, user, ssid); + emit_user_login_changed (service, user); + } + } - g_signal_emit (service, - signals[USER_DELETED], - 0, - user_id); - + g_free (username); } -UserData * -users_service_dbus_get_user_by_username (UsersServiceDbus *self, - const gchar *username) +/* Receives a list of sessions and calls on_session_added() for each of them */ +static void +on_session_list (ConsoleKitSeat * seat_proxy, + GAsyncResult * result, + UsersServiceDbus * self) { - GHashTableIter iter; - gpointer value; + GError * error = NULL; + gchar ** sessions = NULL; + g_debug ("%s bootstrapping the session list", G_STRLOC); - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), NULL); + console_kit_seat_call_get_sessions_finish (seat_proxy, + &sessions, + result, + &error); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - - g_hash_table_iter_init (&iter, priv->users); - while (g_hash_table_iter_next (&iter, NULL, &value)) + if (error != NULL) { - UserData *user = value; - if (strcmp (user->user_name, username) == 0) - return user; + g_debug ("%s: %s", G_STRLOC, error->message); + g_error_free (error); + } + else if (sessions != NULL) + { + int i; + + for (i=0; sessions[i]; i++) + { + g_debug ("%s adding initial session '%s'", G_STRLOC, sessions[i]); + on_session_added (seat_proxy, sessions[i], self); + } + + g_strfreev (sessions); } - return NULL; + g_debug ("%s done bootstrapping the session list", G_STRLOC); } +/*** +**** Public API +***/ + +/** + * users_service_dbus_get_user_list: + * + * Returns: (transfer container): a list of AccountsUser objects + */ GList * -users_service_dbus_get_user_list (UsersServiceDbus *self) +users_service_dbus_get_user_list (UsersServiceDbus * self) { g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), NULL); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); + return g_hash_table_get_values (self->priv->users); +} - return g_hash_table_get_values (priv->users); +/** + * users_service_dbus_show_greeter: + * + * Ask the Display Mnaager to switch to the greeter screen. + */ +void +users_service_dbus_show_greeter (UsersServiceDbus * self) +{ + g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); + + display_manager_seat_call_switch_to_greeter_sync (get_display_proxy(self), + NULL, + NULL); } -gboolean -users_service_dbus_show_greeter (UsersServiceDbus *self) +/** + * users_service_dbus_activate_guest_session: + * + * Activates the guest account. + */ +void +users_service_dbus_activate_guest_session (UsersServiceDbus * self) { - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - return org_freedesktop_DisplayManager_Seat_switch_to_greeter(priv->display_manager_proxy, NULL); + g_return_if_fail(IS_USERS_SERVICE_DBUS(self)); + + display_manager_seat_call_switch_to_guest_sync (get_display_proxy(self), + "", + NULL, + NULL); } -/* Activates the guest account if it can. */ -gboolean -users_service_dbus_activate_guest_session (UsersServiceDbus *self) +/** + * users_service_dbus_activate_user_session: + * + * Activates a specific user. + */ +void +users_service_dbus_activate_user_session (UsersServiceDbus * self, + AccountsUser * user) { - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - return org_freedesktop_DisplayManager_Seat_switch_to_guest(priv->display_manager_proxy, "", NULL); + g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); + + const char * const username = accounts_user_get_user_name (user); + display_manager_seat_call_switch_to_user_sync (get_display_proxy(self), + username, + "", + NULL, + NULL); } -/* Activates a specific user */ +/** + * users_service_dbus_guest_session_enabled: + * + * Tells whether or not guest sessions are allowed. + */ gboolean -users_service_dbus_activate_user_session (UsersServiceDbus *self, - UserData *user) +users_service_dbus_guest_session_enabled (UsersServiceDbus * self) { - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - return org_freedesktop_DisplayManager_Seat_switch_to_user(priv->display_manager_proxy, user->user_name, "", NULL); + g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); + + return display_manager_seat_get_has_guest_account (get_display_proxy(self)); } gboolean -users_service_dbus_can_activate_session (UsersServiceDbus *self) +users_service_dbus_can_activate_session (UsersServiceDbus * self) { - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); gboolean can_activate = FALSE; - GError *error = NULL; - if (!priv->seat_proxy) - { - create_seat_proxy (self); - } + g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), can_activate); - if (!priv->seat || priv->seat[0] == '\0') - { - return FALSE; - } - - if (!dbus_g_proxy_call (priv->seat_proxy, - "CanActivateSessions", - &error, - G_TYPE_INVALID, - G_TYPE_BOOLEAN, &can_activate, - G_TYPE_INVALID)) + GError * error = NULL; + console_kit_seat_call_can_activate_sessions_sync (self->priv->seat_proxy, + &can_activate, + NULL, + &error); + if (error != NULL) { - if (error != NULL){ - g_warning ("Failed to determine if seat can activate sessions: %s", - error->message); - g_error_free (error); - } - return FALSE; + g_warning ("%s: %s", G_STRLOC, error->message); + g_error_free (error); } return can_activate; } -/* Sets the menu item that represents the guest account */ -void -users_service_dbus_set_guest_item (UsersServiceDbus * self, DbusmenuMenuitem * mi) +gboolean +users_service_dbus_is_guest_logged_in (UsersServiceDbus * self) { - g_return_if_fail(IS_USERS_SERVICE_DBUS(self)); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - priv->guest_item = mi; - - if (priv->guest_session_id != NULL) { - dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, TRUE); - } + g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), FALSE); - return; + return self->priv->guest_ssid != NULL; } -gboolean users_service_dbus_guest_session_enabled (UsersServiceDbus * self) +gboolean +users_service_dbus_is_user_logged_in (UsersServiceDbus * self, + AccountsUser * user) { - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - - return priv->guest_session_enabled; -} + g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), FALSE); + g_return_val_if_fail (IS_ACCOUNTS_USER(user), FALSE); + return user_count_sessions (user) > 0; +} |