diff options
author | Ray Strode <rstrode@redhat.com> | 2012-12-11 10:22:12 -0500 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2012-12-12 12:25:40 -0500 |
commit | acb79f31770318f461f2dec95d0ba971cbfbc177 (patch) | |
tree | 04e5d7b3be1a234a267c3b0da40038a691f8ae6a | |
parent | f28d5bcb9e55a27fad6096c19141e8b54eadf958 (diff) |
lib: don't lose sessions list for users at startup
ActUser objects can be germinated from various sources:
1) a get_user call
2) a get_user_by_id call
3) a list_users call
Because of this, there may be one ActUser objects in
the wild holding the users session lists, and another
holding all the user information returned from the account
service.
This commit makes sure at the, end of the day, we consolidate
all the information we know, so some doesn't get dropped on
the floor.
Related to gnome bug https://bugzilla.gnome.org/show_bug.cgi?id=671858
-rw-r--r-- | src/libaccountsservice/act-user-manager.c | 13 | ||||
-rw-r--r-- | src/libaccountsservice/act-user-private.h | 2 | ||||
-rw-r--r-- | src/libaccountsservice/act-user.c | 89 |
3 files changed, 97 insertions, 7 deletions
diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c index 75910de..741c8d4 100644 --- a/src/libaccountsservice/act-user-manager.c +++ b/src/libaccountsservice/act-user-manager.c @@ -860,15 +860,16 @@ on_new_user_loaded (ActUser *user, old_user = lookup_user_by_name (manager, username); - /* If username got added earlier by a different means, trump it now. + /* If username hasn't been added, yet, add it now */ - if (old_user != NULL) { - g_debug ("ActUserManager: user '%s' was already known, " - "replacing with freshly loaded object", username); - remove_user (manager, old_user); + if (old_user == NULL) { + g_debug ("ActUserManager: %s was not yet known, adding it", + describe_user (user)); + add_user (manager, user); + } else { + _act_user_load_from_user (old_user, user); } - add_user (manager, user); g_object_unref (user); out: diff --git a/src/libaccountsservice/act-user-private.h b/src/libaccountsservice/act-user-private.h index 5022652..81f00d4 100644 --- a/src/libaccountsservice/act-user-private.h +++ b/src/libaccountsservice/act-user-private.h @@ -34,6 +34,8 @@ void _act_user_update_from_object_path (ActUser *user, const char *object_path); void _act_user_update_login_frequency (ActUser *user, int login_frequency); +void _act_user_load_from_user (ActUser *user, + ActUser *user_to_copy); void _act_user_add_session (ActUser *user, const char *session_id); diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c index 4f60561..2c1fcb8 100644 --- a/src/libaccountsservice/act-user.c +++ b/src/libaccountsservice/act-user.c @@ -107,6 +107,8 @@ struct _ActUser { ActUserAccountType account_type; ActUserPasswordMode password_mode; + guint uid_set : 1; + guint is_loaded : 1; guint locked : 1; guint automatic_login : 1; @@ -983,8 +985,9 @@ collect_props (const gchar *key, guint64 new_uid; new_uid = g_variant_get_uint64 (value); - if ((guint64) user->uid != new_uid) { + 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) { @@ -1300,6 +1303,90 @@ _act_user_update_login_frequency (ActUser *user, } } +static void +copy_sessions_list (ActUser *user, + ActUser *user_to_copy) +{ + GList *node; + + for (node = g_list_last (user_to_copy->sessions); + node != NULL; + node = node->prev) { + user->sessions = g_list_prepend (user->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"); + } + + if (user->user_name == NULL) { + user->user_name = g_strdup (user_to_copy->user_name); + g_object_notify (G_OBJECT (user), "user-name"); + } + + if (user->sessions == NULL) { + copy_sessions_list (user, user_to_copy); + g_signal_emit (user, signals[SESSIONS_CHANGED], 0); + } + + user->real_name = g_strdup (user_to_copy->real_name); + g_object_notify (G_OBJECT (user), "real-name"); + + user->password_hint = g_strdup (user_to_copy->real_name); + g_object_notify (G_OBJECT (user), "password-hint"); + + user->home_dir = g_strdup (user_to_copy->home_dir); + g_object_notify (G_OBJECT (user), "home-directory"); + + user->shell = g_strdup (user_to_copy->shell); + g_object_notify (G_OBJECT (user), "shell"); + + user->email = g_strdup (user_to_copy->email); + g_object_notify (G_OBJECT (user), "email"); + + user->location = g_strdup (user_to_copy->location); + g_object_notify (G_OBJECT (user), "location"); + + user->icon_file = g_strdup (user_to_copy->icon_file); + g_object_notify (G_OBJECT (user), "icon-file"); + + user->language = g_strdup (user_to_copy->language); + g_object_notify (G_OBJECT (user), "language"); + + 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 = g_variant_ref (user_to_copy->login_history); + 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"); + + set_is_loaded (user, TRUE); +} + /** * act_user_is_loaded: * @user: a #ActUser |