summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Vollmer <mvollmer@redhat.com>2013-05-30 13:08:37 +0300
committerMatthias Clasen <mclasen@redhat.com>2013-06-05 20:40:34 -0400
commit506c13c88fb032e16b6e64490f00c1f736ed6e42 (patch)
tree850e83a8f821e7d4a6c088cc963edad00ea84e4c
parent230ca6faadd49a7d83d8e918759d9343f2e1fd56 (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.c94
-rw-r--r--src/libaccountsservice/act-user-private.h9
-rw-r--r--src/libaccountsservice/act-user.c108
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);
}