import gdm-3.28.3-22.el8
This commit is contained in:
parent
d267cceb47
commit
1657319ce7
@ -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
|
||||
|
@ -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,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
|
||||
|
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,7 +10,7 @@
|
||||
Name: gdm
|
||||
Epoch: 1
|
||||
Version: 3.28.3
|
||||
Release: 20%{?dist}
|
||||
Release: 22%{?dist}
|
||||
Summary: The GNOME Display Manager
|
||||
|
||||
License: GPLv2+
|
||||
@ -38,7 +38,12 @@ 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
|
||||
|
||||
Patch99: system-dconf.patch
|
||||
Patch91: 0001-session-worker-expose-worker-state-enum-to-type-syst.patch
|
||||
Patch92: 0002-session-worker-kill-user-sessions-when-stop-gdm-serv.patch
|
||||
Patch93: 0003-session-worker-uninitialize-pam-if-worker-is-killed.patch
|
||||
Patch94: 0004-data-reap-gdm-sessions-on-shutdown.patch
|
||||
|
||||
Patch9999: system-dconf.patch
|
||||
|
||||
BuildRequires: pam-devel >= 0:%{pam_version}
|
||||
BuildRequires: desktop-file-utils >= %{desktop_file_utils_version}
|
||||
@ -192,6 +197,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 +300,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 +343,15 @@ fi
|
||||
%{_libdir}/pkgconfig/gdm-pam-extensions.pc
|
||||
|
||||
%changelog
|
||||
* 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