import gdm-3.28.3-28.el8

This commit is contained in:
CentOS Sources 2020-01-21 14:18:04 -05:00 committed by Stepan Oksanichenko
parent 1c4bd4148e
commit 392665b522
16 changed files with 3861 additions and 54 deletions

View File

@ -0,0 +1,135 @@
From b9f38b65417923624bf97a18daf1c2ede5e8651e Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Sun, 15 Dec 2019 14:51:44 -0500
Subject: [PATCH] daemon: fix wayland detection when deciding to bypass
Xsession
At the moment if there's a session file with the same name in
both /usr/share/xsessions and /usr/share/wayland-sessions, GDM
will think the wayland is getting used when deciding whether or
not to bypass the /etc/gdm/Xsession script, even if wayland is
explicitly being ignored.
This commit fixes the check.
---
daemon/gdm-session.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index a8263ba11..ecb2b3cac 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -3145,96 +3145,96 @@ gdm_session_get_session_id (GdmSession *self)
return conversation->session_id;
}
const char *
gdm_session_get_conversation_session_id (GdmSession *self,
const char *service_name)
{
GdmSessionConversation *conversation;
g_return_val_if_fail (GDM_IS_SESSION (self), NULL);
conversation = find_conversation_by_name (self, service_name);
if (conversation == NULL) {
return NULL;
}
return conversation->session_id;
}
static char *
get_session_filename (GdmSession *self)
{
return g_strdup_printf ("%s.desktop", get_session_name (self));
}
#ifdef ENABLE_WAYLAND_SUPPORT
static gboolean
gdm_session_is_wayland_session (GdmSession *self)
{
- GKeyFile *key_file;
+ g_autoptr (GKeyFile) key_file = NULL;
gboolean is_wayland_session = FALSE;
- char *filename;
- char *full_path = NULL;
+ g_autofree char *filename = NULL;
+ g_autofree char *full_path = NULL;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
filename = get_session_filename (self);
- key_file = load_key_file_for_file (self, filename, "wayland", &full_path);
+ if (!self->priv->ignore_wayland) {
+ key_file = load_key_file_for_file (self, filename, "wayland", &full_path);
- if (key_file == NULL) {
- goto out;
- }
+ if (key_file == NULL) {
+ goto out;
+ }
- if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) {
- is_wayland_session = TRUE;
+ if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) {
+ is_wayland_session = TRUE;
+ }
}
- g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no");
out:
- g_clear_pointer (&key_file, (GDestroyNotify) g_key_file_free);
- g_free (filename);
+ g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no");
+
return is_wayland_session;
}
#endif
static void
update_session_type (GdmSession *self)
{
#ifdef ENABLE_WAYLAND_SUPPORT
gboolean is_wayland_session = FALSE;
- if (!self->priv->ignore_wayland)
- is_wayland_session = gdm_session_is_wayland_session (self);
+ is_wayland_session = gdm_session_is_wayland_session (self);
if (is_wayland_session) {
set_session_type (self, "wayland");
} else {
set_session_type (self, NULL);
}
#endif
}
gboolean
gdm_session_bypasses_xsession (GdmSession *self)
{
GError *error;
GKeyFile *key_file;
gboolean res;
gboolean bypasses_xsession = FALSE;
char *filename = NULL;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
#ifdef ENABLE_WAYLAND_SUPPORT
if (gdm_session_is_wayland_session (self)) {
bypasses_xsession = TRUE;
goto out;
}
#endif
filename = get_session_filename (self);
--
2.18.1

View File

@ -1,31 +0,0 @@
From 84eac5437175efc3804e8a6133c06484d6016b26 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 4 Jan 2019 16:40:07 -0500
Subject: [PATCH] data: disable wayland for legacy QXL VMs
There are a number of issues right now with the QXL driver that
prevent it from working well with wayland.
These days QXL is deprecated in favor of virtio anyway.
This commit forces Xorg fallback for QXL VMs.
---
data/61-gdm.rules.in | 3 +++
1 file changed, 3 insertions(+)
diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in
index 26cf9cf51..ec19aa447 100644
--- a/data/61-gdm.rules.in
+++ b/data/61-gdm.rules.in
@@ -1,5 +1,8 @@
# disable Wayland on Cirrus chipsets
ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland"
+# disable Wayland on legacy QXL virtual machines
+ATTR{vendor}=="0x1b36", ATTR{device}=="0x0100", RUN+="@libexecdir@/gdm-disable-wayland"
+
# disable Wayland when using the proprietary nvidia driver
DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland"
--
2.17.1

View File

@ -1,4 +1,4 @@
From 21be64e1ba86bd57a4257a7526c9b4ee430bfdaa Mon Sep 17 00:00:00 2001
From 13a617e15cca421962be888b5607a9900bbfef51 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 11 Feb 2019 18:14:07 -0500
Subject: [PATCH] data: disable wayland on server chips and dual gpu setups
@ -12,10 +12,10 @@ This commit forces Xorg for those cases.
1 file changed, 18 insertions(+)
diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in
index ec19aa447..1c308d511 100644
index 26cf9cf51..e3631740d 100644
--- a/data/61-gdm.rules.in
+++ b/data/61-gdm.rules.in
@@ -1,8 +1,26 @@
@@ -1,5 +1,23 @@
# disable Wayland on Cirrus chipsets
ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland"
@ -33,9 +33,6 @@ index ec19aa447..1c308d511 100644
+ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", RUN+="@libexecdir@/gdm-disable-wayland"
+ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", RUN+="@libexecdir@/gdm-disable-wayland"
+
# disable Wayland on legacy QXL virtual machines
ATTR{vendor}=="0x1b36", ATTR{device}=="0x0100", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland when using the proprietary nvidia driver
DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland"
+
@ -43,5 +40,5 @@ index ec19aa447..1c308d511 100644
+SUBSYSTEM=="drm", KERNEL=="card[1-9]*", RUN+="@libexecdir@/gdm-disable-wayland"
+
--
2.18.1
2.21.0

View File

@ -0,0 +1,44 @@
From 7d9b41f1d82589999f8c89ed3bcc4eec6cee4978 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 6 Dec 2019 13:59:43 -0500
Subject: [PATCH] data: enable wayland on cirrus
cirrus in the 5.2 kernel was substantially rewritten and is more wayland
ready.
This commit reenables wayland on cirrus.
---
data/61-gdm.rules.in | 3 ---
1 file changed, 3 deletions(-)
diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in
index e3631740d..fc2e3315c 100644
--- a/data/61-gdm.rules.in
+++ b/data/61-gdm.rules.in
@@ -1,23 +1,20 @@
-# disable Wayland on Cirrus chipsets
-ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland"
-
# disable Wayland on Matrox chipsets
ATTR{vendor}=="0x102b", ATTR{device}=="0x0522", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0524", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0530", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0532", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0533", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0534", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0536", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0538", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland on aspeed chipsets
ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland when using the proprietary nvidia driver
DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland on hybrid graphics setups for now
SUBSYSTEM=="drm", KERNEL=="card[1-9]*", RUN+="@libexecdir@/gdm-disable-wayland"
--
2.21.0

View File

@ -0,0 +1,55 @@
From ab9510df0b5f7bc29662804991729c6d6ee38b70 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 12 Dec 2019 16:56:16 -0500
Subject: [PATCH] data: only disable wayland on passthrough virt setups
at the moment we disable wayland on all hybrid graphics setups,
but most hybrid graphics setups work fine.
The case we really care about is passthrough virt. in that case,
wayland is a bad idea because:
1) kernel crashes
2) mutter provides no way to disable one of the cards, and will
always use one as a secondary gpu
This commit forces xorg in passthrough setups so the user can use
an xorg.conf to turn one of the cards off.
---
data/61-gdm.rules.in | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in
index fc2e3315c..f971224cf 100644
--- a/data/61-gdm.rules.in
+++ b/data/61-gdm.rules.in
@@ -1,20 +1,25 @@
# disable Wayland on Matrox chipsets
ATTR{vendor}=="0x102b", ATTR{device}=="0x0522", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0524", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0530", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0532", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0533", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0534", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0536", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x102b", ATTR{device}=="0x0538", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland on aspeed chipsets
ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", RUN+="@libexecdir@/gdm-disable-wayland"
ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", RUN+="@libexecdir@/gdm-disable-wayland"
# disable Wayland when using the proprietary nvidia driver
DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland"
-# disable Wayland on hybrid graphics setups for now
-SUBSYSTEM=="drm", KERNEL=="card[1-9]*", RUN+="@libexecdir@/gdm-disable-wayland"
+# disable Wayland on passthrough graphics setups for now (assumes passthrough if
+# there is more than one card, and one of the cards is virt: cirrus, bochs, qxl)
+ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", ENV{GDM_HAS_VIRTUAL_GPU}="1"
+ATTR{vendor}=="0x1b36", ATTR{device}=="0x0100", ENV{GDM_HAS_VIRTUAL_GPU}="1"
+ATTR{vendor}=="0x1234", ATTR{device}=="0x1111", ENV{GDM_HAS_VIRTUAL_GPU}="1"
+
+SUBSYSTEM=="drm", KERNEL=="card[1-9]*", ENV{GDM_HAS_VIRTUAL_GPU}=="1", RUN+="@libexecdir@/gdm-disable-wayland"
--
2.21.0

View File

