diff --git a/js/ui/endSessionDialog.js b/js/ui/endSessionDialog.js index 70f996a32..3403d69b8 100644 --- a/js/ui/endSessionDialog.js +++ b/js/ui/endSessionDialog.js @@ -22,8 +22,8 @@ const DBus = imports.dbus; const Lang = imports.lang; const Signals = imports.signals; +const AccountsService = imports.gi.AccountsService; const Clutter = imports.gi.Clutter; -const Gdm = imports.gi.Gdm; const GLib = imports.gi.GLib; const Gtk = imports.gi.Gtk; const Pango = imports.gi.Pango; @@ -237,7 +237,7 @@ EndSessionDialog.prototype = { _init: function() { ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'end-session-dialog' }); - this._user = Gdm.UserManager.ref_default().get_user(GLib.get_user_name()); + this._user = AccountsService.UserManager.get_default().get_user(GLib.get_user_name()); this._secondsLeft = 0; this._totalSecondsToStayOpen = 0; diff --git a/js/ui/polkitAuthenticationAgent.js b/js/ui/polkitAuthenticationAgent.js index a99cf3f6d..8ab7e480c 100644 --- a/js/ui/polkitAuthenticationAgent.js +++ b/js/ui/polkitAuthenticationAgent.js @@ -23,10 +23,10 @@ const Lang = imports.lang; const Signals = imports.signals; const Shell = imports.gi.Shell; +const AccountsService = imports.gi.AccountsService; const Clutter = imports.gi.Clutter; const St = imports.gi.St; const Pango = imports.gi.Pango; -const Gdm = imports.gi.Gdm; const Gio = imports.gi.Gio; const Mainloop = imports.mainloop; const Polkit = imports.gi.Polkit; @@ -92,7 +92,7 @@ AuthenticationDialog.prototype = { let userName = userNames[0]; - this._user = Gdm.UserManager.ref_default().get_user(userName); + this._user = AccountsService.UserManager.get_default().get_user(userName); let userRealName = this._user.get_real_name() this._userLoadedId = this._user.connect('notify::is_loaded', Lang.bind(this, this._onUserChanged)); diff --git a/js/ui/userMenu.js b/js/ui/userMenu.js index b9f9f16c3..8d71ce287 100644 --- a/js/ui/userMenu.js +++ b/js/ui/userMenu.js @@ -1,6 +1,6 @@ /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ -const Gdm = imports.gi.Gdm; +const AccountsService = imports.gi.AccountsService; const DBus = imports.dbus; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; @@ -183,10 +183,9 @@ IMStatusChooserItem.prototype = { this._IMStatusChanged(mgr, presence, s, msg); })); - this._gdm = Gdm.UserManager.ref_default(); - this._gdm.queue_load(); + this._userManager = AccountsService.UserManager.get_default(); - this._user = this._gdm.get_user(GLib.get_user_name()); + this._user = this._userManager.get_user(GLib.get_user_name()); this._userLoadedId = this._user.connect('notify::is-loaded', Lang.bind(this, @@ -367,10 +366,9 @@ UserMenuButton.prototype = { this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA }); - this._gdm = Gdm.UserManager.ref_default(); - this._gdm.queue_load(); + this._userManager = AccountsService.UserManager.get_default(); - this._user = this._gdm.get_user(GLib.get_user_name()); + this._user = this._userManager.get_user(GLib.get_user_name()); this._presence = new GnomeSession.Presence(); this._session = new GnomeSession.SessionManager(); this._haveShutdown = true; @@ -416,9 +414,12 @@ UserMenuButton.prototype = { this._userChangedId = this._user.connect('changed', Lang.bind(this, this._updateUserName)); this._createSubMenu(); - this._gdm.connect('notify::is-loaded', Lang.bind(this, this._updateSwitchUser)); - this._gdm.connect('user-added', Lang.bind(this, this._updateSwitchUser)); - this._gdm.connect('user-removed', Lang.bind(this, this._updateSwitchUser)); + this._userManager.connect('notify::is-loaded', + Lang.bind(this, this._updateSwitchUser)); + this._userManager.connect('user-added', + Lang.bind(this, this._updateSwitchUser)); + this._userManager.connect('user-removed', + Lang.bind(this, this._updateSwitchUser)); this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY, Lang.bind(this, this._updateSwitchUser)); this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY, @@ -459,7 +460,7 @@ UserMenuButton.prototype = { _updateSwitchUser: function() { let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY); - if (allowSwitch && this._gdm.can_switch ()) + if (allowSwitch && this._userManager.can_switch ()) this._loginScreenItem.actor.show(); else this._loginScreenItem.actor.hide(); @@ -619,7 +620,7 @@ UserMenuButton.prototype = { // Ensure we only move to GDM after the screensaver has activated; in some // OS configurations, the X server may block event processing on VT switch this._screenSaverProxy.SetActiveRemote(true, Lang.bind(this, function() { - this._gdm.goto_login_session(); + this._userManager.goto_login_session(); })); }, diff --git a/src/Makefile-gdmuser.am b/src/Makefile-gdmuser.am deleted file mode 100644 index 84563b891..000000000 --- a/src/Makefile-gdmuser.am +++ /dev/null @@ -1,35 +0,0 @@ -gdmuser_cflags = \ - -I$(top_srcdir)/src \ - -DPREFIX=\""$(prefix)"\" \ - -DLIBDIR=\""$(libdir)"\" \ - -DDATADIR=\""$(datadir)"\" \ - -DG_DISABLE_DEPRECATED \ - -DG_LOG_DOMAIN=\"GdmUser\" \ - -DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \ - $(GDMUSER_CFLAGS) \ - $(NULL) - -# please, keep this sorted alphabetically -gdmuser_source_h = \ - gdmuser/gdm-user.h \ - gdmuser/gdm-user-private.h \ - gdmuser/gdm-user-manager.h \ - $(NULL) - -# please, keep this sorted alphabetically -gdmuser_source_c = \ - gdmuser/gdm-user.c \ - gdmuser/gdm-user-manager.c \ - $(NULL) - -noinst_LTLIBRARIES += libgdmuser-1.0.la - -libgdmuser_1_0_la_LIBADD = $(GDMUSER_LIBS) -libgdmuser_1_0_la_SOURCES = \ - $(gdmuser_source_c) \ - $(gdmuser_source_h) \ - $(NULL) -libgdmuser_1_0_la_CPPFLAGS = $(gdmuser_cflags) -libgdmuser_1_0_la_LDFLAGS = $(LDADD) - - diff --git a/src/Makefile.am b/src/Makefile.am index be7351ae0..73e56dfee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -68,7 +68,6 @@ gnome-shell-extension-tool: gnome-shell-extension-tool.in Makefile CLEANFILES += gnome-shell $(bin_SCRIPTS) -include Makefile-gdmuser.am include Makefile-st.am include Makefile-tray.am include Makefile-gvc.am @@ -263,7 +262,6 @@ libgnome_shell_la_LIBADD = \ $(GNOME_SHELL_LIBS) \ $(BLUETOOTH_LIBS) \ libst-1.0.la \ - libgdmuser-1.0.la \ libtray.la \ libgvc.la \ $(NULL) @@ -288,12 +286,3 @@ St_1_0_gir_FILES = $(filter-out %-private.h $(st_non_gir_sources), $(addprefix $ $(addprefix $(srcdir)/,$(st_source_c)) INTROSPECTION_GIRS += St-1.0.gir CLEANFILES += St-1.0.gir - -Gdm-1.0.gir: libgdmuser-1.0.la -Gdm_1_0_gir_INCLUDES = GObject-2.0 GdkPixbuf-2.0 -Gdm_1_0_gir_CFLAGS = $(gdmuser_cflags) -Gdm_1_0_gir_LIBS = libgdmuser-1.0.la -Gdm_1_0_gir_FILES = $(filter-out %-private.h, $(addprefix $(srcdir)/,$(gdmuser_source_h))) \ - $(addprefix $(srcdir)/,$(gdmuser_source_c)) -INTROSPECTION_GIRS += Gdm-1.0.gir -CLEANFILES += Gdm-1.0.gir diff --git a/src/gdmuser/gdm-user-manager.c b/src/gdmuser/gdm-user-manager.c deleted file mode 100644 index 561be328a..000000000 --- a/src/gdmuser/gdm-user-manager.c +++ /dev/null @@ -1,3084 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007-2008 William Jon McCann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_PATHS_H -#include -#endif /* HAVE_PATHS_H */ - -#include -/* Note on sync with gdm; need to use -lib here */ -#include -#include -#include -#include - -#include -#include -#include - -#include "gdm-user-manager.h" -#include "gdm-user-private.h" - -#define GDM_USER_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_USER_MANAGER, GdmUserManagerPrivate)) - -#define CK_NAME "org.freedesktop.ConsoleKit" - -#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" -#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" -#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat" -#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" - -#define GDM_DBUS_TYPE_G_OBJECT_PATH_ARRAY (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH)) - -/* Prefs Defaults */ - -#ifdef __sun -#define FALLBACK_MINIMAL_UID 100 -#else -#define FALLBACK_MINIMAL_UID 500 -#endif - -#ifndef _PATH_SHELLS -#define _PATH_SHELLS "/etc/shells" -#endif -#define PATH_PASSWD "/etc/passwd" - -#ifndef GDM_USERNAME -#define GDM_USERNAME "gdm" -#endif - -#define RELOAD_PASSWD_THROTTLE_SECS 5 - -/* approximately two months */ -#define LOGIN_FREQUENCY_TIME_WINDOW_SECS (60 * 24 * 60 * 60) - -#define ACCOUNTS_NAME "org.freedesktop.Accounts" -#define ACCOUNTS_PATH "/org/freedesktop/Accounts" -#define ACCOUNTS_INTERFACE "org.freedesktop.Accounts" - -typedef enum { - GDM_USER_MANAGER_SEAT_STATE_UNLOADED = 0, - GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID, - GDM_USER_MANAGER_SEAT_STATE_GET_ID, - GDM_USER_MANAGER_SEAT_STATE_GET_PROXY, - GDM_USER_MANAGER_SEAT_STATE_LOADED, -} GdmUserManagerSeatState; - -typedef struct -{ - GdmUserManagerSeatState state; - char *id; - char *session_id; - union { - DBusGProxyCall *get_current_session_call; - DBusGProxyCall *get_seat_id_call; - }; - - DBusGProxy *proxy; -} GdmUserManagerSeat; - -typedef enum { - GDM_USER_MANAGER_NEW_SESSION_STATE_UNLOADED = 0, - GDM_USER_MANAGER_NEW_SESSION_STATE_GET_PROXY, - GDM_USER_MANAGER_NEW_SESSION_STATE_GET_UID, - GDM_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY, - GDM_USER_MANAGER_NEW_SESSION_STATE_MAYBE_ADD, - GDM_USER_MANAGER_NEW_SESSION_STATE_LOADED, -} GdmUserManagerNewSessionState; - -typedef struct -{ - GdmUserManager *manager; - GdmUserManagerNewSessionState state; - char *id; - - union { - DBusGProxyCall *get_unix_user_call; - DBusGProxyCall *get_x11_display_call; - }; - - DBusGProxy *proxy; - - uid_t uid; - char *x11_display; -} GdmUserManagerNewSession; - -typedef enum { - GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED = 0, - GDM_USER_MANAGER_GET_USER_STATE_WAIT_FOR_LOADED, - GDM_USER_MANAGER_GET_USER_STATE_ASK_ACCOUNTS_SERVICE, - GDM_USER_MANAGER_GET_USER_STATE_FETCHED -} GdmUserManagerGetUserState; - -typedef struct -{ - GdmUserManager *manager; - GdmUserManagerGetUserState state; - GdmUser *user; - char *username; - char *object_path; - - DBusGProxyCall *call; -} GdmUserManagerFetchUserRequest; - -struct GdmUserManagerPrivate -{ - GHashTable *users_by_name; - GHashTable *users_by_object_path; - GHashTable *sessions; - GHashTable *shells; - DBusGConnection *connection; - DBusGProxyCall *get_sessions_call; - DBusGProxy *accounts_proxy; - - GdmUserManagerSeat seat; - - GSList *new_sessions; - GSList *new_users; - GSList *fetch_user_requests; - - GFileMonitor *passwd_monitor; - GFileMonitor *shells_monitor; - - GSList *exclude_usernames; - GSList *include_usernames; - gboolean include_all; - - gboolean load_passwd_pending; - - guint load_id; - guint reload_passwd_id; - guint ck_history_id; - guint ck_history_watchdog_id; - GPid ck_history_pid; - - gboolean is_loaded; - gboolean has_multiple_users; - gboolean listing_cached_users; -}; - -enum { - PROP_0, - PROP_INCLUDE_ALL, - PROP_INCLUDE_USERNAMES_LIST, - PROP_EXCLUDE_USERNAMES_LIST, - PROP_IS_LOADED, - PROP_HAS_MULTIPLE_USERS -}; - -enum { - USER_ADDED, - USER_REMOVED, - USER_IS_LOGGED_IN_CHANGED, - USER_CHANGED, - LAST_SIGNAL -}; - -static guint signals [LAST_SIGNAL] = { 0, }; - -static void gdm_user_manager_class_init (GdmUserManagerClass *klass); -static void gdm_user_manager_init (GdmUserManager *user_manager); -static void gdm_user_manager_finalize (GObject *object); - -static void load_users_manually (GdmUserManager *manager); -static void monitor_local_users (GdmUserManager *manager); -static void load_seat_incrementally (GdmUserManager *manager); -static void unload_seat (GdmUserManager *manager); -static void load_users (GdmUserManager *manager); -static void queue_load_seat_and_users (GdmUserManager *manager); -static void monitor_local_users (GdmUserManager *manager); - -static void load_new_session_incrementally (GdmUserManagerNewSession *new_session); -static void set_is_loaded (GdmUserManager *manager, gboolean is_loaded); - -static void on_new_user_loaded (GdmUser *user, - GParamSpec *pspec, - GdmUserManager *manager); -static void give_up_and_fetch_user_locally (GdmUserManager *manager, - GdmUserManagerFetchUserRequest *request); -static void fetch_user_locally (GdmUserManager *manager, - GdmUser *user, - const char *username); -static void fetch_user_incrementally (GdmUserManagerFetchUserRequest *request); - -static void maybe_set_is_loaded (GdmUserManager *manager); -static gpointer user_manager_object = NULL; - -G_DEFINE_TYPE (GdmUserManager, gdm_user_manager, G_TYPE_OBJECT) - -GQuark -gdm_user_manager_error_quark (void) -{ - static GQuark ret = 0; - if (ret == 0) { - ret = g_quark_from_static_string ("gdm_user_manager_error"); - } - - return ret; -} - -static gboolean -start_new_login_session (GdmUserManager *manager) -{ - GError *error; - gboolean res; - - res = g_spawn_command_line_async ("gdmflexiserver -s", &error); - if (! res) { - if (error != NULL) { - g_warning ("Unable to start new login: %s", error->message); - g_error_free (error); - } else { - g_warning ("Unable to start new login"); - } - } - - return res; -} - -static gboolean -activate_session_id (GdmUserManager *manager, - const char *seat_id, - const char *session_id) -{ - DBusError local_error; - DBusMessage *message; - DBusMessage *reply; - gboolean ret; - - ret = FALSE; - reply = NULL; - - dbus_error_init (&local_error); - message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", - seat_id, - "org.freedesktop.ConsoleKit.Seat", - "ActivateSession"); - if (message == NULL) { - goto out; - } - - if (! dbus_message_append_args (message, - DBUS_TYPE_OBJECT_PATH, &session_id, - DBUS_TYPE_INVALID)) { - goto out; - } - - - dbus_error_init (&local_error); - reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (manager->priv->connection), - message, - -1, - &local_error); - if (reply == NULL) { - if (dbus_error_is_set (&local_error)) { - g_warning ("Unable to activate session: %s", local_error.message); - dbus_error_free (&local_error); - goto out; - } - } - - ret = TRUE; - out: - if (message != NULL) { - dbus_message_unref (message); - } - if (reply != NULL) { - dbus_message_unref (reply); - } - - return ret; -} - -static gboolean -session_is_login_window (GdmUserManager *manager, - const char *session_id) -{ - DBusGProxy *proxy; - GError *error; - gboolean res; - gboolean ret; - char *session_type; - - ret = FALSE; - - proxy = dbus_g_proxy_new_for_name (manager->priv->connection, - CK_NAME, - session_id, - CK_SESSION_INTERFACE); - if (proxy == NULL) { - g_warning ("Failed to connect to the ConsoleKit seat object"); - goto out; - } - - session_type = NULL; - error = NULL; - res = dbus_g_proxy_call (proxy, - "GetSessionType", - &error, - G_TYPE_INVALID, - G_TYPE_STRING, &session_type, - G_TYPE_INVALID); - if (! res) { - if (error != NULL) { - g_debug ("GdmUserManager: Failed to identify the session type: %s", error->message); - g_error_free (error); - } else { - g_debug ("GdmUserManager: Failed to identify the session type"); - } - goto out; - } - - if (session_type == NULL || session_type[0] == '\0' || strcmp (session_type, "LoginWindow") != 0) { - goto out; - } - - ret = TRUE; - - out: - if (proxy != NULL) { - g_object_unref (proxy); - } - - return ret; -} - -static char * -_get_login_window_session_id (GdmUserManager *manager) -{ - gboolean res; - gboolean can_activate_sessions; - GError *error; - GPtrArray *sessions; - char *primary_ssid; - int i; - - if (manager->priv->seat.id == NULL || manager->priv->seat.id[0] == '\0') { - g_debug ("GdmUserManager: display seat ID is not set; can't switch sessions"); - return NULL; - } - - primary_ssid = NULL; - sessions = NULL; - - can_activate_sessions = gdm_user_manager_can_switch (manager); - - if (! can_activate_sessions) { - g_debug ("GdmUserManager: seat is unable to activate sessions"); - goto out; - } - - error = NULL; - res = dbus_g_proxy_call (manager->priv->seat.proxy, - "GetSessions", - &error, - G_TYPE_INVALID, - dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &sessions, - G_TYPE_INVALID); - if (! res) { - if (error != NULL) { - g_warning ("unable to determine sessions for user: %s", - error->message); - g_error_free (error); - } else { - g_warning ("unable to determine sessions for user"); - } - goto out; - } - - for (i = 0; i < sessions->len; i++) { - char *ssid; - - ssid = g_ptr_array_index (sessions, i); - - if (session_is_login_window (manager, ssid)) { - primary_ssid = g_strdup (ssid); - break; - } - } - g_ptr_array_foreach (sessions, (GFunc)g_free, NULL); - g_ptr_array_free (sessions, TRUE); - - out: - - return primary_ssid; -} - -gboolean -gdm_user_manager_goto_login_session (GdmUserManager *manager) -{ - gboolean ret; - gboolean res; - char *ssid; - - g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), FALSE); - g_return_val_if_fail (manager->priv->is_loaded, FALSE); - - ret = FALSE; - - /* First look for any existing LoginWindow sessions on the seat. - If none are found, create a new one. */ - - ssid = _get_login_window_session_id (manager); - if (ssid != NULL) { - res = activate_session_id (manager, manager->priv->seat.id, ssid); - if (res) { - ret = TRUE; - } - } - - if (! ret) { - res = start_new_login_session (manager); - if (res) { - ret = TRUE; - } - } - - return ret; -} - -gboolean -gdm_user_manager_can_switch (GdmUserManager *manager) -{ - gboolean res; - gboolean can_activate_sessions; - GError *error; - - if (!manager->priv->is_loaded) { - g_debug ("GdmUserManager: Unable to switch sessions until fully loaded"); - return FALSE; - } - - if (manager->priv->seat.id == NULL || manager->priv->seat.id[0] == '\0') { - g_debug ("GdmUserManager: display seat ID is not set; can't switch sessions"); - return FALSE; - } - - g_debug ("GdmUserManager: checking if seat can activate sessions"); - - error = NULL; - res = dbus_g_proxy_call (manager->priv->seat.proxy, - "CanActivateSessions", - &error, - G_TYPE_INVALID, - G_TYPE_BOOLEAN, &can_activate_sessions, - G_TYPE_INVALID); - if (! res) { - if (error != NULL) { - g_warning ("unable to determine if seat can activate sessions: %s", - error->message); - g_error_free (error); - } else { - g_warning ("unable to determine if seat can activate sessions"); - } - return FALSE; - } - - return can_activate_sessions; -} - -gboolean -gdm_user_manager_activate_user_session (GdmUserManager *manager, - GdmUser *user) -{ - gboolean ret; - const char *ssid; - gboolean res; - - gboolean can_activate_sessions; - g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), FALSE); - g_return_val_if_fail (GDM_IS_USER (user), FALSE); - g_return_val_if_fail (manager->priv->is_loaded, FALSE); - - ret = FALSE; - - can_activate_sessions = gdm_user_manager_can_switch (manager); - - if (! can_activate_sessions) { - g_debug ("GdmUserManager: seat is unable to activate sessions"); - goto out; - } - - ssid = gdm_user_get_primary_session_id (user); - if (ssid == NULL) { - goto out; - } - - res = activate_session_id (manager, manager->priv->seat.id, ssid); - if (! res) { - g_debug ("GdmUserManager: unable to activate session: %s", ssid); - goto out; - } - - ret = TRUE; - out: - return ret; -} - -static void -on_user_sessions_changed (GdmUser *user, - GdmUserManager *manager) -{ - guint nsessions; - - if (! manager->priv->is_loaded) { - return; - } - - nsessions = gdm_user_get_num_sessions (user); - - g_debug ("GdmUserManager: sessions changed user=%s num=%d", - gdm_user_get_user_name (user), - nsessions); - - /* only signal on zero and one */ - if (nsessions > 1) { - return; - } - - g_signal_emit (manager, signals [USER_IS_LOGGED_IN_CHANGED], 0, user); -} - -static void -on_user_changed (GdmUser *user, - GdmUserManager *manager) -{ - if (manager->priv->is_loaded) { - g_debug ("GdmUserManager: user changed"); - g_signal_emit (manager, signals[USER_CHANGED], 0, user); - } -} - -static void -on_get_seat_id_finished (DBusGProxy *proxy, - DBusGProxyCall *call, - GdmUserManager *manager) -{ - GError *error; - char *seat_id; - gboolean res; - - g_assert (manager->priv->seat.get_seat_id_call == call); - - error = NULL; - seat_id = NULL; - res = dbus_g_proxy_end_call (proxy, - call, - &error, - DBUS_TYPE_G_OBJECT_PATH, - &seat_id, - G_TYPE_INVALID); - manager->priv->seat.get_seat_id_call = NULL; - g_object_unref (proxy); - - if (! res) { - if (error != NULL) { - g_debug ("Failed to identify the seat of the " - "current session: %s", - error->message); - g_error_free (error); - } else { - g_debug ("Failed to identify the seat of the " - "current session"); - } - unload_seat (manager); - maybe_set_is_loaded (manager); - return; - } - - g_debug ("GdmUserManager: Found current seat: %s", seat_id); - - manager->priv->seat.id = seat_id; - manager->priv->seat.state++; - - load_seat_incrementally (manager); -} - -static void -get_seat_id_for_current_session (GdmUserManager *manager) -{ - DBusGProxy *proxy; - DBusGProxyCall *call; - - proxy = dbus_g_proxy_new_for_name (manager->priv->connection, - CK_NAME, - manager->priv->seat.session_id, - CK_SESSION_INTERFACE); - if (proxy == NULL) { - g_warning ("Failed to connect to the ConsoleKit session object"); - goto failed; - } - - call = dbus_g_proxy_begin_call (proxy, - "GetSeatId", - (DBusGProxyCallNotify) - on_get_seat_id_finished, - manager, - NULL, - G_TYPE_INVALID); - if (call == NULL) { - g_warning ("GdmUserManager: failed to make GetSeatId call"); - goto failed; - } - - manager->priv->seat.get_seat_id_call = call; - - return; - -failed: - if (proxy != NULL) { - g_object_unref (proxy); - } - - unload_seat (manager); -} - -static gint -match_name_cmpfunc (gconstpointer a, - gconstpointer b) -{ - return g_strcmp0 ((char *) a, - (char *) b); -} - -static gboolean -username_in_exclude_list (GdmUserManager *manager, - const char *username) -{ - GSList *found; - gboolean ret = FALSE; - - /* always exclude the "gdm" user. */ - if (username == NULL || (strcmp (username, GDM_USERNAME) == 0)) { - return TRUE; - } - - if (manager->priv->exclude_usernames != NULL) { - found = g_slist_find_custom (manager->priv->exclude_usernames, - username, - match_name_cmpfunc); - if (found != NULL) { - ret = TRUE; - } - } - - return ret; -} - -static void -add_session_for_user (GdmUserManager *manager, - GdmUser *user, - const char *ssid) -{ - g_hash_table_insert (manager->priv->sessions, - g_strdup (ssid), - g_strdup (gdm_user_get_user_name (user))); - - _gdm_user_add_session (user, ssid); - g_debug ("GdmUserManager: added session for user: %s", gdm_user_get_user_name (user)); -} - -static void -set_has_multiple_users (GdmUserManager *manager, - gboolean has_multiple_users) -{ - if (manager->priv->has_multiple_users != has_multiple_users) { - manager->priv->has_multiple_users = has_multiple_users; - g_object_notify (G_OBJECT (manager), "has-multiple-users"); - } -} - -static GdmUser * -create_new_user (GdmUserManager *manager) -{ - GdmUser *user; - - user = g_object_new (GDM_TYPE_USER, NULL); - - manager->priv->new_users = g_slist_prepend (manager->priv->new_users, user); - - g_signal_connect (user, "notify::is-loaded", G_CALLBACK (on_new_user_loaded), manager); - - return g_object_ref (user); -} - -static void -add_user (GdmUserManager *manager, - GdmUser *user) -{ - const char *object_path; - - g_hash_table_insert (manager->priv->users_by_name, - g_strdup (gdm_user_get_user_name (user)), - g_object_ref (user)); - - object_path = gdm_user_get_object_path (user); - if (object_path != NULL) { - g_hash_table_insert (manager->priv->users_by_object_path, - (gpointer) object_path, - g_object_ref (user)); - } - - g_signal_connect (user, - "sessions-changed", - G_CALLBACK (on_user_sessions_changed), - manager); - g_signal_connect (user, - "changed", - G_CALLBACK (on_user_changed), - manager); - - if (manager->priv->is_loaded) { - g_signal_emit (manager, signals[USER_ADDED], 0, user); - } - - if (g_hash_table_size (manager->priv->users_by_name) > 1) { - set_has_multiple_users (manager, TRUE); - } -} - -static void -remove_user (GdmUserManager *manager, - GdmUser *user) -{ - g_object_ref (user); - - g_signal_handlers_disconnect_by_func (user, on_user_changed, manager); - g_signal_handlers_disconnect_by_func (user, on_user_sessions_changed, manager); - if (gdm_user_get_object_path (user) != NULL) { - g_hash_table_remove (manager->priv->users_by_object_path, gdm_user_get_object_path (user)); - } - - if (gdm_user_get_user_name (user) != NULL) { - g_hash_table_remove (manager->priv->users_by_name, gdm_user_get_user_name (user)); - } - - if (manager->priv->is_loaded) { - g_signal_emit (manager, signals[USER_REMOVED], 0, user); - } - - g_object_unref (user); - - if (g_hash_table_size (manager->priv->users_by_name) > 1) { - set_has_multiple_users (manager, FALSE); - } -} - -static void -on_new_user_loaded (GdmUser *user, - GParamSpec *pspec, - GdmUserManager *manager) -{ - const char *username; - GdmUser *old_user; - - if (!gdm_user_is_loaded (user)) { - return; - } - - g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager); - manager->priv->new_users = g_slist_remove (manager->priv->new_users, - user); - - username = gdm_user_get_user_name (user); - - if (username == NULL) { - const char *object_path; - - object_path = gdm_user_get_object_path (user); - - if (object_path != NULL) { - g_warning ("GdmUserManager: user has no username " - "(object path: %s, uid: %lu)", - object_path, gdm_user_get_uid (user)); - } else { - g_warning ("GdmUserManager: user has no username (uid: %lu)", - gdm_user_get_uid (user)); - } - g_object_unref (user); - return; - } - - if (username_in_exclude_list (manager, username)) { - g_debug ("GdmUserManager: excluding user '%s'", username); - g_object_unref (user); - return; - } - - old_user = g_hash_table_lookup (manager->priv->users_by_name, username); - - /* If username got added earlier by a different means, trump it now. - */ - if (old_user != NULL) { - remove_user (manager, old_user); - } - - add_user (manager, user); - g_object_unref (user); - - if (manager->priv->new_users == NULL) { - set_is_loaded (manager, TRUE); - } -} - -static GdmUser * -add_new_user_for_object_path (const char *object_path, - GdmUserManager *manager) -{ - GdmUser *user; - - user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path); - - if (user != NULL) { - return user; - } - user = create_new_user (manager); - _gdm_user_update_from_object_path (user, object_path); - - return user; -} - -static void -on_new_user_in_accounts_service (DBusGProxy *proxy, - const char *object_path, - gpointer user_data) -{ - GdmUserManager *manager = GDM_USER_MANAGER (user_data); - - add_new_user_for_object_path (object_path, manager); -} - -static void -on_user_removed_in_accounts_service (DBusGProxy *proxy, - const char *object_path, - gpointer user_data) -{ - GdmUserManager *manager = GDM_USER_MANAGER (user_data); - GdmUser *user; - - user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path); - - if (user == NULL) { - g_debug ("GdmUserManager: ignoring untracked user %s", object_path); - return; - } else { - g_debug ("GdmUserManager: tracked user %s removed from accounts service", object_path); - } - - manager->priv->new_users = g_slist_remove (manager->priv->new_users, user); - - remove_user (manager, user); -} - -static void -on_get_current_session_finished (DBusGProxy *proxy, - DBusGProxyCall *call, - GdmUserManager *manager) -{ - GError *error; - char *session_id; - gboolean res; - - g_assert (manager->priv->seat.get_current_session_call == call); - g_assert (manager->priv->seat.state == GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID); - - error = NULL; - session_id = NULL; - res = dbus_g_proxy_end_call (proxy, - call, - &error, - DBUS_TYPE_G_OBJECT_PATH, - &session_id, - G_TYPE_INVALID); - manager->priv->seat.get_current_session_call = NULL; - g_object_unref (proxy); - - if (! res) { - if (error != NULL) { - g_debug ("Failed to identify the current session: %s", - error->message); - g_error_free (error); - } else { - g_debug ("Failed to identify the current session"); - } - unload_seat (manager); - maybe_set_is_loaded (manager); - return; - } - - manager->priv->seat.session_id = session_id; - manager->priv->seat.state++; - - load_seat_incrementally (manager); -} - -static void -get_current_session_id (GdmUserManager *manager) -{ - DBusGProxy *proxy; - DBusGProxyCall *call; - - proxy = dbus_g_proxy_new_for_name (manager->priv->connection, - CK_NAME, - CK_MANAGER_PATH, - CK_MANAGER_INTERFACE); - if (proxy == NULL) { - g_warning ("Failed to connect to the ConsoleKit manager object"); - goto failed; - } - - call = dbus_g_proxy_begin_call (proxy, - "GetCurrentSession", - (DBusGProxyCallNotify) - on_get_current_session_finished, - manager, - NULL, - G_TYPE_INVALID); - if (call == NULL) { - g_warning ("GdmUserManager: failed to make GetCurrentSession call"); - goto failed; - } - - manager->priv->seat.get_current_session_call = call; - - return; - -failed: - if (proxy != NULL) { - g_object_unref (proxy); - } - - unload_seat (manager); -} - -static void -unload_new_session (GdmUserManagerNewSession *new_session) -{ - GdmUserManager *manager; - - manager = new_session->manager; - - manager->priv->new_sessions = g_slist_remove (manager->priv->new_sessions, - new_session); - - if (new_session->proxy != NULL) { - g_object_unref (new_session->proxy); - } - - g_free (new_session->x11_display); - g_free (new_session->id); - - g_slice_free (GdmUserManagerNewSession, new_session); -} - -static void -get_proxy_for_new_session (GdmUserManagerNewSession *new_session) -{ - GdmUserManager *manager; - DBusGProxy *proxy; - - manager = new_session->manager; - - proxy = dbus_g_proxy_new_for_name (manager->priv->connection, - CK_NAME, - new_session->id, - CK_SESSION_INTERFACE); - if (proxy == NULL) { - g_warning ("Failed to connect to the ConsoleKit '%s' object", - new_session->id); - unload_new_session (new_session); - return; - } - - new_session->proxy = proxy; - new_session->state++; - - load_new_session_incrementally (new_session); -} - -static void -on_get_unix_user_finished (DBusGProxy *proxy, - DBusGProxyCall *call, - GdmUserManagerNewSession *new_session) -{ - GError *error; - guint uid; - gboolean res; - - g_assert (new_session->get_unix_user_call == call); - - error = NULL; - - uid = (guint) -1; - res = dbus_g_proxy_end_call (proxy, - call, - &error, - G_TYPE_UINT, &uid, - G_TYPE_INVALID); - new_session->get_unix_user_call = NULL; - - if (! res) { - if (error != NULL) { - g_debug ("Failed to get uid of session '%s': %s", - new_session->id, error->message); - g_error_free (error); - } else { - g_debug ("Failed to get uid of session '%s'", - new_session->id); - } - unload_new_session (new_session); - return; - } - - g_debug ("GdmUserManager: Found uid of session '%s': %u", - new_session->id, uid); - - new_session->uid = (uid_t) uid; - new_session->state++; - - load_new_session_incrementally (new_session); -} - -static void -get_uid_for_new_session (GdmUserManagerNewSession *new_session) -{ - DBusGProxyCall *call; - - g_assert (new_session->proxy != NULL); - - call = dbus_g_proxy_begin_call (new_session->proxy, - "GetUnixUser", - (DBusGProxyCallNotify) - on_get_unix_user_finished, - new_session, - NULL, - G_TYPE_INVALID); - if (call == NULL) { - g_warning ("GdmUserManager: failed to make GetUnixUser call"); - goto failed; - } - - new_session->get_unix_user_call = call; - return; - -failed: - unload_new_session (new_session); -} - -static void -on_find_user_by_name_finished (DBusGProxy *proxy, - DBusGProxyCall *call, - GdmUserManagerFetchUserRequest *request) -{ - GdmUserManager *manager; - GError *error; - char *object_path; - gboolean res; - - g_assert (request->call == call); - - error = NULL; - object_path = NULL; - manager = request->manager; - res = dbus_g_proxy_end_call (manager->priv->accounts_proxy, - call, - &error, - DBUS_TYPE_G_OBJECT_PATH, - &object_path, - G_TYPE_INVALID); - if (! res) { - if (error != NULL) { - g_debug ("GdmUserManager: Failed to find user %s: %s", - request->username, error->message); - g_error_free (error); - } else { - g_debug ("GdmUserManager: Failed to find user %s", - request->username); - } - give_up_and_fetch_user_locally (manager, request); - return; - } - - g_debug ("GdmUserManager: Found object path of user '%s': %s", - request->username, object_path); - request->object_path = object_path; - request->state++; - - fetch_user_incrementally (request); -} - -static void -find_user_in_accounts_service (GdmUserManager *manager, - GdmUserManagerFetchUserRequest *request) -{ - DBusGProxyCall *call; - - g_debug ("GdmUserManager: Looking for user %s in accounts service", - request->username); - - g_assert (manager->priv->accounts_proxy != NULL); - - call = dbus_g_proxy_begin_call (manager->priv->accounts_proxy, - "FindUserByName", - (DBusGProxyCallNotify) - on_find_user_by_name_finished, - request, - NULL, - G_TYPE_STRING, - request->username, - G_TYPE_INVALID); - - if (call == NULL) { - g_warning ("GdmUserManager: failed to make FindUserByName('%s') call", - request->username); - goto failed; - } - - request->call = call; - return; - -failed: - give_up_and_fetch_user_locally (manager, request); -} - -static void -set_is_loaded (GdmUserManager *manager, - gboolean is_loaded) -{ - if (manager->priv->is_loaded != is_loaded) { - manager->priv->is_loaded = is_loaded; - g_object_notify (G_OBJECT (manager), "is-loaded"); - } -} - -static void -on_list_cached_users_finished (DBusGProxy *proxy, - DBusGProxyCall *call_id, - gpointer data) -{ - GdmUserManager *manager = data; - GError *error = NULL; - GPtrArray *paths; - - manager->priv->listing_cached_users = FALSE; - if (!dbus_g_proxy_end_call (proxy, - call_id, - &error, - dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &paths, - G_TYPE_INVALID)) { - g_debug ("GdmUserManager: ListCachedUsers failed: %s", error->message); - g_error_free (error); - - g_object_unref (manager->priv->accounts_proxy); - manager->priv->accounts_proxy = NULL; - - load_users_manually (manager); - - return; - } - - maybe_set_is_loaded (manager); - - g_ptr_array_foreach (paths, (GFunc)add_new_user_for_object_path, manager); - - g_ptr_array_foreach (paths, (GFunc)g_free, NULL); - g_ptr_array_free (paths, TRUE); - - /* Add users who are specifically included */ - if (manager->priv->include_usernames != NULL) { - GSList *l; - - for (l = manager->priv->include_usernames; l != NULL; l = l->next) { - GdmUser *user; - - g_debug ("GdmUserManager: Adding included user %s", (char *)l->data); - /* - * The call to gdm_user_manager_get_user will add the user if it is - * valid and not already in the hash. - */ - user = gdm_user_manager_get_user (manager, l->data); - if (user == NULL) { - g_debug ("GdmUserManager: unable to lookup user '%s'", (char *)l->data); - } - } - } -} - -static void -on_get_x11_display_finished (DBusGProxy *proxy, - DBusGProxyCall *call, - GdmUserManagerNewSession *new_session) -{ - GError *error; - char *x11_display; - gboolean res; - - g_assert (new_session->get_x11_display_call == call); - - error = NULL; - x11_display = NULL; - res = dbus_g_proxy_end_call (proxy, - call, - &error, - G_TYPE_STRING, - &x11_display, - G_TYPE_INVALID); - new_session->get_x11_display_call = NULL; - - if (! res) { - if (error != NULL) { - g_debug ("Failed to get the x11 display of session '%s': %s", - new_session->id, error->message); - g_error_free (error); - } else { - g_debug ("Failed to get the x11 display of session '%s'", - new_session->id); - } - unload_new_session (new_session); - return; - } - - g_debug ("GdmUserManager: Found x11 display of session '%s': %s", - new_session->id, x11_display); - - new_session->x11_display = x11_display; - new_session->state++; - - load_new_session_incrementally (new_session); -} - -static void -get_x11_display_for_new_session (GdmUserManagerNewSession *new_session) -{ - DBusGProxyCall *call; - - g_assert (new_session->proxy != NULL); - - call = dbus_g_proxy_begin_call (new_session->proxy, - "GetX11Display", - (DBusGProxyCallNotify) - on_get_x11_display_finished, - new_session, - NULL, - G_TYPE_INVALID); - if (call == NULL) { - g_warning ("GdmUserManager: failed to make GetX11Display call"); - goto failed; - } - - new_session->get_x11_display_call = call; - return; - -failed: - unload_new_session (new_session); -} - -static gboolean -get_pwent_for_name (const char *name, - struct passwd **pwentp) -{ - struct passwd *pwent; - - do { - errno = 0; - pwent = getpwnam (name); - } while (pwent == NULL && errno == EINTR); - - if (pwentp != NULL) { - *pwentp = pwent; - } - - return (pwent != NULL); -} - -static gboolean -get_pwent_for_uid (uid_t uid, - struct passwd **pwentp) -{ - struct passwd *pwent; - - do { - errno = 0; - pwent = getpwuid (uid); - } while (pwent == NULL && errno == EINTR); - - if (pwentp != NULL) { - *pwentp = pwent; - } - - return (pwent != NULL); -} - -static void -maybe_add_new_session (GdmUserManagerNewSession *new_session) -{ - GdmUserManager *manager; - struct passwd *pwent; - GdmUser *user; - - manager = GDM_USER_MANAGER (new_session->manager); - - errno = 0; - get_pwent_for_uid (new_session->uid, &pwent); - if (pwent == NULL) { - g_warning ("Unable to lookup user ID %d: %s", - (int) new_session->uid, g_strerror (errno)); - goto failed; - } - - /* check exclusions up front */ - if (username_in_exclude_list (manager, pwent->pw_name)) { - g_debug ("GdmUserManager: excluding user '%s'", pwent->pw_name); - goto failed; - } - - user = gdm_user_manager_get_user (manager, pwent->pw_name); - if (user == NULL) { - return; - } - - add_session_for_user (manager, user, new_session->id); - - /* if we haven't yet gotten the login frequency - then at least add one because the session exists */ - if (gdm_user_get_login_frequency (user) == 0) { - _gdm_user_update_login_frequency (user, 1); - } - - manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_LOADED; - unload_new_session (new_session); - return; - -failed: - unload_new_session (new_session); -} - -static void -load_new_session (GdmUserManager *manager, - const char *session_id) -{ - GdmUserManagerNewSession *new_session; - - new_session = g_slice_new0 (GdmUserManagerNewSession); - - new_session->manager = manager; - new_session->id = g_strdup (session_id); - new_session->state = GDM_USER_MANAGER_NEW_SESSION_STATE_UNLOADED + 1; - - manager->priv->new_sessions = g_slist_prepend (manager->priv->new_sessions, - new_session); - load_new_session_incrementally (new_session); -} - -static void -seat_session_added (DBusGProxy *seat_proxy, - const char *session_id, - GdmUserManager *manager) -{ - g_debug ("GdmUserManager: Session added: %s", session_id); - - load_new_session (manager, session_id); -} - -static gint -match_new_session_cmpfunc (gconstpointer a, - gconstpointer b) -{ - GdmUserManagerNewSession *new_session; - const char *session_id; - - new_session = (GdmUserManagerNewSession *) a; - session_id = (const char *) b; - - return strcmp (new_session->id, session_id); -} - -static void -seat_session_removed (DBusGProxy *seat_proxy, - const char *session_id, - GdmUserManager *manager) -{ - GdmUser *user; - GSList *found; - char *username; - - g_debug ("GdmUserManager: Session removed: %s", session_id); - - found = g_slist_find_custom (manager->priv->new_sessions, - session_id, - match_new_session_cmpfunc); - - if (found != NULL) { - GdmUserManagerNewSession *new_session; - - new_session = (GdmUserManagerNewSession *) found->data; - - if (new_session->state > GDM_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY) { - g_debug ("GdmUserManager: New session for uid %d on " - "x11 display %s removed before fully loading", - (int) new_session->uid, new_session->x11_display); - } else if (new_session->state > GDM_USER_MANAGER_NEW_SESSION_STATE_GET_UID) { - g_debug ("GdmUserManager: New session for uid %d " - "removed before fully loading", - (int) new_session->uid); - } else { - g_debug ("GdmUserManager: New session removed " - "before fully loading"); - } - unload_new_session (new_session); - return; - } - - /* since the session object may already be gone - * we can't query CK directly */ - - username = g_hash_table_lookup (manager->priv->sessions, session_id); - if (username == NULL) { - return; - } - - user = g_hash_table_lookup (manager->priv->users_by_name, username); - if (user == NULL) { - /* nothing to do */ - return; - } - - g_debug ("GdmUserManager: Session removed for %s", username); - _gdm_user_remove_session (user, session_id); -} - -static void -on_seat_proxy_destroy (DBusGProxy *proxy, - GdmUserManager *manager) -{ - g_debug ("GdmUserManager: seat proxy destroyed"); - - manager->priv->seat.proxy = NULL; -} - -static void -get_seat_proxy (GdmUserManager *manager) -{ - DBusGProxy *proxy; - GError *error; - - g_assert (manager->priv->seat.proxy == NULL); - - error = NULL; - proxy = dbus_g_proxy_new_for_name_owner (manager->priv->connection, - CK_NAME, - manager->priv->seat.id, - CK_SEAT_INTERFACE, - &error); - - if (proxy == NULL) { - if (error != NULL) { - g_warning ("Failed to connect to the ConsoleKit seat object: %s", - error->message); - g_error_free (error); - } else { - g_warning ("Failed to connect to the ConsoleKit seat object"); - } - unload_seat (manager); - return; - } - - g_signal_connect (proxy, "destroy", G_CALLBACK (on_seat_proxy_destroy), manager); - - dbus_g_proxy_add_signal (proxy, - "SessionAdded", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (proxy, - "SessionRemoved", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (proxy, - "SessionAdded", - G_CALLBACK (seat_session_added), - manager, - NULL); - dbus_g_proxy_connect_signal (proxy, - "SessionRemoved", - G_CALLBACK (seat_session_removed), - manager, - NULL); - manager->priv->seat.proxy = proxy; - manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_LOADED; -} - -static void -unload_seat (GdmUserManager *manager) -{ - manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED; - - if (manager->priv->seat.proxy != NULL) { - g_object_unref (manager->priv->seat.proxy); - manager->priv->seat.proxy = NULL; - } - - g_free (manager->priv->seat.id); - manager->priv->seat.id = NULL; - - g_free (manager->priv->seat.session_id); - manager->priv->seat.session_id = NULL; -} - -static void -get_accounts_proxy (GdmUserManager *manager) -{ - DBusGProxy *proxy; - - g_assert (manager->priv->accounts_proxy == NULL); - - proxy = dbus_g_proxy_new_for_name (manager->priv->connection, - ACCOUNTS_NAME, - ACCOUNTS_PATH, - ACCOUNTS_INTERFACE); - manager->priv->accounts_proxy = proxy; - - dbus_g_proxy_add_signal (proxy, - "UserAdded", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (proxy, - "UserDeleted", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (proxy, - "UserAdded", - G_CALLBACK (on_new_user_in_accounts_service), - manager, - NULL); - dbus_g_proxy_connect_signal (proxy, - "UserDeleted", - G_CALLBACK (on_user_removed_in_accounts_service), - manager, - NULL); -} - -static void -load_new_session_incrementally (GdmUserManagerNewSession *new_session) -{ - switch (new_session->state) { - case GDM_USER_MANAGER_NEW_SESSION_STATE_GET_PROXY: - get_proxy_for_new_session (new_session); - break; - case GDM_USER_MANAGER_NEW_SESSION_STATE_GET_UID: - get_uid_for_new_session (new_session); - break; - case GDM_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY: - get_x11_display_for_new_session (new_session); - break; - case GDM_USER_MANAGER_NEW_SESSION_STATE_MAYBE_ADD: - maybe_add_new_session (new_session); - break; - case GDM_USER_MANAGER_NEW_SESSION_STATE_LOADED: - break; - default: - g_assert_not_reached (); - } -} - -static void -free_fetch_user_request (GdmUserManagerFetchUserRequest *request) -{ - GdmUserManager *manager; - - manager = request->manager; - - manager->priv->fetch_user_requests = g_slist_remove (manager->priv->fetch_user_requests, request); - g_free (request->username); - g_free (request->object_path); - g_slice_free (GdmUserManagerFetchUserRequest, request); -} - -static void -give_up_and_fetch_user_locally (GdmUserManager *manager, - GdmUserManagerFetchUserRequest *request) -{ - - g_debug ("GdmUserManager: account service unavailable, " - "fetching user %s locally", - request->username); - fetch_user_locally (manager, request->user, request->username); - request->state = GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED; -} - -static void -on_user_manager_maybe_ready_for_request (GdmUserManager *manager, - GParamSpec *pspec, - GdmUserManagerFetchUserRequest *request) -{ - if (!manager->priv->is_loaded) { - return; - } - - g_signal_handlers_disconnect_by_func (manager, on_user_manager_maybe_ready_for_request, request); - - request->state++; - fetch_user_incrementally (request); -} - -static void -fetch_user_incrementally (GdmUserManagerFetchUserRequest *request) -{ - GdmUserManager *manager; - - g_debug ("GdmUserManager: finding user %s state %d", - request->username, request->state); - manager = request->manager; - switch (request->state) { - case GDM_USER_MANAGER_GET_USER_STATE_WAIT_FOR_LOADED: - if (manager->priv->is_loaded) { - request->state++; - fetch_user_incrementally (request); - } else { - g_debug ("GdmUserManager: waiting for user manager to load before finding user %s", - request->username); - g_signal_connect (manager, "notify::is-loaded", - G_CALLBACK (on_user_manager_maybe_ready_for_request), request); - - } - break; - - case GDM_USER_MANAGER_GET_USER_STATE_ASK_ACCOUNTS_SERVICE: - if (manager->priv->accounts_proxy == NULL) { - give_up_and_fetch_user_locally (manager, request); - } else { - find_user_in_accounts_service (manager, request); - } - break; - case GDM_USER_MANAGER_GET_USER_STATE_FETCHED: - g_debug ("GdmUserManager: user %s fetched", request->username); - _gdm_user_update_from_object_path (request->user, request->object_path); - break; - case GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED: - g_debug ("GdmUserManager: user %s was not fetched", request->username); - break; - default: - g_assert_not_reached (); - } - - if (request->state == GDM_USER_MANAGER_GET_USER_STATE_FETCHED || - request->state == GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED) { - g_debug ("GdmUserManager: finished handling request for user %s", - request->username); - free_fetch_user_request (request); - } -} - -static void -fetch_user_from_accounts_service (GdmUserManager *manager, - GdmUser *user, - const char *username) -{ - GdmUserManagerFetchUserRequest *request; - - request = g_slice_new0 (GdmUserManagerFetchUserRequest); - - request->manager = manager; - request->username = g_strdup (username); - request->user = user; - request->state = GDM_USER_MANAGER_GET_USER_STATE_UNFETCHED + 1; - - manager->priv->fetch_user_requests = g_slist_prepend (manager->priv->fetch_user_requests, - request); - fetch_user_incrementally (request); -} - -static void -fetch_user_locally (GdmUserManager *manager, - GdmUser *user, - const char *username) -{ - struct passwd *pwent; - - get_pwent_for_name (username, &pwent); - - if (pwent != NULL) { - _gdm_user_update_from_pwent (user, pwent); - } -} - -/** - * gdm_user_manager_get_user: - * @manager: the manager to query. - * @username: the login name of the user to get. - * - * Retrieves a pointer to the #GdmUser object for the login @username - * from @manager. Trying to use this object before its - * #GdmUser:is-loaded property is %TRUE will result in undefined - * behavior. - * - * Returns: (transfer none): #GdmUser object - **/ -GdmUser * -gdm_user_manager_get_user (GdmUserManager *manager, - const char *username) -{ - GdmUser *user; - - g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL); - g_return_val_if_fail (username != NULL && username[0] != '\0', NULL); - - user = g_hash_table_lookup (manager->priv->users_by_name, username); - - /* if we don't have it loaded try to load it now */ - if (user == NULL) { - user = create_new_user (manager); - - if (manager->priv->accounts_proxy != NULL) { - fetch_user_from_accounts_service (manager, user, username); - } else { - fetch_user_locally (manager, user, username); - } - } - - return user; -} - -/** - * gdm_user_manager_get_user_by_uid: - * @manager: the manager to query. - * @uid: the uid of the user to get. - * - * Retrieves a pointer to the #GdmUser object for the uid @uid - * from @manager. Trying to use this object before its - * #GdmUser:is-loaded property is %TRUE will result in undefined - * behavior. - * - * Returns: (transfer none): #GdmUser object - */ -GdmUser * -gdm_user_manager_get_user_by_uid (GdmUserManager *manager, - gulong uid) -{ - struct passwd *pwent; - - g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL); - - get_pwent_for_uid (uid, &pwent); - if (pwent == NULL) { - g_warning ("GdmUserManager: unable to lookup uid %d", (int)uid); - return NULL; - } - - return gdm_user_manager_get_user (manager, pwent->pw_name); -} - -static void -listify_hash_values_hfunc (gpointer key, - gpointer value, - gpointer user_data) -{ - GSList **list = user_data; - - *list = g_slist_prepend (*list, value); -} - -/** - * gdm_user_manager_list_users: - * @manager: a #GdmUserManager - * - * Get a list of system user accounts - * - * Returns: (element-type GdmUser) (transfer full): List of #GdmUser objects - */ -GSList * -gdm_user_manager_list_users (GdmUserManager *manager) -{ - GSList *retval; - - g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL); - - retval = NULL; - g_hash_table_foreach (manager->priv->users_by_name, listify_hash_values_hfunc, &retval); - - return g_slist_sort (retval, (GCompareFunc) gdm_user_collate); -} - -static gboolean -parse_value_as_ulong (const char *value, - gulong *ulongval) -{ - char *end_of_valid_long; - glong long_value; - gulong ulong_value; - - errno = 0; - long_value = strtol (value, &end_of_valid_long, 10); - - if (*value == '\0' || *end_of_valid_long != '\0') { - return FALSE; - } - - ulong_value = long_value; - if (ulong_value != long_value || errno == ERANGE) { - return FALSE; - } - - *ulongval = ulong_value; - - return TRUE; -} - -static gboolean -parse_ck_history_line (const char *line, - char **user_namep, - gulong *frequencyp) -{ - GRegex *re; - GMatchInfo *match_info; - gboolean res; - gboolean ret; - GError *error; - - ret = FALSE; - re = NULL; - match_info = NULL; - - error = NULL; - re = g_regex_new ("(?P[0-9a-zA-Z]+)[ ]+(?P[0-9]+)", 0, 0, &error); - if (re == NULL) { - if (error != NULL) { - g_critical ("%s", error->message); - } else { - g_critical ("Error in regex call"); - } - goto out; - } - - g_regex_match (re, line, 0, &match_info); - - res = g_match_info_matches (match_info); - if (! res) { - g_warning ("Unable to parse history: %s", line); - goto out; - } - - if (user_namep != NULL) { - *user_namep = g_match_info_fetch_named (match_info, "username"); - } - - if (frequencyp != NULL) { - char *freq; - freq = g_match_info_fetch_named (match_info, "frequency"); - res = parse_value_as_ulong (freq, frequencyp); - g_free (freq); - if (! res) { - goto out; - } - } - - ret = TRUE; - - out: - if (match_info != NULL) { - g_match_info_free (match_info); - } - if (re != NULL) { - g_regex_unref (re); - } - return ret; -} - -static void -process_ck_history_line (GdmUserManager *manager, - const char *line) -{ - gboolean res; - char *username; - gulong frequency; - GdmUser *user; - - frequency = 0; - username = NULL; - res = parse_ck_history_line (line, &username, &frequency); - if (! res) { - return; - } - - if (username_in_exclude_list (manager, username)) { - g_debug ("GdmUserManager: excluding user '%s'", username); - g_free (username); - return; - } - - user = gdm_user_manager_get_user (manager, username); - if (user == NULL) { - g_debug ("GdmUserManager: unable to lookup user '%s'", username); - g_free (username); - return; - } - - _gdm_user_update_login_frequency (user, frequency); - g_free (username); -} - -static void -maybe_set_is_loaded (GdmUserManager *manager) -{ - if (manager->priv->is_loaded) { - return; - } - - if (manager->priv->ck_history_pid != 0) { - return; - } - - if (manager->priv->load_passwd_pending) { - return; - } - - if (manager->priv->get_sessions_call != NULL) { - return; - } - - if (manager->priv->listing_cached_users) { - return; - } - - /* Don't set is_loaded yet unless the seat is already loaded - * or failed to load. - */ - if (manager->priv->seat.state != GDM_USER_MANAGER_SEAT_STATE_LOADED - && manager->priv->seat.state != GDM_USER_MANAGER_SEAT_STATE_UNLOADED) { - return; - } - - set_is_loaded (manager, TRUE); -} - -static gboolean -ck_history_watch (GIOChannel *source, - GIOCondition condition, - GdmUserManager *manager) -{ - GIOStatus status; - gboolean done = FALSE; - - g_return_val_if_fail (manager != NULL, FALSE); - - if (condition & G_IO_IN) { - char *str; - GError *error; - - error = NULL; - status = g_io_channel_read_line (source, &str, NULL, NULL, &error); - if (error != NULL) { - g_warning ("GdmUserManager: unable to read line: %s", error->message); - g_error_free (error); - } - - if (status == G_IO_STATUS_NORMAL) { - g_debug ("GdmUserManager: history output: %s", str); - process_ck_history_line (manager, str); - } else if (status == G_IO_STATUS_EOF) { - done = TRUE; - } - - g_free (str); - } else if (condition & G_IO_HUP) { - done = TRUE; - } - - if (done) { - manager->priv->ck_history_id = 0; - if (manager->priv->ck_history_watchdog_id != 0) { - g_source_remove (manager->priv->ck_history_watchdog_id); - manager->priv->ck_history_watchdog_id = 0; - } - manager->priv->ck_history_pid = 0; - - maybe_set_is_loaded (manager); - - return FALSE; - } - - return TRUE; -} - -static int -signal_pid (int pid, - int signal) -{ - int status = -1; - - status = kill (pid, signal); - - if (status < 0) { - if (errno == ESRCH) { - g_debug ("Child process %lu was already dead.", - (unsigned long) pid); - } else { - char buf [1024]; - snprintf (buf, - sizeof (buf), - "Couldn't kill child process %lu", - (unsigned long) pid); - perror (buf); - } - } - - return status; -} - -static gboolean -ck_history_watchdog (GdmUserManager *manager) -{ - if (manager->priv->ck_history_pid > 0) { - g_debug ("Killing ck-history process"); - signal_pid (manager->priv->ck_history_pid, SIGTERM); - manager->priv->ck_history_pid = 0; - } - - manager->priv->ck_history_watchdog_id = 0; - return FALSE; -} - -static gboolean -load_ck_history (GdmUserManager *manager) -{ - char *command; - char *since; - const char *seat_id; - GError *error; - gboolean res; - char **argv; - int standard_out; - GIOChannel *channel; - GTimeVal tv; - - g_assert (manager->priv->ck_history_id == 0); - - command = NULL; - - seat_id = NULL; - if (manager->priv->seat.id != NULL - && g_str_has_prefix (manager->priv->seat.id, "/org/freedesktop/ConsoleKit/")) { - - seat_id = manager->priv->seat.id + strlen ("/org/freedesktop/ConsoleKit/"); - } - - if (seat_id == NULL) { - g_warning ("Unable to load CK history: no seat-id found"); - goto out; - } - - g_get_current_time (&tv); - tv.tv_sec -= LOGIN_FREQUENCY_TIME_WINDOW_SECS; - since = g_time_val_to_iso8601 (&tv); - - command = g_strdup_printf ("ck-history --frequent --since='%s' --seat='%s' --session-type=''", - since, - seat_id); - g_free (since); - g_debug ("GdmUserManager: running '%s'", command); - error = NULL; - if (! g_shell_parse_argv (command, NULL, &argv, &error)) { - if (error != NULL) { - g_warning ("Could not parse command: %s", error->message); - g_error_free (error); - } else { - g_warning ("Could not parse command"); - } - goto out; - } - - error = NULL; - res = g_spawn_async_with_pipes (NULL, - argv, - NULL, - G_SPAWN_SEARCH_PATH, - NULL, - NULL, - &manager->priv->ck_history_pid, /* pid */ - NULL, - &standard_out, - NULL, - &error); - g_strfreev (argv); - if (! res) { - if (error != NULL) { - g_warning ("Unable to run ck-history: %s", error->message); - g_error_free (error); - } else { - g_warning ("Unable to run ck-history"); - } - goto out; - } - - channel = g_io_channel_unix_new (standard_out); - g_io_channel_set_close_on_unref (channel, TRUE); - g_io_channel_set_flags (channel, - g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK, - NULL); - manager->priv->ck_history_watchdog_id = g_timeout_add_seconds (1, (GSourceFunc) ck_history_watchdog, manager); - manager->priv->ck_history_id = g_io_add_watch (channel, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - (GIOFunc)ck_history_watch, - manager); - g_io_channel_unref (channel); - - out: - - g_free (command); - - return manager->priv->ck_history_id != 0; -} - -static void -reload_passwd_file (GHashTable *valid_shells, - GSList *exclude_users, - GSList *include_users, - gboolean include_all, - GHashTable *current_users_by_name, - GSList **added_users, - GSList **removed_users) -{ - FILE *fp; - GHashTableIter iter; - GHashTable *new_users_by_name; - GdmUser *user; - char *name; - - new_users_by_name = g_hash_table_new_full (g_str_hash, - g_str_equal, - NULL, - g_object_unref); - - errno = 0; - fp = fopen (PATH_PASSWD, "r"); - if (fp == NULL) { - g_warning ("Unable to open %s: %s", PATH_PASSWD, g_strerror (errno)); - goto out; - } - - /* Make sure we keep users who are logged in no matter what. */ - g_hash_table_iter_init (&iter, current_users_by_name); - while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) { - struct passwd *pwent; - - get_pwent_for_name (name, &pwent); - if (pwent == NULL) { - continue; - } - - g_object_freeze_notify (G_OBJECT (user)); - _gdm_user_update_from_pwent (user, pwent); - g_hash_table_insert (new_users_by_name, (char *)gdm_user_get_user_name (user), g_object_ref (user)); - } - - if (include_users != NULL) { - GSList *l; - for (l = include_users; l != NULL; l = l->next) { - struct passwd *pwent; - - get_pwent_for_name (l->data, &pwent); - if (pwent == NULL) { - continue; - } - - user = g_hash_table_lookup (new_users_by_name, pwent->pw_name); - if (user != NULL) { - /* already there */ - continue; - } - - user = g_hash_table_lookup (current_users_by_name, pwent->pw_name); - if (user == NULL) { - user = g_object_new (GDM_TYPE_USER, NULL); - } else { - g_object_ref (user); - } - g_object_freeze_notify (G_OBJECT (user)); - _gdm_user_update_from_pwent (user, pwent); - g_hash_table_insert (new_users_by_name, (char *)gdm_user_get_user_name (user), user); - } - } - - if (include_all != TRUE) { - g_debug ("GdmUserManager: include_all is FALSE"); - } else { - struct passwd *pwent; - - g_debug ("GdmUserManager: include_all is TRUE"); - - for (pwent = fgetpwent (fp); - pwent != NULL; - pwent = fgetpwent (fp)) { - - /* Skip users below MinimalUID... */ - if (pwent->pw_uid < FALLBACK_MINIMAL_UID) { - continue; - } - - /* ...And users w/ invalid shells... */ - if (pwent->pw_shell == NULL - || !g_hash_table_lookup (valid_shells, pwent->pw_shell)) { - g_debug ("GdmUserManager: skipping user with bad shell: %s", pwent->pw_name); - continue; - } - - /* always exclude the "gdm" user. */ - if (strcmp (pwent->pw_name, GDM_USERNAME) == 0) { - continue; - } - - /* ...And explicitly excluded users */ - if (exclude_users != NULL) { - GSList *found; - - found = g_slist_find_custom (exclude_users, - pwent->pw_name, - match_name_cmpfunc); - if (found != NULL) { - g_debug ("GdmUserManager: explicitly skipping user: %s", pwent->pw_name); - continue; - } - } - - user = g_hash_table_lookup (new_users_by_name, pwent->pw_name); - if (user != NULL) { - /* already there */ - continue; - } - - user = g_hash_table_lookup (current_users_by_name, pwent->pw_name); - if (user == NULL) { - user = g_object_new (GDM_TYPE_USER, NULL); - } else { - g_object_ref (user); - } - - /* Freeze & update users not already in the new list */ - g_object_freeze_notify (G_OBJECT (user)); - _gdm_user_update_from_pwent (user, pwent); - g_hash_table_insert (new_users_by_name, (char *)gdm_user_get_user_name (user), user); - } - } - - /* Go through and handle added users */ - g_hash_table_iter_init (&iter, new_users_by_name); - while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) { - GdmUser *user2; - user2 = g_hash_table_lookup (current_users_by_name, name); - if (user2 == NULL) { - *added_users = g_slist_prepend (*added_users, g_object_ref (user)); - } - } - - /* Go through and handle removed users */ - g_hash_table_iter_init (&iter, current_users_by_name); - while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) { - GdmUser *user2; - user2 = g_hash_table_lookup (new_users_by_name, name); - if (user2 == NULL) { - *removed_users = g_slist_prepend (*removed_users, g_object_ref (user)); - } - } - - out: - /* Cleanup */ - - fclose (fp); - - g_hash_table_iter_init (&iter, new_users_by_name); - while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) { - g_object_thaw_notify (G_OBJECT (user)); - } - - g_hash_table_destroy (new_users_by_name); -} - -typedef struct { - GdmUserManager *manager; - GSList *exclude_users; - GSList *include_users; - gboolean include_all; - GHashTable *shells; - GHashTable *current_users_by_name; - GSList *added_users; - GSList *removed_users; -} PasswdData; - -static void -passwd_data_free (PasswdData *data) -{ - if (data->manager != NULL) { - g_object_unref (data->manager); - } - - g_slist_foreach (data->added_users, (GFunc) g_object_unref, NULL); - g_slist_free (data->added_users); - - g_slist_foreach (data->removed_users, (GFunc) g_object_unref, NULL); - g_slist_free (data->removed_users); - - g_slist_foreach (data->exclude_users, (GFunc) g_free, NULL); - g_slist_free (data->exclude_users); - - g_slist_foreach (data->include_users, (GFunc) g_free, NULL); - g_slist_free (data->include_users); - - g_slice_free (PasswdData, data); -} - -static gboolean -reload_passwd_job_done (PasswdData *data) -{ - GSList *l; - - g_debug ("GdmUserManager: done reloading passwd file"); - - /* Go through and handle added users */ - for (l = data->added_users; l != NULL; l = l->next) { - add_user (data->manager, l->data); - } - - /* Go through and handle removed users */ - for (l = data->removed_users; l != NULL; l = l->next) { - remove_user (data->manager, l->data); - } - - data->manager->priv->load_passwd_pending = FALSE; - - if (! data->manager->priv->is_loaded) { - maybe_set_is_loaded (data->manager); - - if (data->manager->priv->include_all == TRUE) { - monitor_local_users (data->manager); - } - } - - passwd_data_free (data); - - return FALSE; -} - -static gboolean -do_reload_passwd_job (GIOSchedulerJob *job, - GCancellable *cancellable, - PasswdData *data) -{ - g_debug ("GdmUserManager: reloading passwd file worker"); - - reload_passwd_file (data->shells, - data->exclude_users, - data->include_users, - data->include_all, - data->current_users_by_name, - &data->added_users, - &data->removed_users); - - g_io_scheduler_job_send_to_mainloop_async (job, - (GSourceFunc) reload_passwd_job_done, - data, - NULL); - - return FALSE; -} - -static GSList * -slist_deep_copy (const GSList *list) -{ - GSList *retval; - GSList *l; - - if (list == NULL) - return NULL; - - retval = g_slist_copy ((GSList *) list); - for (l = retval; l != NULL; l = l->next) { - l->data = g_strdup (l->data); - } - - return retval; -} - -static void -schedule_reload_passwd (GdmUserManager *manager) -{ - PasswdData *passwd_data; - - manager->priv->load_passwd_pending = TRUE; - - passwd_data = g_slice_new0 (PasswdData); - passwd_data->manager = g_object_ref (manager); - passwd_data->shells = manager->priv->shells; - passwd_data->exclude_users = slist_deep_copy (manager->priv->exclude_usernames); - passwd_data->include_users = slist_deep_copy (manager->priv->include_usernames); - passwd_data->include_all = manager->priv->include_all; - passwd_data->current_users_by_name = manager->priv->users_by_name; - passwd_data->added_users = NULL; - passwd_data->removed_users = NULL; - - g_debug ("GdmUserManager: scheduling a passwd file update"); - - g_io_scheduler_push_job ((GIOSchedulerJobFunc) do_reload_passwd_job, - passwd_data, - NULL, - G_PRIORITY_DEFAULT, - NULL); -} - -static void -load_sessions_from_array (GdmUserManager *manager, - const char * const *session_ids, - int number_of_sessions) -{ - int i; - - for (i = 0; i < number_of_sessions; i++) { - load_new_session (manager, session_ids[i]); - } -} - -static void -on_get_sessions_finished (DBusGProxy *proxy, - DBusGProxyCall *call, - GdmUserManager *manager) -{ - GError *error; - gboolean res; - GPtrArray *sessions; - - g_assert (manager->priv->get_sessions_call == call); - - error = NULL; - sessions = NULL; - res = dbus_g_proxy_end_call (proxy, - call, - &error, - GDM_DBUS_TYPE_G_OBJECT_PATH_ARRAY, - &sessions, - G_TYPE_INVALID); - - if (! res) { - if (error != NULL) { - g_warning ("unable to determine sessions for seat: %s", - error->message); - g_error_free (error); - } else { - g_warning ("unable to determine sessions for seat"); - } - return; - } - - manager->priv->get_sessions_call = NULL; - g_assert (sessions->len <= G_MAXINT); - load_sessions_from_array (manager, - (const char * const *) sessions->pdata, - (int) sessions->len); - g_ptr_array_foreach (sessions, (GFunc) g_free, NULL); - g_ptr_array_free (sessions, TRUE); - maybe_set_is_loaded (manager); -} - -static void -load_sessions (GdmUserManager *manager) -{ - DBusGProxyCall *call; - - if (manager->priv->seat.proxy == NULL) { - g_debug ("GdmUserManager: no seat proxy; can't load sessions"); - return; - } - - call = dbus_g_proxy_begin_call (manager->priv->seat.proxy, - "GetSessions", - (DBusGProxyCallNotify) - on_get_sessions_finished, - manager, - NULL, - G_TYPE_INVALID); - - if (call == NULL) { - g_warning ("GdmUserManager: failed to make GetSessions call"); - return; - } - - manager->priv->get_sessions_call = call; -} - -static void -reload_shells (GdmUserManager *manager) -{ - char *shell; - - setusershell (); - - g_hash_table_remove_all (manager->priv->shells); - for (shell = getusershell (); shell != NULL; shell = getusershell ()) { - /* skip well known not-real shells */ - if (shell == NULL - || strcmp (shell, "/sbin/nologin") == 0 - || strcmp (shell, "/bin/false") == 0) { - g_debug ("GdmUserManager: skipping shell %s", shell); - continue; - } - g_hash_table_insert (manager->priv->shells, - g_strdup (shell), - GUINT_TO_POINTER (TRUE)); - } - - endusershell (); -} - -static void -load_users_manually (GdmUserManager *manager) -{ - manager->priv->shells = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - NULL); - reload_shells (manager); - - load_sessions (manager); - - load_ck_history (manager); - schedule_reload_passwd (manager); -} - -static void -load_users (GdmUserManager *manager) -{ - g_assert (manager->priv->accounts_proxy != NULL); - g_debug ("GdmUserManager: calling 'ListCachedUsers'"); - - dbus_g_proxy_begin_call (manager->priv->accounts_proxy, - "ListCachedUsers", - on_list_cached_users_finished, - manager, - NULL, - G_TYPE_INVALID); - manager->priv->listing_cached_users = TRUE; -} - -static void -load_seat_incrementally (GdmUserManager *manager) -{ - g_assert (manager->priv->seat.proxy == NULL); - - switch (manager->priv->seat.state) { - case GDM_USER_MANAGER_SEAT_STATE_GET_SESSION_ID: - get_current_session_id (manager); - break; - case GDM_USER_MANAGER_SEAT_STATE_GET_ID: - get_seat_id_for_current_session (manager); - break; - case GDM_USER_MANAGER_SEAT_STATE_GET_PROXY: - get_seat_proxy (manager); - break; - case GDM_USER_MANAGER_SEAT_STATE_LOADED: - break; - default: - g_assert_not_reached (); - } - - if (manager->priv->seat.state == GDM_USER_MANAGER_SEAT_STATE_LOADED) { - load_sessions (manager); - load_ck_history (manager); - } - - maybe_set_is_loaded (manager); -} - -static gboolean -load_idle (GdmUserManager *manager) -{ - manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED + 1; - load_seat_incrementally (manager); - load_users (manager); - manager->priv->load_id = 0; - - return FALSE; -} - -static void -queue_load_seat_and_users (GdmUserManager *manager) -{ - if (manager->priv->load_id > 0) { - return; - } - - manager->priv->load_id = g_idle_add ((GSourceFunc)load_idle, manager); -} - -static gboolean -reload_passwd_idle (GdmUserManager *manager) -{ - schedule_reload_passwd (manager); - manager->priv->reload_passwd_id = 0; - - return FALSE; -} - -static void -queue_reload_passwd (GdmUserManager *manager) -{ - if (manager->priv->reload_passwd_id > 0) { - g_source_remove (manager->priv->reload_passwd_id); - } - - manager->priv->reload_passwd_id = g_timeout_add_seconds (RELOAD_PASSWD_THROTTLE_SECS, (GSourceFunc)reload_passwd_idle, manager); -} - -static void -on_shells_monitor_changed (GFileMonitor *monitor, - GFile *file, - GFile *other_file, - GFileMonitorEvent event_type, - GdmUserManager *manager) -{ - if (event_type != G_FILE_MONITOR_EVENT_CHANGED && - event_type != G_FILE_MONITOR_EVENT_CREATED) { - return; - } - - reload_shells (manager); - queue_reload_passwd (manager); -} - -static void -on_passwd_monitor_changed (GFileMonitor *monitor, - GFile *file, - GFile *other_file, - GFileMonitorEvent event_type, - GdmUserManager *manager) -{ - if (event_type != G_FILE_MONITOR_EVENT_CHANGED && - event_type != G_FILE_MONITOR_EVENT_CREATED) { - return; - } - - queue_reload_passwd (manager); -} - -static void -gdm_user_manager_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GdmUserManager *manager; - - manager = GDM_USER_MANAGER (object); - - switch (prop_id) { - case PROP_IS_LOADED: - g_value_set_boolean (value, manager->priv->is_loaded); - break; - case PROP_HAS_MULTIPLE_USERS: - g_value_set_boolean (value, manager->priv->has_multiple_users); - break; - case PROP_INCLUDE_ALL: - g_value_set_boolean (value, manager->priv->include_all); - break; - case PROP_INCLUDE_USERNAMES_LIST: - g_value_set_pointer (value, manager->priv->include_usernames); - break; - case PROP_EXCLUDE_USERNAMES_LIST: - g_value_set_pointer (value, manager->priv->exclude_usernames); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -set_include_usernames (GdmUserManager *manager, - GSList *list) -{ - if (manager->priv->include_usernames != NULL) { - g_slist_foreach (manager->priv->include_usernames, (GFunc) g_free, NULL); - g_slist_free (manager->priv->include_usernames); - } - manager->priv->include_usernames = slist_deep_copy (list); -} - -static void -set_exclude_usernames (GdmUserManager *manager, - GSList *list) -{ - if (manager->priv->exclude_usernames != NULL) { - g_slist_foreach (manager->priv->exclude_usernames, (GFunc) g_free, NULL); - g_slist_free (manager->priv->exclude_usernames); - } - manager->priv->exclude_usernames = slist_deep_copy (list); -} - -static void -set_include_all (GdmUserManager *manager, - gboolean all) -{ - if (manager->priv->include_all != all) { - manager->priv->include_all = all; - } -} - -static void -gdm_user_manager_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GdmUserManager *self; - - self = GDM_USER_MANAGER (object); - - switch (prop_id) { - case PROP_INCLUDE_ALL: - set_include_all (self, g_value_get_boolean (value)); - break; - case PROP_INCLUDE_USERNAMES_LIST: - set_include_usernames (self, g_value_get_pointer (value)); - break; - case PROP_EXCLUDE_USERNAMES_LIST: - set_exclude_usernames (self, g_value_get_pointer (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -monitor_local_users (GdmUserManager *manager) -{ - GFile *file; - GError *error; - - g_debug ("GdmUserManager: Monitoring local users"); - - /* /etc/shells */ - file = g_file_new_for_path (_PATH_SHELLS); - error = NULL; - manager->priv->shells_monitor = g_file_monitor_file (file, - G_FILE_MONITOR_NONE, - NULL, - &error); - if (manager->priv->shells_monitor != NULL) { - g_signal_connect (manager->priv->shells_monitor, - "changed", - G_CALLBACK (on_shells_monitor_changed), - manager); - } else { - g_warning ("Unable to monitor %s: %s", _PATH_SHELLS, error->message); - g_error_free (error); - } - g_object_unref (file); - - /* /etc/passwd */ - file = g_file_new_for_path (PATH_PASSWD); - manager->priv->passwd_monitor = g_file_monitor_file (file, - G_FILE_MONITOR_NONE, - NULL, - &error); - if (manager->priv->passwd_monitor != NULL) { - g_signal_connect (manager->priv->passwd_monitor, - "changed", - G_CALLBACK (on_passwd_monitor_changed), - manager); - } else { - g_warning ("Unable to monitor %s: %s", PATH_PASSWD, error->message); - g_error_free (error); - } - g_object_unref (file); -} - -static void -gdm_user_manager_class_init (GdmUserManagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = gdm_user_manager_finalize; - object_class->get_property = gdm_user_manager_get_property; - object_class->set_property = gdm_user_manager_set_property; - - g_object_class_install_property (object_class, - PROP_IS_LOADED, - g_param_spec_boolean ("is-loaded", - NULL, - NULL, - FALSE, - G_PARAM_READABLE)); - g_object_class_install_property (object_class, - PROP_HAS_MULTIPLE_USERS, - g_param_spec_boolean ("has-multiple-users", - NULL, - NULL, - FALSE, - G_PARAM_READABLE)); - g_object_class_install_property (object_class, - PROP_INCLUDE_ALL, - g_param_spec_boolean ("include-all", - NULL, - NULL, - FALSE, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_INCLUDE_USERNAMES_LIST, - g_param_spec_pointer ("include-usernames-list", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, - PROP_EXCLUDE_USERNAMES_LIST, - g_param_spec_pointer ("exclude-usernames-list", - NULL, - NULL, - G_PARAM_READWRITE)); - - signals [USER_ADDED] = - g_signal_new ("user-added", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdmUserManagerClass, user_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GDM_TYPE_USER); - signals [USER_REMOVED] = - g_signal_new ("user-removed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdmUserManagerClass, user_removed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GDM_TYPE_USER); - signals [USER_IS_LOGGED_IN_CHANGED] = - g_signal_new ("user-is-logged-in-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdmUserManagerClass, user_is_logged_in_changed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GDM_TYPE_USER); - signals [USER_CHANGED] = - g_signal_new ("user-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdmUserManagerClass, user_changed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GDM_TYPE_USER); - - g_type_class_add_private (klass, sizeof (GdmUserManagerPrivate)); -} - -/** - * gdm_user_manager_queue_load: - * @manager: a #GdmUserManager - * - * Queue loading users into user manager. This must be called, and the - * #GdmUserManager:is-loaded property must be %TRUE before calling - * gdm_user_manager_list_users() - */ -void -gdm_user_manager_queue_load (GdmUserManager *manager) -{ - g_return_if_fail (GDM_IS_USER_MANAGER (manager)); - - if (! manager->priv->is_loaded) { - queue_load_seat_and_users (manager); - } -} - -static void -gdm_user_manager_init (GdmUserManager *manager) -{ - GError *error; - - manager->priv = GDM_USER_MANAGER_GET_PRIVATE (manager); - - /* sessions */ - manager->priv->sessions = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_free); - - /* users */ - manager->priv->users_by_name = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - manager->priv->users_by_object_path = g_hash_table_new_full (g_str_hash, - g_str_equal, - NULL, - g_object_unref); - - g_assert (manager->priv->seat.proxy == NULL); - - error = NULL; - manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (manager->priv->connection == NULL) { - if (error != NULL) { - g_warning ("Failed to connect to the D-Bus daemon: %s", error->message); - g_error_free (error); - } else { - g_warning ("Failed to connect to the D-Bus daemon"); - } - return; - } - - get_accounts_proxy (manager); - - manager->priv->seat.state = GDM_USER_MANAGER_SEAT_STATE_UNLOADED; -} - -static void -gdm_user_manager_finalize (GObject *object) -{ - GdmUserManager *manager; - GSList *node; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_USER_MANAGER (object)); - - manager = GDM_USER_MANAGER (object); - - g_return_if_fail (manager->priv != NULL); - - if (manager->priv->ck_history_pid > 0) { - g_debug ("Killing ck-history process"); - signal_pid (manager->priv->ck_history_pid, SIGTERM); - } - - g_slist_foreach (manager->priv->new_sessions, - (GFunc) unload_new_session, NULL); - g_slist_free (manager->priv->new_sessions); - - g_slist_foreach (manager->priv->fetch_user_requests, - (GFunc) free_fetch_user_request, NULL); - g_slist_free (manager->priv->fetch_user_requests); - - node = manager->priv->new_users; - while (node != NULL) { - GdmUser *user; - GSList *next_node; - - user = GDM_USER (node->data); - next_node = node->next; - - g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager); - g_object_unref (user); - manager->priv->new_users = g_slist_delete_link (manager->priv->new_users, node); - node = next_node; - } - - unload_seat (manager); - - if (manager->priv->exclude_usernames != NULL) { - g_slist_foreach (manager->priv->exclude_usernames, (GFunc) g_free, NULL); - g_slist_free (manager->priv->exclude_usernames); - } - - if (manager->priv->include_usernames != NULL) { - g_slist_foreach (manager->priv->include_usernames, (GFunc) g_free, NULL); - g_slist_free (manager->priv->include_usernames); - } - - if (manager->priv->seat.proxy != NULL) { - g_object_unref (manager->priv->seat.proxy); - } - - if (manager->priv->accounts_proxy != NULL) { - g_object_unref (manager->priv->accounts_proxy); - } - - if (manager->priv->ck_history_id != 0) { - g_source_remove (manager->priv->ck_history_id); - manager->priv->ck_history_id = 0; - } - - if (manager->priv->ck_history_watchdog_id != 0) { - g_source_remove (manager->priv->ck_history_watchdog_id); - manager->priv->ck_history_watchdog_id = 0; - } - - if (manager->priv->load_id > 0) { - g_source_remove (manager->priv->load_id); - manager->priv->load_id = 0; - } - - if (manager->priv->reload_passwd_id > 0) { - g_source_remove (manager->priv->reload_passwd_id); - manager->priv->reload_passwd_id = 0; - } - - g_hash_table_destroy (manager->priv->sessions); - - if (manager->priv->passwd_monitor != NULL) { - g_file_monitor_cancel (manager->priv->passwd_monitor); - } - - g_hash_table_destroy (manager->priv->users_by_name); - g_hash_table_destroy (manager->priv->users_by_object_path); - - if (manager->priv->shells_monitor != NULL) { - g_file_monitor_cancel (manager->priv->shells_monitor); - } - - if (manager->priv->shells != NULL) { - g_hash_table_destroy (manager->priv->shells); - } - - G_OBJECT_CLASS (gdm_user_manager_parent_class)->finalize (object); -} - -/** - * gdm_user_manager_ref_default: - * - * Queue loading users into user manager. This must be called, and the - * #GdmUserManager:is-loaded property must be %TRUE before calling - * gdm_user_manager_list_users() - * - * Returns: (transfer full): user manager object - */ -GdmUserManager * -gdm_user_manager_ref_default (void) -{ - if (user_manager_object != NULL) { - g_object_ref (user_manager_object); - } else { - user_manager_object = g_object_new (GDM_TYPE_USER_MANAGER, NULL); - g_object_add_weak_pointer (user_manager_object, - (gpointer *) &user_manager_object); - } - - return GDM_USER_MANAGER (user_manager_object); -} diff --git a/src/gdmuser/gdm-user-manager.h b/src/gdmuser/gdm-user-manager.h deleted file mode 100644 index 8dd9edec3..000000000 --- a/src/gdmuser/gdm-user-manager.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef __GDM_USER_MANAGER_H__ -#define __GDM_USER_MANAGER_H__ - -#include - -#include "gdm-user.h" - -G_BEGIN_DECLS - -#define GDM_TYPE_USER_MANAGER (gdm_user_manager_get_type ()) -#define GDM_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_USER_MANAGER, GdmUserManager)) -#define GDM_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_USER_MANAGER, GdmUserManagerClass)) -#define GDM_IS_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_USER_MANAGER)) -#define GDM_IS_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_USER_MANAGER)) -#define GDM_USER_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_USER_MANAGER, GdmUserManagerClass)) - -typedef struct GdmUserManagerPrivate GdmUserManagerPrivate; -typedef struct GdmUserManager GdmUserManager; -typedef struct GdmUserManagerClass GdmUserManagerClass; -typedef enum GdmUserManagerError GdmUserManagerError; - -struct GdmUserManager -{ - GObject parent; - GdmUserManagerPrivate *priv; -}; - -struct GdmUserManagerClass -{ - GObjectClass parent_class; - - void (* user_added) (GdmUserManager *user_manager, - GdmUser *user); - void (* user_removed) (GdmUserManager *user_manager, - GdmUser *user); - void (* user_is_logged_in_changed) (GdmUserManager *user_manager, - GdmUser *user); - void (* user_changed) (GdmUserManager *user_manager, - GdmUser *user); -}; - -enum GdmUserManagerError -{ - GDM_USER_MANAGER_ERROR_GENERAL, - GDM_USER_MANAGER_ERROR_KEY_NOT_FOUND -}; - -#define GDM_USER_MANAGER_ERROR gdm_user_manager_error_quark () - -GQuark gdm_user_manager_error_quark (void); -GType gdm_user_manager_get_type (void); - -GdmUserManager * gdm_user_manager_ref_default (void); - -void gdm_user_manager_queue_load (GdmUserManager *manager); -GSList * gdm_user_manager_list_users (GdmUserManager *manager); -GdmUser * gdm_user_manager_get_user (GdmUserManager *manager, - const char *username); -GdmUser * gdm_user_manager_get_user_by_uid (GdmUserManager *manager, - gulong uid); - -gboolean gdm_user_manager_activate_user_session (GdmUserManager *manager, - GdmUser *user); - -gboolean gdm_user_manager_can_switch (GdmUserManager *manager); - -gboolean gdm_user_manager_goto_login_session (GdmUserManager *manager); - -G_END_DECLS - -#endif /* __GDM_USER_MANAGER_H */ diff --git a/src/gdmuser/gdm-user-private.h b/src/gdmuser/gdm-user-private.h deleted file mode 100644 index 05bda556d..000000000 --- a/src/gdmuser/gdm-user-private.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2004-2005 James M. Cape . - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Private interfaces to the GdmUser object - */ - -#ifndef __GDM_USER_PRIVATE_H_ -#define __GDM_USER_PRIVATE_H_ - -#include - -#include "gdm-user.h" - -G_BEGIN_DECLS - -void _gdm_user_update_from_object_path (GdmUser *user, - const char *object_path); - -void _gdm_user_update_from_pwent (GdmUser *user, - const struct passwd *pwent); - -void _gdm_user_update_login_frequency (GdmUser *user, - guint64 login_frequency); - -void _gdm_user_add_session (GdmUser *user, - const char *session_id); -void _gdm_user_remove_session (GdmUser *user, - const char *session_id); - -G_END_DECLS - -#endif /* !__GDM_USER_PRIVATE__ */ diff --git a/src/gdmuser/gdm-user.c b/src/gdmuser/gdm-user.c deleted file mode 100644 index 0a592cc6a..000000000 --- a/src/gdmuser/gdm-user.c +++ /dev/null @@ -1,1099 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2004-2005 James M. Cape . - * Copyright (C) 2007-2008 William Jon McCann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "gdm-user-private.h" - -#define GDM_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_USER, GdmUserClass)) -#define GDM_IS_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_USER)) -#define GDM_USER_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), GDM_TYPE_USER, GdmUserClass)) - -#define GLOBAL_FACEDIR DATADIR "/faces" -#define MAX_FILE_SIZE 65536 - -#define ACCOUNTS_NAME "org.freedesktop.Accounts" -#define ACCOUNTS_USER_INTERFACE "org.freedesktop.Accounts.User" - -enum { - PROP_0, - PROP_IS_LOADED -}; - -enum { - CHANGED, - SESSIONS_CHANGED, - LAST_SIGNAL -}; - -struct _GdmUser { - GObject parent; - - DBusGConnection *connection; - DBusGProxy *accounts_proxy; - DBusGProxy *object_proxy; - DBusGProxyCall *get_all_call; - char *object_path; - - uid_t uid; - char *user_name; - char *real_name; - char *icon_file; - GList *sessions; - gulong login_frequency; - - guint is_loaded : 1; -}; - -struct _GdmUserClass -{ - GObjectClass parent_class; -}; - -static void gdm_user_finalize (GObject *object); -static gboolean check_user_file (const char *filename); - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (GdmUser, gdm_user, G_TYPE_OBJECT) - -static int -session_compare (const char *a, - const char *b) -{ - if (a == NULL) { - return 1; - } else if (b == NULL) { - return -1; - } - - return strcmp (a, b); -} - -void -_gdm_user_add_session (GdmUser *user, - const char *ssid) -{ - GList *li; - - g_return_if_fail (GDM_IS_USER (user)); - g_return_if_fail (ssid != NULL); - - li = g_list_find_custom (user->sessions, ssid, (GCompareFunc)session_compare); - if (li == NULL) { - g_debug ("GdmUser: adding session %s", ssid); - user->sessions = g_list_prepend (user->sessions, g_strdup (ssid)); - g_signal_emit (user, signals[SESSIONS_CHANGED], 0); - } else { - g_debug ("GdmUser: session already present: %s", ssid); - } -} - -void -_gdm_user_remove_session (GdmUser *user, - const char *ssid) -{ - GList *li; - - g_return_if_fail (GDM_IS_USER (user)); - g_return_if_fail (ssid != NULL); - - li = g_list_find_custom (user->sessions, ssid, (GCompareFunc)session_compare); - if (li != NULL) { - g_debug ("GdmUser: removing session %s", ssid); - g_free (li->data); - user->sessions = g_list_delete_link (user->sessions, li); - g_signal_emit (user, signals[SESSIONS_CHANGED], 0); - } else { - g_debug ("GdmUser: session not found: %s", ssid); - } -} - -guint -gdm_user_get_num_sessions (GdmUser *user) -{ - return g_list_length (user->sessions); -} - -static void -gdm_user_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_user_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GdmUser *user; - - user = GDM_USER (object); - - switch (prop_id) { - case PROP_IS_LOADED: - g_value_set_boolean (value, user->is_loaded); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_user_class_init (GdmUserClass *class) -{ - GObjectClass *gobject_class; - - gobject_class = G_OBJECT_CLASS (class); - - gobject_class->finalize = gdm_user_finalize; - gobject_class->set_property = gdm_user_set_property; - gobject_class->get_property = gdm_user_get_property; - - g_object_class_install_property (gobject_class, - PROP_IS_LOADED, - g_param_spec_boolean ("is-loaded", - NULL, - NULL, - FALSE, - G_PARAM_READABLE)); - - signals [CHANGED] = - g_signal_new ("changed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals [SESSIONS_CHANGED] = - g_signal_new ("sessions-changed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -gdm_user_init (GdmUser *user) -{ - GError *error; - - user->user_name = NULL; - user->real_name = NULL; - user->sessions = NULL; - - error = NULL; - user->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (user->connection == NULL) { - g_warning ("Couldn't connect to system bus: %s", error->message); - } -} - -static void -gdm_user_finalize (GObject *object) -{ - GdmUser *user; - - user = GDM_USER (object); - - g_free (user->user_name); - g_free (user->real_name); - g_free (user->icon_file); - g_free (user->object_path); - - if (user->accounts_proxy != NULL) { - g_object_unref (user->accounts_proxy); - } - - if (user->object_proxy != NULL) { - g_object_unref (user->object_proxy); - } - - if (user->connection != NULL) { - dbus_g_connection_unref (user->connection); - } - - if (G_OBJECT_CLASS (gdm_user_parent_class)->finalize) - (*G_OBJECT_CLASS (gdm_user_parent_class)->finalize) (object); -} - -static void -set_is_loaded (GdmUser *user, - gboolean is_loaded) -{ - if (user->is_loaded != is_loaded) { - user->is_loaded = is_loaded; - g_object_notify (G_OBJECT (user), "is-loaded"); - } -} - -/** - * _gdm_user_update_from_pwent: - * @user: the user object to update. - * @pwent: the user data to use. - * - * Updates the properties of @user using the data in @pwent. - **/ -void -_gdm_user_update_from_pwent (GdmUser *user, - const struct passwd *pwent) -{ - gchar *real_name = NULL; - gboolean changed; - - g_return_if_fail (GDM_IS_USER (user)); - g_return_if_fail (pwent != NULL); - g_return_if_fail (user->object_path == NULL); - - changed = FALSE; - - /* Display Name */ - if (pwent->pw_gecos && pwent->pw_gecos[0] != '\0') { - gchar *first_comma = NULL; - gchar *valid_utf8_name = NULL; - - if (g_utf8_validate (pwent->pw_gecos, -1, NULL)) { - valid_utf8_name = pwent->pw_gecos; - first_comma = strchr (valid_utf8_name, ','); - } else { - g_warning ("User %s has invalid UTF-8 in GECOS field. " - "It would be a good thing to check /etc/passwd.", - pwent->pw_name ? pwent->pw_name : ""); - } - - if (first_comma) { - real_name = g_strndup (valid_utf8_name, - (first_comma - valid_utf8_name)); - } else if (valid_utf8_name) { - real_name = g_strdup (valid_utf8_name); - } else { - real_name = NULL; - } - - if (real_name && real_name[0] == '\0') { - g_free (real_name); - real_name = NULL; - } - } else { - real_name = NULL; - } - - if (g_strcmp0 (real_name, user->real_name) != 0) { - g_free (user->real_name); - user->real_name = real_name; - changed = TRUE; - } else { - g_free (real_name); - } - - /* UID */ - if (pwent->pw_uid != user->uid) { - user->uid = pwent->pw_uid; - changed = TRUE; - } - - /* Username */ - if (g_strcmp0 (pwent->pw_name, user->user_name) != 0) { - g_free (user->icon_file); - user->icon_file = NULL; - if (pwent->pw_name != NULL) { - gboolean res; - - user->icon_file = g_build_filename (GDM_CACHE_DIR, pwent->pw_name, "face", NULL); - - res = check_user_file (user->icon_file); - if (!res) { - g_free (user->icon_file); - user->icon_file = g_build_filename (GLOBAL_FACEDIR, pwent->pw_name, NULL); - } - } - - g_free (user->user_name); - user->user_name = g_strdup (pwent->pw_name); - changed = TRUE; - } - - if (!user->is_loaded) { - set_is_loaded (user, TRUE); - } - - if (changed) { - g_signal_emit (user, signals[CHANGED], 0); - } -} - -/** - * _gdm_user_update_login_frequency: - * @user: the user object to update - * @login_frequency: the number of times the user has logged in - * - * Updates the login frequency of @user - **/ -void -_gdm_user_update_login_frequency (GdmUser *user, - guint64 login_frequency) -{ - g_return_if_fail (GDM_IS_USER (user)); - - if (login_frequency == user->login_frequency) { - return; - } - - user->login_frequency = login_frequency; - g_signal_emit (user, signals[CHANGED], 0); -} - -/** - * gdm_user_get_uid: - * @user: the user object to examine. - * - * Retrieves the ID of @user. - * - * Returns: (transfer none): a pointer to an array of characters which must not be modified or - * freed, or %NULL. - **/ - -gulong -gdm_user_get_uid (GdmUser *user) -{ - g_return_val_if_fail (GDM_IS_USER (user), -1); - - return user->uid; -} - -/** - * gdm_user_get_real_name: - * @user: the user object to examine. - * - * Retrieves a displayable name for @user. By default this is the real name - * of the user, but will fall back to the user name if there is no real name - * defined. - * - * Returns: (transfer none): a pointer to an array of characters which must not be modified or - * freed, or %NULL. - **/ -const char * -gdm_user_get_real_name (GdmUser *user) -{ - g_return_val_if_fail (GDM_IS_USER (user), NULL); - - if (user->real_name == NULL || - user->real_name[0] == '\0') { - return user->user_name; - } - - return user->real_name; -} - -/** - * gdm_user_get_user_name: - * @user: the user object to examine. - * - * Retrieves the login name of @user. - * - * Returns: (transfer none): a pointer to an array of characters which must not be modified or - * freed, or %NULL. - **/ - -const char * -gdm_user_get_user_name (GdmUser *user) -{ - g_return_val_if_fail (GDM_IS_USER (user), NULL); - - return user->user_name; -} - -/** - * gdm_user_get_login_frequency: - * @user: a #GdmUser - * - * Returns the number of times @user has logged in. - * - * Returns: the login frequency - */ -gulong -gdm_user_get_login_frequency (GdmUser *user) -{ - g_return_val_if_fail (GDM_IS_USER (user), 0); - - return user->login_frequency; -} - -int -gdm_user_collate (GdmUser *user1, - GdmUser *user2) -{ - const char *str1; - const char *str2; - gulong num1; - gulong num2; - guint len1; - guint len2; - - g_return_val_if_fail (GDM_IS_USER (user1), 0); - g_return_val_if_fail (GDM_IS_USER (user2), 0); - - num1 = user1->login_frequency; - num2 = user2->login_frequency; - - if (num1 > num2) { - return -1; - } - - if (num1 < num2) { - return 1; - } - - - len1 = g_list_length (user1->sessions); - len2 = g_list_length (user2->sessions); - - if (len1 > len2) { - return -1; - } - - if (len1 < len2) { - return 1; - } - - /* if login frequency is equal try names */ - if (user1->real_name != NULL) { - str1 = user1->real_name; - } else { - str1 = user1->user_name; - } - - if (user2->real_name != NULL) { - str2 = user2->real_name; - } else { - str2 = user2->user_name; - } - - if (str1 == NULL && str2 != NULL) { - return -1; - } - - if (str1 != NULL && str2 == NULL) { - return 1; - } - - if (str1 == NULL && str2 == NULL) { - return 0; - } - - return g_utf8_collate (str1, str2); -} - -static gboolean -check_user_file (const char *filename) -{ - gssize max_file_size = MAX_FILE_SIZE; - struct stat fileinfo; - - /* Exists/Readable? */ - if (stat (filename, &fileinfo) < 0) { - return FALSE; - } - - /* Is a regular file */ - if (G_UNLIKELY (!S_ISREG (fileinfo.st_mode))) { - return FALSE; - } - - /* Size is kosher? */ - if (G_UNLIKELY (fileinfo.st_size > max_file_size)) { - return FALSE; - } - - return TRUE; -} - -static void -rounded_rectangle (cairo_t *cr, - gdouble aspect, - gdouble x, - gdouble y, - gdouble corner_radius, - gdouble width, - gdouble height) -{ - gdouble radius; - gdouble degrees; - - radius = corner_radius / aspect; - degrees = G_PI / 180.0; - - cairo_new_sub_path (cr); - cairo_arc (cr, - x + width - radius, - y + radius, - radius, - -90 * degrees, - 0 * degrees); - cairo_arc (cr, - x + width - radius, - y + height - radius, - radius, - 0 * degrees, - 90 * degrees); - cairo_arc (cr, - x + radius, - y + height - radius, - radius, - 90 * degrees, - 180 * degrees); - cairo_arc (cr, - x + radius, - y + radius, - radius, - 180 * degrees, - 270 * degrees); - cairo_close_path (cr); -} - -static cairo_surface_t * -surface_from_pixbuf (GdkPixbuf *pixbuf) -{ - cairo_surface_t *surface; - cairo_t *cr; - - surface = cairo_image_surface_create (gdk_pixbuf_get_has_alpha (pixbuf) ? - CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf)); - cr = cairo_create (surface); - gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); - cairo_paint (cr); - cairo_destroy (cr); - - return surface; -} - -/** - * go_cairo_convert_data_to_pixbuf: - * @src: a pointer to pixel data in cairo format - * @dst: a pointer to pixel data in pixbuf format - * @width: image width - * @height: image height - * @rowstride: data rowstride - * - * Converts the pixel data stored in @src in CAIRO_FORMAT_ARGB32 cairo format - * to GDK_COLORSPACE_RGB pixbuf format and move them - * to @dst. If @src == @dst, pixel are converted in place. - **/ - -static void -go_cairo_convert_data_to_pixbuf (unsigned char *dst, - unsigned char const *src, - int width, - int height, - int rowstride) -{ - int i,j; - unsigned int t; - unsigned char a, b, c; - - g_return_if_fail (dst != NULL); - -#define MULT(d,c,a,t) G_STMT_START { t = (a)? c * 255 / a: 0; d = t;} G_STMT_END - - if (src == dst || src == NULL) { - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) { -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - MULT(a, dst[2], dst[3], t); - MULT(b, dst[1], dst[3], t); - MULT(c, dst[0], dst[3], t); - dst[0] = a; - dst[1] = b; - dst[2] = c; -#else - MULT(a, dst[1], dst[0], t); - MULT(b, dst[2], dst[0], t); - MULT(c, dst[3], dst[0], t); - dst[3] = dst[0]; - dst[0] = a; - dst[1] = b; - dst[2] = c; -#endif - dst += 4; - } - dst += rowstride - width * 4; - } - } else { - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) { -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - MULT(dst[0], src[2], src[3], t); - MULT(dst[1], src[1], src[3], t); - MULT(dst[2], src[0], src[3], t); - dst[3] = src[3]; -#else - MULT(dst[0], src[1], src[0], t); - MULT(dst[1], src[2], src[0], t); - MULT(dst[2], src[3], src[0], t); - dst[3] = src[0]; -#endif - src += 4; - dst += 4; - } - src += rowstride - width * 4; - dst += rowstride - width * 4; - } - } -#undef MULT -} - -static void -cairo_to_pixbuf (guint8 *src_data, - GdkPixbuf *dst_pixbuf) -{ - unsigned char *src; - unsigned char *dst; - guint w; - guint h; - guint rowstride; - - w = gdk_pixbuf_get_width (dst_pixbuf); - h = gdk_pixbuf_get_height (dst_pixbuf); - rowstride = gdk_pixbuf_get_rowstride (dst_pixbuf); - - dst = gdk_pixbuf_get_pixels (dst_pixbuf); - src = src_data; - - go_cairo_convert_data_to_pixbuf (dst, src, w, h, rowstride); -} - -static GdkPixbuf * -frame_pixbuf (GdkPixbuf *source) -{ - GdkPixbuf *dest; - cairo_t *cr; - cairo_surface_t *surface; - guint w; - guint h; - guint rowstride; - int frame_width; - double radius; - guint8 *data; - - frame_width = 2; - - w = gdk_pixbuf_get_width (source) + frame_width * 2; - h = gdk_pixbuf_get_height (source) + frame_width * 2; - radius = w / 10; - - dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - TRUE, - 8, - w, - h); - rowstride = gdk_pixbuf_get_rowstride (dest); - - - data = g_new0 (guint8, h * rowstride); - - surface = cairo_image_surface_create_for_data (data, - CAIRO_FORMAT_ARGB32, - w, - h, - rowstride); - cr = cairo_create (surface); - cairo_surface_destroy (surface); - - /* set up image */ - cairo_rectangle (cr, 0, 0, w, h); - cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); - cairo_fill (cr); - - rounded_rectangle (cr, - 1.0, - frame_width + 0.5, - frame_width + 0.5, - radius, - w - frame_width * 2 - 1, - h - frame_width * 2 - 1); - cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.3); - cairo_fill_preserve (cr); - - surface = surface_from_pixbuf (source); - cairo_set_source_surface (cr, surface, frame_width, frame_width); - cairo_fill (cr); - cairo_surface_destroy (surface); - - cairo_to_pixbuf (data, dest); - - cairo_destroy (cr); - g_free (data); - - return dest; -} - -/** - * gdm_user_is_logged_in: - * @user: a #GdmUser - * - * Returns whether or not #GdmUser is currently logged in. - * - * Returns: %TRUE or %FALSE - */ -gboolean -gdm_user_is_logged_in (GdmUser *user) -{ - return user->sessions != NULL; -} - -/** - * gdm_user_render_icon: - * @user: a #GdmUser - * @icon_size: the size to render the icon at - * - * Returns a #GdkPixbuf of the account icon belonging to @user - * at the pixel size specified by @icon_size. - * - * Returns: (transfer full): a #GdkPixbuf - */ -GdkPixbuf * -gdm_user_render_icon (GdmUser *user, - gint icon_size) -{ - GdkPixbuf *pixbuf; - GdkPixbuf *framed; - gboolean res; - GError *error; - - g_return_val_if_fail (GDM_IS_USER (user), NULL); - g_return_val_if_fail (icon_size > 12, NULL); - - pixbuf = NULL; - if (user->icon_file) { - res = check_user_file (user->icon_file); - if (res) { - pixbuf = gdk_pixbuf_new_from_file_at_size (user->icon_file, - icon_size, - icon_size, - NULL); - } else { - pixbuf = NULL; - } - } - - if (pixbuf != NULL) { - goto out; - } - - error = NULL; - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - - "avatar-default", - icon_size, - GTK_ICON_LOOKUP_FORCE_SIZE, - &error); - if (error) { - g_warning ("%s", error->message); - g_error_free (error); - } - out: - - if (pixbuf != NULL) { - framed = frame_pixbuf (pixbuf); - if (framed != NULL) { - g_object_unref (pixbuf); - pixbuf = framed; - } - } - - return pixbuf; -} - -/** - * gdm_user_get_icon_file: - * @user: a #GdmUser - * - * Returns the path to the account icon belonging to @user. - * - * Returns: (transfer none): a path to an icon - */ -const char * -gdm_user_get_icon_file (GdmUser *user) -{ - g_return_val_if_fail (GDM_IS_USER (user), NULL); - - return user->icon_file; -} - -/** - * gdm_user_get_object_path: - * @user: a #GdmUser - * - * Returns the user accounts service object path of @user, - * or %NULL if @user doesn't have an object path associated - * with it. - * - * Returns: (transfer none): the primary ConsoleKit session id of the user - */ -const char * -gdm_user_get_object_path (GdmUser *user) -{ - g_return_val_if_fail (GDM_IS_USER (user), NULL); - - return user->object_path; -} - -/** - * gdm_user_get_primary_session_id: - * @user: a #GdmUser - * - * Returns the primary ConsoleKit session id of @user, or %NULL if @user isn't - * logged in. - * - * Returns: (transfer none): the primary ConsoleKit session id of the user - */ -const char * -gdm_user_get_primary_session_id (GdmUser *user) -{ - if (!gdm_user_is_logged_in (user)) { - g_debug ("User %s is not logged in, so has no primary session", - gdm_user_get_user_name (user)); - return NULL; - } - - /* FIXME: better way to choose? */ - return user->sessions->data; -} - -static void -collect_props (const gchar *key, - const GValue *value, - GdmUser *user) -{ - gboolean handled = TRUE; - - if (strcmp (key, "Uid") == 0) { - user->uid = g_value_get_uint64 (value); - } else if (strcmp (key, "UserName") == 0) { - g_free (user->user_name); - user->user_name = g_value_dup_string (value); - } else if (strcmp (key, "RealName") == 0) { - g_free (user->real_name); - user->real_name = g_value_dup_string (value); - } else if (strcmp (key, "AccountType") == 0) { - /* ignore */ - } else if (strcmp (key, "Email") == 0) { - /* ignore */ - } else if (strcmp (key, "Language") == 0) { - /* ignore */ - } else if (strcmp (key, "Location") == 0) { - /* ignore */ - } else if (strcmp (key, "LoginFrequency") == 0) { - user->login_frequency = g_value_get_uint64 (value); - } else if (strcmp (key, "IconFile") == 0) { - gboolean res; - - g_free (user->icon_file); - user->icon_file = g_value_dup_string (value); - - res = check_user_file (user->icon_file); - if (!res) { - g_free (user->icon_file); - user->icon_file = g_build_filename (GLOBAL_FACEDIR, user->user_name, NULL); - } - } else if (strcmp (key, "Locked") == 0) { - /* ignore */ - } else if (strcmp (key, "AutomaticLogin") == 0) { - /* ignore */ - } else if (strcmp (key, "PasswordMode") == 0) { - /* ignore */ - } else if (strcmp (key, "PasswordHint") == 0) { - /* ignore */ - } else if (strcmp (key, "HomeDirectory") == 0) { - /* ignore */ - } else if (strcmp (key, "Shell") == 0) { - /* ignore */ - } else { - handled = FALSE; - } - - if (!handled) { - g_debug ("unhandled property %s", key); - } -} - -static void -on_get_all_finished (DBusGProxy *proxy, - DBusGProxyCall *call, - GdmUser *user) -{ - GError *error; - GHashTable *hash_table; - gboolean res; - - g_assert (user->get_all_call == call); - g_assert (user->object_proxy == proxy); - - error = NULL; - res = dbus_g_proxy_end_call (proxy, - call, - &error, - dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), - &hash_table, - G_TYPE_INVALID); - user->get_all_call = NULL; - user->object_proxy = NULL; - - if (! res) { - g_debug ("Error calling GetAll() when retrieving properties for %s: %s", - user->object_path, error->message); - g_error_free (error); - goto out; - } - g_hash_table_foreach (hash_table, (GHFunc) collect_props, user); - g_hash_table_unref (hash_table); - - if (!user->is_loaded) { - set_is_loaded (user, TRUE); - } - - g_signal_emit (user, signals[CHANGED], 0); - -out: - g_object_unref (proxy); -} - -static gboolean -update_info (GdmUser *user) -{ - DBusGProxy *proxy; - DBusGProxyCall *call; - - proxy = dbus_g_proxy_new_for_name (user->connection, - ACCOUNTS_NAME, - user->object_path, - DBUS_INTERFACE_PROPERTIES); - - call = dbus_g_proxy_begin_call (proxy, - "GetAll", - (DBusGProxyCallNotify) - on_get_all_finished, - user, - NULL, - G_TYPE_STRING, - ACCOUNTS_USER_INTERFACE, - G_TYPE_INVALID); - - if (call == NULL) { - g_warning ("GdmUser: failed to make GetAll call"); - goto failed; - } - - user->get_all_call = call; - user->object_proxy = proxy; - return TRUE; - -failed: - if (proxy != NULL) { - g_object_unref (proxy); - } - - return FALSE; -} - -static void -changed_handler (DBusGProxy *proxy, - gpointer *data) -{ - GdmUser *user = GDM_USER (data); - - update_info (user); -} - -/** - * _gdm_user_update_from_object_path: - * @user: the user object to update. - * @object_path: the object path of the user to use. - * - * Updates the properties of @user from the accounts service via - * the object path in @object_path. - **/ -void -_gdm_user_update_from_object_path (GdmUser *user, - const char *object_path) -{ - g_return_if_fail (GDM_IS_USER (user)); - g_return_if_fail (object_path != NULL); - g_return_if_fail (user->object_path == NULL); - - user->object_path = g_strdup (object_path); - - user->accounts_proxy = dbus_g_proxy_new_for_name (user->connection, - ACCOUNTS_NAME, - user->object_path, - ACCOUNTS_USER_INTERFACE); - dbus_g_proxy_set_default_timeout (user->accounts_proxy, INT_MAX); - dbus_g_proxy_add_signal (user->accounts_proxy, "Changed", G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (user->accounts_proxy, "Changed", - G_CALLBACK (changed_handler), user, NULL); - - if (!update_info (user)) { - g_warning ("Couldn't update info for user with object path %s", object_path); - } -} - -/** - * gdm_user_is_loaded: - * @user: a #GdmUser - * - * Determines whether or not the user object is loaded and ready to read from. - * #GdmUserManager:is-loaded property must be %TRUE before calling - * gdm_user_manager_list_users() - * - * Returns: %TRUE or %FALSE - */ -gboolean -gdm_user_is_loaded (GdmUser *user) -{ - return user->is_loaded; -} diff --git a/src/gdmuser/gdm-user.h b/src/gdmuser/gdm-user.h deleted file mode 100644 index 2f2616ba5..000000000 --- a/src/gdmuser/gdm-user.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2004-2005 James M. Cape . - * Copyright (C) 2007-2008 William Jon McCann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Facade object for user data, owned by GdmUserManager - */ - -#ifndef __GDM_USER_H__ -#define __GDM_USER_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define GDM_TYPE_USER (gdm_user_get_type ()) -#define GDM_USER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDM_TYPE_USER, GdmUser)) -#define GDM_IS_USER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDM_TYPE_USER)) - -typedef struct _GdmUser GdmUser; -typedef struct _GdmUserClass GdmUserClass; - -GType gdm_user_get_type (void) G_GNUC_CONST; - -GdmUser *gdm_user_new_from_object_path (const char *path); -const char *gdm_user_get_object_path (GdmUser *user); - -gulong gdm_user_get_uid (GdmUser *user); -const char *gdm_user_get_user_name (GdmUser *user); -const char *gdm_user_get_real_name (GdmUser *user); -guint gdm_user_get_num_sessions (GdmUser *user); -gboolean gdm_user_is_logged_in (GdmUser *user); -gulong gdm_user_get_login_frequency (GdmUser *user); -const char *gdm_user_get_icon_file (GdmUser *user); -const char *gdm_user_get_primary_session_id (GdmUser *user); - -GdkPixbuf *gdm_user_render_icon (GdmUser *user, - gint icon_size); - -gint gdm_user_collate (GdmUser *user1, - GdmUser *user2); -gboolean gdm_user_is_loaded (GdmUser *user); - -G_END_DECLS - -#endif diff --git a/src/main.c b/src/main.c index 116f00f68..23c33a52a 100644 --- a/src/main.c +++ b/src/main.c @@ -534,7 +534,7 @@ main (int argc, char **argv) /* Disable debug spew from various libraries */ g_log_set_handler ("Gvc", G_LOG_LEVEL_DEBUG, muted_log_handler, NULL); - g_log_set_handler ("GdmUser", G_LOG_LEVEL_DEBUG, + g_log_set_handler ("AccountsService", G_LOG_LEVEL_DEBUG, muted_log_handler, NULL); g_log_set_handler ("Bluetooth", G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_MESSAGE, muted_log_handler, NULL); diff --git a/tools/build/gnome-shell-build-setup.sh b/tools/build/gnome-shell-build-setup.sh index 62888741e..fef109edd 100644 --- a/tools/build/gnome-shell-build-setup.sh +++ b/tools/build/gnome-shell-build-setup.sh @@ -68,7 +68,7 @@ fi # Non-devel packages needed by gnome-shell and its deps: # glxinfo, gstreamer-plugins-base, gstreamer-plugins-good, # gvfs, python, pygobject, gnome-python (gconf), -# icon-naming-utils, zenity, libtasn1-tools +# icon-naming-utils, zenity, libtasn1-tools accountsservice if test "x$system" = xUbuntu -o "x$system" = xDebian -o "x$system" = xLinuxMint ; then reqd=" @@ -84,7 +84,7 @@ if test "x$system" = xUbuntu -o "x$system" = xDebian -o "x$system" = xLinuxMint libltdl-dev libvorbis-dev iso-codes libgnome-keyring-dev libusb-1.0-0-dev libupower-glib-dev libcups2-dev libproxy-dev libdb-dev libproxy-dev libsqlite3-dev libgudev-1.0-dev libsane-dev libwebkitgtk-3.0-0 - libx11-xcb-dev libupower-glib-dev + libx11-xcb-dev libupower-glib-dev accountsservice " if apt-cache show libxcb-util0-dev > /dev/null 2> /dev/null; then @@ -117,7 +117,7 @@ fi if test "x$system" = xFedora ; then reqd=" - binutils curl gcc gcc-c++ make + binutils curl gcc gcc-c++ make accountsservice automake bison flex gettext git gnome-common gnome-doc-utils gperf gvfs intltool libtool pkgconfig dbus-glib-devel gnome-desktop-devel gnome-menus-devel gnome-python2-gconf jasper-devel libffi-devel libical-devel libjpeg-devel libpng-devel