summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2012-10-11 17:29:07 -0400
committerRay Strode <rstrode@redhat.com>2012-10-15 22:20:04 -0400
commit67b24ad9f494256cb580f06d2258ce711ae7b84d (patch)
tree1e3ac6c426909c1375a108e4e19ac38f8290bf12
parentd03635b038eeef2985959f321510d1f018c58958 (diff)
downloadgdm-67b24ad9f494256cb580f06d2258ce711ae7b84d.tar.gz
slave: don't fail if user session already active when activating from unlock
After GDM successfully reauthenticates a user it runs gdm_slave_switch_to_user_session to jump to the user's VT and unlock it. Of course, if the user is reauthenticating from an unlock screen instead of a user switched login screen, then they'll already be on the right VT. gdm_slave_switch_to_user_session fails if the user is already switched to the session specified. This failing behavior is used at login time to decide start a user's session (versus switching to a user's already running session). This commit changes gdm_slave_switch_to_user_session to take an additional parameter to decide whether or not switching to an already active session should fail, or merely skip to the unlocking step. https://bugzilla.gnome.org/show_bug.cgi?id=685988 (cherry picked from commit 99c4f960c0689d310a799e87f6361fb25a8862f6)
-rw-r--r--daemon/gdm-simple-slave.c29
-rw-r--r--daemon/gdm-slave.c81
-rw-r--r--daemon/gdm-slave.h3
3 files changed, 92 insertions, 21 deletions
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index 2e0b68bb..9bc85226 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -311,17 +311,18 @@ gdm_simple_slave_start_session_when_ready (GdmSimpleSlave *slave,
}
static gboolean
-try_migrate_session (GdmSimpleSlave *slave)
+switch_to_and_unlock_session (GdmSimpleSlave *slave,
+ gboolean fail_if_already_switched)
{
char *username;
gboolean res;
- g_debug ("GdmSimpleSlave: trying to migrate session");
-
username = gdm_session_get_username (slave->priv->session);
+ g_debug ("GdmSimpleSlave: trying to switch to session for user %s", username);
+
/* try to switch to an existing session */
- res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username);
+ res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username, fail_if_already_switched);
g_free (username);
return res;
@@ -392,11 +393,18 @@ static gboolean
start_session_timeout (GdmSimpleSlave *slave)
{
gboolean migrated;
-
+ gboolean fail_if_already_switched = TRUE;
g_debug ("GdmSimpleSlave: accredited");
- migrated = try_migrate_session (slave);
+ /* If there's already a session running, jump to it.
+ * If the only session running is the one we just opened,
+ * start a session on it.
+ *
+ * We assume we're in the former case if we need to switch
+ * VTs, and we assume we're in the latter case if we don't.
+ */
+ migrated = switch_to_and_unlock_session (slave, fail_if_already_switched);
g_debug ("GdmSimpleSlave: migrated: %d", migrated);
if (migrated) {
/* We don't stop the slave here because
@@ -438,7 +446,14 @@ on_session_reauthenticated (GdmSession *session,
const char *service_name,
GdmSimpleSlave *slave)
{
- try_migrate_session (slave);
+ gboolean fail_if_already_switched = FALSE;
+
+ /* There should already be a session running, so jump to it's
+ * VT. In the event we're already on the right VT, (i.e. user
+ * used an unlock screen instead of a user switched login screen),
+ * then silently succeed and unlock the session.
+ */
+ switch_to_and_unlock_session (slave, fail_if_already_switched);
}
static void
diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c
index f011207b..287c7d6f 100644
--- a/daemon/gdm-slave.c
+++ b/daemon/gdm-slave.c
@@ -1474,15 +1474,6 @@ activate_session_id_for_systemd (GdmSlave *slave,
GError *error = NULL;
GVariant *reply;
- /* Can't activate what's already active. We want this
- * to fail, because we don't want migration to succeed
- * if the only active session is the one just created
- * at the login screen.
- */
- if (sd_session_is_active (session_id) > 0) {
- return FALSE;
- }
-
reply = g_dbus_connection_call_sync (slave->priv->connection,
"org.freedesktop.login1",
"/org/freedesktop/login1",
@@ -1559,6 +1550,59 @@ activate_session_id (GdmSlave *slave,
#endif
}
+#ifdef WITH_CONSOLE_KIT
+static gboolean
+ck_session_is_active (GdmSlave *slave,
+ const char *seat_id,
+ const char *session_id)
+{
+ GError *error = NULL;
+ GVariant *reply;
+ gboolean is_active;
+
+ reply = g_dbus_connection_call_sync (slave->priv->connection,
+ CK_NAME,
+ session_id,
+ "org.freedesktop.ConsoleKit.Session",
+ "IsActive",
+ NULL,
+ G_VARIANT_TYPE ("(b)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ if (reply == NULL) {
+ g_debug ("GdmSlave: ConsoleKit IsActive %s raised:\n %s\n\n",
+ g_dbus_error_get_remote_error (error), error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ g_variant_get (reply, "(b)", &is_active);
+ g_variant_unref (reply);
+
+ return is_active;
+}
+#endif
+
+static gboolean
+session_is_active (GdmSlave *slave,
+ const char *seat_id,
+ const char *session_id)
+{
+#ifdef WITH_SYSTEMD
+ if (sd_booted () > 0) {
+ return sd_session_is_active (session_id) > 0;
+ }
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+ return ck_session_is_active (slave, seat_id, session_id);
+#else
+ return FALSE;
+#endif
+}
+
#ifdef WITH_SYSTEMD
static gboolean
session_unlock_for_systemd (GdmSlave *slave,
@@ -1645,10 +1689,12 @@ session_unlock (GdmSlave *slave,
gboolean
gdm_slave_switch_to_user_session (GdmSlave *slave,
- const char *username)
+ const char *username,
+ gboolean fail_if_already_switched)
{
gboolean res;
gboolean ret;
+ gboolean session_already_switched;
char *ssid_to_activate;
ret = FALSE;
@@ -1659,14 +1705,23 @@ gdm_slave_switch_to_user_session (GdmSlave *slave,
goto out;
}
+ session_already_switched = session_is_active (slave, slave->priv->display_seat_id, ssid_to_activate);
+
g_debug ("GdmSlave: Activating session: '%s'", ssid_to_activate);
- res = activate_session_id (slave, slave->priv->display_seat_id, ssid_to_activate);
- if (! res) {
- g_debug ("GdmSlave: unable to activate session: %s", ssid_to_activate);
+ if (session_already_switched && fail_if_already_switched) {
+ g_debug ("GdmSlave: unable to activate session since it's already active: %s", ssid_to_activate);
goto out;
}
+ if (!session_already_switched) {
+ res = activate_session_id (slave, slave->priv->display_seat_id, ssid_to_activate);
+ if (! res) {
+ g_debug ("GdmSlave: unable to activate session: %s", ssid_to_activate);
+ goto out;
+ }
+ }
+
res = session_unlock (slave, ssid_to_activate);
if (!res) {
/* this isn't fatal */
diff --git a/daemon/gdm-slave.h b/daemon/gdm-slave.h
index 98e25f50..0647618f 100644
--- a/daemon/gdm-slave.h
+++ b/daemon/gdm-slave.h
@@ -99,7 +99,8 @@ gboolean gdm_slave_add_user_authorization (GdmSlave *slave,
char **filename);
gboolean gdm_slave_switch_to_user_session (GdmSlave *slave,
- const char *username);
+ const char *username,
+ gboolean fail_if_already_switched);
gboolean gdm_slave_connect_to_x11_display (GdmSlave *slave);