summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2018-12-20 14:51:38 -0500
committerRay Strode <rstrode@redhat.com>2022-03-07 10:29:22 -0500
commitec9f23ca25d296b9e32dedb4f1f5daa58b5d0cd1 (patch)
tree5f36828117d1f3a330492a7d1840a09eda557f82
parenta7e45ca7672e7dcd4990781cdc668afda727fd4a (diff)
downloadgdm-ec9f23ca25d296b9e32dedb4f1f5daa58b5d0cd1.tar.gz
manager: allow multiple xdmcp logins for the same user
-rw-r--r--common/gdm-settings-keys.h1
-rw-r--r--daemon/gdm-manager.c71
-rw-r--r--data/gdm.schemas.in5
3 files changed, 59 insertions, 18 deletions
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h
index 87685d3c..4b3a1ffe 100644
--- a/common/gdm-settings-keys.h
+++ b/common/gdm-settings-keys.h
@@ -57,6 +57,7 @@ G_BEGIN_DECLS
#define GDM_KEY_MAX_WAIT_INDIRECT "xdmcp/MaxWaitIndirect"
#define GDM_KEY_PING_INTERVAL "xdmcp/PingIntervalSeconds"
#define GDM_KEY_WILLING "xdmcp/Willing"
+#define GDM_KEY_ALLOW_MULTIPLE_SESSIONS_PER_USER "xdmcp/AllowMultipleSessionsPerUser"
#define GDM_KEY_MULTICAST "chooser/Multicast"
#define GDM_KEY_MULTICAST_ADDR "chooser/MulticastAddr"
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index cc61efc9..dc839aeb 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -593,7 +593,7 @@ switch_to_compatible_user_session (GdmManager *manager,
gboolean ret;
const char *username;
const char *seat_id;
- const char *ssid_to_activate;
+ const char *ssid_to_activate = NULL;
GdmSession *existing_session;
ret = FALSE;
@@ -601,31 +601,44 @@ switch_to_compatible_user_session (GdmManager *manager,
username = gdm_session_get_username (session);
seat_id = gdm_session_get_display_seat_id (session);
- if (!fail_if_already_switched) {
- session = NULL;
- }
+ if (!fail_if_already_switched)
+ ssid_to_activate = gdm_session_get_session_id (session);
- existing_session = find_session_for_user_on_seat (manager, username, seat_id, session);
+ if (ssid_to_activate == NULL) {
+ if (!seat_id || !sd_seat_can_multi_session (seat_id)) {
+ g_debug ("GdmManager: unable to activate existing sessions from login screen unless on seat0");
+ goto out;
+ }
- if (existing_session != NULL) {
- ssid_to_activate = gdm_session_get_session_id (existing_session);
- if (seat_id != NULL) {
- res = gdm_activate_session_by_id (manager->priv->connection, seat_id, ssid_to_activate);
- if (! res) {
- g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate);
- goto out;
- }
+ if (!fail_if_already_switched) {
+ session = NULL;
}
- res = session_unlock (manager, ssid_to_activate);
- if (!res) {
- /* this isn't fatal */
- g_debug ("GdmManager: unable to unlock session: %s", ssid_to_activate);
+ existing_session = find_session_for_user_on_seat (manager, username, seat_id, session);
+
+ if (existing_session != NULL) {
+ ssid_to_activate = gdm_session_get_session_id (existing_session);
}
- } else {
+ }
+
+ if (ssid_to_activate == NULL) {
goto out;
}
+ if (seat_id != NULL) {
+ res = gdm_activate_session_by_id (manager->priv->connection, seat_id, ssid_to_activate);
+ if (! res) {
+ g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate);
+ goto out;
+ }
+ }
+
+ res = session_unlock (manager, ssid_to_activate);
+ if (!res) {
+ /* this isn't fatal */
+ g_debug ("GdmManager: unable to unlock session: %s", ssid_to_activate);
+ }
+
ret = TRUE;
out:
@@ -1117,6 +1130,20 @@ open_temporary_reauthentication_channel (GdmManager *self,
}
static gboolean
+remote_users_can_log_in_more_than_once (GdmManager *manager)
+{
+ gboolean enabled;
+
+ enabled = FALSE;
+
+ gdm_settings_direct_get_boolean (GDM_KEY_ALLOW_MULTIPLE_SESSIONS_PER_USER, &enabled);
+
+ g_debug ("GdmDisplay: Remote users allowed to log in more than once: %s", enabled? "yes" : "no");
+
+ return enabled;
+}
+
+static gboolean
gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager,
GDBusMethodInvocation *invocation,
const char *username)
@@ -1148,6 +1175,14 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager
return TRUE;
}
+ if (is_login_screen && is_remote && remote_users_can_log_in_more_than_once (self)) {
+ g_dbus_method_invocation_return_error_literal (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_ACCESS_DENIED,
+ "Login screen creates new sessions for remote connections");
+ return TRUE;
+ }
+
if (is_login_screen) {
g_debug ("GdmManager: looking for login screen session for user %s on seat %s", username, seat_id);
session = find_session_for_user_on_seat (self,
diff --git a/data/gdm.schemas.in b/data/gdm.schemas.in
index a1035f95..929d13d9 100644
--- a/data/gdm.schemas.in
+++ b/data/gdm.schemas.in
@@ -139,6 +139,11 @@
<signature>s</signature>
<default>@gdmconfdir@/Xwilling</default>
</schema>
+ <schema>
+ <key>xdmcp/AllowMultipleSessionsPerUser</key>
+ <signature>b</signature>
+ <default>false</default>
+ </schema>
</schemalist>
</gdmschemafile>