@ -0,0 +1,269 @@
From 781e865705b0c134271c9ec21655cd5d8ce37fec Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Sat, 14 Dec 2019 13:50:53 -0500
Subject: [PATCH] display: ask accountservice if there are users rather than
enumerate users
At the moment we ask accountsservice to give us the list of users just
to find out if there is a list of users.
That's rather inefficient and might be wrong for directory server users
that have never logged in before.
This commit changes gdm to ask accountsservice the question we really
want to know the answer to; whether or not there are users.
---
daemon/gdm-display.c | 55 ++++++++++++++++++--------------------------
1 file changed, 22 insertions(+), 33 deletions(-)
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 878be88da..875534272 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -57,62 +57,60 @@
struct GdmDisplayPrivate
{
char *id;
char *seat_id;
char *session_id;
char *session_class;
char *session_type;
char *remote_hostname;
int x11_display_number;
char *x11_display_name;
int status;
time_t creation_time;
GTimer *server_timer;
char *x11_cookie;
gsize x11_cookie_size;
GdmDisplayAccessFile *access_file;
guint finish_idle_id;
xcb_connection_t *xcb_connection;
int xcb_screen_number;
GDBusConnection *connection;
GdmDisplayAccessFile *user_access_file;
GdmDBusDisplay *display_skeleton;
GDBusObjectSkeleton *object_skeleton;
- GDBusProxy *accountsservice_proxy;
-
/* this spawns and controls the greeter session */
GdmLaunchEnvironment *launch_environment;
guint is_local : 1;
guint is_initial : 1;
guint allow_timed_login : 1;
guint have_existing_user_accounts : 1;
guint doing_initial_setup : 1;
};
enum {
PROP_0,
PROP_ID,
PROP_STATUS,
PROP_SEAT_ID,
PROP_SESSION_ID,
PROP_SESSION_CLASS,
PROP_SESSION_TYPE,
PROP_REMOTE_HOSTNAME,
PROP_X11_DISPLAY_NUMBER,
PROP_X11_DISPLAY_NAME,
PROP_X11_COOKIE,
PROP_X11_AUTHORITY_FILE,
PROP_IS_CONNECTED,
PROP_IS_LOCAL,
PROP_LAUNCH_ENVIRONMENT,
PROP_IS_INITIAL,
PROP_ALLOW_TIMED_LOGIN,
PROP_HAVE_EXISTING_USER_ACCOUNTS,
PROP_DOING_INITIAL_SETUP,
@@ -512,96 +510,88 @@ queue_finish (GdmDisplay *self)
if (self->priv->finish_idle_id == 0) {
self->priv->finish_idle_id = g_idle_add ((GSourceFunc)finish_idle, self);
}
}
static void
_gdm_display_set_status (GdmDisplay *self,
int status)
{
if (status != self->priv->status) {
self->priv->status = status;
g_object_notify (G_OBJECT (self), "status");
}
}
static gboolean
gdm_display_real_prepare (GdmDisplay *self)
{
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
g_debug ("GdmDisplay: prepare display");
_gdm_display_set_status (self, GDM_DISPLAY_PREPARED);
return TRUE;
}
static void
look_for_existing_users_sync (GdmDisplay *self)
{
- GError *error = NULL;
- GVariant *call_result;
- GVariant *user_list;
-
- self->priv->accountsservice_proxy = g_dbus_proxy_new_sync (self->priv->connection,
- 0, NULL,
- "org.freedesktop.Accounts",
- "/org/freedesktop/Accounts",
- "org.freedesktop.Accounts",
- NULL,
- &error);
-
- if (!self->priv->accountsservice_proxy) {
- g_warning ("Failed to contact accountsservice: %s", error->message);
- goto out;
- }
-
- call_result = g_dbus_proxy_call_sync (self->priv->accountsservice_proxy,
- "ListCachedUsers",
- NULL,
- 0,
+ g_autoptr (GVariant) result = NULL;
+ g_autoptr (GVariant) result_child = NULL;
+ g_autoptr (GError) error = NULL;
+ gboolean has_no_users = FALSE;
+
+ result = g_dbus_connection_call_sync (self->priv->connection,
+ "org.freedesktop.Accounts",
+ "/org/freedesktop/Accounts",
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ g_variant_new ("(ss)", "org.freedesktop.Accounts", "HasNoUsers"),
+ G_VARIANT_TYPE ("(v)"),
+ G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
- if (!call_result) {
- g_warning ("Failed to list cached users: %s", error->message);
- goto out;
+ if (result == NULL) {
+ g_warning ("Failed to contact accountsservice: %s", error->message);
+ return;
}
- g_variant_get (call_result, "(@ao)", &user_list);
- self->priv->have_existing_user_accounts = g_variant_n_children (user_list) > 0;
- g_variant_unref (user_list);
- g_variant_unref (call_result);
-out:
- g_clear_error (&error);
+ g_variant_get (result, "(v)", &result_child);
+ has_no_users = g_variant_get_boolean (result_child);
+ self->priv->have_existing_user_accounts = !has_no_users;
+
+ g_debug ("GdmDisplay: machine does %shave existing user accounts",
+ has_no_users? "not " : "");
}
gboolean
gdm_display_prepare (GdmDisplay *self)
{
gboolean ret;
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
g_debug ("GdmDisplay: Preparing display: %s", self->priv->id);
/* FIXME: we should probably do this in a more global place,
* asynchronously
*/
look_for_existing_users_sync (self);
self->priv->doing_initial_setup = wants_initial_setup (self);
g_object_ref (self);
ret = GDM_DISPLAY_GET_CLASS (self)->prepare (self);
g_object_unref (self);
return ret;
}
gboolean
gdm_display_manage (GdmDisplay *self)
{
gboolean res;
@@ -1332,61 +1322,60 @@ gdm_display_init (GdmDisplay *self)
self->priv = GDM_DISPLAY_GET_PRIVATE (self);
self->priv->creation_time = time (NULL);
self->priv->server_timer = g_timer_new ();
}
static void
gdm_display_finalize (GObject *object)
{
GdmDisplay *self;
g_return_if_fail (object != NULL);
g_return_if_fail (GDM_IS_DISPLAY (object));
self = GDM_DISPLAY (object);
g_return_if_fail (self->priv != NULL);
g_debug ("GdmDisplay: Finalizing display: %s", self->priv->id);
g_free (self->priv->id);
g_free (self->priv->seat_id);
g_free (self->priv->session_class);
g_free (self->priv->remote_hostname);
g_free (self->priv->x11_display_name);
g_free (self->priv->x11_cookie);
g_clear_object (&self->priv->display_skeleton);
g_clear_object (&self->priv->object_skeleton);
g_clear_object (&self->priv->connection);
- g_clear_object (&self->priv->accountsservice_proxy);
if (self->priv->access_file != NULL) {
g_object_unref (self->priv->access_file);
}
if (self->priv->user_access_file != NULL) {
g_object_unref (self->priv->user_access_file);
}
if (self->priv->server_timer != NULL) {
g_timer_destroy (self->priv->server_timer);
}
G_OBJECT_CLASS (gdm_display_parent_class)->finalize (object);
}
GDBusObjectSkeleton *
gdm_display_get_object_skeleton (GdmDisplay *self)
{
return self->priv->object_skeleton;
}
static void
on_launch_environment_session_opened (GdmLaunchEnvironment *launch_environment,
GdmDisplay *self)
{
char *session_id;
g_debug ("GdmDisplay: Greeter session opened");
session_id = gdm_launch_environment_get_session_id (launch_environment);
--
2.21.0

View File

@ -0,0 +1,343 @@
From 53950976344f38a96a17c1bbb3c093f67b49c493 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Thu, 20 Dec 2018 14:51:38 -0500
Subject: [PATCH] manager: allow multiple xdmcp logins for the same user
---
common/gdm-settings-keys.h | 1 +
daemon/gdm-manager.c | 71 ++++++++++++++++++++++++++++----------
data/gdm.schemas.in.in | 5 +++
3 files changed, 59 insertions(+), 18 deletions(-)
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h
index f0059b5cf..33676a851 100644
--- a/common/gdm-settings-keys.h
+++ b/common/gdm-settings-keys.h
@@ -28,37 +28,38 @@ G_BEGIN_DECLS
#define GDM_KEY_USER "daemon/User"
#define GDM_KEY_GROUP "daemon/Group"
#define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable"
#define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin"
#define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable"
#define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin"
#define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay"
#define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable"
#define GDM_KEY_WAYLAND_ENABLE "daemon/WaylandEnable"
#define GDM_KEY_DEBUG "debug/Enable"
#define GDM_KEY_INCLUDE "greeter/Include"
#define GDM_KEY_EXCLUDE "greeter/Exclude"
#define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll"
#define GDM_KEY_DISALLOW_TCP "security/DisallowTCP"
#define GDM_KEY_ALLOW_REMOTE_AUTOLOGIN "security/AllowRemoteAutoLogin"
#define GDM_KEY_XDMCP_ENABLE "xdmcp/Enable"
#define GDM_KEY_SHOW_LOCAL_GREETER "xdmcp/ShowLocalGreeter"
#define GDM_KEY_MAX_PENDING "xdmcp/MaxPending"
#define GDM_KEY_MAX_SESSIONS "xdmcp/MaxSessions"
#define GDM_KEY_MAX_WAIT "xdmcp/MaxWait"
#define GDM_KEY_DISPLAYS_PER_HOST "xdmcp/DisplaysPerHost"
#define GDM_KEY_UDP_PORT "xdmcp/Port"
#define GDM_KEY_INDIRECT "xdmcp/HonorIndirect"
#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"
G_END_DECLS
#endif /* _GDM_SETTINGS_KEYS_H */
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 056560b20..de7357ad5 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -594,93 +594,106 @@ get_display_and_details_for_bus_sender (GdmManager *self,
if (out_tty != NULL) {
*out_tty = get_tty_for_session_id (session_id, &error);
if (error != NULL) {
g_debug ("GdmManager: Error while retrieving tty for session: %s",
error->message);
g_clear_error (&error);
}
}
display = gdm_display_store_find (self->priv->display_store,
lookup_by_session_id,
(gpointer) session_id);
if (out_display != NULL) {
*out_display = display;
}
out:
g_free (session_id);
}
static gboolean
switch_to_compatible_user_session (GdmManager *manager,
GdmSession *session,
gboolean fail_if_already_switched)
{
gboolean res;
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;
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 = activate_session_id (manager, 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 = activate_session_id (manager, 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:
return ret;
}
static GdmDisplay *
get_display_for_user_session (GdmSession *session)
{
return g_object_get_data (G_OBJECT (session), "gdm-display");
}
static GdmSession *
get_user_session_for_display (GdmDisplay *display)
{
if (display == NULL) {
return NULL;
}
return g_object_get_data (G_OBJECT (display), "gdm-user-session");
}
static gboolean
add_session_record (GdmManager *manager,
GdmSession *session,
GPid pid,
SessionRecord record)
{
const char *username;
char *display_name, *hostname, *display_device;
@@ -1088,92 +1101,114 @@ open_temporary_reauthentication_channel (GdmManager *self,
g_signal_connect (session,
"client-disconnected",
G_CALLBACK (on_reauthentication_client_disconnected),
self);
g_signal_connect (session,
"client-rejected",
G_CALLBACK (on_reauthentication_client_rejected),
self);
g_signal_connect (session,
"cancelled",
G_CALLBACK (on_reauthentication_cancelled),
self);
g_signal_connect (session,
"conversation-started",
G_CALLBACK (on_reauthentication_conversation_started),
self);
g_signal_connect (session,
"conversation-stopped",
G_CALLBACK (on_reauthentication_conversation_stopped),
self);
g_signal_connect (session,
"verification-complete",
G_CALLBACK (on_reauthentication_verification_complete),
self);
address = gdm_session_get_server_address (session);
return g_strdup (address);
}
+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)
{
GdmManager *self = GDM_MANAGER (manager);
const char *sender;
GdmDisplay *display = NULL;
GdmSession *session;
GDBusConnection *connection;
char *seat_id = NULL;
char *session_id = NULL;
GPid pid = 0;
uid_t uid = (uid_t) -1;
gboolean is_login_screen = FALSE;
gboolean is_remote = FALSE;
g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
sender = g_dbus_method_invocation_get_sender (invocation);
connection = g_dbus_method_invocation_get_connection (invocation);
get_display_and_details_for_bus_sender (self, connection, sender, &display, &seat_id, &session_id, NULL, &pid, &uid, &is_login_screen, &is_remote);
if (session_id == NULL || pid == 0 || uid == (uid_t) -1) {
g_dbus_method_invocation_return_error_literal (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
_("No session available"));
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,
username,
seat_id,
NULL);
} else {
g_debug ("GdmManager: looking for user session on display");
session = get_user_session_for_display (display);
}
if (session != NULL && gdm_session_is_running (session)) {
gdm_session_start_reauthentication (session, pid, uid);
g_hash_table_insert (self->priv->open_reauthentication_requests,
GINT_TO_POINTER (pid),
invocation);
} else if (is_login_screen) {
g_dbus_method_invocation_return_error_literal (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Login screen only allowed to open reauthentication channels for running sessions");
return TRUE;
} else {
char *address;
address = open_temporary_reauthentication_channel (self,
seat_id,
session_id,
pid,
uid,
is_remote);
diff --git a/data/gdm.schemas.in.in b/data/gdm.schemas.in.in
index 8ad203101..003f92c63 100644
--- a/data/gdm.schemas.in.in
+++ b/data/gdm.schemas.in.in
@@ -102,32 +102,37 @@
<schema>
<key>xdmcp/DisplaysPerHost</key>
<signature>i</signature>
<default>1</default>
</schema>
<schema>
<key>xdmcp/Port</key>
<signature>i</signature>
<default>177</default>
</schema>
<schema>
<key>xdmcp/HonorIndirect</key>
<signature>b</signature>
<default>true</default>
</schema>
<schema>
<key>xdmcp/MaxWaitIndirect</key>
<signature>i</signature>
<default>30</default>
</schema>
<schema>
<key>xdmcp/PingIntervalSeconds</key>
<signature>i</signature>
<default>0</default>
</schema>
<schema>
<key>xdmcp/Willing</key>
<signature>s</signature>
<default>@gdmconfdir@/Xwilling</default>
</schema>
+ <schema>
+ <key>xdmcp/AllowMultipleSessionsPerUser</key>
+ <signature>b</signature>
+ <default>false</default>
+ </schema>
</schemalist>
</gdmschemafile>
--
2.21.0

View File

@ -0,0 +1,87 @@
From ecd37ba6d56a49dd896613f68d1e1754633b9f0c Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Wed, 6 Feb 2019 16:14:52 -0500
Subject: [PATCH 1/4] manager: don't kill timed login session immediately after
it starts
At the moment GDM is misidentifying timed login sessions as if
they are automatic login sessions. That leads to their displays
getting killed sometimes shortly after log in.
This commit corrects the check, so that timed login sessions aren't
treated as autologin sessions.
---
daemon/gdm-manager.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 2118c5834..b2d0578f5 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -1841,61 +1841,62 @@ on_start_user_session (StartUserSessionOperation *operation)
NULL);
} else {
uid_t allowed_uid;
g_object_ref (display);
if (doing_initial_setup) {
g_debug ("GdmManager: closing down initial setup display");
gdm_display_stop_greeter_session (display);
gdm_display_unmanage (display);
gdm_display_finish (display);
/* We can't start the user session until the finished display
* starts to respawn (since starting an X server and bringing
* one down at the same time is a no go)
*/
g_assert (self->priv->initial_login_operation == NULL);
self->priv->initial_login_operation = operation;
starting_user_session_right_away = FALSE;
} else {
g_debug ("GdmManager: session has its display server, reusing our server for another login screen");
}
/* The user session is going to follow the session worker
* into the new display. Untie it from this display and
* create a new session for a future user login. */
allowed_uid = gdm_session_get_allowed_user (operation->session);
g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL);
g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL);
create_user_session_for_display (operation->manager, display, allowed_uid);
- if (g_strcmp0 (operation->service_name, "gdm-autologin") == 0) {
+ if ((g_strcmp0 (operation->service_name, "gdm-autologin") == 0) &&
+ !gdm_session_client_is_connected (operation->session)) {
gboolean was_initial = FALSE;
g_object_get (G_OBJECT (display), "is-initial", &was_initial, NULL);
/* remove the unused prepared greeter display since we're not going
* to have a greeter */
gdm_display_store_remove (self->priv->display_store, display);
g_object_unref (display);
should_be_initial = was_initial;
}
/* Give the user session a new display object for bookkeeping purposes */
create_display_for_user_session (operation->manager,
operation->session,
session_id,
should_be_initial);
}
if (starting_user_session_right_away) {
start_user_session (operation->manager, operation);
}
out:
return G_SOURCE_REMOVE;
}
static void
queue_start_user_session (GdmManager *manager,
GdmSession *session,
--
2.21.0

View File

@ -0,0 +1,470 @@
From 521ff70fe447558461dd38cdec62a7c0a5a74f7a Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 24 Jun 2019 14:48:23 -0400
Subject: [PATCH 1/3] session-worker: expose worker state enum to type system
We're going to need to access the worker state as a property on
the worker object.
This commit hooks it up to glib-mkenums so the requisite goo can
get generated
---
daemon/Makefile.am | 8 +++++
daemon/gdm-session-worker-enum-types.c.in | 42 +++++++++++++++++++++++
daemon/gdm-session-worker-enum-types.h.in | 24 +++++++++++++
daemon/gdm-session-worker.c | 16 +++------
daemon/gdm-session-worker.h | 12 +++++++
5 files changed, 90 insertions(+), 12 deletions(-)
create mode 100644 daemon/gdm-session-worker-enum-types.c.in
create mode 100644 daemon/gdm-session-worker-enum-types.h.in
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index b77c9276e..86a8ee32f 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -14,69 +14,76 @@ AM_CPPFLAGS = \
-DLIBEXECDIR=\"$(libexecdir)\" \
-DLOCALSTATEDIR=\"$(localstatedir)\" \
-DLOGDIR=\"$(logdir)\" \
-DSBINDIR=\"$(sbindir)\" \
-DSYSCONFDIR=\"$(sysconfdir)\" \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
-DGDM_RUN_DIR=\"$(GDM_RUN_DIR)\" \
-DGDM_XAUTH_DIR=\"$(GDM_XAUTH_DIR)\" \
-DGDM_SCREENSHOT_DIR=\"$(GDM_SCREENSHOT_DIR)\" \
-DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \
-DGDM_SESSION_DEFAULT_PATH=\"$(GDM_SESSION_DEFAULT_PATH)\" \
$(DISABLE_DEPRECATED_CFLAGS) \
$(DAEMON_CFLAGS) \
$(XLIB_CFLAGS) \
$(WARN_CFLAGS) \
$(DEBUG_CFLAGS) \
$(SYSTEMD_CFLAGS) \
$(JOURNALD_CFLAGS) \
$(LIBSELINUX_CFLAGS) \
-DLANG_CONFIG_FILE=\"$(LANG_CONFIG_FILE)\" \
$(NULL)
BUILT_SOURCES = \
gdm-display-glue.h \
gdm-manager-glue.h \
gdm-local-display-glue.h \
gdm-local-display-factory-glue.h \
gdm-session-glue.h \
gdm-session-worker-glue.h \
gdm-session-enum-types.h \
+ gdm-session-worker-enum-types.h \
com.redhat.AccountsServiceUser.System.h \
$(NULL)
gdm-session-enum-types.h: gdm-session-enum-types.h.in gdm-session.h
$(AM_V_GEN) glib-mkenums --template $^ > $@
gdm-session-enum-types.c: gdm-session-enum-types.c.in gdm-session.h
$(AM_V_GEN) glib-mkenums --template $^ > $@
+gdm-session-worker-enum-types.h: gdm-session-worker-enum-types.h.in gdm-session-worker.h
+ $(AM_V_GEN) glib-mkenums --template $^ > $@
+
+gdm-session-worker-enum-types.c: gdm-session-worker-enum-types.c.in gdm-session-worker.h
+ $(AM_V_GEN) glib-mkenums --template $^ > $@
+
gdm-display-glue.c gdm-display-glue.h: gdm-display.xml Makefile.am
$(AM_V_GEN)gdbus-codegen \
--c-namespace=GdmDBus \
--interface-prefix=org.gnome.DisplayManager \
--generate-c-code=gdm-display-glue \
$(srcdir)/gdm-display.xml
gdm-local-display-glue.c gdm-local-display-glue.h: gdm-local-display.xml Makefile.am
$(AM_V_GEN)gdbus-codegen \
--c-namespace=GdmDBus \
--interface-prefix=org.gnome.DisplayManager \
--generate-c-code=gdm-local-display-glue \
$(srcdir)/gdm-local-display.xml
gdm-local-display-factory-glue.c gdm-local-display-factory-glue.h : gdm-local-display-factory.xml Makefile.am
$(AM_V_GEN)gdbus-codegen \
--c-namespace=GdmDBus \
--interface-prefix=org.gnome.DisplayManager \
--generate-c-code=gdm-local-display-factory-glue \
$(srcdir)/gdm-local-display-factory.xml
gdm-manager-glue.c gdm-manager-glue.h : gdm-manager.xml Makefile.am
$(AM_V_GEN)gdbus-codegen \
--c-namespace=GdmDBus \
--interface-prefix=org.gnome.DisplayManager \
--generate-c-code=gdm-manager-glue \
$(srcdir)/gdm-manager.xml
gdm-session-glue.c gdm-session-glue.h : gdm-session.xml Makefile.am
$(AM_V_GEN)gdbus-codegen \
@@ -128,60 +135,61 @@ gdm_session_worker_SOURCES = \
session-worker-main.c \
com.redhat.AccountsServiceUser.System.h \
com.redhat.AccountsServiceUser.System.c \
gdm-session.c \
gdm-session.h \
gdm-session-settings.h \
gdm-session-settings.c \
gdm-session-auditor.h \
gdm-session-auditor.c \
gdm-session-record.c \
gdm-session-record.h \
gdm-session-worker.h \
gdm-session-worker.c \
gdm-session-worker-job.c \
gdm-session-worker-common.c \
gdm-session-worker-common.h \
gdm-dbus-util.c \
gdm-dbus-util.h \
$(NULL)
if SUPPORTS_PAM_EXTENSIONS
gdm_session_worker_SOURCES += $(top_srcdir)/pam-extensions/gdm-pam-extensions.h
endif
nodist_gdm_session_worker_SOURCES = \
gdm-session-glue.h \
gdm-session-glue.c \
gdm-session-worker-glue.c \
gdm-session-worker-glue.h \
gdm-session-enum-types.c \
+ gdm-session-worker-enum-types.c \
gdm-session-enum-types.h \
$(NULL)
gdm_wayland_session_LDADD = \
$(top_builddir)/common/libgdmcommon.la \
$(GTK_LIBS) \
$(COMMON_LIBS) \
$(SYSTEMD_LIBS) \
$(NULL)
gdm_wayland_session_SOURCES = \
gdm-manager-glue.h \
gdm-manager-glue.c \
gdm-wayland-session.c \
$(NULL)
gdm_x_session_LDADD = \
$(top_builddir)/common/libgdmcommon.la \
$(GTK_LIBS) \
$(COMMON_LIBS) \
$(SYSTEMD_LIBS) \
$(XLIB_LIBS) \
$(NULL)
gdm_x_session_SOURCES = \
gdm-manager-glue.h \
gdm-manager-glue.c \
gdm-x-session.c \
$(NULL)
diff --git a/daemon/gdm-session-worker-enum-types.c.in b/daemon/gdm-session-worker-enum-types.c.in
new file mode 100644
index 000000000..c02869076
--- /dev/null
+++ b/daemon/gdm-session-worker-enum-types.c.in
@@ -0,0 +1,42 @@
+/*** BEGIN file-header ***/
+
+#include <glib-object.h>
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+#include "@filename@"
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+
+GType
+@enum_name@_get_type (void)
+{
+ static GType etype = 0;
+
+ if (G_UNLIKELY(etype == 0)) {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+
+ etype = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
+ }
+
+ return etype;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+ /**/
+/*** END file-tail ***/
diff --git a/daemon/gdm-session-worker-enum-types.h.in b/daemon/gdm-session-worker-enum-types.h.in
new file mode 100644
index 000000000..64f4b4bb6
--- /dev/null
+++ b/daemon/gdm-session-worker-enum-types.h.in
@@ -0,0 +1,24 @@
+/*** BEGIN file-header ***/
+#ifndef GDM_SESSION_WORKER_ENUM_TYPES_H
+#define GDM_SESSION_WORKER_ENUM_TYPES_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* GDM_SESSION_WORKER_ENUM_TYPES_H */
+/*** END file-tail ***/
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index ae86d28ac..f6935ab1d 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -83,83 +83,72 @@
#define GDM_SESSION_WORKER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerPrivate))
#define GDM_SESSION_DBUS_PATH "/org/gnome/DisplayManager/Session"
#define GDM_SESSION_DBUS_NAME "org.gnome.DisplayManager.Session"
#define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel"
#define GDM_WORKER_DBUS_PATH "/org/gnome/DisplayManager/Worker"
#ifndef GDM_PASSWD_AUXILLARY_BUFFER_SIZE
#define GDM_PASSWD_AUXILLARY_BUFFER_SIZE 1024
#endif
#ifndef GDM_SESSION_DEFAULT_PATH
#define GDM_SESSION_DEFAULT_PATH "/usr/local/bin:/usr/bin:/bin"
#endif
#ifndef GDM_SESSION_ROOT_UID
#define GDM_SESSION_ROOT_UID 0
#endif
#ifndef GDM_SESSION_LOG_FILENAME
#define GDM_SESSION_LOG_FILENAME "session.log"
#endif
#define MAX_FILE_SIZE 65536
#define MAX_LOGS 5
#define RELEASE_DISPLAY_SIGNAL (SIGRTMAX)
#define ACQUIRE_DISPLAY_SIGNAL (SIGRTMAX - 1)
-enum {
- GDM_SESSION_WORKER_STATE_NONE = 0,
- GDM_SESSION_WORKER_STATE_SETUP_COMPLETE,
- GDM_SESSION_WORKER_STATE_AUTHENTICATED,
- GDM_SESSION_WORKER_STATE_AUTHORIZED,
- GDM_SESSION_WORKER_STATE_ACCREDITED,
- GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED,
- GDM_SESSION_WORKER_STATE_SESSION_OPENED,
- GDM_SESSION_WORKER_STATE_SESSION_STARTED
-};
-
typedef struct
{
GdmSessionWorker *worker;
GdmSession *session;
GPid pid_of_caller;
uid_t uid_of_caller;
} ReauthenticationRequest;
struct GdmSessionWorkerPrivate
{
- int state;
+ GdmSessionWorkerState state;
int exit_code;
pam_handle_t *pam_handle;
GPid child_pid;
guint child_watch_id;
/* from Setup */
char *service;
char *x11_display_name;
char *x11_authority_file;
char *display_device;
char *display_seat_id;
char *hostname;
char *username;
char *log_file;
char *session_id;
uid_t uid;
gid_t gid;
gboolean password_is_required;
char **extensions;
int cred_flags;
int login_vt;
int session_vt;
int session_tty_fd;
char **arguments;
guint32 cancelled : 1;
@@ -2455,60 +2444,63 @@ gdm_session_worker_set_property (GObject *object,
switch (prop_id) {
case PROP_SERVER_ADDRESS:
gdm_session_worker_set_server_address (self, g_value_get_string (value));
break;
case PROP_IS_REAUTH_SESSION:
gdm_session_worker_set_is_reauth_session (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gdm_session_worker_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GdmSessionWorker *self;
self = GDM_SESSION_WORKER (object);
switch (prop_id) {
case PROP_SERVER_ADDRESS:
g_value_set_string (value, self->priv->server_address);
break;
case PROP_IS_REAUTH_SESSION:
g_value_set_boolean (value, self->priv->is_reauth_session);
break;
+ case PROP_STATE:
+ g_value_set_int (value, self->priv->state);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
gdm_session_worker_handle_set_environment_variable (GdmDBusWorker *object,
GDBusMethodInvocation *invocation,
const char *key,
const char *value)
{
GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
gdm_session_worker_set_environment_variable (worker, key, value);
gdm_dbus_worker_complete_set_environment_variable (object, invocation);
return TRUE;
}
static gboolean
gdm_session_worker_handle_set_session_name (GdmDBusWorker *object,
GDBusMethodInvocation *invocation,
const char *session_name)
{
GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
g_debug ("GdmSessionWorker: session name set to %s", session_name);
if (worker->priv->user_settings != NULL)
gdm_session_settings_set_session_name (worker->priv->user_settings,
session_name);
gdm_dbus_worker_complete_set_session_name (object, invocation);
return TRUE;
diff --git a/daemon/gdm-session-worker.h b/daemon/gdm-session-worker.h
index 5603e80e0..2814eab4d 100644
--- a/daemon/gdm-session-worker.h
+++ b/daemon/gdm-session-worker.h
@@ -1,56 +1,68 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2006 Ray Strode <rstrode@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#ifndef __GDM_SESSION_WORKER_H
#define __GDM_SESSION_WORKER_H
#include <glib-object.h>
#include "gdm-session-worker-glue.h"
#include "gdm-session-worker-common.h"
+#include "gdm-session-worker-enum-types.h"
G_BEGIN_DECLS
#define GDM_TYPE_SESSION_WORKER (gdm_session_worker_get_type ())
#define GDM_SESSION_WORKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_SESSION_WORKER, GdmSessionWorker))
#define GDM_SESSION_WORKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerClass))
#define GDM_IS_SESSION_WORKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_SESSION_WORKER))
#define GDM_IS_SESSION_WORKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_SESSION_WORKER))
#define GDM_SESSION_WORKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerClass))
+typedef enum {
+ GDM_SESSION_WORKER_STATE_NONE = 0,
+ GDM_SESSION_WORKER_STATE_SETUP_COMPLETE,
+ GDM_SESSION_WORKER_STATE_AUTHENTICATED,
+ GDM_SESSION_WORKER_STATE_AUTHORIZED,
+ GDM_SESSION_WORKER_STATE_ACCREDITED,
+ GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED,
+ GDM_SESSION_WORKER_STATE_SESSION_OPENED,
+ GDM_SESSION_WORKER_STATE_SESSION_STARTED
+} GdmSessionWorkerState;
+
typedef struct GdmSessionWorkerPrivate GdmSessionWorkerPrivate;
typedef struct
{
GdmDBusWorkerSkeleton parent;
GdmSessionWorkerPrivate *priv;
} GdmSessionWorker;
typedef struct
{
GdmDBusWorkerSkeletonClass parent_class;
} GdmSessionWorkerClass;
GType gdm_session_worker_get_type (void);
GdmSessionWorker * gdm_session_worker_new (const char *server_address,
gboolean is_for_reauth) G_GNUC_MALLOC;
G_END_DECLS
#endif /* GDM_SESSION_WORKER_H */
--
2.18.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,922 @@
From 4db5bf628396a7191f2392e7d09ab9bbd7c2b533 Mon Sep 17 00:00:00 2001
From: Xiaoguang Wang <xwang@suse.com>
Date: Thu, 16 May 2019 13:26:16 +0800
Subject: [PATCH 2/3] session-worker: kill user sessions when stop gdm service
At the moment the session worker exits as soon as it gets SIGTERM.
That means it may fail to stop the user session (which only happens
in the orderly shutdown path).
This commit sets up a SIGTERM handler that integrates with and
quits the main loop after the session is started.
It still retains the _exit-on-SIGTERM behavior before the session
is started, to ensure a stuck pam module doesn't prevent the
process from dying.
Some small changes to commit by Ray Strode.
Closes #400
---
daemon/gdm-session-worker.c | 39 +++++++++++++++++++++++++++---------
daemon/session-worker-main.c | 33 ++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+), 9 deletions(-)
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index f6935ab1d..aa288ac8e 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -159,60 +159,61 @@ struct GdmSessionWorkerPrivate
guint32 display_is_initial : 1;
guint state_change_idle_id;
GdmSessionDisplayMode display_mode;
char *server_address;
GDBusConnection *connection;
GdmDBusWorkerManager *manager;
GHashTable *reauthentication_requests;
GdmSessionAuditor *auditor;
GdmSessionSettings *user_settings;
GDBusMethodInvocation *pending_invocation;
};
#ifdef SUPPORTS_PAM_EXTENSIONS
static char gdm_pam_extension_environment_block[_POSIX_ARG_MAX];
static const char * const
gdm_supported_pam_extensions[] = {
GDM_PAM_EXTENSION_CHOICE_LIST,
NULL
};
#endif
enum {
PROP_0,
PROP_SERVER_ADDRESS,
PROP_IS_REAUTH_SESSION,
+ PROP_STATE,
};
static void gdm_session_worker_class_init (GdmSessionWorkerClass *klass);
static void gdm_session_worker_init (GdmSessionWorker *session_worker);
static void gdm_session_worker_finalize (GObject *object);
static void gdm_session_worker_set_environment_variable (GdmSessionWorker *worker,
const char *key,
const char *value);
static void queue_state_change (GdmSessionWorker *worker);
static void worker_interface_init (GdmDBusWorkerIface *iface);
typedef int (* GdmSessionWorkerPamNewMessagesFunc) (int,
const struct pam_message **,
struct pam_response **,
gpointer);
G_DEFINE_TYPE_WITH_CODE (GdmSessionWorker,
gdm_session_worker,
GDM_DBUS_TYPE_WORKER_SKELETON,
G_IMPLEMENT_INTERFACE (GDM_DBUS_TYPE_WORKER,
worker_interface_init))
/* adapted from glib script_execute */
static void
script_execute (const gchar *file,
char **argv,
@@ -971,100 +972,111 @@ jump_to_vt (GdmSessionWorker *worker,
g_debug ("GdmSessionWorker: first setting graphics mode to prevent flicker");
if (ioctl (fd, KDSETMODE, KD_GRAPHICS) < 0) {
g_debug ("GdmSessionWorker: couldn't set graphics mode: %m");
}
/* It's possible that the current VT was left in a broken
* combination of states (KD_GRAPHICS with VT_AUTO), that
* can't be switched away from. This call makes sure things
* are set in a way that VT_ACTIVATE should work and
* VT_WAITACTIVE shouldn't hang.
*/
fix_terminal_vt_mode (worker, active_vt_tty_fd);
} else {
fd = active_vt_tty_fd;
}
handle_terminal_vt_switches (worker, fd);
if (ioctl (fd, VT_ACTIVATE, vt_number) < 0) {
g_debug ("GdmSessionWorker: couldn't initiate jump to VT %d: %m",
vt_number);
} else if (ioctl (fd, VT_WAITACTIVE, vt_number) < 0) {
g_debug ("GdmSessionWorker: couldn't finalize jump to VT %d: %m",
vt_number);
}
close (active_vt_tty_fd);
}
+static void
+gdm_session_worker_set_state (GdmSessionWorker *worker,
+ GdmSessionWorkerState state)
+{
+ if (worker->priv->state == state)
+ return;
+
+ worker->priv->state = state;
+ g_object_notify (G_OBJECT (worker), "state");
+}
+
static void
gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker,
int status)
{
g_debug ("GdmSessionWorker: uninitializing PAM");
if (worker->priv->pam_handle == NULL)
return;
gdm_session_worker_get_username (worker, NULL);
if (worker->priv->state >= GDM_SESSION_WORKER_STATE_SESSION_OPENED) {
pam_close_session (worker->priv->pam_handle, 0);
gdm_session_auditor_report_logout (worker->priv->auditor);
} else {
gdm_session_auditor_report_login_failure (worker->priv->auditor,
status,
pam_strerror (worker->priv->pam_handle, status));
}
if (worker->priv->state >= GDM_SESSION_WORKER_STATE_ACCREDITED) {
pam_setcred (worker->priv->pam_handle, PAM_DELETE_CRED);
}
pam_end (worker->priv->pam_handle, status);
worker->priv->pam_handle = NULL;
gdm_session_worker_stop_auditor (worker);
if (g_strcmp0 (worker->priv->display_seat_id, "seat0") == 0) {
if (worker->priv->login_vt != worker->priv->session_vt) {
jump_to_vt (worker, worker->priv->login_vt);
}
}
worker->priv->login_vt = 0;
worker->priv->session_vt = 0;
g_debug ("GdmSessionWorker: state NONE");
- worker->priv->state = GDM_SESSION_WORKER_STATE_NONE;
+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_NONE);
}
static char *
_get_tty_for_pam (const char *x11_display_name,
const char *display_device)
{
#ifdef __sun
return g_strdup (display_device);
#else
return g_strdup (x11_display_name);
#endif
}
#ifdef PAM_XAUTHDATA
static struct pam_xauth_data *
_get_xauth_for_pam (const char *x11_authority_file)
{
FILE *fh;
Xauth *auth = NULL;
struct pam_xauth_data *retval = NULL;
gsize len = sizeof (*retval) + 1;
fh = fopen (x11_authority_file, "r");
if (fh) {
auth = XauReadAuth (fh);
fclose (fh);
}
if (auth) {
len += auth->name_length + auth->data_length;
retval = g_malloc0 (len);
@@ -1173,61 +1185,61 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
goto out;
}
}
/* set RHOST */
if (hostname != NULL && hostname[0] != '\0') {
error_code = pam_set_item (worker->priv->pam_handle, PAM_RHOST, hostname);
g_debug ("error informing authentication system of user's hostname %s: %s",
hostname,
pam_strerror (worker->priv->pam_handle, error_code));
if (error_code != PAM_SUCCESS) {
g_set_error (error,
GDM_SESSION_WORKER_ERROR,
GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
"%s", "");
goto out;
}
}
/* set seat ID */
if (seat_id != NULL && seat_id[0] != '\0') {
gdm_session_worker_set_environment_variable (worker, "XDG_SEAT", seat_id);
}
if (strcmp (service, "gdm-launch-environment") == 0) {
gdm_session_worker_set_environment_variable (worker, "XDG_SESSION_CLASS", "greeter");
}
g_debug ("GdmSessionWorker: state SETUP_COMPLETE");
- worker->priv->state = GDM_SESSION_WORKER_STATE_SETUP_COMPLETE;
+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE);
/* Temporarily set PAM_TTY with the currently active VT (login screen)
PAM_TTY will be reset with the users VT right before the user session is opened */
ensure_login_vt (worker);
g_snprintf (tty_string, 256, "/dev/tty%d", worker->priv->login_vt);
pam_set_item (worker->priv->pam_handle, PAM_TTY, tty_string);
if (!display_is_local)
worker->priv->password_is_required = TRUE;
out:
if (error_code != PAM_SUCCESS) {
gdm_session_worker_uninitialize_pam (worker, error_code);
return FALSE;
}
return TRUE;
}
static gboolean
gdm_session_worker_authenticate_user (GdmSessionWorker *worker,
gboolean password_is_required,
GError **error)
{
int error_code;
int authentication_flags;
g_debug ("GdmSessionWorker: authenticating user %s", worker->priv->username);
authentication_flags = 0;
@@ -1238,61 +1250,61 @@ gdm_session_worker_authenticate_user (GdmSessionWorker *worker,
/* blocking call, does the actual conversation */
error_code = pam_authenticate (worker->priv->pam_handle, authentication_flags);
if (error_code == PAM_AUTHINFO_UNAVAIL) {
g_debug ("GdmSessionWorker: authentication service unavailable");
g_set_error (error,
GDM_SESSION_WORKER_ERROR,
GDM_SESSION_WORKER_ERROR_SERVICE_UNAVAILABLE,
"%s", "");
goto out;
} else if (error_code != PAM_SUCCESS) {
g_debug ("GdmSessionWorker: authentication returned %d: %s", error_code, pam_strerror (worker->priv->pam_handle, error_code));
/*
* Do not display a different message for user unknown versus
* a failed password for a valid user.
*/
if (error_code == PAM_USER_UNKNOWN) {
error_code = PAM_AUTH_ERR;
}
g_set_error (error,
GDM_SESSION_WORKER_ERROR,
GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
"%s", get_friendly_error_message (error_code));
goto out;
}
g_debug ("GdmSessionWorker: state AUTHENTICATED");
- worker->priv->state = GDM_SESSION_WORKER_STATE_AUTHENTICATED;
+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_AUTHENTICATED);
out:
if (error_code != PAM_SUCCESS) {
gdm_session_worker_uninitialize_pam (worker, error_code);
return FALSE;
}
return TRUE;
}
static gboolean
gdm_session_worker_authorize_user (GdmSessionWorker *worker,
gboolean password_is_required,
GError **error)
{
int error_code;
int authentication_flags;
g_debug ("GdmSessionWorker: determining if authenticated user (password required:%d) is authorized to session",
password_is_required);
authentication_flags = 0;
if (password_is_required) {
authentication_flags |= PAM_DISALLOW_NULL_AUTHTOK;
}
/* check that the account isn't disabled or expired
*/
error_code = pam_acct_mgmt (worker->priv->pam_handle, authentication_flags);
@@ -1303,61 +1315,61 @@ gdm_session_worker_authorize_user (GdmSessionWorker *worker,
g_debug ("GdmSessionWorker: authenticated user requires new auth token");
error_code = pam_chauthtok (worker->priv->pam_handle, PAM_CHANGE_EXPIRED_AUTHTOK);
gdm_session_worker_get_username (worker, NULL);
if (error_code != PAM_SUCCESS) {
gdm_session_auditor_report_password_change_failure (worker->priv->auditor);
} else {
gdm_session_auditor_report_password_changed (worker->priv->auditor);
}
}
/* If the user is reauthenticating, then authorization isn't required to
* proceed, the user is already logged in after all.
*/
if (worker->priv->is_reauth_session) {
error_code = PAM_SUCCESS;
}
if (error_code != PAM_SUCCESS) {
g_debug ("GdmSessionWorker: user is not authorized to log in: %s",
pam_strerror (worker->priv->pam_handle, error_code));
g_set_error (error,
GDM_SESSION_WORKER_ERROR,
GDM_SESSION_WORKER_ERROR_AUTHORIZING,
"%s", get_friendly_error_message (error_code));
goto out;
}
g_debug ("GdmSessionWorker: state AUTHORIZED");
- worker->priv->state = GDM_SESSION_WORKER_STATE_AUTHORIZED;
+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_AUTHORIZED);
out:
if (error_code != PAM_SUCCESS) {
gdm_session_worker_uninitialize_pam (worker, error_code);
return FALSE;
}
return TRUE;
}
static void
gdm_session_worker_set_environment_variable (GdmSessionWorker *worker,
const char *key,
const char *value)
{
int error_code;
char *environment_entry;
if (value != NULL) {
environment_entry = g_strdup_printf ("%s=%s", key, value);
} else {
/* empty value means "remove from environment" */
environment_entry = g_strdup (key);
}
error_code = pam_putenv (worker->priv->pam_handle,
environment_entry);
if (error_code != PAM_SUCCESS) {
g_warning ("cannot put %s in pam environment: %s\n",
@@ -1716,61 +1728,61 @@ gdm_session_worker_accredit_user (GdmSessionWorker *worker,
/* If the user is reauthenticating and they've made it this far, then there
* is no reason we should lock them out of their session. They've already
* proved they are they same person who logged in, and that's all we care
* about.
*/
if (worker->priv->is_reauth_session) {
error_code = PAM_SUCCESS;
}
if (error_code != PAM_SUCCESS) {
g_set_error (error,
GDM_SESSION_WORKER_ERROR,
GDM_SESSION_WORKER_ERROR_GIVING_CREDENTIALS,
"%s",
pam_strerror (worker->priv->pam_handle, error_code));
goto out;
}
ret = TRUE;
out:
g_free (home);
g_free (shell);
if (ret) {
g_debug ("GdmSessionWorker: state ACCREDITED");
ret = TRUE;
gdm_session_worker_get_username (worker, NULL);
gdm_session_auditor_report_user_accredited (worker->priv->auditor);
- worker->priv->state = GDM_SESSION_WORKER_STATE_ACCREDITED;
+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_ACCREDITED);
} else {
gdm_session_worker_uninitialize_pam (worker, error_code);
}
return ret;
}
static const char * const *
gdm_session_worker_get_environment (GdmSessionWorker *worker)
{
return (const char * const *) pam_getenvlist (worker->priv->pam_handle);
}
static gboolean
run_script (GdmSessionWorker *worker,
const char *dir)
{
/* scripts are for non-program sessions only */
if (worker->priv->is_program_session) {
return TRUE;
}
return gdm_run_script (dir,
worker->priv->username,
worker->priv->x11_display_name,
worker->priv->display_is_local? NULL : worker->priv->hostname,
worker->priv->x11_authority_file);
}
static void
@@ -2145,61 +2157,61 @@ gdm_session_worker_start_session (GdmSessionWorker *worker,
(char **)
environment,
TRUE);
gdm_log_init ();
g_debug ("GdmSessionWorker: child '%s' could not be started: %s",
worker->priv->arguments[0],
g_strerror (errno));
_exit (EXIT_FAILURE);
}
if (worker->priv->session_tty_fd > 0) {
close (worker->priv->session_tty_fd);
worker->priv->session_tty_fd = -1;
}
/* If we end up execing again, make sure we don't use the executable context set up
* by pam_selinux durin pam_open_session
*/
#ifdef HAVE_SELINUX
setexeccon (NULL);
#endif
worker->priv->child_pid = session_pid;
g_debug ("GdmSessionWorker: session opened creating reply...");
g_assert (sizeof (GPid) <= sizeof (int));
g_debug ("GdmSessionWorker: state SESSION_STARTED");
- worker->priv->state = GDM_SESSION_WORKER_STATE_SESSION_STARTED;
+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SESSION_STARTED);
gdm_session_worker_watch_child (worker);
out:
if (error_code != PAM_SUCCESS) {
gdm_session_worker_uninitialize_pam (worker, error_code);
return FALSE;
}
return TRUE;
}
static gboolean
set_up_for_new_vt (GdmSessionWorker *worker)
{
int fd;
char vt_string[256], tty_string[256];
int session_vt = 0;
fd = open ("/dev/tty0", O_RDWR | O_NOCTTY);
if (fd < 0) {
g_debug ("GdmSessionWorker: couldn't open VT master: %m");
return FALSE;
}
if (worker->priv->display_is_initial) {
session_vt = atoi (GDM_INITIAL_VT);
} else {
if (ioctl(fd, VT_OPENQRY, &session_vt) < 0) {
@@ -2368,61 +2380,61 @@ gdm_session_worker_open_session (GdmSessionWorker *worker,
break;
case GDM_SESSION_DISPLAY_MODE_NEW_VT:
case GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED:
if (!set_up_for_new_vt (worker)) {
g_set_error (error,
GDM_SESSION_WORKER_ERROR,
GDM_SESSION_WORKER_ERROR_OPENING_SESSION,
"Unable to open VT");
return FALSE;
}
break;
}
flags = 0;
if (worker->priv->is_program_session) {
flags |= PAM_SILENT;
}
error_code = pam_open_session (worker->priv->pam_handle, flags);
if (error_code != PAM_SUCCESS) {
g_set_error (error,
GDM_SESSION_WORKER_ERROR,
GDM_SESSION_WORKER_ERROR_OPENING_SESSION,
"%s", pam_strerror (worker->priv->pam_handle, error_code));
goto out;
}
g_debug ("GdmSessionWorker: state SESSION_OPENED");
- worker->priv->state = GDM_SESSION_WORKER_STATE_SESSION_OPENED;
+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SESSION_OPENED);
session_id = gdm_session_worker_get_environment_variable (worker, "XDG_SESSION_ID");
if (session_id != NULL) {
g_free (worker->priv->session_id);
worker->priv->session_id = session_id;
}
out:
if (error_code != PAM_SUCCESS) {
gdm_session_worker_uninitialize_pam (worker, error_code);
return FALSE;
}
gdm_session_worker_get_username (worker, NULL);
gdm_session_auditor_report_login (worker->priv->auditor);
return TRUE;
}
static void
gdm_session_worker_set_server_address (GdmSessionWorker *worker,
const char *address)
{
g_free (worker->priv->server_address);
worker->priv->server_address = g_strdup (address);
}
static void
gdm_session_worker_set_is_reauth_session (GdmSessionWorker *worker,
@@ -2445,61 +2457,61 @@ gdm_session_worker_set_property (GObject *object,
case PROP_SERVER_ADDRESS:
gdm_session_worker_set_server_address (self, g_value_get_string (value));
break;
case PROP_IS_REAUTH_SESSION:
gdm_session_worker_set_is_reauth_session (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gdm_session_worker_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GdmSessionWorker *self;
self = GDM_SESSION_WORKER (object);
switch (prop_id) {
case PROP_SERVER_ADDRESS:
g_value_set_string (value, self->priv->server_address);
break;
case PROP_IS_REAUTH_SESSION:
g_value_set_boolean (value, self->priv->is_reauth_session);
break;
case PROP_STATE:
- g_value_set_int (value, self->priv->state);
+ g_value_set_enum (value, self->priv->state);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
gdm_session_worker_handle_set_environment_variable (GdmDBusWorker *object,
GDBusMethodInvocation *invocation,
const char *key,
const char *value)
{
GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
gdm_session_worker_set_environment_variable (worker, key, value);
gdm_dbus_worker_complete_set_environment_variable (object, invocation);
return TRUE;
}
static gboolean
gdm_session_worker_handle_set_session_name (GdmDBusWorker *object,
GDBusMethodInvocation *invocation,
const char *session_name)
{
GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
g_debug ("GdmSessionWorker: session name set to %s", session_name);
if (worker->priv->user_settings != NULL)
gdm_session_settings_set_session_name (worker->priv->user_settings,
session_name);
gdm_dbus_worker_complete_set_session_name (object, invocation);
@@ -2646,61 +2658,61 @@ do_authorize (GdmSessionWorker *worker)
g_dbus_method_invocation_take_error (worker->priv->pending_invocation, error);
}
worker->priv->pending_invocation = NULL;
}
static void
do_accredit (GdmSessionWorker *worker)
{
GError *error;
gboolean res;
/* get kerberos tickets, setup group lists, etc
*/
error = NULL;
res = gdm_session_worker_accredit_user (worker, &error);
if (res) {
gdm_dbus_worker_complete_establish_credentials (GDM_DBUS_WORKER (worker), worker->priv->pending_invocation);
} else {
g_dbus_method_invocation_take_error (worker->priv->pending_invocation, error);
}
worker->priv->pending_invocation = NULL;
}
static void
save_account_details_now (GdmSessionWorker *worker)
{
g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCREDITED);
g_debug ("GdmSessionWorker: saving account details for user %s", worker->priv->username);
- worker->priv->state = GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED;
+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED);
if (worker->priv->user_settings != NULL) {
if (!gdm_session_settings_save (worker->priv->user_settings,
worker->priv->username)) {
g_warning ("could not save session and language settings");
}
}
queue_state_change (worker);
}
static void
on_settings_is_loaded_changed (GdmSessionSettings *user_settings,
GParamSpec *pspec,
GdmSessionWorker *worker)
{
if (!gdm_session_settings_is_loaded (worker->priv->user_settings)) {
return;
}
/* These signal handlers should be disconnected after the loading,
* so that gdm_session_settings_set_* APIs don't cause the emitting
* of Saved*NameRead D-Bus signals any more.
*/
g_signal_handlers_disconnect_by_func (worker->priv->user_settings,
G_CALLBACK (on_saved_session_name_read),
worker);
g_signal_handlers_disconnect_by_func (worker->priv->user_settings,
G_CALLBACK (on_saved_language_name_read),
worker);
@@ -3461,60 +3473,69 @@ worker_interface_init (GdmDBusWorkerIface *interface)
interface->handle_start_reauthentication = gdm_session_worker_handle_start_reauthentication;
}
static void
gdm_session_worker_class_init (GdmSessionWorkerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gdm_session_worker_get_property;
object_class->set_property = gdm_session_worker_set_property;
object_class->constructor = gdm_session_worker_constructor;
object_class->finalize = gdm_session_worker_finalize;
g_type_class_add_private (klass, sizeof (GdmSessionWorkerPrivate));
g_object_class_install_property (object_class,
PROP_SERVER_ADDRESS,
g_param_spec_string ("server-address",
"server address",
"server address",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_IS_REAUTH_SESSION,
g_param_spec_boolean ("is-reauth-session",
"is reauth session",
"is reauth session",
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (object_class,
+ PROP_STATE,
+ g_param_spec_enum ("state",
+ "state",
+ "state",
+ GDM_TYPE_SESSION_WORKER_STATE,
+ GDM_SESSION_WORKER_STATE_NONE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}
static void
reauthentication_request_free (ReauthenticationRequest *request)
{
g_signal_handlers_disconnect_by_func (request->session,
G_CALLBACK (on_reauthentication_client_connected),
request);
g_signal_handlers_disconnect_by_func (request->session,
G_CALLBACK (on_reauthentication_client_disconnected),
request);
g_signal_handlers_disconnect_by_func (request->session,
G_CALLBACK (on_reauthentication_cancelled),
request);
g_signal_handlers_disconnect_by_func (request->session,
G_CALLBACK (on_reauthentication_conversation_started),
request);
g_signal_handlers_disconnect_by_func (request->session,
G_CALLBACK (on_reauthentication_conversation_stopped),
request);
g_signal_handlers_disconnect_by_func (request->session,
G_CALLBACK (on_reauthentication_verification_complete),
request);
g_clear_object (&request->session);
g_slice_free (ReauthenticationRequest, request);
}
static void
gdm_session_worker_init (GdmSessionWorker *worker)
diff --git a/daemon/session-worker-main.c b/daemon/session-worker-main.c
index 4a3a8ebbe..d96844d2d 100644
--- a/daemon/session-worker-main.c
+++ b/daemon/session-worker-main.c
@@ -37,104 +37,137 @@
#include <glib-object.h>
#include "gdm-common.h"
#include "gdm-log.h"
#include "gdm-session-worker.h"
#include "gdm-settings.h"
#include "gdm-settings-direct.h"
#include "gdm-settings-keys.h"
static GdmSettings *settings = NULL;
static gboolean
on_sigusr1_cb (gpointer user_data)
{
g_debug ("Got USR1 signal");
gdm_log_toggle_debug ();
return TRUE;
}
static gboolean
is_debug_set (void)
{
gboolean debug;
gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug);
return debug;
}
+static gboolean
+on_shutdown_signal_cb (gpointer user_data)
+{
+ GMainLoop *mainloop = user_data;
+
+ g_main_loop_quit (mainloop);
+
+ return FALSE;
+}
+
+static void
+on_state_changed (GdmSessionWorker *worker,
+ GParamSpec *pspec,
+ GMainLoop *main_loop)
+{
+ GdmSessionWorkerState state;
+
+ g_object_get (G_OBJECT (worker), "state", &state, NULL);
+
+ if (state != GDM_SESSION_WORKER_STATE_SESSION_STARTED)
+ return;
+
+ g_unix_signal_add (SIGTERM, on_shutdown_signal_cb, main_loop);
+}
+
static void
on_sigterm_cb (int signal_number)
{
_exit (EXIT_SUCCESS);
}
int
main (int argc,
char **argv)
{
GMainLoop *main_loop;
GOptionContext *context;
GdmSessionWorker *worker;
const char *address;
gboolean is_for_reauth;
static GOptionEntry entries [] = {
{ NULL }
};
signal (SIGTERM, on_sigterm_cb);
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
textdomain (GETTEXT_PACKAGE);
setlocale (LC_ALL, "");
/* Translators: worker is a helper process that does the work
of starting up a session */
context = g_option_context_new (_("GNOME Display Manager Session Worker"));
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_parse (context, &argc, &argv, NULL);
g_option_context_free (context);
gdm_log_init ();
settings = gdm_settings_new ();
if (settings == NULL) {
g_warning ("Unable to initialize settings");
exit (EXIT_FAILURE);
}
if (! gdm_settings_direct_init (settings, DATADIR "/gdm/gdm.schemas", "/")) {
g_warning ("Unable to initialize settings");
exit (EXIT_FAILURE);
}
gdm_log_set_debug (is_debug_set ());
address = g_getenv ("GDM_SESSION_DBUS_ADDRESS");
if (address == NULL) {
g_warning ("GDM_SESSION_DBUS_ADDRESS not set");
exit (EXIT_FAILURE);
}
is_for_reauth = g_getenv ("GDM_SESSION_FOR_REAUTH") != NULL;
worker = gdm_session_worker_new (address, is_for_reauth);
main_loop = g_main_loop_new (NULL, FALSE);
+ g_signal_connect (G_OBJECT (worker),
+ "notify::state",
+ G_CALLBACK (on_state_changed),
+ main_loop);
+
g_unix_signal_add (SIGUSR1, on_sigusr1_cb, NULL);
g_main_loop_run (main_loop);
if (worker != NULL) {
+ g_signal_handlers_disconnect_by_func (worker,
+ G_CALLBACK (on_state_changed),
+ main_loop);
g_object_unref (worker);
}
g_main_loop_unref (main_loop);
g_debug ("Worker finished");
return 0;
}
--
2.18.1

View File

@ -0,0 +1,227 @@
From 7b83c1dc9645cabadfeb253d7eca427f6a26d10f Mon Sep 17 00:00:00 2001
From: Iain Lane <iainl@gnome.org>
Date: Thu, 31 Jan 2019 17:51:52 +0000
Subject: [PATCH 3/4] session: Don't allow greeter operations on an running
session
If a client has a reference to a session that starts running,
refuse to allow further operations on the session.
CVE-2019-3825
---
daemon/gdm-session.c | 75 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index f23a83c5e..a8263ba11 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -1401,130 +1401,205 @@ gdm_session_handle_client_begin_verification_for_user (GdmDBusUserVerifier *u
static gboolean
gdm_session_handle_client_answer_query (GdmDBusUserVerifier *user_verifier_interface,
GDBusMethodInvocation *invocation,
const char *service_name,
const char *answer,
GdmSession *self)
{
gdm_dbus_user_verifier_complete_answer_query (user_verifier_interface,
invocation);
gdm_session_answer_query (self, service_name, answer);
return TRUE;
}
static gboolean
gdm_session_handle_client_cancel (GdmDBusUserVerifier *user_verifier_interface,
GDBusMethodInvocation *invocation,
GdmSession *self)
{
gdm_dbus_user_verifier_complete_cancel (user_verifier_interface,
invocation);
gdm_session_cancel (self);
return TRUE;
}
static gboolean
gdm_session_handle_client_select_session (GdmDBusGreeter *greeter_interface,
GDBusMethodInvocation *invocation,
const char *session,
GdmSession *self)
{
+ if (gdm_session_is_running (self)) {
+ const char *username;
+
+ username = gdm_session_get_username (self);
+ g_debug ("GdmSession: refusing to select session %s since it's already running (for user %s)",
+ session,
+ username);
+ g_dbus_method_invocation_return_error (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Session already running for user %s",
+ username);
+ return TRUE;
+ }
+
if (self->priv->greeter_interface != NULL) {
gdm_dbus_greeter_complete_select_session (greeter_interface,
invocation);
}
gdm_session_select_session (self, session);
return TRUE;
}
static gboolean
gdm_session_handle_client_select_user (GdmDBusGreeter *greeter_interface,
GDBusMethodInvocation *invocation,
const char *username,
GdmSession *self)
{
+ if (gdm_session_is_running (self)) {
+ const char *session_username;
+
+ session_username = gdm_session_get_username (self);
+ g_debug ("GdmSession: refusing to select user %s, since session (%p) already running (for user %s)",
+ username,
+ self,
+ session_username);
+ g_dbus_method_invocation_return_error (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Session already running for user %s",
+ session_username);
+ return TRUE;
+ }
+
if (self->priv->greeter_interface != NULL) {
gdm_dbus_greeter_complete_select_user (greeter_interface,
invocation);
}
g_debug ("GdmSession: client selected user '%s' on session (%p)", username, self);
gdm_session_select_user (self, username);
return TRUE;
}
static gboolean
gdm_session_handle_client_start_session_when_ready (GdmDBusGreeter *greeter_interface,
GDBusMethodInvocation *invocation,
const char *service_name,
gboolean client_is_ready,
GdmSession *self)
{
+ if (gdm_session_is_running (self)) {
+ const char *username;
+
+ username = gdm_session_get_username (self);
+ g_debug ("GdmSession: refusing to start session (%p), since it's already running (for user %s)",
+ self,
+ username);
+ g_dbus_method_invocation_return_error (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Session already running for user %s",
+ username);
+ return TRUE;
+ }
if (self->priv->greeter_interface != NULL) {
gdm_dbus_greeter_complete_start_session_when_ready (greeter_interface,
invocation);
}
g_signal_emit (G_OBJECT (self),
signals [CLIENT_READY_FOR_SESSION_TO_START],
0,
service_name,
client_is_ready);
return TRUE;
}
static gboolean
gdm_session_handle_get_timed_login_details (GdmDBusGreeter *greeter_interface,
GDBusMethodInvocation *invocation,
GdmSession *self)
{
+ if (gdm_session_is_running (self)) {
+ const char *username;
+
+ username = gdm_session_get_username (self);
+ g_debug ("GdmSession: refusing to give timed login details, session (%p) already running (for user %s)",
+ self,
+ username);
+ g_dbus_method_invocation_return_error (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Session already running for user %s",
+ username);
+ return TRUE;
+ }
if (self->priv->greeter_interface != NULL) {
gdm_dbus_greeter_complete_get_timed_login_details (greeter_interface,
invocation,
self->priv->timed_login_username != NULL,
self->priv->timed_login_username != NULL? self->priv->timed_login_username : "",
self->priv->timed_login_delay);
if (self->priv->timed_login_username != NULL) {
gdm_dbus_greeter_emit_timed_login_requested (self->priv->greeter_interface,
self->priv->timed_login_username,
self->priv->timed_login_delay);
}
}
return TRUE;
}
static gboolean
gdm_session_handle_client_begin_auto_login (GdmDBusGreeter *greeter_interface,
GDBusMethodInvocation *invocation,
const char *username,
GdmSession *self)
{
+ const char *session_username;
+
+ if (gdm_session_is_running (self)) {
+ session_username = gdm_session_get_username (self);
+ g_debug ("GdmSession: refusing auto login operation, session (%p) already running for user %s (%s requested)",
+ self,
+ session_username,
+ username);
+ g_dbus_method_invocation_return_error (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Session already owned by user %s",
+ session_username);
+ return TRUE;
+ }
+
if (self->priv->greeter_interface != NULL) {
gdm_dbus_greeter_complete_begin_auto_login (greeter_interface,
invocation);
}
g_debug ("GdmSession: client requesting automatic login for user '%s' on session '%s' (%p)",
username,
gdm_session_get_session_id (self),
self);
gdm_session_setup_for_user (self, "gdm-autologin", username);
return TRUE;
}
static void
export_user_verifier_interface (GdmSession *self,
GDBusConnection *connection)
{
GdmDBusUserVerifier *user_verifier_interface;
user_verifier_interface = GDM_DBUS_USER_VERIFIER (gdm_dbus_user_verifier_skeleton_new ());
g_object_set_data (G_OBJECT (connection), "gdm-session", self);
g_signal_connect (user_verifier_interface,
"handle-enable-extensions",
G_CALLBACK (gdm_session_handle_client_enable_extensions),
connection);
g_signal_connect (user_verifier_interface,
"handle-begin-verification",
--
2.21.0

View File

@ -0,0 +1,85 @@
From 1987a539495f38ade3efc561f65b56316080356e Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 24 Jun 2019 16:21:59 -0400
Subject: [PATCH 3/3] session-worker: uninitialize pam if worker is killed
Right nowe don't uninitialize pam or switch back to the
starting VT if the worker is killed before the session.
This commit fixes that.
---
daemon/gdm-session-worker.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index aa288ac8e..0322037e0 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -3552,60 +3552,64 @@ gdm_session_worker_init (GdmSessionWorker *worker)
static void
gdm_session_worker_unwatch_child (GdmSessionWorker *worker)
{
if (worker->priv->child_watch_id == 0)
return;
g_source_remove (worker->priv->child_watch_id);
worker->priv->child_watch_id = 0;
}
static void
gdm_session_worker_finalize (GObject *object)
{
GdmSessionWorker *worker;
g_return_if_fail (object != NULL);
g_return_if_fail (GDM_IS_SESSION_WORKER (object));
worker = GDM_SESSION_WORKER (object);
g_return_if_fail (worker->priv != NULL);
gdm_session_worker_unwatch_child (worker);
if (worker->priv->child_pid > 0) {
gdm_signal_pid (worker->priv->child_pid, SIGTERM);
gdm_wait_on_pid (worker->priv->child_pid);
}
+ if (worker->priv->pam_handle != NULL) {
+ gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS);
+ }
+
g_clear_object (&worker->priv->user_settings);
g_free (worker->priv->service);
g_free (worker->priv->x11_display_name);
g_free (worker->priv->x11_authority_file);
g_free (worker->priv->display_device);
g_free (worker->priv->display_seat_id);
g_free (worker->priv->hostname);
g_free (worker->priv->username);
g_free (worker->priv->server_address);
g_strfreev (worker->priv->arguments);
g_strfreev (worker->priv->extensions);
g_hash_table_unref (worker->priv->reauthentication_requests);
G_OBJECT_CLASS (gdm_session_worker_parent_class)->finalize (object);
}
GdmSessionWorker *
gdm_session_worker_new (const char *address,
gboolean is_reauth_session)
{
GObject *object;
object = g_object_new (GDM_TYPE_SESSION_WORKER,
"server-address", address,
"is-reauth-session", is_reauth_session,
NULL);
return GDM_SESSION_WORKER (object);
}
--
2.18.1

View File

@ -0,0 +1,105 @@
From 15a19ac7856c539aa9cfbf76997d18b0275aae35 Mon Sep 17 00:00:00 2001
From: Iain Lane <iainl@gnome.org>
Date: Mon, 4 Feb 2019 15:12:38 +0000
Subject: [PATCH 4/4] GdmManager: Don't perform timed login if session gets
started
At the moment it's possible for the login screen to initiate
a timed login operation shortly after a user successfully starts
their session.
GDM won't complete the timed login operation, since a session is
already running, but will erroneously overwrite the username
associated with the session, misattributing the users session
to the timed login user.
Later, attempts to log in as the timed user will instead unlock the
session for the other user, since that session is now associated
with the timed login user.
This commit refuses timed login requests on sessions that are
already running, so the username doesn't get corrupted.
CVE-2019-3825
Closes https://gitlab.gnome.org/GNOME/gdm/issues/460
---
daemon/gdm-manager.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 0cc06a978..056560b20 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -2116,60 +2116,68 @@ on_session_client_ready_for_session_to_start (GdmSession *session,
} else {
g_debug ("GdmManager: Will start session when ready and told");
}
waiting_to_start_user_session = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (session),
"waiting-to-start"));
g_object_set_data (G_OBJECT (session),
"start-when-ready",
GINT_TO_POINTER (client_is_ready));
if (client_is_ready && waiting_to_start_user_session) {
start_user_session_if_ready (manager, session, service_name);
}
}
static void
on_session_client_connected (GdmSession *session,
GCredentials *credentials,
GPid pid_of_client,
GdmManager *manager)
{
GdmDisplay *display;
char *username;
int delay;
gboolean enabled;
gboolean allow_timed_login = FALSE;
g_debug ("GdmManager: client with pid %d connected", (int) pid_of_client);
+ if (gdm_session_is_running (session)) {
+ const char *session_username;
+ session_username = gdm_session_get_username (session);
+ g_debug ("GdmManager: ignoring connection, since session already running (for user %s)",
+ session_username);
+ return;
+ }
+
display = get_display_for_user_session (session);
if (display == NULL) {
return;
}
if (!display_is_on_seat0 (display)) {
return;
}
#ifdef WITH_PLYMOUTH
if (manager->priv->plymouth_is_running) {
plymouth_quit_with_transition ();
manager->priv->plymouth_is_running = FALSE;
}
#endif
g_object_get (G_OBJECT (display), "allow-timed-login", &allow_timed_login, NULL);
if (!allow_timed_login) {
return;
}
enabled = get_timed_login_details (manager, &username, &delay);
if (! enabled) {
return;
}
gdm_session_set_timed_login_details (session, username, delay);
--
2.21.0

View File

@ -0,0 +1,28 @@
From f32adbe9bf26d502cb055b3a6cb98fc57e06bf13 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 26 Jul 2019 14:06:16 -0400
Subject: [PATCH 4/4] data: reap gdm sessions on shutdown
If GDM gets shutdown we should make sure all sessions get shutdown too.
This is a bit of a safety net in case any processes in the session are
lingering after the orderly shutdown.
---
data/gdm.service.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/data/gdm.service.in b/data/gdm.service.in
index 72201c1fd..202ab6753 100644
--- a/data/gdm.service.in
+++ b/data/gdm.service.in
@@ -21,6 +21,7 @@ OnFailure=plymouth-quit.service
[Service]
ExecStart=@sbindir@/gdm
+ExecStopPost=-/usr/bin/bash -c 'for f in /run/systemd/sessions/*; do [ -f $f ] && /usr/bin/fgrep -q SERVICE=gdm $f && loginctl terminate-session $(basename $f); done'
KillMode=mixed
Restart=always
IgnoreSIGPIPE=no
--
2.18.1

View File

@ -10,35 +10,53 @@
Name: gdm
Epoch: 1
Version: 3.28.3
Release: 20%{?dist}
Release: 28%{?dist}
Summary: The GNOME Display Manager
License: GPLv2+
URL: https://wiki.gnome.org/Projects/GDM
Source0: http://download.gnome.org/sources/gdm/3.28/gdm-%{version}.tar.xz
Source1: org.gnome.login-screen.gschema.override
Patch0: 0001-Honor-initial-setup-being-disabled-by-distro-install.patch
Patch00001: 0001-Honor-initial-setup-being-disabled-by-distro-install.patch
Patch11: 0001-utils-add-new-gdm-disable-wayland-binary.patch
Patch10001: 0001-utils-add-new-gdm-disable-wayland-binary.patch
Patch31: 0001-display-access-file-drop-unused-function.patch
Patch20001: 0001-display-access-file-drop-unused-function.patch
Patch41: 0001-data-disable-wayland-for-proprietary-nvidia-machines.patch
Patch42: 0001-data-disable-wayland-for-legacy-QXL-VMs.patch
Patch43: 0001-data-disable-wayland-on-server-chips-and-dual-gpu-se.patch
Patch30001: 0001-data-disable-wayland-for-proprietary-nvidia-machines.patch
Patch30002: 0001-data-disable-wayland-on-server-chips-and-dual-gpu-se.patch
Patch30003: 0001-data-enable-wayland-on-cirrus.patch
Patch30004: 0001-data-only-disable-wayland-on-passthrough-virt-setups.patch
Patch51: 0001-local-display-factory-pause-for-a-few-seconds-before.patch
Patch40001: 0001-local-display-factory-pause-for-a-few-seconds-before.patch
Patch61: 0001-manager-ensure-is-initial-is-transfered-to-autologin.patch
Patch50001: 0001-manager-ensure-is-initial-is-transfered-to-autologin.patch
Patch71: 0001-session-ensure-login-screen-over-XDMCP-connects-to-i.patch
Patch60001: 0001-session-ensure-login-screen-over-XDMCP-connects-to-i.patch
Patch81: 0001-worker-don-t-load-user-settings-for-program-sessions.patch
Patch82: 0002-session-support-new-accountsservice-Session-and-Sess.patch
Patch83: 0003-daemon-save-os-release-in-accountsservice.patch
Patch84: 0004-daemon-handle-upgrades-from-RHEL-7.patch
Patch70001: 0001-worker-don-t-load-user-settings-for-program-sessions.patch
Patch70002: 0002-session-support-new-accountsservice-Session-and-Sess.patch
Patch70003: 0003-daemon-save-os-release-in-accountsservice.patch
Patch70004: 0004-daemon-handle-upgrades-from-RHEL-7.patch
Patch99: system-dconf.patch
Patch80001: 0001-session-worker-expose-worker-state-enum-to-type-syst.patch
Patch80002: 0002-session-worker-kill-user-sessions-when-stop-gdm-serv.patch
Patch80003: 0003-session-worker-uninitialize-pam-if-worker-is-killed.patch
Patch80004: 0004-data-reap-gdm-sessions-on-shutdown.patch
# CVE-2019-3825
Patch90001: 0001-manager-don-t-kill-timed-login-session-immediately-a.patch
Patch90002: 0002-manager-session-Add-some-debugging-around-starting-r.patch
Patch90003: 0003-session-Don-t-allow-greeter-operations-on-an-running.patch
Patch90004: 0004-GdmManager-Don-t-perform-timed-login-if-session-gets.patch
Patch100001: 0001-manager-allow-multiple-xdmcp-logins-for-the-same-use.patch
Patch110001: 0001-display-ask-accountservice-if-there-are-users-rather.patch
Patch120001: 0001-daemon-fix-wayland-detection-when-deciding-to-bypass.patch
Patch999999: system-dconf.patch
BuildRequires: pam-devel >= 0:%{pam_version}
BuildRequires: desktop-file-utils >= %{desktop_file_utils_version}
@ -192,6 +210,8 @@ mkdir -p %{buildroot}%{_datadir}/gdm/autostart/LoginWindow
mkdir -p %{buildroot}/run/gdm
rm -f %{buildroot}%{_bindir}/gdm-screenshot
find %{buildroot} -name '*.a' -delete
find %{buildroot} -name '*.la' -delete
@ -293,7 +313,6 @@ fi
%{_libexecdir}/gdm-x-session
%{_sbindir}/gdm
%{_bindir}/gdmflexiserver
%{_bindir}/gdm-screenshot
%dir %{_datadir}/dconf
%dir %{_datadir}/dconf/profile
%{_datadir}/dconf/profile/gdm
@ -337,6 +356,43 @@ fi
%{_libdir}/pkgconfig/gdm-pam-extensions.pc
%changelog
* Sun Dec 15 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-28
- Correct wayland session detection logic when deciding
whether or not to run Xsession script
Resolves: #1728330
* Sun Dec 15 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-27
- Don't run initial-setup for machines enrolled in IPA setup.
Resolves: #1750516
* Fri Dec 13 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-26
- Forward port RHEL 7 patch to allow multiple logins for the
same user with XDMCP connections.
Resolves: #1710882
* Thu Dec 12 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-25
- Reenable wayland on hybrid setups (except virt pass through)
Resolves: #1749960
- Reenable wayland on qxl
Resolves: #1744452
* Fri Dec 06 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-24
- Reenable wayland on cirrus
Resolves: #1744527
* Thu Nov 21 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-23
- Correct timedlogin based screenlock bypass
Resolves: #1672829
* Mon Jun 24 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-22
- Ensure user session is killed with its worker and that all
user sessions are cleaned up on shutdown
Resolves: #1690714
* Mon Jun 17 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-21
- Drop gdm-screenshot
Resolves: #1680164
* Mon Feb 11 2019 Ray Strode <rstrode@redhat.com> - 3.28.3-20
- Disable wayland on hybrid gpu machines, and server machines
again