diff --git a/.accountsservice.metadata b/.accountsservice.metadata index 794dd8f..9ffdd86 100644 --- a/.accountsservice.metadata +++ b/.accountsservice.metadata @@ -1 +1 @@ -e9d13e6970c52e168eb7d6dc8441a3abafed3dfa SOURCES/accountsservice-0.6.45.tar.xz +8d59b9cdc4121b34748442ee653b92d60607f2cb SOURCES/accountsservice-0.6.50.tar.xz diff --git a/.gitignore b/.gitignore index 677f17f..32db008 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/accountsservice-0.6.45.tar.xz +SOURCES/accountsservice-0.6.50.tar.xz diff --git a/SOURCES/0001-daemon-don-t-treat-explicitly-requested-users-as-cac.patch b/SOURCES/0001-daemon-don-t-treat-explicitly-requested-users-as-cac.patch deleted file mode 100644 index fba593f..0000000 --- a/SOURCES/0001-daemon-don-t-treat-explicitly-requested-users-as-cac.patch +++ /dev/null @@ -1,739 +0,0 @@ -From 59235d291c9aac5f68e17cc927f142cf5e532e46 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 4 May 2017 12:04:05 -0400 -Subject: [PATCH] daemon: don't treat explicitly requested users as "cached" - -The ListCachedUsers method currently returns users that have -been explicitly requested by a client. It's weird that merely -querying a user can make it show up in login screen user lists. -Furthermore, UncacheUser is broken since commit -177509e9460b149ecbf85e75c930be2ea00b7d05 because the user has -been explicitly requested in order to uncache it. So trying -to uncache a user inadvertently caches the user. - -This commit fixes that. ---- - src/daemon.c | 71 +++++++++++++++++++++++++++++++++++++++--------------------- - src/user.c | 17 +++++++++++++++ - src/user.h | 3 +++ - 3 files changed, 66 insertions(+), 25 deletions(-) - -diff --git a/src/daemon.c b/src/daemon.c -index 312394a..6e3e4b3 100644 ---- a/src/daemon.c -+++ b/src/daemon.c -@@ -329,100 +329,108 @@ entry_generator_requested_users (Daemon *daemon, - while (node != NULL) { - const char *name; - - name = node->data; - node = node->next; - - *state = node; - - if (!g_hash_table_lookup (users, name)) { - pwent = getpwnam (name); - if (pwent == NULL) { - g_debug ("user '%s' requested previously but not present on system", name); - } else { - *shadow_entry = getspnam (pwent->pw_name); - - return pwent; - } - } - } - } - - /* Last iteration */ - - *state = NULL; - return NULL; - } - - static void - load_entries (Daemon *daemon, - GHashTable *users, -- gboolean allow_system_users, -+ gboolean explicitly_requested, - EntryGeneratorFunc entry_generator) - { - gpointer generator_state = NULL; - struct passwd *pwent; - struct spwd *spent = NULL; - User *user = NULL; - - g_assert (entry_generator != NULL); - - for (;;) { - spent = NULL; - pwent = entry_generator (daemon, users, &generator_state, &spent); - if (pwent == NULL) - break; - - /* Skip system users... */ -- if (!allow_system_users && !user_classify_is_human (pwent->pw_uid, pwent->pw_name, pwent->pw_shell, spent? spent->sp_pwdp : NULL)) { -+ if (!explicitly_requested && !user_classify_is_human (pwent->pw_uid, pwent->pw_name, pwent->pw_shell, spent? spent->sp_pwdp : NULL)) { - g_debug ("skipping user: %s", pwent->pw_name); - continue; - } - -- /* ignore duplicate entries */ -- if (g_hash_table_lookup (users, pwent->pw_name)) { -- continue; -- } -+ /* Only process users that haven't been processed yet. -+ * We do always make sure entries get promoted -+ * to "cached" status if they are supposed to be -+ */ -+ -+ user = g_hash_table_lookup (users, pwent->pw_name); - -- user = g_hash_table_lookup (daemon->priv->users, pwent->pw_name); - if (user == NULL) { -- user = user_new (daemon, pwent->pw_uid); -- } else { -- g_object_ref (user); -- } -+ user = g_hash_table_lookup (daemon->priv->users, pwent->pw_name); -+ if (user == NULL) { -+ user = user_new (daemon, pwent->pw_uid); -+ } else { -+ g_object_ref (user); -+ } - -- /* freeze & update users not already in the new list */ -- g_object_freeze_notify (G_OBJECT (user)); -- user_update_from_pwent (user, pwent, spent); -+ /* freeze & update users not already in the new list */ -+ g_object_freeze_notify (G_OBJECT (user)); -+ user_update_from_pwent (user, pwent, spent); - -- g_hash_table_insert (users, g_strdup (user_get_user_name (user)), user); -- g_debug ("loaded user: %s", user_get_user_name (user)); -+ g_hash_table_insert (users, g_strdup (user_get_user_name (user)), user); -+ g_debug ("loaded user: %s", user_get_user_name (user)); -+ } -+ -+ if (!explicitly_requested) { -+ user_set_cached (user, TRUE); -+ } - } - - /* Generator should have cleaned up */ - g_assert (generator_state == NULL); - } - - static GHashTable * - create_users_hash_table (void) - { - return g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - } - - static void - reload_users (Daemon *daemon) - { - GHashTable *users; - GHashTable *old_users; - GHashTable *local; - GHashTableIter iter; - gpointer name; - User *user; - - /* Track the users that we saw during our (re)load */ - users = create_users_hash_table (); - - /* - * NOTE: As we load data from all the sources, notifies are -@@ -432,71 +440,79 @@ reload_users (Daemon *daemon) - - /* Load the local users into our hash table */ - load_entries (daemon, users, FALSE, entry_generator_fgetpwent); - local = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_iter_init (&iter, users); - while (g_hash_table_iter_next (&iter, &name, NULL)) - g_hash_table_add (local, name); - - /* and add users to hash table that were explicitly requested */ - load_entries (daemon, users, TRUE, entry_generator_requested_users); - - /* Now add/update users from other sources, possibly non-local */ - load_entries (daemon, users, FALSE, entry_generator_cachedir); - - wtmp_helper_update_login_frequencies (users); - - /* Mark which users are local, which are not */ - g_hash_table_iter_init (&iter, users); - while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) - user_update_local_account_property (user, g_hash_table_lookup (local, name) != NULL); - - g_hash_table_destroy (local); - - /* Swap out the users */ - old_users = daemon->priv->users; - daemon->priv->users = users; - - /* Remove all the old users */ - g_hash_table_iter_init (&iter, old_users); - while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) { -- if (!g_hash_table_lookup (users, name)) { -+ User *refreshed_user; -+ -+ refreshed_user = g_hash_table_lookup (users, name); -+ -+ if (!refreshed_user || !user_get_cached (refreshed_user)) { - user_unregister (user); - accounts_accounts_emit_user_deleted (ACCOUNTS_ACCOUNTS (daemon), - user_get_object_path (user)); - } - } - - /* Register all the new users */ - g_hash_table_iter_init (&iter, users); - while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) { -- if (!g_hash_table_lookup (old_users, name)) { -+ User *stale_user; -+ -+ stale_user = g_hash_table_lookup (old_users, name); -+ -+ if (!stale_user || !user_get_cached (stale_user) && user_get_cached (user)) { - user_register (user); - accounts_accounts_emit_user_added (ACCOUNTS_ACCOUNTS (daemon), - user_get_object_path (user)); - } - g_object_thaw_notify (G_OBJECT (user)); - } - - g_hash_table_destroy (old_users); - } - - static gboolean - reload_users_timeout (Daemon *daemon) - { - reload_users (daemon); - daemon->priv->reload_id = 0; - - return FALSE; - } - - static gboolean load_autologin (Daemon *daemon, - gchar **name, - gboolean *enabled, - GError **error); - - static gboolean - reload_autologin_timeout (Daemon *daemon) - { - gboolean enabled; - gchar *name = NULL; - GError *error = NULL; -@@ -911,60 +927,65 @@ list_user_data_new (Daemon *daemon, - static void - list_user_data_free (ListUserData *data) - { - g_object_unref (data->daemon); - g_free (data); - } - - static gboolean - finish_list_cached_users (gpointer user_data) - { - ListUserData *data = user_data; - GPtrArray *object_paths; - GHashTableIter iter; - const gchar *name; - User *user; - uid_t uid; - const gchar *shell; - - object_paths = g_ptr_array_new (); - - g_hash_table_iter_init (&iter, data->daemon->priv->users); - while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&user)) { - uid = user_get_uid (user); - shell = user_get_shell (user); - - if (!user_classify_is_human (uid, name, shell, NULL)) { - g_debug ("user %s %ld excluded", name, (long) uid); - continue; - } - -+ if (!user_get_cached (user)) { -+ g_debug ("user %s %ld not cached", name, (long) uid); -+ continue; -+ } -+ - g_debug ("user %s %ld not excluded", name, (long) uid); - g_ptr_array_add (object_paths, (gpointer) user_get_object_path (user)); - } - g_ptr_array_add (object_paths, NULL); - - accounts_accounts_complete_list_cached_users (NULL, data->context, (const gchar * const *) object_paths->pdata); - - g_ptr_array_free (object_paths, TRUE); - - list_user_data_free (data); - - return FALSE; - } - - static gboolean - daemon_list_cached_users (AccountsAccounts *accounts, - GDBusMethodInvocation *context) - { - Daemon *daemon = (Daemon*)accounts; - ListUserData *data; - - data = list_user_data_new (daemon, context); - - if (daemon->priv->reload_id > 0) { - /* reload in progress, wait a bit */ - g_idle_add (finish_list_cached_users, data); - } - else { - finish_list_cached_users (data); - } -@@ -1151,123 +1172,123 @@ daemon_cache_user (AccountsAccounts *accounts, - static void - daemon_uncache_user_authorized_cb (Daemon *daemon, - User *dummy, - GDBusMethodInvocation *context, - gpointer data) - { - const gchar *user_name = data; - gchar *filename; - User *user; - - sys_log (context, "uncache user '%s'", user_name); - - user = daemon_local_find_user_by_name (daemon, user_name); - if (user == NULL) { - throw_error (context, ERROR_USER_DOES_NOT_EXIST, - "No user with the name %s found", user_name); - return; - } - - /* Always use the canonical user name looked up */ - user_name = user_get_user_name (user); - - filename = g_build_filename (USERDIR, user_name, NULL); - g_remove (filename); - g_free (filename); - - filename = g_build_filename (ICONDIR, user_name, NULL); - g_remove (filename); - g_free (filename); - -+ user_set_cached (user, FALSE); -+ - accounts_accounts_complete_uncache_user (NULL, context); - - queue_reload_users (daemon); - } - - static gboolean - daemon_uncache_user (AccountsAccounts *accounts, - GDBusMethodInvocation *context, - const gchar *user_name) - { - Daemon *daemon = (Daemon*)accounts; - - daemon_local_check_auth (daemon, - NULL, - "org.freedesktop.accounts.user-administration", - TRUE, - daemon_uncache_user_authorized_cb, - context, - g_strdup (user_name), - g_free); - - return TRUE; - } - - typedef struct { - uid_t uid; - gboolean remove_files; - } DeleteUserData; - - static void - daemon_delete_user_authorized_cb (Daemon *daemon, - User *dummy, - GDBusMethodInvocation *context, - gpointer data) - - { - DeleteUserData *ud = data; - GError *error; - gchar *filename; - struct passwd *pwent; - const gchar *argv[6]; -+ User *user; - - pwent = getpwuid (ud->uid); - - if (pwent == NULL) { - throw_error (context, ERROR_USER_DOES_NOT_EXIST, "No user with uid %d found", ud->uid); - - return; - } - - sys_log (context, "delete user '%s' (%d)", pwent->pw_name, ud->uid); - -- if (daemon->priv->autologin != NULL) { -- User *user; -+ user = daemon_local_find_user_by_id (daemon, ud->uid); - -- user = daemon_local_find_user_by_id (daemon, ud->uid); -+ if (user != NULL) { -+ user_set_cached (user, FALSE); - -- g_assert (user != NULL); -- -- if (daemon->priv->autologin == user) { -+ if (daemon->priv->autologin == user) { - daemon_local_set_automatic_login (daemon, user, FALSE, NULL); - } -- - } - - filename = g_build_filename (USERDIR, pwent->pw_name, NULL); - g_remove (filename); - g_free (filename); - - filename = g_build_filename (ICONDIR, pwent->pw_name, NULL); - g_remove (filename); - g_free (filename); - - argv[0] = "/usr/sbin/userdel"; - if (ud->remove_files) { - argv[1] = "-f"; - argv[2] = "-r"; - argv[3] = "--"; - argv[4] = pwent->pw_name; - argv[5] = NULL; - } - else { - argv[1] = "-f"; - argv[2] = "--"; - argv[3] = pwent->pw_name; - argv[4] = NULL; - } - - error = NULL; - if (!spawn_with_login_uid (context, argv, &error)) { - throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); - g_error_free (error); - return; -diff --git a/src/user.c b/src/user.c -index 802d07a..a83cfe4 100644 ---- a/src/user.c -+++ b/src/user.c -@@ -83,60 +83,61 @@ struct User { - GKeyFile *keyfile; - - uid_t uid; - gid_t gid; - gchar *user_name; - gchar *real_name; - AccountType account_type; - PasswordMode password_mode; - gchar *password_hint; - gchar *home_dir; - gchar *shell; - gchar *email; - gchar *language; - gchar *x_session; - gchar *location; - guint64 login_frequency; - gint64 login_time; - gint64 expiration_time; - gint64 last_change_time; - gint64 min_days_between_changes; - gint64 max_days_between_changes; - gint64 days_to_warn; - gint64 days_after_expiration_until_lock; - GVariant *login_history; - gchar *icon_file; - gchar *default_icon_file; - gboolean locked; - gboolean automatic_login; - gboolean system_account; - gboolean local_account; -+ gboolean cached; - - guint *extension_ids; - guint n_extension_ids; - }; - - typedef struct UserClass - { - AccountsUserSkeletonClass parent_class; - } UserClass; - - static void user_accounts_user_iface_init (AccountsUserIface *iface); - - G_DEFINE_TYPE_WITH_CODE (User, user, ACCOUNTS_TYPE_USER_SKELETON, G_IMPLEMENT_INTERFACE (ACCOUNTS_TYPE_USER, user_accounts_user_iface_init)); - - static gint - account_type_from_pwent (struct passwd *pwent) - { - struct group *grp; - gint i; - - if (pwent->pw_uid == 0) { - g_debug ("user is root so account type is administrator"); - return ACCOUNT_TYPE_ADMINISTRATOR; - } - - grp = getgrnam (ADMIN_GROUP); - if (grp == NULL) { - g_debug (ADMIN_GROUP " group not found"); - return ACCOUNT_TYPE_STANDARD; - } -@@ -339,109 +340,112 @@ user_update_from_keyfile (User *user, - user->location = s; - g_object_notify (G_OBJECT (user), "location"); - } - - s = g_key_file_get_string (keyfile, "User", "PasswordHint", NULL); - if (s != NULL) { - g_free (user->password_hint); - user->password_hint = s; - g_object_notify (G_OBJECT (user), "password-hint"); - } - - s = g_key_file_get_string (keyfile, "User", "Icon", NULL); - if (s != NULL) { - g_free (user->icon_file); - user->icon_file = s; - g_object_notify (G_OBJECT (user), "icon-file"); - } - - if (g_key_file_has_key (keyfile, "User", "SystemAccount", NULL)) { - gboolean system_account; - - system_account = g_key_file_get_boolean (keyfile, "User", "SystemAccount", NULL); - if (system_account != user->system_account) { - user->system_account = system_account; - g_object_notify (G_OBJECT (user), "system-account"); - } - } - - g_clear_pointer (&user->keyfile, g_key_file_unref); - user->keyfile = g_key_file_ref (keyfile); -+ user_set_cached (user, TRUE); - - g_object_thaw_notify (G_OBJECT (user)); - } - - void - user_update_local_account_property (User *user, - gboolean local) - { - if (local == user->local_account) - return; - user->local_account = local; - g_object_notify (G_OBJECT (user), "local-account"); - } - - void - user_update_system_account_property (User *user, - gboolean system) - { - if (system == user->system_account) - return; - user->system_account = system; - g_object_notify (G_OBJECT (user), "system-account"); - } - - static void - user_save_to_keyfile (User *user, - GKeyFile *keyfile) - { - g_key_file_remove_group (keyfile, "User", NULL); - - if (user->email) - g_key_file_set_string (keyfile, "User", "Email", user->email); - - if (user->language) - g_key_file_set_string (keyfile, "User", "Language", user->language); - - if (user->x_session) - g_key_file_set_string (keyfile, "User", "XSession", user->x_session); - - if (user->location) - g_key_file_set_string (keyfile, "User", "Location", user->location); - - if (user->password_hint) - g_key_file_set_string (keyfile, "User", "PasswordHint", user->password_hint); - - if (user->icon_file) - g_key_file_set_string (keyfile, "User", "Icon", user->icon_file); - - g_key_file_set_boolean (keyfile, "User", "SystemAccount", user->system_account); -+ -+ user_set_cached (user, TRUE); - } - - static void - save_extra_data (User *user) - { - gchar *filename; - gchar *data; - GError *error; - - user_save_to_keyfile (user, user->keyfile); - - error = NULL; - data = g_key_file_to_data (user->keyfile, NULL, &error); - if (error == NULL) { - filename = g_build_filename (USERDIR, - user->user_name, - NULL); - g_file_set_contents (filename, data, -1, &error); - g_free (filename); - g_free (data); - } - if (error) { - g_warning ("Saving data for user %s failed: %s", - user->user_name, error->message); - g_error_free (error); - } - } - - static void - move_extra_data (const gchar *old_name, -@@ -810,60 +814,73 @@ user_get_user_name (User *user) - gboolean - user_get_system_account (User *user) - { - return user->system_account; - } - - gboolean - user_get_local_account (User *user) - { - return user->local_account; - } - - const gchar * - user_get_object_path (User *user) - { - return user->object_path; - } - - uid_t - user_get_uid (User *user) - { - return user->uid; - } - - const gchar * - user_get_shell(User *user) - { - return user->shell; - } - -+gboolean -+user_get_cached (User *user) -+{ -+ return user->cached; -+} -+ -+void -+user_set_cached (User *user, -+ gboolean cached) -+{ -+ user->cached = cached; -+} -+ - static void - throw_error (GDBusMethodInvocation *context, - gint error_code, - const gchar *format, - ...) - { - va_list args; - gchar *message; - - va_start (args, format); - message = g_strdup_vprintf (format, args); - va_end (args); - - g_dbus_method_invocation_return_error (context, ERROR, error_code, "%s", message); - - g_free (message); - } - - static void - user_change_real_name_authorized_cb (Daemon *daemon, - User *user, - GDBusMethodInvocation *context, - gpointer data) - - { - gchar *name = data; - GError *error; - const gchar *argv[6]; - - if (g_strcmp0 (user->real_name, name) != 0) { -diff --git a/src/user.h b/src/user.h -index 22548f9..39c6f13 100644 ---- a/src/user.h -+++ b/src/user.h -@@ -36,47 +36,50 @@ G_BEGIN_DECLS - #define IS_USER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TYPE_USER)) - - typedef enum { - ACCOUNT_TYPE_STANDARD, - ACCOUNT_TYPE_ADMINISTRATOR, - #define ACCOUNT_TYPE_LAST ACCOUNT_TYPE_ADMINISTRATOR - } AccountType; - - typedef enum { - PASSWORD_MODE_REGULAR, - PASSWORD_MODE_SET_AT_LOGIN, - PASSWORD_MODE_NONE, - #define PASSWORD_MODE_LAST PASSWORD_MODE_NONE - } PasswordMode; - - /* local methods */ - - GType user_get_type (void) G_GNUC_CONST; - User * user_new (Daemon *daemon, - uid_t uid); - - void user_update_from_pwent (User *user, - struct passwd *pwent, - struct spwd *spent); - void user_update_from_keyfile (User *user, - GKeyFile *keyfile); - void user_update_local_account_property (User *user, - gboolean local); - void user_update_system_account_property (User *user, - gboolean system); -+gboolean user_get_cached (User *user); -+void user_set_cached (User *user, -+ gboolean cached); - - void user_register (User *user); - void user_unregister (User *user); - void user_changed (User *user); - - void user_save (User *user); - - const gchar * user_get_user_name (User *user); - gboolean user_get_system_account (User *user); - gboolean user_get_local_account (User *user); - const gchar * user_get_object_path (User *user); - uid_t user_get_uid (User *user); - const gchar * user_get_shell (User *user); - - G_END_DECLS - - #endif --- -2.12.2 - diff --git a/SOURCES/0001-lib-don-t-set-loaded-state-until-seat-is-fetched.patch b/SOURCES/0001-lib-don-t-set-loaded-state-until-seat-is-fetched.patch new file mode 100644 index 0000000..5d6777d --- /dev/null +++ b/SOURCES/0001-lib-don-t-set-loaded-state-until-seat-is-fetched.patch @@ -0,0 +1,90 @@ +From c7fa612023a163e8b2352e1170c6df3fceb19b27 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 19 Jul 2018 13:14:09 -0400 +Subject: [PATCH] lib: don't set loaded state until seat is fetched + +At the moment we set is-loaded on the user-manager +object as soon as we start fetching the seat, but +we should waiting until the seat is fetched, so +that can_switch() will return the correct value +if the caller waited until the loaded signal +to use it. + +This commit changes the >= to > which I believe +was the original intention anyway. + +https://bugs.freedesktop.org/show_bug.cgi?id=107298 +--- + src/libaccountsservice/act-user-manager.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c +index 325421b..e7e26b1 100644 +--- a/src/libaccountsservice/act-user-manager.c ++++ b/src/libaccountsservice/act-user-manager.c +@@ -2355,61 +2355,61 @@ act_user_manager_list_users (ActUserManager *manager) + queue_load_seat_incrementally (manager); + } + + retval = NULL; + g_hash_table_foreach (manager->priv->normal_users_by_name, listify_hash_values_hfunc, &retval); + + return g_slist_sort (retval, (GCompareFunc) act_user_collate); + } + + static void + maybe_set_is_loaded (ActUserManager *manager) + { + if (manager->priv->is_loaded) { + g_debug ("ActUserManager: already loaded, so not setting loaded property"); + return; + } + + if (manager->priv->getting_sessions) { + g_debug ("ActUserManager: GetSessions call pending, so not setting loaded property"); + return; + } + + if (manager->priv->new_users_inhibiting_load != NULL) { + g_debug ("ActUserManager: Loading new users, so not setting loaded property"); + return; + } + + /* Don't set is_loaded yet unless the seat is already loaded enough + * or failed to load. + */ +- if (manager->priv->seat.state >= ACT_USER_MANAGER_SEAT_STATE_GET_ID) { ++ if (manager->priv->seat.state > ACT_USER_MANAGER_SEAT_STATE_GET_ID) { + g_debug ("ActUserManager: Seat loaded, so now setting loaded property"); + } else if (manager->priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_UNLOADED) { + g_debug ("ActUserManager: Seat wouldn't load, so giving up on it and setting loaded property"); + } else { + g_debug ("ActUserManager: Seat still actively loading, so not setting loaded property"); + return; + } + + set_is_loaded (manager, TRUE); + } + + + 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 +-- +2.17.1 + diff --git a/SOURCES/0001-lib-move-g_object_ref-call-for-clarity.patch b/SOURCES/0001-lib-move-g_object_ref-call-for-clarity.patch deleted file mode 100644 index e57aa0c..0000000 --- a/SOURCES/0001-lib-move-g_object_ref-call-for-clarity.patch +++ /dev/null @@ -1,92 +0,0 @@ -From e1672162fc37c37fb09450991316fbfe22029882 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 27 Sep 2017 10:39:05 -0400 -Subject: [PATCH 01/13] lib: move g_object_ref call for clarity - -create_new_user creates an ActUser object and returns it to -the caller. Before returning the object, it also adds the -object to a list of "new users" to track when it fully loads. - -It's idiomatic to return the original ref to the caller of -a constructor, but create_new_user instead gives the original -reference to the new_users list. Their's no practical difference, -but this commit moves the ref around for clarity. ---- - src/libaccountsservice/act-user-manager.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c -index 914a1c9..d866725 100644 ---- a/src/libaccountsservice/act-user-manager.c -+++ b/src/libaccountsservice/act-user-manager.c -@@ -816,65 +816,65 @@ static void - add_session_for_user (ActUserManager *manager, - ActUser *user, - const char *ssid, - gboolean is_ours) - { - g_hash_table_insert (manager->priv->sessions, - g_strdup (ssid), - g_object_ref (user)); - - _act_user_add_session (user, ssid, is_ours); - g_debug ("ActUserManager: added session for %s", describe_user (user)); - } - - static void - set_has_multiple_users (ActUserManager *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 ActUser * - create_new_user (ActUserManager *manager) - { - ActUser *user; - - user = g_object_new (ACT_TYPE_USER, NULL); - -- manager->priv->new_users = g_slist_prepend (manager->priv->new_users, user); -+ manager->priv->new_users = g_slist_prepend (manager->priv->new_users, g_object_ref (user)); - - g_signal_connect_object (user, "notify::is-loaded", G_CALLBACK (on_new_user_loaded), manager, 0); - -- return g_object_ref (user); -+ return user; - } - - static void - add_user (ActUserManager *manager, - ActUser *user) - { - const char *object_path; - - g_debug ("ActUserManager: tracking user '%s'", act_user_get_user_name (user)); - if (act_user_is_system_account (user)) { - g_hash_table_insert (manager->priv->system_users_by_name, - g_strdup (act_user_get_user_name (user)), - g_object_ref (user)); - } else { - g_hash_table_insert (manager->priv->normal_users_by_name, - g_strdup (act_user_get_user_name (user)), - g_object_ref (user)); - } - - object_path = act_user_get_object_path (user); - if (object_path != NULL) { - g_hash_table_replace (manager->priv->users_by_object_path, - (gpointer) object_path, - g_object_ref (user)); - } - - g_signal_connect_object (user, - "sessions-changed", - G_CALLBACK (on_user_sessions_changed), - manager, 0); --- -2.14.1 - diff --git a/SOURCES/0002-lib-leak-fix.patch b/SOURCES/0002-lib-leak-fix.patch deleted file mode 100644 index 93cb907..0000000 --- a/SOURCES/0002-lib-leak-fix.patch +++ /dev/null @@ -1,93 +0,0 @@ -From bb381997525a1ff74f1bbac3556d566b62f3ef1b Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 27 Sep 2017 10:41:47 -0400 -Subject: [PATCH 02/13] lib: leak fix - -If a new user is added by accounts service, we currently leak -a reference to it. That leads to transient user objects living -longer than they're supposed which uses memory and produces -excess bus traffic. ---- - src/libaccountsservice/act-user-manager.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c -index d866725..c8d0443 100644 ---- a/src/libaccountsservice/act-user-manager.c -+++ b/src/libaccountsservice/act-user-manager.c -@@ -1088,68 +1088,71 @@ add_new_user_for_object_path (const char *object_path, - user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path); - - if (user != NULL) { - g_debug ("ActUserManager: tracking existing %s with object path %s", - describe_user (user), object_path); - return user; - } - - user = find_new_user_with_object_path (manager, object_path); - - if (user != NULL) { - g_debug ("ActUserManager: tracking existing (but very recently added) %s with object path %s", - describe_user (user), object_path); - return user; - } - - g_debug ("ActUserManager: tracking new user with object path %s", object_path); - - user = create_new_user (manager); - _act_user_update_from_object_path (user, object_path); - - return user; - } - - static void - on_new_user_in_accounts_service (GDBusProxy *proxy, - const char *object_path, - gpointer user_data) - { - ActUserManager *manager = ACT_USER_MANAGER (user_data); -+ ActUser *user; - - if (!manager->priv->is_loaded) { - g_debug ("ActUserManager: ignoring new user in accounts service with object path %s since not loaded yet", object_path); - return; - } - - g_debug ("ActUserManager: new user in accounts service with object path %s", object_path); -- add_new_user_for_object_path (object_path, manager); -+ user = add_new_user_for_object_path (object_path, manager); -+ -+ g_object_unref (user); - } - - static void - on_user_removed_in_accounts_service (GDBusProxy *proxy, - const char *object_path, - gpointer user_data) - { - ActUserManager *manager = ACT_USER_MANAGER (user_data); - ActUser *user; - - user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path); - - if (user == NULL) { - g_debug ("ActUserManager: ignoring untracked user %s", object_path); - return; - } else { - g_debug ("ActUserManager: 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 (GObject *object, - GAsyncResult *result, - gpointer data) - { - ConsoleKitManager *proxy = CONSOLE_KIT_MANAGER (object); --- -2.14.1 - diff --git a/SOURCES/0003-lib-another-leak-fix.patch b/SOURCES/0003-lib-another-leak-fix.patch deleted file mode 100644 index 511d16f..0000000 --- a/SOURCES/0003-lib-another-leak-fix.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 889561310b794f0443dc5c520b09151fe4b260ec Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 27 Sep 2017 10:43:33 -0400 -Subject: [PATCH 03/13] lib: another leak fix - -If a user gets removed from account service before it's fully loaded, -then we neglect to drop its reference on the new_users lists. - -This commit fixes that. ---- - src/libaccountsservice/act-user-manager.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c -index c8d0443..ac06e24 100644 ---- a/src/libaccountsservice/act-user-manager.c -+++ b/src/libaccountsservice/act-user-manager.c -@@ -1108,71 +1108,77 @@ add_new_user_for_object_path (const char *object_path, - - return user; - } - - static void - on_new_user_in_accounts_service (GDBusProxy *proxy, - const char *object_path, - gpointer user_data) - { - ActUserManager *manager = ACT_USER_MANAGER (user_data); - ActUser *user; - - if (!manager->priv->is_loaded) { - g_debug ("ActUserManager: ignoring new user in accounts service with object path %s since not loaded yet", object_path); - return; - } - - g_debug ("ActUserManager: new user in accounts service with object path %s", object_path); - user = add_new_user_for_object_path (object_path, manager); - - g_object_unref (user); - } - - static void - on_user_removed_in_accounts_service (GDBusProxy *proxy, - const char *object_path, - gpointer user_data) - { - ActUserManager *manager = ACT_USER_MANAGER (user_data); - ActUser *user; -+ GSList *node; - - user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path); - - if (user == NULL) { - g_debug ("ActUserManager: ignoring untracked user %s", object_path); - return; - } else { - g_debug ("ActUserManager: tracked user %s removed from accounts service", object_path); - } - -- manager->priv->new_users = g_slist_remove (manager->priv->new_users, user); -+ node = g_slist_find (manager->priv->new_users, user); -+ if (node != NULL) { -+ 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); -+ } - - remove_user (manager, user); - } - - static void - on_get_current_session_finished (GObject *object, - GAsyncResult *result, - gpointer data) - { - ConsoleKitManager *proxy = CONSOLE_KIT_MANAGER (object); - ActUserManager *manager = data; - GError *error = NULL; - char *session_id; - - g_assert (manager->priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_ID); - - if (!console_kit_manager_call_get_current_session_finish (proxy, &session_id, result, &error)) { - 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); - - goto out; - } - - manager->priv->seat.session_id = session_id; --- -2.14.1 - diff --git a/SOURCES/0004-daemon-don-t-send-spurious-change-signals-when-wtmp-.patch b/SOURCES/0004-daemon-don-t-send-spurious-change-signals-when-wtmp-.patch deleted file mode 100644 index 98ea0c5..0000000 --- a/SOURCES/0004-daemon-don-t-send-spurious-change-signals-when-wtmp-.patch +++ /dev/null @@ -1,116 +0,0 @@ -From d93c4a3be8a56d55ecfc814eeef5c1bf1efe33de Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 27 Sep 2017 11:01:28 -0400 -Subject: [PATCH 04/13] daemon: don't send spurious change signals when wtmp - changes - -Right now, we unintentionally send out a changed signal for -every tracked user anytime wtmp changes. - -This commit fixes that. ---- - src/wtmp-helper.c | 22 +++++++++++++++++++--- - 1 file changed, 19 insertions(+), 3 deletions(-) - -diff --git a/src/wtmp-helper.c b/src/wtmp-helper.c -index 787480b..a1edffe 100644 ---- a/src/wtmp-helper.c -+++ b/src/wtmp-helper.c -@@ -138,75 +138,91 @@ wtmp_helper_update_login_frequencies (GHashTable *users) - &key, &value)) { - accounting = g_new (UserAccounting, 1); - accounting->frequency = 0; - accounting->previous_logins = NULL; - - g_hash_table_insert (login_hash, g_strdup (wtmp_entry->ut_user), accounting); - } else { - accounting = value; - } - - accounting->frequency++; - accounting->time = wtmp_entry->ut_tv.tv_sec; - - /* Add zero logout time to change it later on logout record */ - previous_login = g_new (UserPreviousLogin, 1); - previous_login->id = g_strdup (wtmp_entry->ut_line); - previous_login->login_time = wtmp_entry->ut_tv.tv_sec; - previous_login->logout_time = 0; - accounting->previous_logins = g_list_prepend (accounting->previous_logins, previous_login); - - g_hash_table_insert (logout_hash, g_strdup (wtmp_entry->ut_line), previous_login); - } - - /* Last iteration */ - endutxent (); - - g_hash_table_iter_init (&iter, login_hash); - while (g_hash_table_iter_next (&iter, &key, &value)) { - UserAccounting *accounting = (UserAccounting *) value; - UserPreviousLogin *previous_login; -+ gboolean changed = FALSE; -+ guint64 old_login_frequency; -+ guint64 old_login_time; - - user = g_hash_table_lookup (users, key); - if (user == NULL) { - g_list_free_full (accounting->previous_logins, (GDestroyNotify) user_previous_login_free); - continue; - } - -- g_object_set (user, "login-frequency", accounting->frequency, NULL); -- g_object_set (user, "login-time", accounting->time, NULL); -+ g_object_get (user, -+ "login-frequency", &old_login_frequency, -+ "login-time", &old_login_time, -+ NULL); -+ -+ if (old_login_frequency != accounting->frequency) { -+ g_object_set (user, "login-frequency", accounting->frequency, NULL); -+ changed = TRUE; -+ } -+ -+ if (old_login_time != accounting->time) { -+ g_object_set (user, "login-time", accounting->time, NULL); -+ changed = TRUE; -+ } - - builder = g_variant_builder_new (G_VARIANT_TYPE ("a(xxa{sv})")); - for (l = g_list_last (accounting->previous_logins); l != NULL; l = l->prev) { - previous_login = l->data; - - builder2 = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); - g_variant_builder_add (builder2, "{sv}", "type", g_variant_new_string (previous_login->id)); - g_variant_builder_add (builder, "(xxa{sv})", previous_login->login_time, previous_login->logout_time, builder2); - g_variant_builder_unref (builder2); - } - g_object_set (user, "login-history", g_variant_new ("a(xxa{sv})", builder), NULL); - g_variant_builder_unref (builder); - g_list_free_full (accounting->previous_logins, (GDestroyNotify) user_previous_login_free); - -- user_changed (user); -+ if (changed) -+ user_changed (user); - } - - g_hash_table_unref (login_hash); - g_hash_table_unref (logout_hash); - } - - const gchar * - wtmp_helper_get_path_for_monitor (void) - { - return PATH_WTMP; - } - - #else /* HAVE_UTMPX_H */ - - const gchar * - wtmp_helper_get_path_for_monitor (void) - { - return NULL; - } - - #endif /* HAVE_UTMPX_H */ --- -2.14.1 - diff --git a/SOURCES/0005-lib-consolidate-change-notification.patch b/SOURCES/0005-lib-consolidate-change-notification.patch deleted file mode 100644 index 1df5d42..0000000 --- a/SOURCES/0005-lib-consolidate-change-notification.patch +++ /dev/null @@ -1,228 +0,0 @@ -From 42bd3bd41d69100308a22df43482569f6ab53dbe Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 27 Sep 2017 14:44:48 -0400 -Subject: [PATCH 05/13] lib: consolidate change notification - -if the daemon sends out multiple change notifications for a user -because several properties changed in quick succession, try to -batch them up, and only update info at the end. ---- - src/libaccountsservice/act-user.c | 20 +++++++++++++++++++- - 1 file changed, 19 insertions(+), 1 deletion(-) - -diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c -index dbb9b53..17acacb 100644 ---- a/src/libaccountsservice/act-user.c -+++ b/src/libaccountsservice/act-user.c -@@ -113,60 +113,62 @@ struct _ActUser { - char *object_path; - - uid_t uid; - char *user_name; - char *real_name; - char *password_hint; - char *home_dir; - char *shell; - char *email; - char *location; - char *icon_file; - char *language; - char *x_session; - GList *our_sessions; - GList *other_sessions; - int login_frequency; - gint64 login_time; - GVariant *login_history; - - ActUserAccountType account_type; - ActUserPasswordMode password_mode; - - guint uid_set : 1; - - guint is_loaded : 1; - guint locked : 1; - guint automatic_login : 1; - guint system_account : 1; - guint local_account : 1; - guint nonexistent : 1; -+ -+ guint update_info_timeout_id; - }; - - struct _ActUserClass - { - GObjectClass parent_class; - }; - - static void act_user_finalize (GObject *object); - - static guint signals[LAST_SIGNAL] = { 0 }; - - G_DEFINE_TYPE (ActUser, act_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 - _act_user_add_session (ActUser *user, - const char *ssid, - gboolean is_ours) -@@ -573,60 +575,64 @@ act_user_finalize (GObject *object) - - g_free (user->user_name); - g_free (user->real_name); - g_free (user->icon_file); - g_free (user->language); - g_free (user->object_path); - g_free (user->password_hint); - g_free (user->home_dir); - g_free (user->shell); - g_free (user->email); - g_free (user->location); - if (user->login_history) - g_variant_unref (user->login_history); - - if (user->accounts_proxy != NULL) { - g_object_unref (user->accounts_proxy); - } - - if (user->object_proxy != NULL) { - g_object_unref (user->object_proxy); - } - - if (user->get_all_cancellable != NULL) { - g_object_unref (user->get_all_cancellable); - } - - if (user->connection != NULL) { - g_object_unref (user->connection); - } - -+ if (user->update_info_timeout_id != 0) { -+ g_source_remove (user->update_info_timeout_id); -+ } -+ - if (G_OBJECT_CLASS (act_user_parent_class)->finalize) - (*G_OBJECT_CLASS (act_user_parent_class)->finalize) (object); - } - - static void - set_is_loaded (ActUser *user, - gboolean is_loaded) - { - if (user->is_loaded != is_loaded) { - user->is_loaded = is_loaded; - g_object_notify (G_OBJECT (user), "is-loaded"); - } - } - - /** - * act_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. - **/ - - uid_t - act_user_get_uid (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), -1); - - return user->uid; -@@ -1339,67 +1345,79 @@ on_get_all_finished (GObject *object, - g_variant_unref (res); - - if (!user->is_loaded) { - set_is_loaded (user, TRUE); - } - - g_signal_emit (user, signals[CHANGED], 0); - } - - static void - update_info (ActUser *user) - { - g_assert (G_IS_DBUS_PROXY (user->object_proxy)); - - if (user->get_all_cancellable != NULL) { - g_cancellable_cancel (user->get_all_cancellable); - g_clear_object (&user->get_all_cancellable); - } - - user->get_all_cancellable = g_cancellable_new (); - g_dbus_proxy_call (user->object_proxy, - "GetAll", - g_variant_new ("(s)", ACCOUNTS_USER_INTERFACE), - G_DBUS_CALL_FLAGS_NONE, - -1, - user->get_all_cancellable, - on_get_all_finished, - user); - } - -+static gboolean -+on_timeout_update_info (ActUser *user) -+{ -+ update_info (user); -+ user->update_info_timeout_id = 0; -+ -+ return G_SOURCE_REMOVE; -+} -+ - static void - changed_handler (AccountsUser *object, - gpointer *data) - { - ActUser *user = ACT_USER (data); - -- update_info (user); -+ if (user->update_info_timeout_id != 0) -+ return; -+ -+ user->update_info_timeout_id = g_timeout_add (250, (GSourceFunc) on_timeout_update_info, user); - } - - /** - * _act_user_update_as_nonexistent: - * @user: the user object to update. - * - * Set's the 'non-existent' property of @user to #TRUE - * Can only be called before the user is loaded. - **/ - void - _act_user_update_as_nonexistent (ActUser *user) - { - g_return_if_fail (ACT_IS_USER (user)); - g_return_if_fail (!act_user_is_loaded (user)); - g_return_if_fail (user->object_path == NULL); - - user->nonexistent = TRUE; - g_object_notify (G_OBJECT (user), "nonexistent"); - - set_is_loaded (user, TRUE); - } - - /** - * _act_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. - **/ --- -2.14.1 - diff --git a/SOURCES/0006-daemon-add-new-HasMultipleUsers-and-HasNoUsers-prope.patch b/SOURCES/0006-daemon-add-new-HasMultipleUsers-and-HasNoUsers-prope.patch deleted file mode 100644 index ffe254c..0000000 --- a/SOURCES/0006-daemon-add-new-HasMultipleUsers-and-HasNoUsers-prope.patch +++ /dev/null @@ -1,271 +0,0 @@ -From dc41728b9c4ec35fb7bd41cdc646b77dcb41f6dd Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 2 Oct 2017 15:45:01 -0400 -Subject: [PATCH 06/13] daemon: add new HasMultipleUsers and HasNoUsers - properties - -Every gnome-shell instance wants to know if the system has multiple -users or not, in order to know whether or not to show the -'Switch User' feature in the menu. - -accountsservice doesn't provide this information directly, though, -so libaccountsservice instead requests a list of all users on the -system and counts the provided list, filtering out system users. - -This is a lot of work for every gnome-shell instance to do, when -it doesn't actually need the list of users at all. - -This adds a new property HasMultipleUsers which libaccountsservice -can watch for instead. For good measure, this commit also adds a -HasNoUsers boolean which can be used to know whether or not to start -gnome-initial-setup. ---- - data/org.freedesktop.Accounts.xml | 20 ++++++++++++++++++++ - src/daemon.c | 24 +++++++++++++++++++++--- - 2 files changed, 41 insertions(+), 3 deletions(-) - -diff --git a/data/org.freedesktop.Accounts.xml b/data/org.freedesktop.Accounts.xml -index 692540a..ed7db50 100644 ---- a/data/org.freedesktop.Accounts.xml -+++ b/data/org.freedesktop.Accounts.xml -@@ -197,32 +197,52 @@ - - Emitted when a user is added. - - - - - - - - Object path of the user that was deleted. - - - - - Emitted when a user is deleted. - - - - - - - - - - The version of the running daemon. - - - - - -+ -+ -+ -+ -+ Whether or not the system has no users -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ Whether or not the system has multiple users -+ -+ -+ -+ -+ - - -diff --git a/src/daemon.c b/src/daemon.c -index 6e3e4b3..a4e18df 100644 ---- a/src/daemon.c -+++ b/src/daemon.c -@@ -35,60 +35,61 @@ - #include - #include - #include - - #include - #include - #include - #include - #include - #include - - #include "user-classify.h" - #include "wtmp-helper.h" - #include "daemon.h" - #include "util.h" - - #define PATH_PASSWD "/etc/passwd" - #define PATH_SHADOW "/etc/shadow" - #define PATH_GROUP "/etc/group" - #define PATH_GDM_CUSTOM "/etc/gdm/custom.conf" - - enum { - PROP_0, - PROP_DAEMON_VERSION - }; - - struct DaemonPrivate { - GDBusConnection *bus_connection; - - GHashTable *users; -+ gsize number_of_normal_users; - GList *explicitly_requested_users; - - User *autologin; - - GFileMonitor *passwd_monitor; - GFileMonitor *shadow_monitor; - GFileMonitor *group_monitor; - GFileMonitor *gdm_monitor; - GFileMonitor *wtmp_monitor; - - guint reload_id; - guint autologin_id; - - PolkitAuthority *authority; - GHashTable *extension_ifaces; - }; - - typedef struct passwd * (* EntryGeneratorFunc) (Daemon *, GHashTable *, gpointer *, struct spwd **shadow_entry); - - static void daemon_accounts_accounts_iface_init (AccountsAccountsIface *iface); - - G_DEFINE_TYPE_WITH_CODE (Daemon, daemon, ACCOUNTS_TYPE_ACCOUNTS_SKELETON, G_IMPLEMENT_INTERFACE (ACCOUNTS_TYPE_ACCOUNTS, daemon_accounts_accounts_iface_init)); - - #define DAEMON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_DAEMON, DaemonPrivate)) - - static const GDBusErrorEntry accounts_error_entries[] = - { - { ERROR_FAILED, "org.freedesktop.Accounts.Error.Failed" }, - { ERROR_USER_EXISTS, "org.freedesktop.Accounts.Error.UserExists" }, - { ERROR_USER_DOES_NOT_EXIST, "org.freedesktop.Accounts.Error.UserDoesNotExist" }, -@@ -395,98 +396,115 @@ load_entries (Daemon *daemon, - - /* freeze & update users not already in the new list */ - g_object_freeze_notify (G_OBJECT (user)); - user_update_from_pwent (user, pwent, spent); - - g_hash_table_insert (users, g_strdup (user_get_user_name (user)), user); - g_debug ("loaded user: %s", user_get_user_name (user)); - } - - if (!explicitly_requested) { - user_set_cached (user, TRUE); - } - } - - /* Generator should have cleaned up */ - g_assert (generator_state == NULL); - } - - static GHashTable * - create_users_hash_table (void) - { - return g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - } - - static void - reload_users (Daemon *daemon) - { -+ AccountsAccounts *accounts = ACCOUNTS_ACCOUNTS (daemon); -+ gboolean had_no_users, has_no_users, had_multiple_users, has_multiple_users; - GHashTable *users; - GHashTable *old_users; - GHashTable *local; - GHashTableIter iter; -+ gsize number_of_normal_users = 0; - gpointer name; - User *user; - - /* Track the users that we saw during our (re)load */ - users = create_users_hash_table (); - - /* - * NOTE: As we load data from all the sources, notifies are - * frozen in load_entries() and then thawed as we process - * them below. - */ - - /* Load the local users into our hash table */ - load_entries (daemon, users, FALSE, entry_generator_fgetpwent); - local = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_iter_init (&iter, users); - while (g_hash_table_iter_next (&iter, &name, NULL)) - g_hash_table_add (local, name); - - /* and add users to hash table that were explicitly requested */ - load_entries (daemon, users, TRUE, entry_generator_requested_users); - - /* Now add/update users from other sources, possibly non-local */ - load_entries (daemon, users, FALSE, entry_generator_cachedir); - - wtmp_helper_update_login_frequencies (users); - -- /* Mark which users are local, which are not */ -+ /* Count the non-system users. Mark which users are local, which are not. */ - g_hash_table_iter_init (&iter, users); -- while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) -+ while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) { -+ if (!user_get_system_account (user)) -+ number_of_normal_users++; - user_update_local_account_property (user, g_hash_table_lookup (local, name) != NULL); -- -+ } - g_hash_table_destroy (local); - -+ had_no_users = accounts_accounts_get_has_no_users (accounts); -+ has_no_users = number_of_normal_users == 0; -+ -+ if (had_no_users != has_no_users) -+ accounts_accounts_set_has_no_users (accounts, has_no_users); -+ -+ had_multiple_users = accounts_accounts_get_has_multiple_users (accounts); -+ has_multiple_users = number_of_normal_users > 1; -+ -+ if (had_multiple_users != has_multiple_users) -+ accounts_accounts_set_has_multiple_users (accounts, has_multiple_users); -+ - /* Swap out the users */ - old_users = daemon->priv->users; - daemon->priv->users = users; - - /* Remove all the old users */ - g_hash_table_iter_init (&iter, old_users); - while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) { - User *refreshed_user; - - refreshed_user = g_hash_table_lookup (users, name); - - if (!refreshed_user || !user_get_cached (refreshed_user)) { - user_unregister (user); - accounts_accounts_emit_user_deleted (ACCOUNTS_ACCOUNTS (daemon), - user_get_object_path (user)); - } - } - - /* Register all the new users */ - g_hash_table_iter_init (&iter, users); - while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) { - User *stale_user; - - stale_user = g_hash_table_lookup (old_users, name); - - if (!stale_user || !user_get_cached (stale_user) && user_get_cached (user)) { - user_register (user); - accounts_accounts_emit_user_added (ACCOUNTS_ACCOUNTS (daemon), - user_get_object_path (user)); - } --- -2.14.1 - diff --git a/SOURCES/0007-lib-use-new-has-multiple-users-property-from-account.patch b/SOURCES/0007-lib-use-new-has-multiple-users-property-from-account.patch deleted file mode 100644 index b623df0..0000000 --- a/SOURCES/0007-lib-use-new-has-multiple-users-property-from-account.patch +++ /dev/null @@ -1,327 +0,0 @@ -From 7849fa559cdcc197524135295bdb8e8aa13e2c13 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 2 Oct 2017 16:17:43 -0400 -Subject: [PATCH 07/13] lib: use new has-multiple-users property from - accountsservice - -This commit changes accountsservice to use the new has-multiple-users -property provided by the daemon. ---- - src/libaccountsservice/act-user-manager.c | 27 ++++++++++----------------- - 1 file changed, 10 insertions(+), 17 deletions(-) - -diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c -index ac06e24..30bbd78 100644 ---- a/src/libaccountsservice/act-user-manager.c -+++ b/src/libaccountsservice/act-user-manager.c -@@ -856,146 +856,130 @@ add_user (ActUserManager *manager, - { - const char *object_path; - - g_debug ("ActUserManager: tracking user '%s'", act_user_get_user_name (user)); - if (act_user_is_system_account (user)) { - g_hash_table_insert (manager->priv->system_users_by_name, - g_strdup (act_user_get_user_name (user)), - g_object_ref (user)); - } else { - g_hash_table_insert (manager->priv->normal_users_by_name, - g_strdup (act_user_get_user_name (user)), - g_object_ref (user)); - } - - object_path = act_user_get_object_path (user); - if (object_path != NULL) { - g_hash_table_replace (manager->priv->users_by_object_path, - (gpointer) object_path, - g_object_ref (user)); - } - - g_signal_connect_object (user, - "sessions-changed", - G_CALLBACK (on_user_sessions_changed), - manager, 0); - g_signal_connect_object (user, - "changed", - G_CALLBACK (on_user_changed), - manager, 0); - -- if (g_hash_table_size (manager->priv->normal_users_by_name) > 1) { -- set_has_multiple_users (manager, TRUE); -- } -- - if (manager->priv->is_loaded) { - g_debug ("ActUserManager: loaded, so emitting user-added signal"); - g_signal_emit (manager, signals[USER_ADDED], 0, user); - } else { - g_debug ("ActUserManager: not yet loaded, so not emitting user-added signal"); - } - } - - static void - remove_user (ActUserManager *manager, - ActUser *user) - { - g_debug ("ActUserManager: no longer tracking user '%s' (with object path %s)", - act_user_get_user_name (user), - act_user_get_object_path (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 (act_user_get_object_path (user) != NULL) { - g_hash_table_remove (manager->priv->users_by_object_path, act_user_get_object_path (user)); - } - if (act_user_get_user_name (user) != NULL) { - g_hash_table_remove (manager->priv->normal_users_by_name, act_user_get_user_name (user)); - g_hash_table_remove (manager->priv->system_users_by_name, act_user_get_user_name (user)); - - } - -- if (g_hash_table_size (manager->priv->normal_users_by_name) <= 1) { -- set_has_multiple_users (manager, FALSE); -- } -- - if (manager->priv->is_loaded) { - g_debug ("ActUserManager: loaded, so emitting user-removed signal"); - g_signal_emit (manager, signals[USER_REMOVED], 0, user); - } else { - g_debug ("ActUserManager: not yet loaded, so not emitting user-removed signal"); - } - - g_debug ("ActUserManager: user '%s' (with object path %s) now removed", - act_user_get_user_name (user), - act_user_get_object_path (user)); - g_object_unref (user); - } - - static void - update_user (ActUserManager *manager, - ActUser *user) - { - const char *username; - - g_debug ("ActUserManager: updating %s", describe_user (user)); - - username = act_user_get_user_name (user); - if (g_hash_table_lookup (manager->priv->system_users_by_name, username) != NULL) { - if (!act_user_is_system_account (user)) { - g_debug ("ActUserManager: %s is no longer a system account, treating as normal user", - describe_user (user)); - g_hash_table_insert (manager->priv->normal_users_by_name, - g_strdup (act_user_get_user_name (user)), - g_object_ref (user)); - g_hash_table_remove (manager->priv->system_users_by_name, username); - g_signal_emit (manager, signals[USER_ADDED], 0, user); -- -- if (g_hash_table_size (manager->priv->normal_users_by_name) > 1) { -- set_has_multiple_users (manager, TRUE); -- } - } - } else { - if (act_user_is_system_account (user)) { - g_debug ("ActUserManager: %s is no longer a normal account, treating as system user", - describe_user (user)); - g_hash_table_insert (manager->priv->system_users_by_name, - g_strdup (act_user_get_user_name (user)), - g_object_ref (user)); - g_hash_table_remove (manager->priv->normal_users_by_name, username); - g_signal_emit (manager, signals[USER_REMOVED], 0, user); -- -- if (g_hash_table_size (manager->priv->normal_users_by_name) <= 1) { -- set_has_multiple_users (manager, FALSE); -- } - } - } - } - - static ActUser * - lookup_user_by_name (ActUserManager *manager, - const char *username) - { - ActUser *user; - - user = g_hash_table_lookup (manager->priv->normal_users_by_name, username); - - if (user == NULL) { - user = g_hash_table_lookup (manager->priv->system_users_by_name, username); - } - - return user; - } - - static void - on_new_user_loaded (ActUser *user, - GParamSpec *pspec, - ActUserManager *manager) - { - const char *username; - ActUser *old_user; - - if (!act_user_is_loaded (user)) { - g_debug ("ActUserManager: %s loaded function called when not loaded", - describe_user (user)); -@@ -2682,89 +2666,92 @@ set_include_usernames (ActUserManager *manager, - } - - static void - set_exclude_usernames (ActUserManager *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 - act_user_manager_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) - { - ActUserManager *self; - - self = ACT_USER_MANAGER (object); - - switch (prop_id) { - 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; -+ case PROP_HAS_MULTIPLE_USERS: -+ set_has_multiple_users (self, g_value_get_boolean (value)); -+ break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static void - act_user_manager_class_init (ActUserManagerClass *klass) - { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = act_user_manager_finalize; - object_class->get_property = act_user_manager_get_property; - object_class->set_property = act_user_manager_set_property; - - g_object_class_install_property (object_class, - PROP_IS_LOADED, - g_param_spec_boolean ("is-loaded", - "Is loaded", - "Determines whether or not the manager object is loaded and ready to read from.", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, - PROP_HAS_MULTIPLE_USERS, - g_param_spec_boolean ("has-multiple-users", - "Has multiple users", - "Whether more than one normal user is present", - FALSE, -- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); -+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, - PROP_INCLUDE_USERNAMES_LIST, - g_param_spec_pointer ("include-usernames-list", - "Include usernames list", - "Usernames who are specifically included", - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_EXCLUDE_USERNAMES_LIST, - g_param_spec_pointer ("exclude-usernames-list", - "Exclude usernames list", - "Usernames who are specifically excluded", - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * ActUserManager::user-added: - * @gobject: the object which received the signal - * @user: the #ActUser that was added - * - * Emitted when a user is added to the user manager. - */ - signals [USER_ADDED] = - g_signal_new ("user-added", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ActUserManagerClass, user_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, ACT_TYPE_USER); - /** -@@ -2865,60 +2852,66 @@ act_user_manager_init (ActUserManager *manager) - - error = NULL; - manager->priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &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; - } - - manager->priv->accounts_proxy = accounts_accounts_proxy_new_sync (manager->priv->connection, - G_DBUS_PROXY_FLAGS_NONE, - ACCOUNTS_NAME, - ACCOUNTS_PATH, - NULL, - &error); - if (manager->priv->accounts_proxy == NULL) { - if (error != NULL) { - g_warning ("Failed to create accounts proxy: %s", error->message); - g_error_free (error); - } else { - g_warning ("Failed to create_accounts_proxy"); - } - return; - } - g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (manager->priv->accounts_proxy), G_MAXINT); - -+ g_object_bind_property (G_OBJECT (manager->priv->accounts_proxy), -+ "has-multiple-users", -+ G_OBJECT (manager), -+ "has-multiple-users", -+ G_BINDING_SYNC_CREATE); -+ - g_signal_connect (manager->priv->accounts_proxy, - "user-added", - G_CALLBACK (on_new_user_in_accounts_service), - manager); - g_signal_connect (manager->priv->accounts_proxy, - "user-deleted", - G_CALLBACK (on_user_removed_in_accounts_service), - manager); - - manager->priv->seat.state = ACT_USER_MANAGER_SEAT_STATE_UNLOADED; - } - - static void - act_user_manager_finalize (GObject *object) - { - ActUserManager *manager; - GSList *node; - - g_debug ("ActUserManager: finalizing user manager"); - - g_return_if_fail (object != NULL); - g_return_if_fail (ACT_IS_USER_MANAGER (object)); - - manager = ACT_USER_MANAGER (object); - - g_return_if_fail (manager->priv != NULL); - - g_slist_foreach (manager->priv->new_sessions, - (GFunc) unload_new_session, NULL); - g_slist_free (manager->priv->new_sessions); --- -2.14.1 - diff --git a/SOURCES/0008-lib-factor-user-loading-functions-into-helpers.patch b/SOURCES/0008-lib-factor-user-loading-functions-into-helpers.patch deleted file mode 100644 index df19f31..0000000 --- a/SOURCES/0008-lib-factor-user-loading-functions-into-helpers.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 86048b515f2f2edcea0f2aab2abf5e15f7b777d6 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 3 Oct 2017 09:58:42 -0400 -Subject: [PATCH 08/13] lib: factor user loading functions into helpers - -Right now, we process ListCachedUser results open coded. - -This commit moves the processing to helper functions. ---- - src/libaccountsservice/act-user-manager.c | 85 +++++++++++++++++-------------- - 1 file changed, 48 insertions(+), 37 deletions(-) - -diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c -index 30bbd78..556b070 100644 ---- a/src/libaccountsservice/act-user-manager.c -+++ b/src/libaccountsservice/act-user-manager.c -@@ -1473,124 +1473,135 @@ find_user_in_accounts_service (ActUserManager *manager, - switch (request->type) { - case ACT_USER_MANAGER_FETCH_USER_FROM_USERNAME_REQUEST: - accounts_accounts_call_find_user_by_name (manager->priv->accounts_proxy, - request->username, - NULL, - on_find_user_by_name_finished, - request); - break; - case ACT_USER_MANAGER_FETCH_USER_FROM_ID_REQUEST: - accounts_accounts_call_find_user_by_id (manager->priv->accounts_proxy, - request->uid, - NULL, - on_find_user_by_id_finished, - request); - break; - - } - } - - static void - set_is_loaded (ActUserManager *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 (GObject *object, -- GAsyncResult *result, -- gpointer data) -+load_user_paths (ActUserManager *manager, -+ const char * const * user_paths) - { -- AccountsAccounts *proxy = ACCOUNTS_ACCOUNTS (object); -- ActUserManager *manager = data; -- gchar **user_paths; -- GError *error = NULL; -- -- manager->priv->listing_cached_users = FALSE; -- if (!accounts_accounts_call_list_cached_users_finish (proxy, &user_paths, result, &error)) { -- g_debug ("ActUserManager: ListCachedUsers failed: %s", error->message); -- g_error_free (error); -- -- g_object_unref (manager->priv->accounts_proxy); -- manager->priv->accounts_proxy = NULL; -- -- g_debug ("ActUserManager: unrefing manager owned by failed ListCachedUsers call"); -- g_object_unref (manager); -- return; -- } -- - /* We now have a batch of unloaded users that we know about. Once that initial - * batch is loaded up, we can mark the manager as loaded. - * - * (see on_new_user_loaded) - */ -- if (g_strv_length (user_paths) > 0) { -+ if (g_strv_length ((char **) user_paths) > 0) { - int i; - - g_debug ("ActUserManager: ListCachedUsers finished, will set loaded property after list is fully loaded"); - for (i = 0; user_paths[i] != NULL; i++) { - ActUser *user; - - user = add_new_user_for_object_path (user_paths[i], manager); - if (!manager->priv->is_loaded) { - manager->priv->new_users_inhibiting_load = g_slist_prepend (manager->priv->new_users_inhibiting_load, user); - } - } - } else { - g_debug ("ActUserManager: ListCachedUsers finished with empty list, maybe setting loaded property now"); - maybe_set_is_loaded (manager); - } -+} - -- g_strfreev (user_paths); -+static void -+load_included_usernames (ActUserManager *manager) -+{ -+ GSList *l; - - /* 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) { -- ActUser *user; -+ for (l = manager->priv->include_usernames; l != NULL; l = l->next) { -+ ActUser *user; - -- g_debug ("ActUserManager: Adding included user %s", (char *)l->data); -- /* -- * The call to act_user_manager_get_user will add the user if it is -- * valid and not already in the hash. -- */ -- user = act_user_manager_get_user (manager, l->data); -- if (user == NULL) { -- g_debug ("ActUserManager: unable to lookup user '%s'", (char *)l->data); -- } -+ g_debug ("ActUserManager: Adding included user %s", (char *)l->data); -+ /* -+ * The call to act_user_manager_get_user will add the user if it is -+ * valid and not already in the hash. -+ */ -+ user = act_user_manager_get_user (manager, l->data); -+ if (user == NULL) { -+ g_debug ("ActUserManager: unable to lookup user '%s'", (char *)l->data); - } - } -+} -+ -+static void -+on_list_cached_users_finished (GObject *object, -+ GAsyncResult *result, -+ gpointer data) -+{ -+ AccountsAccounts *proxy = ACCOUNTS_ACCOUNTS (object); -+ ActUserManager *manager = data; -+ gchar **user_paths; -+ GError *error = NULL; -+ -+ manager->priv->listing_cached_users = FALSE; -+ -+ if (!accounts_accounts_call_list_cached_users_finish (proxy, &user_paths, result, &error)) { -+ g_debug ("ActUserManager: ListCachedUsers failed: %s", error->message); -+ g_error_free (error); -+ -+ g_object_unref (manager->priv->accounts_proxy); -+ manager->priv->accounts_proxy = NULL; -+ -+ g_debug ("ActUserManager: unrefing manager owned by failed ListCachedUsers call"); -+ g_object_unref (manager); -+ return; -+ } -+ -+ load_user_paths (manager, (const char * const *) user_paths); -+ g_strfreev (user_paths); -+ -+ load_included_usernames (manager); - - g_debug ("ActUserManager: unrefing manager owned by finished ListCachedUsers call"); - g_object_unref (manager); - } - - static void - on_get_x11_display_finished (GObject *object, - GAsyncResult *result, - gpointer data) - { - ConsoleKitSession *proxy = CONSOLE_KIT_SESSION (object); - ActUserManagerNewSession *new_session = data; - GError *error = NULL; - char *x11_display; - - new_session->pending_calls--; - - if (new_session->cancellable == NULL || g_cancellable_is_cancelled (new_session->cancellable)) { - unload_new_session (new_session); - return; - } - - if (!console_kit_session_call_get_x11_display_finish (proxy, &x11_display, result, &error)) { - 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); --- -2.14.1 - diff --git a/SOURCES/0009-lib-move-accounts-proxy-creation-to-helper.patch b/SOURCES/0009-lib-move-accounts-proxy-creation-to-helper.patch deleted file mode 100644 index d3bc83c..0000000 --- a/SOURCES/0009-lib-move-accounts-proxy-creation-to-helper.patch +++ /dev/null @@ -1,255 +0,0 @@ -From c2b6a64834df38b493d946fab55667cebdb991b6 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 3 Oct 2017 10:00:51 -0400 -Subject: [PATCH 09/13] lib: move accounts proxy creation to helper - -This commit factors out hte accounts proxy creation to a -helper function. ---- - src/libaccountsservice/act-user-manager.c | 74 ++++++++++++++++++------------- - 1 file changed, 43 insertions(+), 31 deletions(-) - -diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c -index 556b070..5ac157d 100644 ---- a/src/libaccountsservice/act-user-manager.c -+++ b/src/libaccountsservice/act-user-manager.c -@@ -197,60 +197,61 @@ struct ActUserManagerPrivate - guint load_id; - - gboolean is_loaded; - gboolean has_multiple_users; - gboolean getting_sessions; - gboolean listing_cached_users; - }; - - enum { - PROP_0, - 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 act_user_manager_class_init (ActUserManagerClass *klass); - static void act_user_manager_init (ActUserManager *user_manager); - static void act_user_manager_finalize (GObject *object); - -+static gboolean ensure_accounts_proxy (ActUserManager *manager); - static gboolean load_seat_incrementally (ActUserManager *manager); - static void unload_seat (ActUserManager *manager); - static void load_users (ActUserManager *manager); - static void act_user_manager_queue_load (ActUserManager *manager); - static void queue_load_seat_and_users (ActUserManager *manager); - - static void load_new_session_incrementally (ActUserManagerNewSession *new_session); - static void set_is_loaded (ActUserManager *manager, gboolean is_loaded); - - static void on_new_user_loaded (ActUser *user, - GParamSpec *pspec, - ActUserManager *manager); - static void give_up (ActUserManager *manager, - ActUserManagerFetchUserRequest *request); - static void fetch_user_incrementally (ActUserManagerFetchUserRequest *request); - - static void maybe_set_is_loaded (ActUserManager *manager); - static void update_user (ActUserManager *manager, - ActUser *user); - static gpointer user_manager_object = NULL; - - G_DEFINE_TYPE (ActUserManager, act_user_manager, G_TYPE_OBJECT) - - static const GDBusErrorEntry error_entries[] = { - { ACT_USER_MANAGER_ERROR_FAILED, "org.freedesktop.Accounts.Error.Failed" }, - { ACT_USER_MANAGER_ERROR_USER_EXISTS, "org.freedesktop.Accounts.Error.UserExists" }, - { ACT_USER_MANAGER_ERROR_USER_DOES_NOT_EXIST, "org.freedesktop.Accounts.Error.UserDoesNotExist" }, - { ACT_USER_MANAGER_ERROR_PERMISSION_DENIED, "org.freedesktop.Accounts.Error.PermissionDenied" }, - { ACT_USER_MANAGER_ERROR_NOT_SUPPORTED, "org.freedesktop.Accounts.Error.NotSupported" } - }; -@@ -2805,132 +2806,143 @@ act_user_manager_class_init (ActUserManagerClass *klass) - signals [USER_CHANGED] = - g_signal_new ("user-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ActUserManagerClass, user_changed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, ACT_TYPE_USER); - - g_type_class_add_private (klass, sizeof (ActUserManagerPrivate)); - } - - /** - * act_user_manager_queue_load: - * @manager: a #ActUserManager - * - * Queue loading users into user manager. This must be called, and the - * #ActUserManager:is-loaded property must be %TRUE before calling - * act_user_manager_list_users() - */ - static void - act_user_manager_queue_load (ActUserManager *manager) - { - g_return_if_fail (ACT_IS_USER_MANAGER (manager)); - - if (! manager->priv->is_loaded) { - queue_load_seat_and_users (manager); - } - } - -+static gboolean -+ensure_accounts_proxy (ActUserManager *manager) -+{ -+ GError *error = NULL; -+ -+ if (manager->priv->accounts_proxy != NULL) { -+ return TRUE; -+ } -+ -+ manager->priv->accounts_proxy = accounts_accounts_proxy_new_sync (manager->priv->connection, -+ G_DBUS_PROXY_FLAGS_NONE, -+ ACCOUNTS_NAME, -+ ACCOUNTS_PATH, -+ NULL, -+ &error); -+ if (error != NULL) { -+ g_debug ("ActUserManager: getting account proxy failed: %s", error->message); -+ g_clear_error (&error); -+ return FALSE; -+ } -+ -+ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (manager->priv->accounts_proxy), G_MAXINT); -+ -+ g_object_bind_property (G_OBJECT (manager->priv->accounts_proxy), -+ "has-multiple-users", -+ G_OBJECT (manager), -+ "has-multiple-users", -+ G_BINDING_SYNC_CREATE); -+ -+ g_signal_connect (manager->priv->accounts_proxy, -+ "user-added", -+ G_CALLBACK (on_new_user_in_accounts_service), -+ manager); -+ g_signal_connect (manager->priv->accounts_proxy, -+ "user-deleted", -+ G_CALLBACK (on_user_removed_in_accounts_service), -+ manager); -+ -+ return TRUE; -+} -+ - static void - act_user_manager_init (ActUserManager *manager) - { - GError *error; - - manager->priv = ACT_USER_MANAGER_GET_PRIVATE (manager); - - act_user_manager_error_quark (); /* register dbus errors */ - - /* sessions */ - manager->priv->sessions = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - /* users */ - manager->priv->normal_users_by_name = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - manager->priv->system_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); - - error = NULL; - manager->priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &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; - } - -- manager->priv->accounts_proxy = accounts_accounts_proxy_new_sync (manager->priv->connection, -- G_DBUS_PROXY_FLAGS_NONE, -- ACCOUNTS_NAME, -- ACCOUNTS_PATH, -- NULL, -- &error); -- if (manager->priv->accounts_proxy == NULL) { -- if (error != NULL) { -- g_warning ("Failed to create accounts proxy: %s", error->message); -- g_error_free (error); -- } else { -- g_warning ("Failed to create_accounts_proxy"); -- } -- return; -- } -- g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (manager->priv->accounts_proxy), G_MAXINT); -- -- g_object_bind_property (G_OBJECT (manager->priv->accounts_proxy), -- "has-multiple-users", -- G_OBJECT (manager), -- "has-multiple-users", -- G_BINDING_SYNC_CREATE); -- -- g_signal_connect (manager->priv->accounts_proxy, -- "user-added", -- G_CALLBACK (on_new_user_in_accounts_service), -- manager); -- g_signal_connect (manager->priv->accounts_proxy, -- "user-deleted", -- G_CALLBACK (on_user_removed_in_accounts_service), -- manager); -+ ensure_accounts_proxy (manager); - - manager->priv->seat.state = ACT_USER_MANAGER_SEAT_STATE_UNLOADED; - } - - static void - act_user_manager_finalize (GObject *object) - { - ActUserManager *manager; - GSList *node; - - g_debug ("ActUserManager: finalizing user manager"); - - g_return_if_fail (object != NULL); - g_return_if_fail (ACT_IS_USER_MANAGER (object)); - - manager = ACT_USER_MANAGER (object); - - g_return_if_fail (manager->priv != NULL); - - 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); - - g_slist_free (manager->priv->new_users_inhibiting_load); - - node = manager->priv->new_users; --- -2.14.1 - diff --git a/SOURCES/0010-lib-retry-connecting-to-accountsservice-when-loading.patch b/SOURCES/0010-lib-retry-connecting-to-accountsservice-when-loading.patch deleted file mode 100644 index c9ef806..0000000 --- a/SOURCES/0010-lib-retry-connecting-to-accountsservice-when-loading.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 9b03e52b2504f215f960549c53bd4f617797dedd Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 3 Oct 2017 10:04:28 -0400 -Subject: [PATCH 10/13] lib: retry connecting to accountsservice when loading - users - -If we were unable to connect to accountsservice and we need to -load users again, then try again. ---- - src/libaccountsservice/act-user-manager.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c -index 5ac157d..c8a0e20 100644 ---- a/src/libaccountsservice/act-user-manager.c -+++ b/src/libaccountsservice/act-user-manager.c -@@ -2544,60 +2544,64 @@ load_console_kit_sessions (ActUserManager *manager) - g_debug ("ActUserManager: no seat proxy; can't load sessions"); - return; - } - - manager->priv->getting_sessions = TRUE; - console_kit_seat_call_get_sessions (manager->priv->seat.seat_proxy, - NULL, - on_get_sessions_finished, - g_object_ref (manager)); - } - - static void - load_sessions (ActUserManager *manager) - { - #ifdef WITH_SYSTEMD - if (LOGIND_RUNNING()) { - reload_systemd_sessions (manager); - maybe_set_is_loaded (manager); - return; - } - #endif - load_console_kit_sessions (manager); - } - - static void - load_users (ActUserManager *manager) - { - g_assert (manager->priv->accounts_proxy != NULL); - g_debug ("ActUserManager: calling 'ListCachedUsers'"); - -+ if (!ensure_accounts_proxy (manager)) { -+ return; -+ } -+ - accounts_accounts_call_list_cached_users (manager->priv->accounts_proxy, - NULL, - on_list_cached_users_finished, - g_object_ref (manager)); - manager->priv->listing_cached_users = TRUE; - } - - static gboolean - load_seat_incrementally (ActUserManager *manager) - { - manager->priv->seat.load_idle_id = 0; - - switch (manager->priv->seat.state) { - case ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_ID: - get_current_session_id (manager); - break; - case ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_PROXY: - get_session_proxy (manager); - break; - case ACT_USER_MANAGER_SEAT_STATE_GET_ID: - get_seat_id_for_current_session (manager); - break; - case ACT_USER_MANAGER_SEAT_STATE_GET_SEAT_PROXY: - get_seat_proxy (manager); - break; - case ACT_USER_MANAGER_SEAT_STATE_LOADED: - g_debug ("ActUserManager: Seat loading sequence complete"); - break; - default: - g_assert_not_reached (); --- -2.14.1 - diff --git a/SOURCES/0011-lib-simplify-code-dramatically.patch b/SOURCES/0011-lib-simplify-code-dramatically.patch deleted file mode 100644 index e8d01db..0000000 --- a/SOURCES/0011-lib-simplify-code-dramatically.patch +++ /dev/null @@ -1,1478 +0,0 @@ -From 1e2385077256bd5156d4269becc3a9e0a2d29c58 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 3 Oct 2017 13:48:52 -0400 -Subject: [PATCH 11/13] lib: simplify code dramatically - -ActUser is a wrapper over the accountsservice daemon's -managed user objects. There's a nearly 1-to-1 correspondence -between properties on the proxy to the daemon and properties -on the ActUser object. - -This commit dramatically reduces the code, by leveraging the -proxies properties directly, rather than duplicating the values -on the ActUser object. - -At the same time, it drops manual GetAll() calls for synchronizing -the proxies properties, since it's completely redundant with the -work the proxy is doing under the hood anyway. ---- - src/libaccountsservice/act-user.c | 676 ++++++++------------------------------ - 1 file changed, 143 insertions(+), 533 deletions(-) - -diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c -index 17acacb..94884a1 100644 ---- a/src/libaccountsservice/act-user.c -+++ b/src/libaccountsservice/act-user.c -@@ -81,94 +81,66 @@ enum { - PROP_PASSWORD_HINT, - PROP_HOME_DIR, - PROP_SHELL, - PROP_EMAIL, - PROP_LOCATION, - PROP_LOCKED, - PROP_AUTOMATIC_LOGIN, - PROP_SYSTEM_ACCOUNT, - PROP_NONEXISTENT, - PROP_LOCAL_ACCOUNT, - PROP_LOGIN_FREQUENCY, - PROP_LOGIN_TIME, - PROP_LOGIN_HISTORY, - PROP_ICON_FILE, - PROP_LANGUAGE, - PROP_X_SESSION, - PROP_IS_LOADED - }; - - enum { - CHANGED, - SESSIONS_CHANGED, - LAST_SIGNAL - }; - - struct _ActUser { - GObject parent; - - GDBusConnection *connection; - AccountsUser *accounts_proxy; -- GDBusProxy *object_proxy; -- GCancellable *get_all_cancellable; -- char *object_path; -- -- uid_t uid; -- char *user_name; -- char *real_name; -- char *password_hint; -- char *home_dir; -- char *shell; -- char *email; -- char *location; -- char *icon_file; -- char *language; -- char *x_session; -+ - GList *our_sessions; - GList *other_sessions; -- int login_frequency; -- gint64 login_time; -- GVariant *login_history; -- -- ActUserAccountType account_type; -- ActUserPasswordMode password_mode; -- -- guint uid_set : 1; - - guint is_loaded : 1; -- guint locked : 1; -- guint automatic_login : 1; -- guint system_account : 1; -- guint local_account : 1; - guint nonexistent : 1; -- -- guint update_info_timeout_id; - }; - - struct _ActUserClass - { - GObjectClass parent_class; - }; - - static void act_user_finalize (GObject *object); - - static guint signals[LAST_SIGNAL] = { 0 }; - - G_DEFINE_TYPE (ActUser, act_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 - _act_user_add_session (ActUser *user, - const char *ssid, - gboolean is_ours) -@@ -238,128 +210,75 @@ act_user_get_num_sessions (ActUser *user) - /** - * act_user_get_num_sessions_anywhere: - * @user: a user - * - * Get the number of sessions for a user on any seat of any type. - * See also act_user_get_num_sessions(). - * - * (Currently, this function is only implemented for systemd-logind. - * For ConsoleKit, it is equivalent to act_user_get_num_sessions.) - * - * Returns: the number of sessions - */ - guint - act_user_get_num_sessions_anywhere (ActUser *user) - { - return (g_list_length (user->our_sessions) - + g_list_length (user->other_sessions)); - } - - static void - act_user_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) - { - ActUser *user; - - user = ACT_USER (object); - - switch (param_id) { -- case PROP_UID: -- g_value_set_int (value, user->uid); -- break; -- case PROP_USER_NAME: -- g_value_set_string (value, user->user_name); -- break; -- case PROP_REAL_NAME: -- g_value_set_string (value, user->real_name); -- break; -- case PROP_ACCOUNT_TYPE: -- g_value_set_int (value, user->account_type); -- break; -- case PROP_PASSWORD_MODE: -- g_value_set_int (value, user->password_mode); -- break; -- case PROP_PASSWORD_HINT: -- g_value_set_string (value, user->password_hint); -- break; -- case PROP_HOME_DIR: -- g_value_set_string (value, user->home_dir); -- break; -- case PROP_LOGIN_FREQUENCY: -- g_value_set_int (value, user->login_frequency); -- break; -- case PROP_LOGIN_TIME: -- g_value_set_int64 (value, user->login_time); -- break; -- case PROP_LOGIN_HISTORY: -- g_value_set_variant (value, user->login_history); -- break; -- case PROP_SHELL: -- g_value_set_string (value, user->shell); -- break; -- case PROP_EMAIL: -- g_value_set_string (value, user->email); -- break; -- case PROP_LOCATION: -- g_value_set_string (value, user->location); -- break; -- case PROP_ICON_FILE: -- g_value_set_string (value, user->icon_file); -- break; -- case PROP_LANGUAGE: -- g_value_set_string (value, user->language); -- break; -- case PROP_X_SESSION: -- g_value_set_string (value, user->x_session); -- break; -- case PROP_LOCKED: -- g_value_set_boolean (value, user->locked); -- break; -- case PROP_AUTOMATIC_LOGIN: -- g_value_set_boolean (value, user->automatic_login); -- break; -- case PROP_SYSTEM_ACCOUNT: -- g_value_set_boolean (value, user->system_account); -- break; -- case PROP_LOCAL_ACCOUNT: -- g_value_set_boolean (value, user->local_account); -- break; - case PROP_NONEXISTENT: - g_value_set_boolean (value, user->nonexistent); - break; - case PROP_IS_LOADED: - g_value_set_boolean (value, user->is_loaded); - break; - default: -- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); -+ if (user->accounts_proxy != NULL) { -+ const char *property_name; -+ -+ property_name = g_param_spec_get_name (pspec); -+ -+ g_object_get_property (G_OBJECT (user->accounts_proxy), property_name, value); -+ -+ } - break; - } - } - - - static void - act_user_class_init (ActUserClass *class) - { - GObjectClass *gobject_class; - - gobject_class = G_OBJECT_CLASS (class); - - gobject_class->finalize = act_user_finalize; - gobject_class->get_property = act_user_get_property; - - g_object_class_install_property (gobject_class, - PROP_REAL_NAME, - g_param_spec_string ("real-name", - "Real Name", - "The real name to display for this user.", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, - PROP_ACCOUNT_TYPE, - g_param_spec_int ("account-type", - "Account Type", - "The account type for this user.", - ACT_USER_ACCOUNT_TYPE_STANDARD, - ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR, -@@ -525,1082 +444,773 @@ act_user_class_init (ActUserClass *class) - * Emitted when the user accounts changes in some way. - */ - 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); - /** - * ActUser::sessions-changed: - * - * Emitted when the list of sessions for this user changes. - */ - 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 - act_user_init (ActUser *user) - { - GError *error = NULL; - -- user->local_account = TRUE; -- user->user_name = NULL; -- user->real_name = NULL; - user->our_sessions = NULL; - user->other_sessions = NULL; -- user->login_history = NULL; - - user->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - if (user->connection == NULL) { - g_warning ("Couldn't connect to system bus: %s", error->message); - g_error_free (error); - } - } - - static void - act_user_finalize (GObject *object) - { - ActUser *user; - - user = ACT_USER (object); - -- g_free (user->user_name); -- g_free (user->real_name); -- g_free (user->icon_file); -- g_free (user->language); -- g_free (user->object_path); -- g_free (user->password_hint); -- g_free (user->home_dir); -- g_free (user->shell); -- g_free (user->email); -- g_free (user->location); -- if (user->login_history) -- g_variant_unref (user->login_history); -- - if (user->accounts_proxy != NULL) { - g_object_unref (user->accounts_proxy); - } - -- if (user->object_proxy != NULL) { -- g_object_unref (user->object_proxy); -- } -- -- if (user->get_all_cancellable != NULL) { -- g_object_unref (user->get_all_cancellable); -- } -- - if (user->connection != NULL) { - g_object_unref (user->connection); - } - -- if (user->update_info_timeout_id != 0) { -- g_source_remove (user->update_info_timeout_id); -- } -- - if (G_OBJECT_CLASS (act_user_parent_class)->finalize) - (*G_OBJECT_CLASS (act_user_parent_class)->finalize) (object); - } - - static void - set_is_loaded (ActUser *user, - gboolean is_loaded) - { - if (user->is_loaded != is_loaded) { - user->is_loaded = is_loaded; - g_object_notify (G_OBJECT (user), "is-loaded"); - } - } - - /** - * act_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. - **/ - - uid_t - act_user_get_uid (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), -1); - -- return user->uid; -+ if (user->accounts_proxy == NULL) -+ return -1; -+ -+ return accounts_user_get_uid (user->accounts_proxy); - } - - /** - * act_user_get_real_name: - * @user: the user object to examine. - * - * Retrieves the display name of @user. - * - * Returns: (transfer none): a pointer to an array of characters which must not be modified or - * freed, or %NULL. - **/ - const char * - act_user_get_real_name (ActUser *user) - { -+ const char *real_name = NULL; -+ - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- if (user->real_name == NULL || -- user->real_name[0] == '\0') { -- return user->user_name; -+ real_name = accounts_user_get_real_name (user->accounts_proxy); -+ -+ if (real_name == NULL || real_name[0] == '\0') { -+ real_name = accounts_user_get_user_name (user->accounts_proxy); - } - -- return user->real_name; -+ return real_name; - } - - /** - * act_user_get_account_type: - * @user: the user object to examine. - * - * Retrieves the account type of @user. - * - * Returns: a #ActUserAccountType - **/ - ActUserAccountType - act_user_get_account_type (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), ACT_USER_ACCOUNT_TYPE_STANDARD); - -- return user->account_type; -+ if (user->accounts_proxy == NULL) -+ return ACT_USER_ACCOUNT_TYPE_STANDARD; -+ -+ return accounts_user_get_account_type (user->accounts_proxy); - } - - /** - * act_user_get_password_mode: - * @user: the user object to examine. - * - * Retrieves the password mode of @user. - * - * Returns: a #ActUserPasswordMode - **/ - ActUserPasswordMode - act_user_get_password_mode (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), ACT_USER_PASSWORD_MODE_REGULAR); - -- return user->password_mode; -+ if (user->accounts_proxy == NULL) -+ return ACT_USER_PASSWORD_MODE_REGULAR; -+ -+ return accounts_user_get_password_mode (user->accounts_proxy); - } - - /** - * act_user_get_password_hint: - * @user: the user object to examine. - * - * Retrieves the password hint set by @user. - * - * Returns: (transfer none): a pointer to an array of characters which must not be modified or - * freed, or %NULL. - **/ - const char * - act_user_get_password_hint (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- return user->password_hint; -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ -+ return accounts_user_get_password_hint (user->accounts_proxy); - } - - /** - * act_user_get_home_dir: - * @user: the user object to examine. - * - * Retrieves the home directory for @user. - * - * Returns: (transfer none): a pointer to an array of characters which must not be modified or - * freed, or %NULL. - **/ - const char * - act_user_get_home_dir (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- return user->home_dir; -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ -+ return accounts_user_get_home_directory (user->accounts_proxy); - } - - /** - * act_user_get_shell: - * @user: the user object to examine. - * - * Retrieves the shell assigned to @user. - * - * Returns: (transfer none): a pointer to an array of characters which must not be modified or - * freed, or %NULL. - **/ - const char * - act_user_get_shell (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- return user->shell; -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ -+ return accounts_user_get_shell (user->accounts_proxy); - } - - /** - * act_user_get_email: - * @user: the user object to examine. - * - * Retrieves the email address set by @user. - * - * Returns: (transfer none): a pointer to an array of characters which must not be modified or - * freed, or %NULL. - **/ - const char * - act_user_get_email (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- return user->email; -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ -+ return accounts_user_get_email (user->accounts_proxy); - } - - /** - * act_user_get_location: - * @user: the user object to examine. - * - * Retrieves the location set by @user. - * - * Returns: (transfer none): a pointer to an array of characters which must not be modified or - * freed, or %NULL. - **/ - const char * - act_user_get_location (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- return user->location; -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ -+ return accounts_user_get_location (user->accounts_proxy); - } - - /** - * act_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 * - act_user_get_user_name (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- return user->user_name; -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ -+ return accounts_user_get_user_name (user->accounts_proxy); - } - - /** - * act_user_get_login_frequency: - * @user: a #ActUser - * - * Returns the number of times @user has logged in. - * - * Returns: the login frequency - */ - int - act_user_get_login_frequency (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), 0); - -- return user->login_frequency; -+ if (user->accounts_proxy == NULL) -+ return 0; -+ -+ return accounts_user_get_login_frequency (user->accounts_proxy); - } - - /** - * act_user_get_login_time: - * @user: a #ActUser - * - * Returns the last login time for @user. - * - * Returns: (transfer none): the login time - */ - gint64 --act_user_get_login_time (ActUser *user) { -+act_user_get_login_time (ActUser *user) -+{ - g_return_val_if_fail (ACT_IS_USER (user), 0); - -- return user->login_time; -+ if (user->accounts_proxy == NULL) -+ return 0; -+ -+ return accounts_user_get_login_time (user->accounts_proxy); - } - - /** - * act_user_get_login_history: - * @user: a #ActUser - * - * Returns the login history for @user. - * - * Returns: (transfer none): a pointer to GVariant of type "a(xxa{sv})" - * which must not be modified or freed, or %NULL. - */ - const GVariant * --act_user_get_login_history (ActUser *user) { -+act_user_get_login_history (ActUser *user) -+{ - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- return user->login_history; -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ -+ return accounts_user_get_login_history (user->accounts_proxy); - } - - /** - * act_user_collate: - * @user1: a user - * @user2: a user - * - * Organize the user by login frequency and names. - * - * Returns: negative if @user1 is before @user2, zero if equal - * or positive if @user1 is after @user2 - */ - int - act_user_collate (ActUser *user1, - ActUser *user2) - { - const char *str1; - const char *str2; - int num1; - int num2; - guint len1; - guint len2; - - g_return_val_if_fail (ACT_IS_USER (user1), 0); - g_return_val_if_fail (ACT_IS_USER (user2), 0); - -- num1 = user1->login_frequency; -- num2 = user2->login_frequency; -+ num1 = act_user_get_login_frequency (user1); -+ num2 = act_user_get_login_frequency (user2); - - if (num1 > num2) { - return -1; - } - - if (num1 < num2) { - return 1; - } - - - len1 = g_list_length (user1->our_sessions); - len2 = g_list_length (user2->our_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; -- } -+ str1 = act_user_get_real_name (user1); -+ str2 = act_user_get_real_name (user2); - - 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); - } - - /** - * act_user_is_logged_in: - * @user: a #ActUser - * - * Returns whether or not #ActUser is currently graphically logged in - * on the same seat as the seat of the session of the calling process. - * - * Returns: %TRUE or %FALSE - */ - gboolean - act_user_is_logged_in (ActUser *user) - { - return user->our_sessions != NULL; - } - - /** - * act_user_is_logged_in_anywhere: - * @user: a #ActUser - * - * Returns whether or not #ActUser is currently logged in in any way - * whatsoever. See also act_user_is_logged_in(). - * - * (Currently, this function is only implemented for systemd-logind. - * For ConsoleKit, it is equivalent to act_user_is_logged_in.) - * - * Returns: %TRUE or %FALSE - */ - gboolean - act_user_is_logged_in_anywhere (ActUser *user) - { - return user->our_sessions != NULL || user->other_sessions != NULL; - } - - /** - * act_user_get_locked: - * @user: a #ActUser - * - * Returns whether or not the #ActUser account is locked. - * - * Returns: %TRUE or %FALSE - */ - gboolean - act_user_get_locked (ActUser *user) - { -- return user->locked;; -+ return accounts_user_get_locked (user->accounts_proxy); - } - - /** - * act_user_get_automatic_login: - * @user: a #ActUser - * - * Returns whether or not #ActUser is automatically logged in at boot time. - * - * Returns: %TRUE or %FALSE - */ - gboolean - act_user_get_automatic_login (ActUser *user) - { -- return user->automatic_login; -+ g_return_val_if_fail (ACT_IS_USER (user), FALSE); -+ -+ if (user->accounts_proxy == NULL) -+ return FALSE; -+ -+ return accounts_user_get_automatic_login (user->accounts_proxy); - } - - /** - * act_user_is_system_account: - * @user: a #ActUser - * - * Returns whether or not #ActUser represents a 'system account' like - * 'root' or 'nobody'. - * - * Returns: %TRUE or %FALSE - */ - gboolean - act_user_is_system_account (ActUser *user) - { -- return user->system_account; -+ g_return_val_if_fail (ACT_IS_USER (user), TRUE); -+ -+ if (user->accounts_proxy == NULL) -+ return TRUE; -+ -+ return accounts_user_get_system_account (user->accounts_proxy); - } - - /** - * act_user_is_local_account: - * @user: the user object to examine. - * - * Retrieves whether the user is a local account or not. - * - * Returns: (transfer none): %TRUE if the user is local - **/ - gboolean - act_user_is_local_account (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), FALSE); - -- return user->local_account; -+ if (user->accounts_proxy == NULL) -+ return FALSE; -+ -+ return accounts_user_get_local_account (user->accounts_proxy); - } - - /** - * act_user_is_nonexistent: - * @user: the user object to examine. - * - * Retrieves whether the user is nonexistent or not. - * - * Returns: (transfer none): %TRUE if the user is nonexistent - **/ - gboolean - act_user_is_nonexistent (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), FALSE); - - return user->nonexistent; - } - - /** - * act_user_get_icon_file: - * @user: a #ActUser - * - * Returns the path to the account icon belonging to @user. - * - * Returns: (transfer none): a path to an icon - */ - const char * - act_user_get_icon_file (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- return user->icon_file; -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ -+ return accounts_user_get_icon_file (user->accounts_proxy); - } - - /** - * act_user_get_language: - * @user: a #ActUser - * - * Returns the path to the configured locale of @user. - * - * Returns: (transfer none): a path to an icon - */ - const char * - act_user_get_language (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- return user->language; -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ -+ return accounts_user_get_language (user->accounts_proxy); - } - - /** - * act_user_get_x_session: - * @user: a #ActUser - * - * Returns the path to the configured X session for @user. - * - * Returns: (transfer none): a path to an icon - */ - const char * - act_user_get_x_session (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- return user->x_session; -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ -+ return accounts_user_get_xsession (user->accounts_proxy); - } - - /** - * act_user_get_object_path: - * @user: a #ActUser - * - * 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 object path of the user - */ - const char * - act_user_get_object_path (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -- return user->object_path; -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ -+ return g_dbus_proxy_get_object_path (G_DBUS_PROXY (user->accounts_proxy)); - } - - /** - * act_user_get_primary_session_id: - * @user: a #ActUser - * - * Returns the id of the primary session of @user, or %NULL if @user - * has no primary session. The primary session will always be - * graphical and will be chosen from the sessions on the same seat as - * the seat of the session of the calling process. - * - * Returns: (transfer none): the id of the primary session of the user - */ - const char * - act_user_get_primary_session_id (ActUser *user) - { - if (user->our_sessions == NULL) { - g_debug ("User %s is not logged in here, so has no primary session", - act_user_get_user_name (user)); - return NULL; - } - - /* FIXME: better way to choose? */ - return user->our_sessions->data; - } - --static void --collect_props (const gchar *key, -- GVariant *value, -- ActUser *user) --{ -- gboolean handled = TRUE; -- -- if (strcmp (key, "Uid") == 0) { -- guint64 new_uid; -- -- new_uid = g_variant_get_uint64 (value); -- if (!user->uid_set || (guint64) user->uid != new_uid) { -- user->uid = (uid_t) new_uid; -- user->uid_set = TRUE; -- g_object_notify (G_OBJECT (user), "uid"); -- } -- } else if (strcmp (key, "UserName") == 0) { -- const char *new_user_name; -- -- new_user_name = g_variant_get_string (value, NULL); -- if (g_strcmp0 (user->user_name, new_user_name) != 0) { -- g_free (user->user_name); -- user->user_name = g_strdup (new_user_name); -- g_object_notify (G_OBJECT (user), "user-name"); -- } -- } else if (strcmp (key, "RealName") == 0) { -- const char *new_real_name; -- -- new_real_name = g_variant_get_string (value, NULL); -- if (g_strcmp0 (user->real_name, new_real_name) != 0) { -- g_free (user->real_name); -- user->real_name = g_strdup (new_real_name); -- g_object_notify (G_OBJECT (user), "real-name"); -- } -- } else if (strcmp (key, "AccountType") == 0) { -- int new_account_type; -- -- new_account_type = g_variant_get_int32 (value); -- if ((int) user->account_type != new_account_type) { -- user->account_type = (ActUserAccountType) new_account_type; -- g_object_notify (G_OBJECT (user), "account-type"); -- } -- } else if (strcmp (key, "PasswordMode") == 0) { -- int new_password_mode; -- -- new_password_mode = g_variant_get_int32 (value); -- if ((int) user->password_mode != new_password_mode) { -- user->password_mode = (ActUserPasswordMode) new_password_mode; -- g_object_notify (G_OBJECT (user), "password-mode"); -- } -- } else if (strcmp (key, "PasswordHint") == 0) { -- const char *new_password_hint; -- -- new_password_hint = g_variant_get_string (value, NULL); -- if (g_strcmp0 (user->password_hint, new_password_hint) != 0) { -- g_free (user->password_hint); -- user->password_hint = g_strdup (new_password_hint); -- g_object_notify (G_OBJECT (user), "password-hint"); -- } -- } else if (strcmp (key, "HomeDirectory") == 0) { -- const char *new_home_dir; -- -- new_home_dir = g_variant_get_string (value, NULL); -- if (g_strcmp0 (user->home_dir, new_home_dir) != 0) { -- g_free (user->home_dir); -- user->home_dir = g_strdup (new_home_dir); -- g_object_notify (G_OBJECT (user), "home-directory"); -- } -- } else if (strcmp (key, "Shell") == 0) { -- const char *new_shell; -- -- new_shell = g_variant_get_string (value, NULL); -- if (g_strcmp0 (user->shell, new_shell) != 0) { -- g_free (user->shell); -- user->shell = g_strdup (new_shell); -- g_object_notify (G_OBJECT (user), "shell"); -- } -- } else if (strcmp (key, "Email") == 0) { -- const char *new_email; -- -- new_email = g_variant_get_string (value, NULL); -- if (g_strcmp0 (user->email, new_email) != 0) { -- g_free (user->email); -- user->email = g_strdup (new_email); -- g_object_notify (G_OBJECT (user), "email"); -- } -- } else if (strcmp (key, "Location") == 0) { -- const char *new_location; -- -- new_location = g_variant_get_string (value, NULL); -- if (g_strcmp0 (user->location, new_location) != 0) { -- g_free (user->location); -- user->location = g_strdup (new_location); -- g_object_notify (G_OBJECT (user), "location"); -- } -- } else if (strcmp (key, "Locked") == 0) { -- gboolean new_locked_state; -- -- new_locked_state = g_variant_get_boolean (value); -- if (new_locked_state != user->locked) { -- user->locked = new_locked_state; -- g_object_notify (G_OBJECT (user), "locked"); -- } -- } else if (strcmp (key, "AutomaticLogin") == 0) { -- gboolean new_automatic_login_state; -- -- new_automatic_login_state = g_variant_get_boolean (value); -- if (new_automatic_login_state != user->automatic_login) { -- user->automatic_login = new_automatic_login_state; -- g_object_notify (G_OBJECT (user), "automatic-login"); -- } -- } else if (strcmp (key, "SystemAccount") == 0) { -- gboolean new_system_account_state; -- -- new_system_account_state = g_variant_get_boolean (value); -- if (new_system_account_state != user->system_account) { -- user->system_account = new_system_account_state; -- g_object_notify (G_OBJECT (user), "system-account"); -- } -- } else if (strcmp (key, "LocalAccount") == 0) { -- gboolean new_local; -- -- new_local = g_variant_get_boolean (value); -- if (user->local_account != new_local) { -- user->local_account = new_local; -- g_object_notify (G_OBJECT (user), "local-account"); -- } -- } else if (strcmp (key, "LoginFrequency") == 0) { -- int new_login_frequency; -- -- new_login_frequency = (int) g_variant_get_uint64 (value); -- if ((int) user->login_frequency != (int) new_login_frequency) { -- user->login_frequency = new_login_frequency; -- g_object_notify (G_OBJECT (user), "login-frequency"); -- } -- } else if (strcmp (key, "LoginTime") == 0) { -- gint64 new_login_time = g_variant_get_int64 (value); -- -- if (user->login_time != new_login_time) { -- user->login_time = new_login_time; -- g_object_notify (G_OBJECT (user), "login-time"); -- } -- } else if (strcmp (key, "LoginHistory") == 0) { -- GVariant *new_login_history = value; -- -- if (user->login_history == NULL || -- !g_variant_equal (user->login_history, new_login_history)) { -- if (user->login_history) -- g_variant_unref (user->login_history); -- user->login_history = g_variant_ref (new_login_history); -- g_object_notify (G_OBJECT (user), "login-history"); -- } -- } else if (strcmp (key, "IconFile") == 0) { -- const char *new_icon_file; -- -- new_icon_file = g_variant_get_string (value, NULL); -- if (g_strcmp0 (user->icon_file, new_icon_file) != 0) { -- g_free (user->icon_file); -- user->icon_file = g_strdup (new_icon_file); -- g_object_notify (G_OBJECT (user), "icon-file"); -- } -- } else if (strcmp (key, "Language") == 0) { -- const char *new_language; -- -- new_language = g_variant_get_string (value, NULL); -- if (g_strcmp0 (user->language, new_language) != 0) { -- g_free (user->language); -- user->language = g_strdup (new_language); -- g_object_notify (G_OBJECT (user), "language"); -- } -- } else if (strcmp (key, "XSession") == 0) { -- const char *new_x_session; -- -- new_x_session = g_variant_get_string (value, NULL); -- if (g_strcmp0 (user->x_session, new_x_session) != 0) { -- g_free (user->x_session); -- user->x_session = g_strdup (new_x_session); -- g_object_notify (G_OBJECT (user), "x-session"); -- } -- } else { -- handled = FALSE; -- } -- -- if (!handled) { -- g_debug ("unhandled property %s", key); -- } --} -- --static void --on_get_all_finished (GObject *object, -- GAsyncResult *result, -- gpointer data) --{ -- GDBusProxy *proxy = G_DBUS_PROXY (object); -- ActUser *user = data; -- GError *error; -- GVariant *res; -- GVariantIter *iter; -- gchar *key; -- GVariant *value; -- -- g_assert (G_IS_DBUS_PROXY (user->object_proxy)); -- g_assert (user->object_proxy == proxy); -- -- error = NULL; -- res = g_dbus_proxy_call_finish (proxy, result, &error); -- -- g_clear_object (&user->get_all_cancellable); -- -- if (! res) { -- g_debug ("Error calling GetAll() when retrieving properties for %s: %s", -- user->object_path, error->message); -- g_error_free (error); -- -- if (!user->is_loaded) { -- set_is_loaded (user, TRUE); -- } -- return; -- } -- -- g_variant_get (res, "(a{sv})", &iter); -- while (g_variant_iter_next (iter, "{sv}", &key, &value)) { -- collect_props (key, value, user); -- g_free (key); -- g_variant_unref (value); -- } -- g_variant_iter_free (iter); -- g_variant_unref (res); -- -- if (!user->is_loaded) { -- set_is_loaded (user, TRUE); -- } -- -- g_signal_emit (user, signals[CHANGED], 0); --} -- --static void --update_info (ActUser *user) --{ -- g_assert (G_IS_DBUS_PROXY (user->object_proxy)); -- -- if (user->get_all_cancellable != NULL) { -- g_cancellable_cancel (user->get_all_cancellable); -- g_clear_object (&user->get_all_cancellable); -- } -- -- user->get_all_cancellable = g_cancellable_new (); -- g_dbus_proxy_call (user->object_proxy, -- "GetAll", -- g_variant_new ("(s)", ACCOUNTS_USER_INTERFACE), -- G_DBUS_CALL_FLAGS_NONE, -- -1, -- user->get_all_cancellable, -- on_get_all_finished, -- user); --} -- --static gboolean --on_timeout_update_info (ActUser *user) --{ -- update_info (user); -- user->update_info_timeout_id = 0; -- -- return G_SOURCE_REMOVE; --} -- --static void --changed_handler (AccountsUser *object, -- gpointer *data) --{ -- ActUser *user = ACT_USER (data); -- -- if (user->update_info_timeout_id != 0) -- return; -- -- user->update_info_timeout_id = g_timeout_add (250, (GSourceFunc) on_timeout_update_info, user); --} -- - /** - * _act_user_update_as_nonexistent: - * @user: the user object to update. - * - * Set's the 'non-existent' property of @user to #TRUE - * Can only be called before the user is loaded. - **/ - void - _act_user_update_as_nonexistent (ActUser *user) - { - g_return_if_fail (ACT_IS_USER (user)); - g_return_if_fail (!act_user_is_loaded (user)); -- g_return_if_fail (user->object_path == NULL); -+ g_return_if_fail (act_user_get_object_path (user) == NULL); - - user->nonexistent = TRUE; - g_object_notify (G_OBJECT (user), "nonexistent"); - - set_is_loaded (user, TRUE); - } - -+static void -+on_accounts_proxy_changed (ActUser *user) -+{ -+ g_signal_emit (user, signals[CHANGED], 0); -+} -+ - /** - * _act_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 - _act_user_update_from_object_path (ActUser *user, - const char *object_path) - { -- GError *error = NULL; -+ AccountsUser *accounts_proxy; -+ GError *error = NULL; - - g_return_if_fail (ACT_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 = accounts_user_proxy_new_sync (user->connection, -- G_DBUS_PROXY_FLAGS_NONE, -- ACCOUNTS_NAME, -- user->object_path, -- NULL, -- &error); -- if (!user->accounts_proxy) { -+ g_return_if_fail (act_user_get_object_path (user) == NULL); -+ -+ accounts_proxy = accounts_user_proxy_new_sync (user->connection, -+ G_DBUS_PROXY_FLAGS_NONE, -+ ACCOUNTS_NAME, -+ object_path, -+ NULL, -+ &error); -+ if (!accounts_proxy) { - g_warning ("Couldn't create accounts proxy: %s", error->message); - g_error_free (error); - return; - } -- g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (user->accounts_proxy), INT_MAX); - -- g_signal_connect (user->accounts_proxy, "changed", G_CALLBACK (changed_handler), user); -+ user->accounts_proxy = accounts_proxy; - -- user->object_proxy = g_dbus_proxy_new_sync (user->connection, -- G_DBUS_PROXY_FLAGS_NONE, -- 0, -- ACCOUNTS_NAME, -- user->object_path, -- "org.freedesktop.DBus.Properties", -- NULL, -- &error); -- if (!user->object_proxy) { -- g_warning ("Couldn't create accounts property proxy: %s", error->message); -- g_error_free (error); -- return; -- } -+ g_signal_connect_object (user->accounts_proxy, -+ "changed", -+ G_CALLBACK (on_accounts_proxy_changed), -+ user, -+ G_CONNECT_SWAPPED); - -- update_info (user); -+ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (user->accounts_proxy), INT_MAX); -+ -+ set_is_loaded (user, TRUE); - } - - void - _act_user_update_login_frequency (ActUser *user, - int login_frequency) - { -- if (user->login_frequency != login_frequency) { -- user->login_frequency = login_frequency; -- g_object_notify (G_OBJECT (user), "login-frequency"); -+ if (act_user_get_login_frequency (user) == login_frequency) { -+ return; - } -+ -+ accounts_user_set_login_frequency (user->accounts_proxy, -+ login_frequency); - } - - static void - copy_sessions_lists (ActUser *user, - ActUser *user_to_copy) - { - GList *node; - - for (node = g_list_last (user_to_copy->our_sessions); - node != NULL; - node = node->prev) { - user->our_sessions = g_list_prepend (user->our_sessions, g_strdup (node->data)); - } - - for (node = g_list_last (user_to_copy->other_sessions); - node != NULL; - node = node->prev) { - user->other_sessions = g_list_prepend (user->other_sessions, g_strdup (node->data)); - } - } - - void - _act_user_load_from_user (ActUser *user, - ActUser *user_to_copy) - { - if (!user_to_copy->is_loaded) { - return; - } - -- /* loading users may already have a uid, user name, or session list -- * from creation, so only update them if necessary -- */ -- if (!user->uid_set) { -- user->uid = user_to_copy->uid; -- g_object_notify (G_OBJECT (user), "uid"); -- } -+ user->accounts_proxy = g_object_ref (user_to_copy->accounts_proxy); - -- if (user->user_name == NULL) { -- user->user_name = g_strdup (user_to_copy->user_name); -- g_object_notify (G_OBJECT (user), "user-name"); -- } -+ g_signal_connect_object (user->accounts_proxy, -+ "changed", -+ G_CALLBACK (on_accounts_proxy_changed), -+ user, -+ G_CONNECT_SWAPPED); - - if (user->our_sessions == NULL && user->other_sessions == NULL) { - copy_sessions_lists (user, user_to_copy); - g_signal_emit (user, signals[SESSIONS_CHANGED], 0); - } - -- g_free (user->real_name); -- user->real_name = g_strdup (user_to_copy->real_name); -- g_object_notify (G_OBJECT (user), "real-name"); -- -- g_free (user->password_hint); -- user->password_hint = g_strdup (user_to_copy->password_hint); -- g_object_notify (G_OBJECT (user), "password-hint"); -- -- g_free (user->home_dir); -- user->home_dir = g_strdup (user_to_copy->home_dir); -- g_object_notify (G_OBJECT (user), "home-directory"); -- -- g_free (user->shell); -- user->shell = g_strdup (user_to_copy->shell); -- g_object_notify (G_OBJECT (user), "shell"); -- -- g_free (user->email); -- user->email = g_strdup (user_to_copy->email); -- g_object_notify (G_OBJECT (user), "email"); -- -- g_free (user->location); -- user->location = g_strdup (user_to_copy->location); -- g_object_notify (G_OBJECT (user), "location"); -- -- g_free (user->icon_file); -- user->icon_file = g_strdup (user_to_copy->icon_file); -- g_object_notify (G_OBJECT (user), "icon-file"); -- -- g_free (user->language); -- user->language = g_strdup (user_to_copy->language); -- g_object_notify (G_OBJECT (user), "language"); -- -- g_free (user->x_session); -- user->x_session = g_strdup (user_to_copy->x_session); -- g_object_notify (G_OBJECT (user), "x-session"); -- -- user->login_frequency = user_to_copy->login_frequency; -- g_object_notify (G_OBJECT (user), "login-frequency"); -- -- user->login_time = user_to_copy->login_time; -- g_object_notify (G_OBJECT (user), "login-time"); -- -- user->login_history = user_to_copy->login_history ? g_variant_ref (user_to_copy->login_history) : NULL; -- g_object_notify (G_OBJECT (user), "login-history"); -- -- user->account_type = user_to_copy->account_type; -- g_object_notify (G_OBJECT (user), "account-type"); -- -- user->password_mode = user_to_copy->password_mode; -- g_object_notify (G_OBJECT (user), "password-mode"); -- -- user->nonexistent = user_to_copy->nonexistent; -- g_object_notify (G_OBJECT (user), "nonexistent"); -- - set_is_loaded (user, TRUE); - } - - /** - * act_user_is_loaded: - * @user: a #ActUser - * - * Determines whether or not the user object is loaded and ready to read from. - * #ActUserManager:is-loaded property must be %TRUE before calling - * act_user_manager_list_users() - * - * Returns: %TRUE or %FALSE - */ - gboolean - act_user_is_loaded (ActUser *user) - { - return user->is_loaded; - } - - /** - * act_user_get_login_history: - * @user: the user object to query. - * @expiration_time: time users passwor expires - * @last_change_time, - * @min_days_between_changes, - * @max_days_between_changes, - * @days_to_warn, - * @days_after_expiration_until_lock) - * - * Assigns a new email to @user. --- -2.14.1 - diff --git a/SOURCES/0012-lib-don-t-track-user-added-user-removed-until-we-get.patch b/SOURCES/0012-lib-don-t-track-user-added-user-removed-until-we-get.patch deleted file mode 100644 index 31cf17b..0000000 --- a/SOURCES/0012-lib-don-t-track-user-added-user-removed-until-we-get.patch +++ /dev/null @@ -1,237 +0,0 @@ -From f674b04a79a7974a697ad69a997bec21742d3299 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 4 Oct 2017 11:21:44 -0400 -Subject: [PATCH 12/13] lib: don't track user-added/user-removed until we get - initial list - -There's no reason to process user-added and user-removed signals -until we have our starting list. Those signals are supposed to -be a delta off that list anyway. ---- - src/libaccountsservice/act-user-manager.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c -index c8a0e20..11049e0 100644 ---- a/src/libaccountsservice/act-user-manager.c -+++ b/src/libaccountsservice/act-user-manager.c -@@ -173,60 +173,61 @@ typedef struct - char *object_path; - char *description; - } ActUserManagerFetchUserRequest; - - struct ActUserManagerPrivate - { - GHashTable *normal_users_by_name; - GHashTable *system_users_by_name; - GHashTable *users_by_object_path; - GHashTable *sessions; - GDBusConnection *connection; - AccountsAccounts *accounts_proxy; - ConsoleKitManager *ck_manager_proxy; - - ActUserManagerSeat seat; - - GSList *new_sessions; - GSList *new_users; - GSList *new_users_inhibiting_load; - GSList *fetch_user_requests; - - GSList *exclude_usernames; - GSList *include_usernames; - - guint load_id; - - gboolean is_loaded; - gboolean has_multiple_users; - gboolean getting_sessions; - gboolean listing_cached_users; -+ gboolean list_cached_users_done; - }; - - enum { - PROP_0, - 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 act_user_manager_class_init (ActUserManagerClass *klass); - static void act_user_manager_init (ActUserManager *user_manager); - static void act_user_manager_finalize (GObject *object); - - static gboolean ensure_accounts_proxy (ActUserManager *manager); - static gboolean load_seat_incrementally (ActUserManager *manager); - static void unload_seat (ActUserManager *manager); - static void load_users (ActUserManager *manager); - static void act_user_manager_queue_load (ActUserManager *manager); - static void queue_load_seat_and_users (ActUserManager *manager); -@@ -1075,80 +1076,92 @@ add_new_user_for_object_path (const char *object_path, - if (user != NULL) { - g_debug ("ActUserManager: tracking existing %s with object path %s", - describe_user (user), object_path); - return user; - } - - user = find_new_user_with_object_path (manager, object_path); - - if (user != NULL) { - g_debug ("ActUserManager: tracking existing (but very recently added) %s with object path %s", - describe_user (user), object_path); - return user; - } - - g_debug ("ActUserManager: tracking new user with object path %s", object_path); - - user = create_new_user (manager); - _act_user_update_from_object_path (user, object_path); - - return user; - } - - static void - on_new_user_in_accounts_service (GDBusProxy *proxy, - const char *object_path, - gpointer user_data) - { - ActUserManager *manager = ACT_USER_MANAGER (user_data); - ActUser *user; - -+ /* Only track user changes if the user has requested a list -+ * of users */ -+ if (!manager->priv->list_cached_users_done) { -+ return; -+ } -+ - if (!manager->priv->is_loaded) { - g_debug ("ActUserManager: ignoring new user in accounts service with object path %s since not loaded yet", object_path); - return; - } - - g_debug ("ActUserManager: new user in accounts service with object path %s", object_path); - user = add_new_user_for_object_path (object_path, manager); - - g_object_unref (user); - } - - static void - on_user_removed_in_accounts_service (GDBusProxy *proxy, - const char *object_path, - gpointer user_data) - { - ActUserManager *manager = ACT_USER_MANAGER (user_data); - ActUser *user; - GSList *node; - -+ /* Only track user changes if the user has requested a list -+ * of users */ -+ if (!manager->priv->list_cached_users_done) { -+ return; -+ } -+ - user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path); - - if (user == NULL) { - g_debug ("ActUserManager: ignoring untracked user %s", object_path); - return; - } else { - g_debug ("ActUserManager: tracked user %s removed from accounts service", object_path); - } - - node = g_slist_find (manager->priv->new_users, user); - if (node != NULL) { - 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); - } - - remove_user (manager, user); - } - - static void - on_get_current_session_finished (GObject *object, - GAsyncResult *result, - gpointer data) - { - ConsoleKitManager *proxy = CONSOLE_KIT_MANAGER (object); - ActUserManager *manager = data; - GError *error = NULL; - char *session_id; - - g_assert (manager->priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_ID); -@@ -1532,60 +1545,61 @@ load_included_usernames (ActUserManager *manager) - { - GSList *l; - - /* Add users who are specifically included */ - for (l = manager->priv->include_usernames; l != NULL; l = l->next) { - ActUser *user; - - g_debug ("ActUserManager: Adding included user %s", (char *)l->data); - /* - * The call to act_user_manager_get_user will add the user if it is - * valid and not already in the hash. - */ - user = act_user_manager_get_user (manager, l->data); - if (user == NULL) { - g_debug ("ActUserManager: unable to lookup user '%s'", (char *)l->data); - } - } - } - - static void - on_list_cached_users_finished (GObject *object, - GAsyncResult *result, - gpointer data) - { - AccountsAccounts *proxy = ACCOUNTS_ACCOUNTS (object); - ActUserManager *manager = data; - gchar **user_paths; - GError *error = NULL; - - manager->priv->listing_cached_users = FALSE; -+ manager->priv->list_cached_users_done = TRUE; - - if (!accounts_accounts_call_list_cached_users_finish (proxy, &user_paths, result, &error)) { - g_debug ("ActUserManager: ListCachedUsers failed: %s", error->message); - g_error_free (error); - - g_object_unref (manager->priv->accounts_proxy); - manager->priv->accounts_proxy = NULL; - - g_debug ("ActUserManager: unrefing manager owned by failed ListCachedUsers call"); - g_object_unref (manager); - return; - } - - load_user_paths (manager, (const char * const *) user_paths); - g_strfreev (user_paths); - - load_included_usernames (manager); - - g_debug ("ActUserManager: unrefing manager owned by finished ListCachedUsers call"); - g_object_unref (manager); - } - - static void - on_get_x11_display_finished (GObject *object, - GAsyncResult *result, - gpointer data) - { - ConsoleKitSession *proxy = CONSOLE_KIT_SESSION (object); - ActUserManagerNewSession *new_session = data; - GError *error = NULL; --- -2.14.1 - diff --git a/SOURCES/0013-lib-only-track-users-after-act_user_manager_list_use.patch b/SOURCES/0013-lib-only-track-users-after-act_user_manager_list_use.patch deleted file mode 100644 index a0cce3e..0000000 --- a/SOURCES/0013-lib-only-track-users-after-act_user_manager_list_use.patch +++ /dev/null @@ -1,741 +0,0 @@ -From b1ec3114a49c9e5331a4f7c106a58867499ac1ce Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 4 Oct 2017 11:28:50 -0400 -Subject: [PATCH 13/13] lib: only track users after act_user_manager_list_users - -At the moment, as soon as someone calls -act_user_manager_get_default() we end up firing of an asynchronous -call to get a list of all users. This is problematic since not all -programs using accountsservice want a list of users. - -This commit changes the code to only get a list of users when the -caller invokes act_user_manager_list_users. This does mean some calls -that were async before are synchronous now, but user proxies were -always obtained synchronously, and they're by far the slowest part -of listing users, so I don't expect this introduce any noticeable -blocking. - -Longer term, to fix the sync i/o bits, I think we should -probably ditch libaccountsservice and just make accountsservice use -ObjectManager interfaces over d-bus. ---- - src/libaccountsservice/act-user-manager.c | 145 +++++++++++++++--------------- - 1 file changed, 75 insertions(+), 70 deletions(-) - -diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c -index 11049e0..d0b38e2 100644 ---- a/src/libaccountsservice/act-user-manager.c -+++ b/src/libaccountsservice/act-user-manager.c -@@ -172,92 +172,93 @@ typedef struct - }; - char *object_path; - char *description; - } ActUserManagerFetchUserRequest; - - struct ActUserManagerPrivate - { - GHashTable *normal_users_by_name; - GHashTable *system_users_by_name; - GHashTable *users_by_object_path; - GHashTable *sessions; - GDBusConnection *connection; - AccountsAccounts *accounts_proxy; - ConsoleKitManager *ck_manager_proxy; - - ActUserManagerSeat seat; - - GSList *new_sessions; - GSList *new_users; - GSList *new_users_inhibiting_load; - GSList *fetch_user_requests; - - GSList *exclude_usernames; - GSList *include_usernames; - - guint load_id; - - gboolean is_loaded; - gboolean has_multiple_users; - gboolean getting_sessions; -- gboolean listing_cached_users; - gboolean list_cached_users_done; - }; - - enum { - PROP_0, - 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 act_user_manager_class_init (ActUserManagerClass *klass); - static void act_user_manager_init (ActUserManager *user_manager); - static void act_user_manager_finalize (GObject *object); - - static gboolean ensure_accounts_proxy (ActUserManager *manager); - static gboolean load_seat_incrementally (ActUserManager *manager); - static void unload_seat (ActUserManager *manager); - static void load_users (ActUserManager *manager); -+static void load_user (ActUserManager *manager, -+ const char *username); - static void act_user_manager_queue_load (ActUserManager *manager); --static void queue_load_seat_and_users (ActUserManager *manager); -+static void queue_load_seat (ActUserManager *manager); - - static void load_new_session_incrementally (ActUserManagerNewSession *new_session); - static void set_is_loaded (ActUserManager *manager, gboolean is_loaded); - - static void on_new_user_loaded (ActUser *user, - GParamSpec *pspec, - ActUserManager *manager); - static void give_up (ActUserManager *manager, - ActUserManagerFetchUserRequest *request); - static void fetch_user_incrementally (ActUserManagerFetchUserRequest *request); - - static void maybe_set_is_loaded (ActUserManager *manager); - static void update_user (ActUserManager *manager, - ActUser *user); - static gpointer user_manager_object = NULL; - - G_DEFINE_TYPE (ActUserManager, act_user_manager, G_TYPE_OBJECT) - - static const GDBusErrorEntry error_entries[] = { - { ACT_USER_MANAGER_ERROR_FAILED, "org.freedesktop.Accounts.Error.Failed" }, - { ACT_USER_MANAGER_ERROR_USER_EXISTS, "org.freedesktop.Accounts.Error.UserExists" }, - { ACT_USER_MANAGER_ERROR_USER_DOES_NOT_EXIST, "org.freedesktop.Accounts.Error.UserDoesNotExist" }, - { ACT_USER_MANAGER_ERROR_PERMISSION_DENIED, "org.freedesktop.Accounts.Error.PermissionDenied" }, - { ACT_USER_MANAGER_ERROR_NOT_SUPPORTED, "org.freedesktop.Accounts.Error.NotSupported" } - }; - - GQuark - act_user_manager_error_quark (void) - { - static volatile gsize ret = 0; -@@ -711,91 +712,87 @@ on_get_seat_id_finished (GObject *object, - GAsyncResult *result, - gpointer data) - { - ConsoleKitSession *proxy = CONSOLE_KIT_SESSION (object); - ActUserManager *manager = data; - GError *error = NULL; - char *seat_id; - - if (!console_kit_session_call_get_seat_id_finish (proxy, &seat_id, result, &error)) { - 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"); - } - - g_debug ("ActUserManager: GetSeatId call failed, so unloading seat"); - unload_seat (manager); - - goto out; - } - - g_debug ("ActUserManager: Found current seat: %s", seat_id); - - manager->priv->seat.id = seat_id; - manager->priv->seat.state++; - -- load_seat_incrementally (manager); -- - out: - g_debug ("ActUserManager: unrefing manager owned by GetSeatId request"); - g_object_unref (manager); - } - - #ifdef WITH_SYSTEMD - static void - _get_systemd_seat_id (ActUserManager *manager) - { - int res; - char *seat_id; - - res = sd_session_get_seat (NULL, &seat_id); - - if (res == -ENOENT) { - seat_id = NULL; - } else if (res < 0) { - g_warning ("Could not get current seat: %s", - strerror (-res)); - unload_seat (manager); - return; - } - - manager->priv->seat.id = g_strdup (seat_id); - free (seat_id); - - manager->priv->seat.state++; -- -- queue_load_seat_incrementally (manager); - } - #endif - - static void - get_seat_id_for_current_session (ActUserManager *manager) - { - #ifdef WITH_SYSTEMD - if (LOGIND_RUNNING()) { - _get_systemd_seat_id (manager); - return; - } - #endif - console_kit_session_call_get_seat_id (manager->priv->seat.session_proxy, - NULL, - on_get_seat_id_finished, - g_object_ref (manager)); - } - - static gint - match_name_cmpfunc (gconstpointer a, - gconstpointer b) - { - return g_strcmp0 ((char *) a, - (char *) b); - } - - static gboolean - username_in_exclude_list (ActUserManager *manager, - const char *username) - { -@@ -1520,106 +1517,64 @@ load_user_paths (ActUserManager *manager, - /* We now have a batch of unloaded users that we know about. Once that initial - * batch is loaded up, we can mark the manager as loaded. - * - * (see on_new_user_loaded) - */ - if (g_strv_length ((char **) user_paths) > 0) { - int i; - - g_debug ("ActUserManager: ListCachedUsers finished, will set loaded property after list is fully loaded"); - for (i = 0; user_paths[i] != NULL; i++) { - ActUser *user; - - user = add_new_user_for_object_path (user_paths[i], manager); - if (!manager->priv->is_loaded) { - manager->priv->new_users_inhibiting_load = g_slist_prepend (manager->priv->new_users_inhibiting_load, user); - } - } - } else { - g_debug ("ActUserManager: ListCachedUsers finished with empty list, maybe setting loaded property now"); - maybe_set_is_loaded (manager); - } - } - - static void - load_included_usernames (ActUserManager *manager) - { - GSList *l; - - /* Add users who are specifically included */ - for (l = manager->priv->include_usernames; l != NULL; l = l->next) { -- ActUser *user; -- - g_debug ("ActUserManager: Adding included user %s", (char *)l->data); -- /* -- * The call to act_user_manager_get_user will add the user if it is -- * valid and not already in the hash. -- */ -- user = act_user_manager_get_user (manager, l->data); -- if (user == NULL) { -- g_debug ("ActUserManager: unable to lookup user '%s'", (char *)l->data); -- } -- } --} -- --static void --on_list_cached_users_finished (GObject *object, -- GAsyncResult *result, -- gpointer data) --{ -- AccountsAccounts *proxy = ACCOUNTS_ACCOUNTS (object); -- ActUserManager *manager = data; -- gchar **user_paths; -- GError *error = NULL; -- -- manager->priv->listing_cached_users = FALSE; -- manager->priv->list_cached_users_done = TRUE; -- -- if (!accounts_accounts_call_list_cached_users_finish (proxy, &user_paths, result, &error)) { -- g_debug ("ActUserManager: ListCachedUsers failed: %s", error->message); -- g_error_free (error); -- -- g_object_unref (manager->priv->accounts_proxy); -- manager->priv->accounts_proxy = NULL; - -- g_debug ("ActUserManager: unrefing manager owned by failed ListCachedUsers call"); -- g_object_unref (manager); -- return; -+ load_user (manager, l->data); - } -- -- load_user_paths (manager, (const char * const *) user_paths); -- g_strfreev (user_paths); -- -- load_included_usernames (manager); -- -- g_debug ("ActUserManager: unrefing manager owned by finished ListCachedUsers call"); -- g_object_unref (manager); - } - - static void - on_get_x11_display_finished (GObject *object, - GAsyncResult *result, - gpointer data) - { - ConsoleKitSession *proxy = CONSOLE_KIT_SESSION (object); - ActUserManagerNewSession *new_session = data; - GError *error = NULL; - char *x11_display; - - new_session->pending_calls--; - - if (new_session->cancellable == NULL || g_cancellable_is_cancelled (new_session->cancellable)) { - unload_new_session (new_session); - return; - } - - if (!console_kit_session_call_get_x11_display_finish (proxy, &x11_display, result, &error)) { - 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; -@@ -2361,60 +2316,99 @@ fetch_user_with_id_from_accounts_service (ActUserManager *manager, - * from @manager. Trying to use this object before its - * #ActUser:is-loaded property is %TRUE will result in undefined - * behavior. - * - * Returns: (transfer none): #ActUser object - **/ - ActUser * - act_user_manager_get_user (ActUserManager *manager, - const char *username) - { - ActUser *user; - - g_return_val_if_fail (ACT_IS_USER_MANAGER (manager), NULL); - g_return_val_if_fail (username != NULL && username[0] != '\0', NULL); - - user = lookup_user_by_name (manager, username); - - /* if we don't have it loaded try to load it now */ - if (user == NULL) { - g_debug ("ActUserManager: trying to track new user with username %s", username); - user = create_new_user (manager); - - if (manager->priv->accounts_proxy != NULL) { - fetch_user_with_username_from_accounts_service (manager, user, username); - } - } - - return user; - } - -+static void -+load_user (ActUserManager *manager, -+ const char *username) -+{ -+ ActUser *user; -+ GError *error = NULL; -+ char *object_path = NULL; -+ gboolean user_found; -+ -+ g_return_if_fail (ACT_IS_USER_MANAGER (manager)); -+ g_return_if_fail (username != NULL && username[0] != '\0'); -+ -+ user = lookup_user_by_name (manager, username); -+ -+ if (user == NULL) { -+ g_debug ("ActUserManager: trying to track new user with username %s", username); -+ user = create_new_user (manager); -+ } -+ -+ user_found = accounts_accounts_call_find_user_by_name_sync (manager->priv->accounts_proxy, -+ username, -+ &object_path, -+ NULL, -+ &error); -+ -+ if (!user_found) { -+ if (error != NULL) { -+ g_debug ("ActUserManager: Failed to find user '%s': %s", -+ username, error->message); -+ g_clear_error (&error); -+ } else { -+ g_debug ("ActUserManager: Failed to find user '%s'", -+ username); -+ } -+ } -+ -+ _act_user_update_from_object_path (user, object_path); -+} -+ - /** - * act_user_manager_get_user_by_id: - * @manager: the manager to query. - * @id: the uid of the user to get. - * - * Retrieves a pointer to the #ActUser object for the user with the - * given uid from @manager. Trying to use this object before its - * #ActUser:is-loaded property is %TRUE will result in undefined - * behavior. - * - * Returns: (transfer none): #ActUser object - */ - ActUser * - act_user_manager_get_user_by_id (ActUserManager *manager, - uid_t id) - { - ActUser *user; - gchar *object_path; - - g_return_val_if_fail (ACT_IS_USER_MANAGER (manager), NULL); - - object_path = g_strdup_printf ("/org/freedesktop/Accounts/User%lu", (gulong) id); - user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path); - g_free (object_path); - - if (user != NULL) { - return g_object_ref (user); - } else { - g_debug ("ActUserManager: trying to track new user with uid %lu", (gulong) id); - user = create_new_user (manager); -@@ -2425,93 +2419,95 @@ act_user_manager_get_user_by_id (ActUserManager *manager, - } - - return user; - } - - static void - listify_hash_values_hfunc (gpointer key, - gpointer value, - gpointer user_data) - { - GSList **list = user_data; - - *list = g_slist_prepend (*list, value); - } - - /** - * act_user_manager_list_users: - * @manager: a #ActUserManager - * - * Get a list of system user accounts - * - * Returns: (element-type ActUser) (transfer container): List of #ActUser objects - */ - GSList * - act_user_manager_list_users (ActUserManager *manager) - { - GSList *retval; - - g_return_val_if_fail (ACT_IS_USER_MANAGER (manager), NULL); - -+ if (!manager->priv->list_cached_users_done) { -+ load_users (manager); -+ -+ if (manager->priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_GET_SEAT_PROXY) -+ queue_load_seat_incrementally (manager); -+ } -+ - retval = NULL; - g_hash_table_foreach (manager->priv->normal_users_by_name, listify_hash_values_hfunc, &retval); - - return g_slist_sort (retval, (GCompareFunc) act_user_collate); - } - - static void - maybe_set_is_loaded (ActUserManager *manager) - { - if (manager->priv->is_loaded) { - g_debug ("ActUserManager: already loaded, so not setting loaded property"); - return; - } - - if (manager->priv->getting_sessions) { - g_debug ("ActUserManager: GetSessions call pending, so not setting loaded property"); - return; - } - -- if (manager->priv->listing_cached_users) { -- g_debug ("ActUserManager: Listing cached users, so not setting loaded property"); -- return; -- } -- - if (manager->priv->new_users_inhibiting_load != NULL) { - g_debug ("ActUserManager: Loading new users, so not setting loaded property"); - return; - } - -- /* Don't set is_loaded yet unless the seat is already loaded -+ /* Don't set is_loaded yet unless the seat is already loaded enough - * or failed to load. - */ -- if (manager->priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_LOADED) { -+ if (manager->priv->seat.state >= ACT_USER_MANAGER_SEAT_STATE_GET_ID) { - g_debug ("ActUserManager: Seat loaded, so now setting loaded property"); - } else if (manager->priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_UNLOADED) { - g_debug ("ActUserManager: Seat wouldn't load, so giving up on it and setting loaded property"); - } else { - g_debug ("ActUserManager: Seat still actively loading, so not setting loaded property"); - return; - } - - set_is_loaded (manager, TRUE); - } - - - 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 -@@ -2555,125 +2551,134 @@ static void - load_console_kit_sessions (ActUserManager *manager) - { - if (manager->priv->seat.seat_proxy == NULL) { - g_debug ("ActUserManager: no seat proxy; can't load sessions"); - return; - } - - manager->priv->getting_sessions = TRUE; - console_kit_seat_call_get_sessions (manager->priv->seat.seat_proxy, - NULL, - on_get_sessions_finished, - g_object_ref (manager)); - } - - static void - load_sessions (ActUserManager *manager) - { - #ifdef WITH_SYSTEMD - if (LOGIND_RUNNING()) { - reload_systemd_sessions (manager); - maybe_set_is_loaded (manager); - return; - } - #endif - load_console_kit_sessions (manager); - } - - static void - load_users (ActUserManager *manager) - { -- g_assert (manager->priv->accounts_proxy != NULL); -- g_debug ("ActUserManager: calling 'ListCachedUsers'"); -+ GError *error = NULL; -+ char **user_paths = NULL; -+ gboolean could_list = FALSE; - - if (!ensure_accounts_proxy (manager)) { - return; - } - -- accounts_accounts_call_list_cached_users (manager->priv->accounts_proxy, -- NULL, -- on_list_cached_users_finished, -- g_object_ref (manager)); -- manager->priv->listing_cached_users = TRUE; -+ g_debug ("ActUserManager: calling 'ListCachedUsers'"); -+ -+ could_list = accounts_accounts_call_list_cached_users_sync (manager->priv->accounts_proxy, -+ &user_paths, -+ NULL, &error); -+ -+ if (!could_list) { -+ g_debug ("ActUserManager: ListCachedUsers failed: %s", error->message); -+ g_clear_error (&error); -+ return; -+ } -+ -+ load_user_paths (manager, (const char * const *) user_paths); -+ g_strfreev (user_paths); -+ -+ load_included_usernames (manager); -+ -+ manager->priv->list_cached_users_done = TRUE; - } - - static gboolean - load_seat_incrementally (ActUserManager *manager) - { - manager->priv->seat.load_idle_id = 0; - - switch (manager->priv->seat.state) { - case ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_ID: - get_current_session_id (manager); - break; - case ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_PROXY: - get_session_proxy (manager); - break; - case ACT_USER_MANAGER_SEAT_STATE_GET_ID: - get_seat_id_for_current_session (manager); - break; - case ACT_USER_MANAGER_SEAT_STATE_GET_SEAT_PROXY: - get_seat_proxy (manager); - break; - case ACT_USER_MANAGER_SEAT_STATE_LOADED: - g_debug ("ActUserManager: Seat loading sequence complete"); - break; - default: - g_assert_not_reached (); - } - - if (manager->priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_LOADED) { - load_sessions (manager); - } - - maybe_set_is_loaded (manager); - - return FALSE; - } - - static gboolean - load_idle (ActUserManager *manager) - { -- /* The order below is important: load_seat_incrementally might -- set "is-loaded" immediately and we thus need to call -- load_users before it. -- */ -- load_users (manager); - manager->priv->seat.state = ACT_USER_MANAGER_SEAT_STATE_UNLOADED + 1; - load_seat_incrementally (manager); - manager->priv->load_id = 0; - - return FALSE; - } - - static void --queue_load_seat_and_users (ActUserManager *manager) -+queue_load_seat (ActUserManager *manager) - { - if (manager->priv->load_id > 0) { - return; - } - - manager->priv->load_id = g_idle_add ((GSourceFunc)load_idle, manager); - } - - static void - act_user_manager_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) - { - ActUserManager *manager; - - manager = ACT_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_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); -@@ -2820,61 +2825,61 @@ act_user_manager_class_init (ActUserManagerClass *klass) - * @user: the #ActUser that changed - * - * One of the users has changed - */ - signals [USER_CHANGED] = - g_signal_new ("user-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ActUserManagerClass, user_changed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, ACT_TYPE_USER); - - g_type_class_add_private (klass, sizeof (ActUserManagerPrivate)); - } - - /** - * act_user_manager_queue_load: - * @manager: a #ActUserManager - * - * Queue loading users into user manager. This must be called, and the - * #ActUserManager:is-loaded property must be %TRUE before calling - * act_user_manager_list_users() - */ - static void - act_user_manager_queue_load (ActUserManager *manager) - { - g_return_if_fail (ACT_IS_USER_MANAGER (manager)); - - if (! manager->priv->is_loaded) { -- queue_load_seat_and_users (manager); -+ queue_load_seat (manager); - } - } - - static gboolean - ensure_accounts_proxy (ActUserManager *manager) - { - GError *error = NULL; - - if (manager->priv->accounts_proxy != NULL) { - return TRUE; - } - - manager->priv->accounts_proxy = accounts_accounts_proxy_new_sync (manager->priv->connection, - G_DBUS_PROXY_FLAGS_NONE, - ACCOUNTS_NAME, - ACCOUNTS_PATH, - NULL, - &error); - if (error != NULL) { - g_debug ("ActUserManager: getting account proxy failed: %s", error->message); - g_clear_error (&error); - return FALSE; - } - - g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (manager->priv->accounts_proxy), G_MAXINT); - - g_object_bind_property (G_OBJECT (manager->priv->accounts_proxy), - "has-multiple-users", - G_OBJECT (manager), - "has-multiple-users", --- -2.14.1 - diff --git a/SOURCES/0014-lib-fix-crasher-if-accounts-proxy-is-unavailable.patch b/SOURCES/0014-lib-fix-crasher-if-accounts-proxy-is-unavailable.patch deleted file mode 100644 index 68b8d1a..0000000 --- a/SOURCES/0014-lib-fix-crasher-if-accounts-proxy-is-unavailable.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 4e22d1a68e8ddcdea761fc51ea8c2ced0055fe60 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 3 Nov 2017 09:47:04 -0400 -Subject: [PATCH 14/14] lib: fix crasher if accounts proxy is unavailable - -Right now if the accounts proxy is unavailable act_user_get_real_name -crashes instead of returning NULL as advertised. - -This commit makes it return NULL. - -https://bugs.freedesktop.org/show_bug.cgi?id=103560 ---- - src/libaccountsservice/act-user.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c -index 94884a1..a24f25a 100644 ---- a/src/libaccountsservice/act-user.c -+++ b/src/libaccountsservice/act-user.c -@@ -520,60 +520,63 @@ set_is_loaded (ActUser *user, - * freed, or %NULL. - **/ - - uid_t - act_user_get_uid (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), -1); - - if (user->accounts_proxy == NULL) - return -1; - - return accounts_user_get_uid (user->accounts_proxy); - } - - /** - * act_user_get_real_name: - * @user: the user object to examine. - * - * Retrieves the display name of @user. - * - * Returns: (transfer none): a pointer to an array of characters which must not be modified or - * freed, or %NULL. - **/ - const char * - act_user_get_real_name (ActUser *user) - { - const char *real_name = NULL; - - g_return_val_if_fail (ACT_IS_USER (user), NULL); - -+ if (user->accounts_proxy == NULL) -+ return NULL; -+ - real_name = accounts_user_get_real_name (user->accounts_proxy); - - if (real_name == NULL || real_name[0] == '\0') { - real_name = accounts_user_get_user_name (user->accounts_proxy); - } - - return real_name; - } - - /** - * act_user_get_account_type: - * @user: the user object to examine. - * - * Retrieves the account type of @user. - * - * Returns: a #ActUserAccountType - **/ - ActUserAccountType - act_user_get_account_type (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), ACT_USER_ACCOUNT_TYPE_STANDARD); - - if (user->accounts_proxy == NULL) - return ACT_USER_ACCOUNT_TYPE_STANDARD; - - return accounts_user_get_account_type (user->accounts_proxy); - } - - /** - * act_user_get_password_mode: --- -2.14.2 - diff --git a/SOURCES/0015-act-user-Prevent-segfault-if-accounts_proxy-is-not-c.patch b/SOURCES/0015-act-user-Prevent-segfault-if-accounts_proxy-is-not-c.patch deleted file mode 100644 index b6b10fe..0000000 --- a/SOURCES/0015-act-user-Prevent-segfault-if-accounts_proxy-is-not-c.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 919e8972a6635539499f153a28d92e0c4052b354 Mon Sep 17 00:00:00 2001 -From: Ondrej Holy -Date: Tue, 30 Jan 2018 08:58:20 +0100 -Subject: [PATCH 15/15] act-user: Prevent segfault if accounts_proxy is not - created - -act_user_get_locked may segfault if accounts_proxy is not created (e.g. -when run under root). All other functions which rely on accounts_proxy -already contain checks for NULL and valid ActUser. Do the same also in -act_user_get_locked in order to avoid segfaults in certain cases. - -https://bugs.freedesktop.org/show_bug.cgi?id=104851 ---- - src/libaccountsservice/act-user.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c -index a24f25a..e21c9db 100644 ---- a/src/libaccountsservice/act-user.c -+++ b/src/libaccountsservice/act-user.c -@@ -859,60 +859,65 @@ act_user_is_logged_in (ActUser *user) - - /** - * act_user_is_logged_in_anywhere: - * @user: a #ActUser - * - * Returns whether or not #ActUser is currently logged in in any way - * whatsoever. See also act_user_is_logged_in(). - * - * (Currently, this function is only implemented for systemd-logind. - * For ConsoleKit, it is equivalent to act_user_is_logged_in.) - * - * Returns: %TRUE or %FALSE - */ - gboolean - act_user_is_logged_in_anywhere (ActUser *user) - { - return user->our_sessions != NULL || user->other_sessions != NULL; - } - - /** - * act_user_get_locked: - * @user: a #ActUser - * - * Returns whether or not the #ActUser account is locked. - * - * Returns: %TRUE or %FALSE - */ - gboolean - act_user_get_locked (ActUser *user) - { -+ g_return_val_if_fail (ACT_IS_USER (user), TRUE); -+ -+ if (user->accounts_proxy == NULL) -+ return TRUE; -+ - return accounts_user_get_locked (user->accounts_proxy); - } - - /** - * act_user_get_automatic_login: - * @user: a #ActUser - * - * Returns whether or not #ActUser is automatically logged in at boot time. - * - * Returns: %TRUE or %FALSE - */ - gboolean - act_user_get_automatic_login (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), FALSE); - - if (user->accounts_proxy == NULL) - return FALSE; - - return accounts_user_get_automatic_login (user->accounts_proxy); - } - - /** - * act_user_is_system_account: - * @user: a #ActUser - * - * Returns whether or not #ActUser represents a 'system account' like - * 'root' or 'nobody'. - * - * Returns: %TRUE or %FALSE --- -2.14.3 - diff --git a/SOURCES/0016-daemon-don-t-return-account-expiration-policy-if-not.patch b/SOURCES/0016-daemon-don-t-return-account-expiration-policy-if-not.patch deleted file mode 100644 index ca01fd1..0000000 --- a/SOURCES/0016-daemon-don-t-return-account-expiration-policy-if-not.patch +++ /dev/null @@ -1,214 +0,0 @@ -From 7facd87e8ba34654fc9c46b4a42943e92acafffb Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 7 Feb 2018 11:03:21 -0500 -Subject: [PATCH 16/16] daemon: don't return account expiration policy if not - known - -Right now we assume the user's shadow entry will always be available. -If it's not available, we return fields from it initialized to 0. - -That leads to spurious password expired notifications in GNOME. - -This commit throws a NOT_SUPPORTED error if the shadow file is off -limits. ---- - src/user.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/user.c b/src/user.c -index a83cfe4..cf7eb26 100644 ---- a/src/user.c -+++ b/src/user.c -@@ -79,60 +79,61 @@ struct User { - gchar *object_path; - - Daemon *daemon; - - GKeyFile *keyfile; - - uid_t uid; - gid_t gid; - gchar *user_name; - gchar *real_name; - AccountType account_type; - PasswordMode password_mode; - gchar *password_hint; - gchar *home_dir; - gchar *shell; - gchar *email; - gchar *language; - gchar *x_session; - gchar *location; - guint64 login_frequency; - gint64 login_time; - gint64 expiration_time; - gint64 last_change_time; - gint64 min_days_between_changes; - gint64 max_days_between_changes; - gint64 days_to_warn; - gint64 days_after_expiration_until_lock; - GVariant *login_history; - gchar *icon_file; - gchar *default_icon_file; -+ gboolean account_expiration_policy_known; - gboolean locked; - gboolean automatic_login; - gboolean system_account; - gboolean local_account; - gboolean cached; - - guint *extension_ids; - guint n_extension_ids; - }; - - typedef struct UserClass - { - AccountsUserSkeletonClass parent_class; - } UserClass; - - static void user_accounts_user_iface_init (AccountsUserIface *iface); - - G_DEFINE_TYPE_WITH_CODE (User, user, ACCOUNTS_TYPE_USER_SKELETON, G_IMPLEMENT_INTERFACE (ACCOUNTS_TYPE_USER, user_accounts_user_iface_init)); - - static gint - account_type_from_pwent (struct passwd *pwent) - { - struct group *grp; - gint i; - - if (pwent->pw_uid == 0) { - g_debug ("user is root so account type is administrator"); - return ACCOUNT_TYPE_ADMINISTRATOR; - } - -@@ -261,60 +262,61 @@ user_update_from_pwent (User *user, - locked = TRUE; - } - else { - locked = FALSE; - } - - if (user->locked != locked) { - user->locked = locked; - changed = TRUE; - g_object_notify (G_OBJECT (user), "locked"); - } - - if (passwd == NULL || passwd[0] != 0) { - mode = PASSWORD_MODE_REGULAR; - } - else { - mode = PASSWORD_MODE_NONE; - } - - if (spent) { - if (spent->sp_lstchg == 0) { - mode = PASSWORD_MODE_SET_AT_LOGIN; - } - - user->expiration_time = spent->sp_expire; - user->last_change_time = spent->sp_lstchg; - user->min_days_between_changes = spent->sp_min; - user->max_days_between_changes = spent->sp_max; - user->days_to_warn = spent->sp_warn; - user->days_after_expiration_until_lock = spent->sp_inact; -+ user->account_expiration_policy_known = TRUE; - } - - if (user->password_mode != mode) { - user->password_mode = mode; - changed = TRUE; - g_object_notify (G_OBJECT (user), "password-mode"); - } - - user->system_account = !user_classify_is_human (user->uid, user->user_name, pwent->pw_shell, passwd); - - g_object_thaw_notify (G_OBJECT (user)); - - if (changed) - accounts_user_emit_changed (ACCOUNTS_USER (user)); - } - - void - user_update_from_keyfile (User *user, - GKeyFile *keyfile) - { - gchar *s; - - g_object_freeze_notify (G_OBJECT (user)); - - s = g_key_file_get_string (keyfile, "User", "Language", NULL); - if (s != NULL) { - /* TODO: validate / normalize */ - g_free (user->language); - user->language = s; - g_object_notify (G_OBJECT (user), "language"); -@@ -1154,60 +1156,65 @@ user_set_x_session (AccountsUser *auser, - - if (!get_caller_uid (context, &uid)) { - throw_error (context, ERROR_FAILED, "identifying caller failed"); - return FALSE; - } - - if (user->uid == (uid_t) uid) - action_id = "org.freedesktop.accounts.change-own-user-data"; - else - action_id = "org.freedesktop.accounts.user-administration"; - - daemon_local_check_auth (user->daemon, - user, - action_id, - TRUE, - user_change_x_session_authorized_cb, - context, - g_strdup (x_session), - (GDestroyNotify) g_free); - - return TRUE; - } - - static void - user_get_password_expiration_policy_authorized_cb (Daemon *daemon, - User *user, - GDBusMethodInvocation *context, - gpointer data) - - { -+ if (!user->account_expiration_policy_known) { -+ throw_error (context, ERROR_NOT_SUPPORTED, "account expiration policy unknown to accounts service"); -+ return; -+ } -+ - accounts_user_complete_get_password_expiration_policy (ACCOUNTS_USER (user), - context, - user->expiration_time, - user->last_change_time, - user->min_days_between_changes, - user->max_days_between_changes, - user->days_to_warn, - user->days_after_expiration_until_lock); - } - - static gboolean - user_get_password_expiration_policy (AccountsUser *auser, - GDBusMethodInvocation *context) - { - User *user = (User*)auser; - int uid; - const gchar *action_id; - - if (!get_caller_uid (context, &uid)) { - throw_error (context, ERROR_FAILED, "identifying caller failed"); - return FALSE; - } - - if (user->uid == (uid_t) uid) - action_id = "org.freedesktop.accounts.change-own-user-data"; - else - action_id = "org.freedesktop.accounts.user-administration"; - - daemon_local_check_auth (user->daemon, - user, --- -2.14.3 - diff --git a/SOURCES/0017-lib-don-t-try-to-update-login-frequency-manually.patch b/SOURCES/0017-lib-don-t-try-to-update-login-frequency-manually.patch deleted file mode 100644 index 5115683..0000000 --- a/SOURCES/0017-lib-don-t-try-to-update-login-frequency-manually.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 94e16cbaba4e727af4fe40a039110c5d0f0eb467 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 14 Feb 2018 10:00:19 -0500 -Subject: [PATCH 17/17] lib: don't try to update login frequency manually - -The library will try to update the login frequency to 1 if the -requested user isn't finished asynchronously loading yet, but we -know they have an open session. - -That no longer works, since we no longer track login-frequency -separately from the dbus proxy object. - -This commit drops the code, since it's unnecessary anyway. - -To be "on the safe side" we change the value returned for unloaded -users from 0 to 1. This is okay because the value is undefined -before the user is loaded anyway. ---- - src/libaccountsservice/act-user-manager.c | 6 ------ - src/libaccountsservice/act-user.c | 2 +- - 2 files changed, 1 insertion(+), 7 deletions(-) - -diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c -index 6c6628b..6efb772 100644 ---- a/src/libaccountsservice/act-user-manager.c -+++ b/src/libaccountsservice/act-user-manager.c -@@ -1663,66 +1663,60 @@ get_x11_display_for_new_session (ActUserManagerNewSession *new_session) - static void - maybe_add_new_session (ActUserManagerNewSession *new_session) - { - ActUserManager *manager; - ActUser *user; - gboolean is_ours; - - manager = ACT_USER_MANAGER (new_session->manager); - - is_ours = TRUE; - - if (new_session->x11_display == NULL) { - g_debug ("AcUserManager: (mostly) ignoring session '%s' since it's not graphical", - new_session->id); - is_ours = FALSE; - } else if (session_is_login_window (manager, new_session->id)) { - new_session->state = ACT_USER_MANAGER_NEW_SESSION_STATE_LOADED; - unload_new_session (new_session); - return; - } else if (!session_is_on_our_seat (manager, new_session->id)) { - is_ours = FALSE; - } - - user = act_user_manager_get_user_by_id (manager, new_session->uid); - if (user == NULL) { - unload_new_session (new_session); - return; - } - - add_session_for_user (manager, user, new_session->id, is_ours); -- -- /* if we haven't yet gotten the login frequency -- then at least add one because the session exists */ -- if (act_user_get_login_frequency (user) == 0) { -- _act_user_update_login_frequency (user, 1); -- } - } - - static void - load_new_session (ActUserManager *manager, - const char *session_id) - { - ActUserManagerNewSession *new_session; - - new_session = g_slice_new0 (ActUserManagerNewSession); - - new_session->manager = g_object_ref (manager); - new_session->id = g_strdup (session_id); - new_session->state = ACT_USER_MANAGER_NEW_SESSION_STATE_UNLOADED + 1; - new_session->cancellable = g_cancellable_new (); - - manager->priv->new_sessions = g_slist_prepend (manager->priv->new_sessions, - new_session); - load_new_session_incrementally (new_session); - } - - static void - seat_session_added (GDBusProxy *seat_proxy, - const char *session_id, - ActUserManager *manager) - { - g_debug ("ActUserManager: Session added: %s", session_id); - - load_new_session (manager, session_id); - } - -diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c -index e21c9db..bc8b7f8 100644 ---- a/src/libaccountsservice/act-user.c -+++ b/src/libaccountsservice/act-user.c -@@ -705,61 +705,61 @@ act_user_get_location (ActUser *user) - * - * Returns: (transfer none): a pointer to an array of characters which must not be modified or - * freed, or %NULL. - **/ - - const char * - act_user_get_user_name (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), NULL); - - if (user->accounts_proxy == NULL) - return NULL; - - return accounts_user_get_user_name (user->accounts_proxy); - } - - /** - * act_user_get_login_frequency: - * @user: a #ActUser - * - * Returns the number of times @user has logged in. - * - * Returns: the login frequency - */ - int - act_user_get_login_frequency (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), 0); - - if (user->accounts_proxy == NULL) -- return 0; -+ return 1; - - return accounts_user_get_login_frequency (user->accounts_proxy); - } - - /** - * act_user_get_login_time: - * @user: a #ActUser - * - * Returns the last login time for @user. - * - * Returns: (transfer none): the login time - */ - gint64 - act_user_get_login_time (ActUser *user) - { - g_return_val_if_fail (ACT_IS_USER (user), 0); - - if (user->accounts_proxy == NULL) - return 0; - - return accounts_user_get_login_time (user->accounts_proxy); - } - - /** - * act_user_get_login_history: - * @user: a #ActUser - * - * Returns the login history for @user. - * - * Returns: (transfer none): a pointer to GVariant of type "a(xxa{sv})" --- -2.14.3 - diff --git a/SPECS/accountsservice.spec b/SPECS/accountsservice.spec index 5e13e8d..e65eb2f 100644 --- a/SPECS/accountsservice.spec +++ b/SPECS/accountsservice.spec @@ -1,13 +1,12 @@ %global _hardened_build 1 Name: accountsservice -Version: 0.6.45 -Release: 7%{?dist} +Version: 0.6.50 +Release: 2%{?dist} Summary: D-Bus interfaces for querying and manipulating user account information - -Group: System Environment/Daemons License: GPLv3+ -URL: http://www.fedoraproject.org/wiki/Features/UserAccountDialog +URL: https://www.freedesktop.org/wiki/Software/AccountsService/ + #VCS: git:git://git.freedesktop.org/accountsservice Source0: http://www.freedesktop.org/software/accountsservice/accountsservice-%{version}.tar.xz @@ -23,32 +22,15 @@ BuildRequires: git Requires: polkit Requires: shadow-utils -Requires(post): systemd-units -Requires(preun): systemd-units -Requires(postun): systemd-units - -Patch0: 0001-daemon-don-t-treat-explicitly-requested-users-as-cac.patch -Patch1: 0001-lib-move-g_object_ref-call-for-clarity.patch -Patch2: 0002-lib-leak-fix.patch -Patch3: 0003-lib-another-leak-fix.patch -Patch4: 0004-daemon-don-t-send-spurious-change-signals-when-wtmp-.patch -Patch5: 0005-lib-consolidate-change-notification.patch -Patch6: 0006-daemon-add-new-HasMultipleUsers-and-HasNoUsers-prope.patch -Patch7: 0007-lib-use-new-has-multiple-users-property-from-account.patch -Patch8: 0008-lib-factor-user-loading-functions-into-helpers.patch -Patch9: 0009-lib-move-accounts-proxy-creation-to-helper.patch -Patch10: 0010-lib-retry-connecting-to-accountsservice-when-loading.patch -Patch11: 0011-lib-simplify-code-dramatically.patch -Patch12: 0012-lib-don-t-track-user-added-user-removed-until-we-get.patch -Patch13: 0013-lib-only-track-users-after-act_user_manager_list_use.patch -Patch14: 0014-lib-fix-crasher-if-accounts-proxy-is-unavailable.patch -Patch15: 0015-act-user-Prevent-segfault-if-accounts_proxy-is-not-c.patch -Patch16: 0016-daemon-don-t-return-account-expiration-policy-if-not.patch -Patch17: 0017-lib-don-t-try-to-update-login-frequency-manually.patch +Patch0: 0001-lib-don-t-set-loaded-state-until-seat-is-fetched.patch + +%description +The accountsservice project provides a set of D-Bus interfaces for +querying and manipulating user account information and an implementation +of these interfaces, based on the useradd, usermod and userdel commands. %package libs Summary: Client-side library to talk to accountsservice -Group: Development/Libraries Requires: %{name} = %{version}-%{release} %description libs @@ -56,10 +38,8 @@ The accountsservice-libs package contains a library that can be used by applications that want to interact with the accountsservice daemon. - %package devel Summary: Development files for accountsservice-libs -Group: Development/Libraries Requires: %{name}-libs = %{version}-%{release} %description devel @@ -67,12 +47,6 @@ The accountsservice-devel package contains headers and other files needed to build applications that use accountsservice-libs. -%description -The accountsservice project provides a set of D-Bus interfaces for -querying and manipulating user account information and an implementation -of these interfaces, based on the useradd, usermod and userdel commands. - - %prep %autosetup -S git @@ -127,6 +101,20 @@ rm $RPM_BUILD_ROOT%{_libdir}/*.a %{_datadir}/gtk-doc/html/libaccountsservice/* %changelog +* Thu Jul 19 2018 Ray Strode - 0.6.50-2 +- Fix user switching + Resolves: #1597350 + +* Thu Jul 19 2018 Ray Strode - 0.6.50-1 +- Update to 0.6.50 + Related: #1576538 + Related: 1596735 + Related: 1602918 + +* Fri Jun 01 2018 Richard Hughes - 0.6.49-1 +- Update to 0.6.49 + Resolves: #1576538 + * Wed Feb 14 2018 Ray Strode - 0.6.45-7 - Fix bug leading to harmless error in log Resolves: #1544640