summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <halfline@gmail.com>2019-06-28 13:42:09 +0000
committerRay Strode <halfline@gmail.com>2019-06-28 13:42:09 +0000
commit3cdfc557e003f921c0dcf47811dd53b51a925f5a (patch)
tree007af091602bc7631a6cde1b6137647d60a0edfe
parentd461213b5e529e440c4525c1c0e16889a11cc72c (diff)
parent3e8220921bb608afd06ed677104fd2244b901a28 (diff)
downloadgdm-3cdfc557e003f921c0dcf47811dd53b51a925f5a.tar.gz
Merge branch 'wip/kill-user-session' into 'master'
session-worker: kill user sessions when stopping gdm service Closes #400 See merge request GNOME/gdm!74
-rw-r--r--daemon/Makefile.am14
-rw-r--r--daemon/gdm-session-worker-enum-types.c.in42
-rw-r--r--daemon/gdm-session-worker-enum-types.h.in24
-rw-r--r--daemon/gdm-session-worker.c57
-rw-r--r--daemon/gdm-session-worker.h12
-rw-r--r--daemon/session-worker-main.c33
6 files changed, 162 insertions, 20 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 5e9eb5e0..d75d7288 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -40,6 +40,7 @@ BUILT_SOURCES = \
gdm-session-glue.h \
gdm-session-worker-glue.h \
gdm-session-enum-types.h \
+ gdm-session-worker-enum-types.h \
$(NULL)
gdm-session-enum-types.h: gdm-session-enum-types.h.in gdm-session.h
@@ -48,6 +49,12 @@ gdm-session-enum-types.h: gdm-session-enum-types.h.in gdm-session.h
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 \
@@ -145,6 +152,8 @@ nodist_gdm_session_worker_SOURCES = \
gdm-session-worker-glue.h \
gdm-session-enum-types.c \
gdm-session-enum-types.h \
+ gdm-session-worker-enum-types.h \
+ gdm-session-worker-enum-types.c \
$(NULL)
gdm_wayland_session_LDADD = \
@@ -248,6 +257,8 @@ nodist_gdm_SOURCES = \
gdm-session-worker-glue.h \
gdm-session-enum-types.c \
gdm-session-enum-types.h \
+ gdm-session-worker-enum-types.h \
+ gdm-session-worker-enum-types.c \
$(NULL)
XDMCP_SOURCES = \
@@ -285,6 +296,7 @@ CLEANFILES = \
gdm-session-glue.c \
gdm-session-worker-glue.c \
gdm-session-enum-types.c \
+ gdm-session-worker-enum-types.c \
gdm-local-display-glue.c \
$(BUILT_SOURCES) \
$(NULL)
@@ -298,4 +310,6 @@ EXTRA_DIST = \
gdm-local-display-factory.xml \
gdm-session-enum-types.c.in \
gdm-session-enum-types.h.in \
+ gdm-session-worker-enum-types.c.in \
+ gdm-session-worker-enum-types.h.in \
$(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 00000000..c0286907
--- /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 00000000..64f4b4bb
--- /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 a5f90c4b..cc565a4c 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -110,17 +110,6 @@
#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;
@@ -132,7 +121,7 @@ typedef struct
struct GdmSessionWorkerPrivate
{
- int state;
+ GdmSessionWorkerState state;
int exit_code;
@@ -197,6 +186,7 @@ enum {
PROP_0,
PROP_SERVER_ADDRESS,
PROP_IS_REAUTH_SESSION,
+ PROP_STATE,
};
static void gdm_session_worker_class_init (GdmSessionWorkerClass *klass);
@@ -1022,6 +1012,17 @@ jump_to_vt (GdmSessionWorker *worker,
}
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)
{
@@ -1060,7 +1061,7 @@ gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker,
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 *
@@ -1223,7 +1224,7 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
}
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 */
@@ -1289,7 +1290,7 @@ gdm_session_worker_authenticate_user (GdmSessionWorker *worker,
}
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) {
@@ -1354,7 +1355,7 @@ gdm_session_worker_authorize_user (GdmSessionWorker *worker,
}
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) {
@@ -1767,7 +1768,7 @@ gdm_session_worker_accredit_user (GdmSessionWorker *worker,
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);
}
@@ -2196,7 +2197,7 @@ gdm_session_worker_start_session (GdmSessionWorker *worker,
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);
@@ -2419,7 +2420,7 @@ gdm_session_worker_open_session (GdmSessionWorker *worker,
}
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");
@@ -2495,6 +2496,9 @@ gdm_session_worker_get_property (GObject *object,
case PROP_IS_REAUTH_SESSION:
g_value_set_boolean (value, self->priv->is_reauth_session);
break;
+ case PROP_STATE:
+ g_value_set_enum (value, self->priv->state);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -2678,7 +2682,7 @@ 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 (!gdm_session_settings_save (worker->priv->user_settings,
worker->priv->username)) {
g_warning ("could not save session and language settings");
@@ -3471,6 +3475,15 @@ gdm_session_worker_class_init (GdmSessionWorkerClass *klass)
"is reauth session",
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
+
+ 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
@@ -3542,6 +3555,10 @@ gdm_session_worker_finalize (GObject *object)
gdm_wait_on_pid (worker->priv->child_pid);
}
+ if (worker->priv->pam_handle != NULL) {
+ gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS);
+ }
+
g_object_unref (worker->priv->user_settings);
g_free (worker->priv->service);
g_free (worker->priv->x11_display_name);
diff --git a/daemon/gdm-session-worker.h b/daemon/gdm-session-worker.h
index 5603e80e..2814eab4 100644
--- a/daemon/gdm-session-worker.h
+++ b/daemon/gdm-session-worker.h
@@ -25,6 +25,7 @@
#include "gdm-session-worker-glue.h"
#include "gdm-session-worker-common.h"
+#include "gdm-session-worker-enum-types.h"
G_BEGIN_DECLS
@@ -35,6 +36,17 @@ G_BEGIN_DECLS
#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
diff --git a/daemon/session-worker-main.c b/daemon/session-worker-main.c
index 4a3a8ebb..d96844d2 100644
--- a/daemon/session-worker-main.c
+++ b/daemon/session-worker-main.c
@@ -64,6 +64,31 @@ is_debug_set (void)
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)
{
@@ -124,11 +149,19 @@ main (int argc,
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);
}