summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2012-12-11 10:22:12 -0500
committerRay Strode <rstrode@redhat.com>2012-12-12 12:25:40 -0500
commitacb79f31770318f461f2dec95d0ba971cbfbc177 (patch)
tree04e5d7b3be1a234a267c3b0da40038a691f8ae6a
parentf28d5bcb9e55a27fad6096c19141e8b54eadf958 (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.c13
-rw-r--r--src/libaccountsservice/act-user-private.h2
-rw-r--r--src/libaccountsservice/act-user.c89
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