diff options
author | Marius Vollmer <mvollmer@redhat.com> | 2013-05-30 13:08:37 +0300 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2013-06-05 20:40:34 -0400 |
commit | 506c13c88fb032e16b6e64490f00c1f736ed6e42 (patch) | |
tree | 850e83a8f821e7d4a6c088cc963edad00ea84e4c | |
parent | 230ca6faadd49a7d83d8e918759d9343f2e1fd56 (diff) |
Don't completely ignore non-graphical sessions.
Instead, offer act_user_is_logged_in_anywhere and
act_user_get_num_sessions_anywhere to inquire about them.
https://bugs.freedesktop.org/show_bug.cgi?id=65160
-rw-r--r-- | src/libaccountsservice/act-user-manager.c | 94 | ||||
-rw-r--r-- | src/libaccountsservice/act-user-private.h | 9 | ||||
-rw-r--r-- | src/libaccountsservice/act-user.c | 108 |
3 files changed, 163 insertions, 48 deletions
diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c index a894e75..e426f7b 100644 --- a/src/libaccountsservice/act-user-manager.c +++ b/src/libaccountsservice/act-user-manager.c @@ -427,6 +427,58 @@ session_is_login_window (ActUserManager *manager, return _ck_session_is_login_window (manager, session_id); } +static gboolean +_ck_session_is_on_our_seat (ActUserManager *manager, + const char *session_id) +{ + /* With ConsoleKit, we only ever see sessions on our seat. */ + return TRUE; +} + +#ifdef WITH_SYSTEMD +static gboolean +_systemd_session_is_on_our_seat (ActUserManager *manager, + const char *session_id) +{ + int res; + int ret; + char *session_seat; + + ret = FALSE; + res = sd_session_get_seat (session_id, &session_seat); + if (res == -ENOENT) { + goto out; + } else if (res < 0) { + g_debug ("failed to determine seat of session %s: %s", + session_id, + strerror (-res)); + goto out; + } + + if (g_strcmp0 (manager->priv->seat.id, session_seat) == 0) { + ret = TRUE; + } + + free (session_seat); + +out: + return ret; +} +#endif + +static gboolean +session_is_on_our_seat (ActUserManager *manager, + const char *session_id) +{ +#ifdef WITH_SYSTEMD + if (LOGIND_RUNNING()) { + return _systemd_session_is_on_our_seat (manager, session_id); + } +#endif + + return _ck_session_is_on_our_seat (manager, session_id); +} + /** * act_user_manager_goto_login_session: * @manager: the user manager @@ -759,13 +811,14 @@ username_in_exclude_list (ActUserManager *manager, static void add_session_for_user (ActUserManager *manager, ActUser *user, - const char *ssid) + 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); + _act_user_add_session (user, ssid, is_ours); g_debug ("ActUserManager: added session for %s", describe_user (user)); } @@ -1514,12 +1567,12 @@ _get_x11_display_for_new_systemd_session (ActUserManagerNewSession *new_session) } if (g_strcmp0 (session_type, "x11") != 0) { - g_debug ("ActUserManager: ignoring %s session '%s' since it's not graphical", + g_debug ("ActUserManager: (mostly) ignoring %s session '%s' since it's not graphical", session_type, new_session->id); free (session_type); - unload_new_session (new_session); - return; + x11_display = NULL; + goto done; } free (session_type); @@ -1537,6 +1590,7 @@ _get_x11_display_for_new_systemd_session (ActUserManagerNewSession *new_session) g_debug ("ActUserManager: Found x11 display of session '%s': %s", new_session->id, x11_display); + done: new_session->x11_display = g_strdup (x11_display); free (x11_display); new_session->state++; @@ -1569,39 +1623,37 @@ 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 || new_session->x11_display[0] == '\0') { - g_debug ("AcUserManager: ignoring session '%s' since it's not graphical", + g_debug ("AcUserManager: (mostly) ignoring session '%s' since it's not graphical", new_session->id); - goto done; - } - - if (session_is_login_window (manager, new_session->id)) { - goto done; + 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) { - goto failed; + unload_new_session (new_session); + return; } - add_session_for_user (manager, user, new_session->id); + 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); } - -done: - new_session->state = ACT_USER_MANAGER_NEW_SESSION_STATE_LOADED; - unload_new_session (new_session); - return; - -failed: - unload_new_session (new_session); } static void diff --git a/src/libaccountsservice/act-user-private.h b/src/libaccountsservice/act-user-private.h index 81f00d4..69156a2 100644 --- a/src/libaccountsservice/act-user-private.h +++ b/src/libaccountsservice/act-user-private.h @@ -37,8 +37,15 @@ void _act_user_update_login_frequency (ActUser *user, void _act_user_load_from_user (ActUser *user, ActUser *user_to_copy); +/* 'Our' sessions are the graphical sessions on the same seat as the + current process. The primary session of a user will always be + choosen from one of our sessions and act_user_is_logged_in only + considers our sessions. +*/ + void _act_user_add_session (ActUser *user, - const char *session_id); + const char *session_id, + gboolean is_ours); void _act_user_remove_session (ActUser *user, const char *session_id); diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c index d356948..402d0e5 100644 --- a/src/libaccountsservice/act-user.c +++ b/src/libaccountsservice/act-user.c @@ -122,7 +122,8 @@ struct _ActUser { char *icon_file; char *language; char *x_session; - GList *sessions; + GList *our_sessions; + GList *other_sessions; int login_frequency; gint64 login_time; GVariant *login_history; @@ -165,17 +166,24 @@ session_compare (const char *a, void _act_user_add_session (ActUser *user, - const char *ssid) + const char *ssid, + gboolean is_ours) { GList *li; g_return_if_fail (ACT_IS_USER (user)); g_return_if_fail (ssid != NULL); - li = g_list_find_custom (user->sessions, ssid, (GCompareFunc)session_compare); + li = g_list_find_custom (user->our_sessions, ssid, (GCompareFunc)session_compare); + if (li == NULL) + li = g_list_find_custom (user->other_sessions, ssid, (GCompareFunc)session_compare); + if (li == NULL) { g_debug ("ActUser: adding session %s", ssid); - user->sessions = g_list_prepend (user->sessions, g_strdup (ssid)); + if (is_ours) + user->our_sessions = g_list_prepend (user->our_sessions, g_strdup (ssid)); + else + user->other_sessions = g_list_prepend (user->other_sessions, g_strdup (ssid)); g_signal_emit (user, signals[SESSIONS_CHANGED], 0); } else { g_debug ("ActUser: session already present: %s", ssid); @@ -186,16 +194,22 @@ void _act_user_remove_session (ActUser *user, const char *ssid) { - GList *li; + GList *li, **headp; g_return_if_fail (ACT_IS_USER (user)); g_return_if_fail (ssid != NULL); - li = g_list_find_custom (user->sessions, ssid, (GCompareFunc)session_compare); + headp = &(user->our_sessions); + li = g_list_find_custom (user->our_sessions, ssid, (GCompareFunc)session_compare); + if (li == NULL) { + headp = &(user->other_sessions); + li = g_list_find_custom (user->other_sessions, ssid, (GCompareFunc)session_compare); + } + if (li != NULL) { g_debug ("ActUser: removing session %s", ssid); g_free (li->data); - user->sessions = g_list_delete_link (user->sessions, li); + *headp = g_list_delete_link (*headp, li); g_signal_emit (user, signals[SESSIONS_CHANGED], 0); } else { g_debug ("ActUser: session not found: %s", ssid); @@ -206,14 +220,31 @@ _act_user_remove_session (ActUser *user, * act_user_get_num_sessions: * @user: a user * - * Get the number of current sessions for a user. + * Get the number of sessions for a user that are graphical and on the + * same seat as the session of the calling process. * * Returns: the number of sessions */ guint act_user_get_num_sessions (ActUser *user) { - return g_list_length (user->sessions); + return g_list_length (user->our_sessions); +} + +/** + * 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(). + * + * 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 @@ -507,7 +538,8 @@ act_user_init (ActUser *user) user->local_account = TRUE; user->user_name = NULL; user->real_name = NULL; - user->sessions = 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); @@ -825,8 +857,8 @@ act_user_collate (ActUser *user1, } - len1 = g_list_length (user1->sessions); - len2 = g_list_length (user2->sessions); + len1 = g_list_length (user1->our_sessions); + len2 = g_list_length (user2->our_sessions); if (len1 > len2) { return -1; @@ -868,14 +900,30 @@ act_user_collate (ActUser *user1, * act_user_is_logged_in: * @user: a #ActUser * - * Returns whether or not #ActUser is currently logged in. + * 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->sessions != NULL; + 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(). + * + * Returns: %TRUE or %FALSE + */ +gboolean +act_user_is_logged_in_anywhere (ActUser *user) +{ + return user->our_sessions != NULL || user->other_sessions != NULL; } /** @@ -1007,22 +1055,24 @@ act_user_get_object_path (ActUser *user) * act_user_get_primary_session_id: * @user: a #ActUser * - * Returns the primary ConsoleKit session id of @user, or %NULL if @user isn't - * logged in. + * 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 primary ConsoleKit session id of the user + * Returns: (transfer none): the id of the primary session of the user */ const char * act_user_get_primary_session_id (ActUser *user) { - if (!act_user_is_logged_in (user)) { - g_debug ("User %s is not logged in, so has no primary session", + 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->sessions->data; + return user->our_sessions->data; } static void @@ -1355,15 +1405,21 @@ _act_user_update_login_frequency (ActUser *user, } static void -copy_sessions_list (ActUser *user, - ActUser *user_to_copy) +copy_sessions_lists (ActUser *user, + ActUser *user_to_copy) { GList *node; - for (node = g_list_last (user_to_copy->sessions); + 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->sessions = g_list_prepend (user->sessions, g_strdup (node->data)); + user->other_sessions = g_list_prepend (user->other_sessions, g_strdup (node->data)); } } @@ -1388,8 +1444,8 @@ _act_user_load_from_user (ActUser *user, g_object_notify (G_OBJECT (user), "user-name"); } - if (user->sessions == NULL) { - copy_sessions_list (user, user_to_copy); + if (user->our_sessions == NULL && user->other_sessions == NULL) { + copy_sessions_lists (user, user_to_copy); g_signal_emit (user, signals[SESSIONS_CHANGED], 0); } |