|
|
3b7e70 |
From d80807171a457ff87bdc9bd861939161749a37a8 Mon Sep 17 00:00:00 2001
|
|
|
3b7e70 |
From: Ray Strode <rstrode@redhat.com>
|
|
|
81f0aa |
Date: Thu, 20 Dec 2018 14:51:38 -0500
|
|
|
3b7e70 |
Subject: [PATCH 1/3] manager: allow multiple xdmcp logins for the same user
|
|
|
81f0aa |
|
|
|
81f0aa |
---
|
|
|
81f0aa |
common/gdm-settings-keys.h | 1 +
|
|
|
81f0aa |
daemon/gdm-manager.c | 71 ++++++++++++++++++++++++++++----------
|
|
|
3b7e70 |
data/gdm.schemas.in | 5 +++
|
|
|
81f0aa |
3 files changed, 59 insertions(+), 18 deletions(-)
|
|
|
81f0aa |
|
|
|
81f0aa |
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h
|
|
|
3b7e70 |
index 87685d3cd..4b3a1ffeb 100644
|
|
|
81f0aa |
--- a/common/gdm-settings-keys.h
|
|
|
81f0aa |
+++ b/common/gdm-settings-keys.h
|
|
|
3b7e70 |
@@ -30,37 +30,38 @@ G_BEGIN_DECLS
|
|
|
81f0aa |
#define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable"
|
|
|
81f0aa |
#define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin"
|
|
|
81f0aa |
#define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable"
|
|
|
81f0aa |
#define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin"
|
|
|
81f0aa |
#define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay"
|
|
|
81f0aa |
#define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable"
|
|
|
3b7e70 |
#define GDM_KEY_PREFERRED_DISPLAY_SERVER "daemon/PreferredDisplayServer"
|
|
|
81f0aa |
#define GDM_KEY_WAYLAND_ENABLE "daemon/WaylandEnable"
|
|
|
3b7e70 |
#define GDM_KEY_XORG_ENABLE "daemon/XorgEnable"
|
|
|
81f0aa |
|
|
|
81f0aa |
#define GDM_KEY_DEBUG "debug/Enable"
|
|
|
81f0aa |
|
|
|
81f0aa |
#define GDM_KEY_INCLUDE "greeter/Include"
|
|
|
81f0aa |
#define GDM_KEY_EXCLUDE "greeter/Exclude"
|
|
|
81f0aa |
#define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll"
|
|
|
81f0aa |
|
|
|
81f0aa |
#define GDM_KEY_DISALLOW_TCP "security/DisallowTCP"
|
|
|
81f0aa |
#define GDM_KEY_ALLOW_REMOTE_AUTOLOGIN "security/AllowRemoteAutoLogin"
|
|
|
81f0aa |
|
|
|
81f0aa |
#define GDM_KEY_XDMCP_ENABLE "xdmcp/Enable"
|
|
|
81f0aa |
#define GDM_KEY_SHOW_LOCAL_GREETER "xdmcp/ShowLocalGreeter"
|
|
|
81f0aa |
#define GDM_KEY_MAX_PENDING "xdmcp/MaxPending"
|
|
|
81f0aa |
#define GDM_KEY_MAX_SESSIONS "xdmcp/MaxSessions"
|
|
|
81f0aa |
#define GDM_KEY_MAX_WAIT "xdmcp/MaxWait"
|
|
|
81f0aa |
#define GDM_KEY_DISPLAYS_PER_HOST "xdmcp/DisplaysPerHost"
|
|
|
81f0aa |
#define GDM_KEY_UDP_PORT "xdmcp/Port"
|
|
|
81f0aa |
#define GDM_KEY_INDIRECT "xdmcp/HonorIndirect"
|
|
|
81f0aa |
#define GDM_KEY_MAX_WAIT_INDIRECT "xdmcp/MaxWaitIndirect"
|
|
|
81f0aa |
#define GDM_KEY_PING_INTERVAL "xdmcp/PingIntervalSeconds"
|
|
|
81f0aa |
#define GDM_KEY_WILLING "xdmcp/Willing"
|
|
|
81f0aa |
+#define GDM_KEY_ALLOW_MULTIPLE_SESSIONS_PER_USER "xdmcp/AllowMultipleSessionsPerUser"
|
|
|
81f0aa |
|
|
|
81f0aa |
#define GDM_KEY_MULTICAST "chooser/Multicast"
|
|
|
81f0aa |
#define GDM_KEY_MULTICAST_ADDR "chooser/MulticastAddr"
|
|
|
81f0aa |
|
|
|
81f0aa |
G_END_DECLS
|
|
|
81f0aa |
|
|
|
81f0aa |
#endif /* _GDM_SETTINGS_KEYS_H */
|
|
|
81f0aa |
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
|
3b7e70 |
index e433acf3b..ce8565bf9 100644
|
|
|
81f0aa |
--- a/daemon/gdm-manager.c
|
|
|
81f0aa |
+++ b/daemon/gdm-manager.c
|
|
|
3b7e70 |
@@ -566,93 +566,106 @@ get_display_and_details_for_bus_sender (GdmManager *self,
|
|
|
81f0aa |
*out_tty = get_tty_for_session_id (session_id, &error);
|
|
|
81f0aa |
|
|
|
81f0aa |
if (error != NULL) {
|
|
|
81f0aa |
g_debug ("GdmManager: Error while retrieving tty for session: %s",
|
|
|
81f0aa |
error->message);
|
|
|
81f0aa |
g_clear_error (&error);
|
|
|
81f0aa |
}
|
|
|
81f0aa |
}
|
|
|
81f0aa |
|
|
|
81f0aa |
display = gdm_display_store_find (self->priv->display_store,
|
|
|
81f0aa |
lookup_by_session_id,
|
|
|
81f0aa |
(gpointer) session_id);
|
|
|
81f0aa |
|
|
|
3b7e70 |
out:
|
|
|
81f0aa |
if (out_display != NULL) {
|
|
|
81f0aa |
*out_display = display;
|
|
|
81f0aa |
}
|
|
|
3b7e70 |
|
|
|
81f0aa |
g_free (session_id);
|
|
|
81f0aa |
}
|
|
|
81f0aa |
|
|
|
81f0aa |
static gboolean
|
|
|
81f0aa |
switch_to_compatible_user_session (GdmManager *manager,
|
|
|
81f0aa |
GdmSession *session,
|
|
|
81f0aa |
gboolean fail_if_already_switched)
|
|
|
81f0aa |
{
|
|
|
81f0aa |
gboolean res;
|
|
|
81f0aa |
gboolean ret;
|
|
|
81f0aa |
const char *username;
|
|
|
81f0aa |
const char *seat_id;
|
|
|
81f0aa |
- const char *ssid_to_activate;
|
|
|
81f0aa |
+ const char *ssid_to_activate = NULL;
|
|
|
81f0aa |
GdmSession *existing_session;
|
|
|
81f0aa |
|
|
|
81f0aa |
ret = FALSE;
|
|
|
81f0aa |
|
|
|
81f0aa |
username = gdm_session_get_username (session);
|
|
|
81f0aa |
seat_id = gdm_session_get_display_seat_id (session);
|
|
|
81f0aa |
|
|
|
81f0aa |
- if (!fail_if_already_switched) {
|
|
|
81f0aa |
- session = NULL;
|
|
|
81f0aa |
- }
|
|
|
81f0aa |
+ if (!fail_if_already_switched)
|
|
|
81f0aa |
+ ssid_to_activate = gdm_session_get_session_id (session);
|
|
|
81f0aa |
|
|
|
81f0aa |
- existing_session = find_session_for_user_on_seat (manager, username, seat_id, session);
|
|
|
81f0aa |
+ if (ssid_to_activate == NULL) {
|
|
|
81f0aa |
+ if (!seat_id || !sd_seat_can_multi_session (seat_id)) {
|
|
|
81f0aa |
+ g_debug ("GdmManager: unable to activate existing sessions from login screen unless on seat0");
|
|
|
81f0aa |
+ goto out;
|
|
|
81f0aa |
+ }
|
|
|
81f0aa |
|
|
|
81f0aa |
- if (existing_session != NULL) {
|
|
|
81f0aa |
- ssid_to_activate = gdm_session_get_session_id (existing_session);
|
|
|
81f0aa |
- if (seat_id != NULL) {
|
|
|
3b7e70 |
- res = gdm_activate_session_by_id (manager->priv->connection, seat_id, ssid_to_activate);
|
|
|
81f0aa |
- if (! res) {
|
|
|
81f0aa |
- g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate);
|
|
|
81f0aa |
- goto out;
|
|
|
81f0aa |
- }
|
|
|
81f0aa |
+ if (!fail_if_already_switched) {
|
|
|
81f0aa |
+ session = NULL;
|
|
|
81f0aa |
}
|
|
|
81f0aa |
|
|
|
81f0aa |
- res = session_unlock (manager, ssid_to_activate);
|
|
|
81f0aa |
- if (!res) {
|
|
|
81f0aa |
- /* this isn't fatal */
|
|
|
81f0aa |
- g_debug ("GdmManager: unable to unlock session: %s", ssid_to_activate);
|
|
|
81f0aa |
+ existing_session = find_session_for_user_on_seat (manager, username, seat_id, session);
|
|
|
81f0aa |
+
|
|
|
81f0aa |
+ if (existing_session != NULL) {
|
|
|
81f0aa |
+ ssid_to_activate = gdm_session_get_session_id (existing_session);
|
|
|
81f0aa |
}
|
|
|
81f0aa |
- } else {
|
|
|
81f0aa |
+ }
|
|
|
81f0aa |
+
|
|
|
81f0aa |
+ if (ssid_to_activate == NULL) {
|
|
|
81f0aa |
goto out;
|
|
|
81f0aa |
}
|
|
|
81f0aa |
|
|
|
81f0aa |
+ if (seat_id != NULL) {
|
|
|
3b7e70 |
+ res = gdm_activate_session_by_id (manager->priv->connection, seat_id, ssid_to_activate);
|
|
|
81f0aa |
+ if (! res) {
|
|
|
81f0aa |
+ g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate);
|
|
|
81f0aa |
+ goto out;
|
|
|
81f0aa |
+ }
|
|
|
81f0aa |
+ }
|
|
|
81f0aa |
+
|
|
|
81f0aa |
+ res = session_unlock (manager, ssid_to_activate);
|
|
|
81f0aa |
+ if (!res) {
|
|
|
81f0aa |
+ /* this isn't fatal */
|
|
|
81f0aa |
+ g_debug ("GdmManager: unable to unlock session: %s", ssid_to_activate);
|
|
|
81f0aa |
+ }
|
|
|
81f0aa |
+
|
|
|
81f0aa |
ret = TRUE;
|
|
|
81f0aa |
|
|
|
81f0aa |
out:
|
|
|
81f0aa |
return ret;
|
|
|
81f0aa |
}
|
|
|
81f0aa |
|
|
|
81f0aa |
static GdmDisplay *
|
|
|
81f0aa |
get_display_for_user_session (GdmSession *session)
|
|
|
81f0aa |
{
|
|
|
81f0aa |
return g_object_get_data (G_OBJECT (session), "gdm-display");
|
|
|
81f0aa |
}
|
|
|
81f0aa |
|
|
|
81f0aa |
static GdmSession *
|
|
|
81f0aa |
get_user_session_for_display (GdmDisplay *display)
|
|
|
81f0aa |
{
|
|
|
81f0aa |
if (display == NULL) {
|
|
|
81f0aa |
return NULL;
|
|
|
81f0aa |
}
|
|
|
81f0aa |
|
|
|
81f0aa |
return g_object_get_data (G_OBJECT (display), "gdm-user-session");
|
|
|
81f0aa |
}
|
|
|
81f0aa |
|
|
|
81f0aa |
static gboolean
|
|
|
81f0aa |
add_session_record (GdmManager *manager,
|
|
|
81f0aa |
GdmSession *session,
|
|
|
81f0aa |
GPid pid,
|
|
|
81f0aa |
SessionRecord record)
|
|
|
81f0aa |
{
|
|
|
81f0aa |
const char *username;
|
|
|
81f0aa |
char *display_name, *hostname, *display_device;
|
|
|
3b7e70 |
@@ -1089,92 +1102,114 @@ open_temporary_reauthentication_channel (GdmManager *self,
|
|
|
81f0aa |
g_signal_connect (session,
|
|
|
81f0aa |
"client-disconnected",
|
|
|
81f0aa |
G_CALLBACK (on_reauthentication_client_disconnected),
|
|
|
81f0aa |
self);
|
|
|
81f0aa |
g_signal_connect (session,
|
|
|
81f0aa |
"client-rejected",
|
|
|
81f0aa |
G_CALLBACK (on_reauthentication_client_rejected),
|
|
|
81f0aa |
self);
|
|
|
81f0aa |
g_signal_connect (session,
|
|
|
81f0aa |
"cancelled",
|
|
|
81f0aa |
G_CALLBACK (on_reauthentication_cancelled),
|
|
|
81f0aa |
self);
|
|
|
81f0aa |
g_signal_connect (session,
|
|
|
81f0aa |
"conversation-started",
|
|
|
81f0aa |
G_CALLBACK (on_reauthentication_conversation_started),
|
|
|
81f0aa |
self);
|
|
|
81f0aa |
g_signal_connect (session,
|
|
|
81f0aa |
"conversation-stopped",
|
|
|
81f0aa |
G_CALLBACK (on_reauthentication_conversation_stopped),
|
|
|
81f0aa |
self);
|
|
|
81f0aa |
g_signal_connect (session,
|
|
|
81f0aa |
"verification-complete",
|
|
|
81f0aa |
G_CALLBACK (on_reauthentication_verification_complete),
|
|
|
81f0aa |
self);
|
|
|
81f0aa |
|
|
|
81f0aa |
address = gdm_session_get_server_address (session);
|
|
|
81f0aa |
|
|
|
81f0aa |
return g_strdup (address);
|
|
|
81f0aa |
}
|
|
|
81f0aa |
|
|
|
81f0aa |
+static gboolean
|
|
|
81f0aa |
+remote_users_can_log_in_more_than_once (GdmManager *manager)
|
|
|
81f0aa |
+{
|
|
|
81f0aa |
+ gboolean enabled;
|
|
|
81f0aa |
+
|
|
|
81f0aa |
+ enabled = FALSE;
|
|
|
81f0aa |
+
|
|
|
81f0aa |
+ gdm_settings_direct_get_boolean (GDM_KEY_ALLOW_MULTIPLE_SESSIONS_PER_USER, &enabled);
|
|
|
81f0aa |
+
|
|
|
81f0aa |
+ g_debug ("GdmDisplay: Remote users allowed to log in more than once: %s", enabled? "yes" : "no");
|
|
|
81f0aa |
+
|
|
|
81f0aa |
+ return enabled;
|
|
|
81f0aa |
+}
|
|
|
81f0aa |
+
|
|
|
81f0aa |
static gboolean
|
|
|
81f0aa |
gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager,
|
|
|
81f0aa |
GDBusMethodInvocation *invocation,
|
|
|
81f0aa |
const char *username)
|
|
|
81f0aa |
{
|
|
|
81f0aa |
GdmManager *self = GDM_MANAGER (manager);
|
|
|
81f0aa |
const char *sender;
|
|
|
81f0aa |
GdmDisplay *display = NULL;
|
|
|
81f0aa |
GdmSession *session;
|
|
|
81f0aa |
GDBusConnection *connection;
|
|
|
81f0aa |
char *seat_id = NULL;
|
|
|
81f0aa |
char *session_id = NULL;
|
|
|
81f0aa |
GPid pid = 0;
|
|
|
81f0aa |
uid_t uid = (uid_t) -1;
|
|
|
81f0aa |
gboolean is_login_screen = FALSE;
|
|
|
81f0aa |
gboolean is_remote = FALSE;
|
|
|
81f0aa |
|
|
|
81f0aa |
g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
|
|
|
81f0aa |
|
|
|
81f0aa |
sender = g_dbus_method_invocation_get_sender (invocation);
|
|
|
81f0aa |
connection = g_dbus_method_invocation_get_connection (invocation);
|
|
|
81f0aa |
get_display_and_details_for_bus_sender (self, connection, sender, &display, &seat_id, &session_id, NULL, &pid, &uid, &is_login_screen, &is_remote);
|
|
|
81f0aa |
|
|
|
81f0aa |
if (session_id == NULL || pid == 0 || uid == (uid_t) -1) {
|
|
|
81f0aa |
g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
81f0aa |
G_DBUS_ERROR,
|
|
|
81f0aa |
G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
81f0aa |
_("No session available"));
|
|
|
81f0aa |
|
|
|
81f0aa |
return TRUE;
|
|
|
81f0aa |
}
|
|
|
81f0aa |
|
|
|
81f0aa |
+ if (is_login_screen && is_remote && remote_users_can_log_in_more_than_once (self)) {
|
|
|
81f0aa |
+ g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
81f0aa |
+ G_DBUS_ERROR,
|
|
|
81f0aa |
+ G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
81f0aa |
+ "Login screen creates new sessions for remote connections");
|
|
|
3b7e70 |
+ return TRUE;
|
|
|
81f0aa |
+ }
|
|
|
81f0aa |
+
|
|
|
81f0aa |
if (is_login_screen) {
|
|
|
81f0aa |
g_debug ("GdmManager: looking for login screen session for user %s on seat %s", username, seat_id);
|
|
|
81f0aa |
session = find_session_for_user_on_seat (self,
|
|
|
81f0aa |
username,
|
|
|
81f0aa |
seat_id,
|
|
|
81f0aa |
NULL);
|
|
|
81f0aa |
} else {
|
|
|
81f0aa |
g_debug ("GdmManager: looking for user session on display");
|
|
|
81f0aa |
session = get_user_session_for_display (display);
|
|
|
81f0aa |
}
|
|
|
81f0aa |
|
|
|
81f0aa |
if (session != NULL && gdm_session_is_running (session)) {
|
|
|
81f0aa |
gdm_session_start_reauthentication (session, pid, uid);
|
|
|
81f0aa |
g_hash_table_insert (self->priv->open_reauthentication_requests,
|
|
|
81f0aa |
GINT_TO_POINTER (pid),
|
|
|
81f0aa |
invocation);
|
|
|
81f0aa |
} else if (is_login_screen) {
|
|
|
81f0aa |
g_dbus_method_invocation_return_error_literal (invocation,
|
|
|
81f0aa |
G_DBUS_ERROR,
|
|
|
81f0aa |
G_DBUS_ERROR_ACCESS_DENIED,
|
|
|
81f0aa |
"Login screen only allowed to open reauthentication channels for running sessions");
|
|
|
81f0aa |
return TRUE;
|
|
|
81f0aa |
} else {
|
|
|
81f0aa |
char *address;
|
|
|
81f0aa |
address = open_temporary_reauthentication_channel (self,
|
|
|
81f0aa |
seat_id,
|
|
|
81f0aa |
session_id,
|
|
|
81f0aa |
pid,
|
|
|
81f0aa |
uid,
|
|
|
81f0aa |
is_remote);
|
|
|
3b7e70 |
diff --git a/data/gdm.schemas.in b/data/gdm.schemas.in
|
|
|
3b7e70 |
index a1035f95e..929d13d90 100644
|
|
|
3b7e70 |
--- a/data/gdm.schemas.in
|
|
|
3b7e70 |
+++ b/data/gdm.schemas.in
|
|
|
3b7e70 |
@@ -112,33 +112,38 @@
|
|
|
81f0aa |
<schema>
|
|
|
81f0aa |
<key>xdmcp/DisplaysPerHost</key>
|
|
|
81f0aa |
<signature>i</signature>
|
|
|
81f0aa |
<default>1</default>
|
|
|
81f0aa |
</schema>
|
|
|
81f0aa |
<schema>
|
|
|
81f0aa |
<key>xdmcp/Port</key>
|
|
|
81f0aa |
<signature>i</signature>
|
|
|
81f0aa |
<default>177</default>
|
|
|
81f0aa |
</schema>
|
|
|
81f0aa |
<schema>
|
|
|
81f0aa |
<key>xdmcp/HonorIndirect</key>
|
|
|
81f0aa |
<signature>b</signature>
|
|
|
81f0aa |
<default>true</default>
|
|
|
81f0aa |
</schema>
|
|
|
81f0aa |
<schema>
|
|
|
81f0aa |
<key>xdmcp/MaxWaitIndirect</key>
|
|
|
81f0aa |
<signature>i</signature>
|
|
|
81f0aa |
<default>30</default>
|
|
|
81f0aa |
</schema>
|
|
|
81f0aa |
<schema>
|
|
|
81f0aa |
<key>xdmcp/PingIntervalSeconds</key>
|
|
|
81f0aa |
<signature>i</signature>
|
|
|
81f0aa |
<default>0</default>
|
|
|
81f0aa |
</schema>
|
|
|
81f0aa |
<schema>
|
|
|
81f0aa |
<key>xdmcp/Willing</key>
|
|
|
81f0aa |
<signature>s</signature>
|
|
|
81f0aa |
<default>@gdmconfdir@/Xwilling</default>
|
|
|
81f0aa |
</schema>
|
|
|
81f0aa |
+ <schema>
|
|
|
81f0aa |
+ <key>xdmcp/AllowMultipleSessionsPerUser</key>
|
|
|
81f0aa |
+ <signature>b</signature>
|
|
|
81f0aa |
+ <default>false</default>
|
|
|
81f0aa |
+ </schema>
|
|
|
81f0aa |
</schemalist>
|
|
|
81f0aa |
</gdmschemafile>
|
|
|
3b7e70 |
|
|
|
81f0aa |
--
|
|
|
3b7e70 |
2.30.1
|
|
|
81f0aa |
|