diff options
author | Ray Strode <halfline@gmail.com> | 2019-06-28 13:42:09 +0000 |
---|---|---|
committer | Ray Strode <halfline@gmail.com> | 2019-06-28 13:42:09 +0000 |
commit | 3cdfc557e003f921c0dcf47811dd53b51a925f5a (patch) | |
tree | 007af091602bc7631a6cde1b6137647d60a0edfe | |
parent | d461213b5e529e440c4525c1c0e16889a11cc72c (diff) | |
parent | 3e8220921bb608afd06ed677104fd2244b901a28 (diff) | |
download | gdm-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.am | 14 | ||||
-rw-r--r-- | daemon/gdm-session-worker-enum-types.c.in | 42 | ||||
-rw-r--r-- | daemon/gdm-session-worker-enum-types.h.in | 24 | ||||
-rw-r--r-- | daemon/gdm-session-worker.c | 57 | ||||
-rw-r--r-- | daemon/gdm-session-worker.h | 12 | ||||
-rw-r--r-- | daemon/session-worker-main.c | 33 |
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); } |