import gdm-3.28.3-28.el8
This commit is contained in:
parent
1c4bd4148e
commit
392665b522
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
44
SOURCES/0001-data-enable-wayland-on-cirrus.patch
Normal file
44
SOURCES/0001-data-enable-wayland-on-cirrus.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
28
SOURCES/0004-data-reap-gdm-sessions-on-shutdown.patch
Normal file
28
SOURCES/0004-data-reap-gdm-sessions-on-shutdown.patch
Normal 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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user