|
|
675525 |
From ab06d95076705cdaee9945adb2e22ac75be72952 Mon Sep 17 00:00:00 2001
|
|
|
675525 |
From: Ray Strode <rstrode@redhat.com>
|
|
|
675525 |
Date: Thu, 29 Aug 2019 09:34:04 -0400
|
|
|
675525 |
Subject: [PATCH 7/7] daemon: run PostSession script from mnager not worker
|
|
|
675525 |
|
|
|
675525 |
After a user logs out, the session worker baby sitting
|
|
|
675525 |
the session, may optionally run admin provided PostSession
|
|
|
675525 |
scripts.
|
|
|
675525 |
|
|
|
675525 |
Those scripts aren't getting reliably run on reboots, because
|
|
|
675525 |
systemd kills the worker prematurely.
|
|
|
675525 |
|
|
|
675525 |
There's no easy way to prevent this... the worker is part of
|
|
|
675525 |
the user session and user sessions are terminated immediately
|
|
|
675525 |
at shutdown time.
|
|
|
675525 |
|
|
|
675525 |
This commit moves PostSession handling to the daemon process,
|
|
|
675525 |
where it can happen unimpeded by session bring down.
|
|
|
675525 |
|
|
|
675525 |
This also makes the scripts more reliable in other potential
|
|
|
675525 |
cases where the worker is killed explicitly.
|
|
|
675525 |
---
|
|
|
675525 |
daemon/gdm-manager.c | 40 +++++++++++++++++++++++++++++++++++++
|
|
|
675525 |
daemon/gdm-session-worker.c | 3 ---
|
|
|
675525 |
2 files changed, 40 insertions(+), 3 deletions(-)
|
|
|
675525 |
|
|
|
675525 |
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
|
675525 |
index 779b716be..d31c9d718 100644
|
|
|
675525 |
--- a/daemon/gdm-manager.c
|
|
|
675525 |
+++ b/daemon/gdm-manager.c
|
|
|
675525 |
@@ -1933,70 +1933,107 @@ on_user_session_opened (GdmSession *session,
|
|
|
675525 |
g_object_ref (session));
|
|
|
675525 |
if (g_strcmp0 (service_name, "gdm-autologin") == 0 &&
|
|
|
675525 |
!gdm_session_client_is_connected (session)) {
|
|
|
675525 |
/* If we're auto logging in then don't wait for the go-ahead from a greeter,
|
|
|
675525 |
* (since there is no greeter) */
|
|
|
675525 |
g_object_set_data (G_OBJECT (session), "start-when-ready", GINT_TO_POINTER (TRUE));
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
start_user_session_if_ready (manager, session, service_name);
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
static void
|
|
|
675525 |
on_user_session_started (GdmSession *session,
|
|
|
675525 |
const char *service_name,
|
|
|
675525 |
GPid pid,
|
|
|
675525 |
GdmManager *manager)
|
|
|
675525 |
{
|
|
|
675525 |
g_debug ("GdmManager: session started %d", pid);
|
|
|
675525 |
add_session_record (manager, session, pid, SESSION_RECORD_LOGIN);
|
|
|
675525 |
|
|
|
675525 |
#ifdef WITH_PLYMOUTH
|
|
|
675525 |
if (g_strcmp0 (service_name, "gdm-autologin") == 0) {
|
|
|
675525 |
if (manager->priv->plymouth_is_running) {
|
|
|
675525 |
g_timeout_add_seconds (20, (GSourceFunc) plymouth_quit_with_transition, NULL);
|
|
|
675525 |
manager->priv->plymouth_is_running = FALSE;
|
|
|
675525 |
}
|
|
|
675525 |
}
|
|
|
675525 |
#endif
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
+static void
|
|
|
675525 |
+run_post_session_script (GdmSession *session)
|
|
|
675525 |
+{
|
|
|
675525 |
+ GPid pid;
|
|
|
675525 |
+ GdmDisplay *display;
|
|
|
675525 |
+ gboolean display_is_local = FALSE;
|
|
|
675525 |
+ const char *username;
|
|
|
675525 |
+ g_autofree char *display_name = NULL, *remote_hostname = NULL, *display_auth_file = NULL;
|
|
|
675525 |
+
|
|
|
675525 |
+ display = get_display_for_user_session (session);
|
|
|
675525 |
+
|
|
|
675525 |
+ if (display == NULL)
|
|
|
675525 |
+ return;
|
|
|
675525 |
+
|
|
|
675525 |
+ pid = gdm_session_get_pid (session);
|
|
|
675525 |
+
|
|
|
675525 |
+ if (pid <= 0)
|
|
|
675525 |
+ return;
|
|
|
675525 |
+
|
|
|
675525 |
+ username = gdm_session_get_username (session);
|
|
|
675525 |
+
|
|
|
675525 |
+ g_object_get (G_OBJECT (display),
|
|
|
675525 |
+ "x11-display-name", &display_name,
|
|
|
675525 |
+ "is-local", &display_is_local,
|
|
|
675525 |
+ "remote-hostname", &remote_hostname,
|
|
|
675525 |
+ "x11-authority-file", &display_auth_file,
|
|
|
675525 |
+ NULL);
|
|
|
675525 |
+
|
|
|
675525 |
+ gdm_run_script (GDMCONFDIR "/PostSession",
|
|
|
675525 |
+ username,
|
|
|
675525 |
+ display_name,
|
|
|
675525 |
+ display_is_local? NULL : remote_hostname,
|
|
|
675525 |
+ display_auth_file);
|
|
|
675525 |
+}
|
|
|
675525 |
+
|
|
|
675525 |
static void
|
|
|
675525 |
remove_user_session (GdmManager *manager,
|
|
|
675525 |
GdmSession *session)
|
|
|
675525 |
{
|
|
|
675525 |
GList *node;
|
|
|
675525 |
GdmDisplay *display;
|
|
|
675525 |
|
|
|
675525 |
display = get_display_for_user_session (session);
|
|
|
675525 |
|
|
|
675525 |
if (display != NULL) {
|
|
|
675525 |
+ run_post_session_script (session);
|
|
|
675525 |
+
|
|
|
675525 |
gdm_display_unmanage (display);
|
|
|
675525 |
gdm_display_finish (display);
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
node = g_list_find (manager->priv->user_sessions, session);
|
|
|
675525 |
|
|
|
675525 |
if (node != NULL) {
|
|
|
675525 |
manager->priv->user_sessions = g_list_delete_link (manager->priv->user_sessions, node);
|
|
|
675525 |
gdm_session_close (session);
|
|
|
675525 |
g_object_unref (session);
|
|
|
675525 |
}
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
static void
|
|
|
675525 |
on_session_start_failed (GdmSession *session,
|
|
|
675525 |
const char *service_name,
|
|
|
675525 |
const char *message,
|
|
|
675525 |
GdmManager *manager)
|
|
|
675525 |
{
|
|
|
675525 |
g_debug ("GdmManager: session failed to start: %s", message);
|
|
|
675525 |
remove_user_session (manager, session);
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
static void
|
|
|
675525 |
on_user_session_exited (GdmSession *session,
|
|
|
675525 |
int code,
|
|
|
675525 |
GdmManager *manager)
|
|
|
675525 |
{
|
|
|
675525 |
GPid pid;
|
|
|
675525 |
|
|
|
675525 |
@@ -2753,60 +2790,63 @@ finish_display (const char *id,
|
|
|
675525 |
if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED)
|
|
|
675525 |
gdm_display_unmanage (display);
|
|
|
675525 |
gdm_display_finish (display);
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
static void
|
|
|
675525 |
gdm_manager_dispose (GObject *object)
|
|
|
675525 |
{
|
|
|
675525 |
GdmManager *manager;
|
|
|
675525 |
|
|
|
675525 |
g_return_if_fail (object != NULL);
|
|
|
675525 |
g_return_if_fail (GDM_IS_MANAGER (object));
|
|
|
675525 |
|
|
|
675525 |
manager = GDM_MANAGER (object);
|
|
|
675525 |
|
|
|
675525 |
g_return_if_fail (manager->priv != NULL);
|
|
|
675525 |
|
|
|
675525 |
gdm_manager_stop (manager);
|
|
|
675525 |
|
|
|
675525 |
#ifdef HAVE_LIBXDMCP
|
|
|
675525 |
g_clear_object (&manager->priv->xdmcp_factory);
|
|
|
675525 |
#endif
|
|
|
675525 |
g_clear_object (&manager->priv->local_factory);
|
|
|
675525 |
g_clear_pointer (&manager->priv->open_reauthentication_requests,
|
|
|
675525 |
(GDestroyNotify)
|
|
|
675525 |
g_hash_table_unref);
|
|
|
675525 |
g_clear_pointer (&manager->priv->transient_sessions,
|
|
|
675525 |
(GDestroyNotify)
|
|
|
675525 |
g_hash_table_unref);
|
|
|
675525 |
|
|
|
675525 |
+ g_list_foreach (manager->priv->user_sessions,
|
|
|
675525 |
+ (GFunc) run_post_session_script,
|
|
|
675525 |
+ NULL);
|
|
|
675525 |
g_list_foreach (manager->priv->user_sessions,
|
|
|
675525 |
(GFunc) gdm_session_close,
|
|
|
675525 |
NULL);
|
|
|
675525 |
g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref);
|
|
|
675525 |
manager->priv->user_sessions = NULL;
|
|
|
675525 |
|
|
|
675525 |
g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
|
|
|
675525 |
G_CALLBACK (on_display_added),
|
|
|
675525 |
manager);
|
|
|
675525 |
g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
|
|
|
675525 |
G_CALLBACK (on_display_removed),
|
|
|
675525 |
manager);
|
|
|
675525 |
|
|
|
675525 |
if (!g_dbus_connection_is_closed (manager->priv->connection)) {
|
|
|
675525 |
gdm_display_store_foreach (manager->priv->display_store,
|
|
|
675525 |
(GdmDisplayStoreFunc)unexport_display,
|
|
|
675525 |
manager);
|
|
|
675525 |
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager));
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
gdm_display_store_foreach (manager->priv->display_store,
|
|
|
675525 |
(GdmDisplayStoreFunc) finish_display,
|
|
|
675525 |
manager);
|
|
|
675525 |
|
|
|
675525 |
gdm_display_store_clear (manager->priv->display_store);
|
|
|
675525 |
|
|
|
675525 |
g_dbus_object_manager_server_set_connection (manager->priv->object_manager, NULL);
|
|
|
675525 |
|
|
|
675525 |
g_clear_object (&manager->priv->connection);
|
|
|
675525 |
g_clear_object (&manager->priv->object_manager);
|
|
|
675525 |
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
|
|
|
675525 |
index 07117d857..b0861b971 100644
|
|
|
675525 |
--- a/daemon/gdm-session-worker.c
|
|
|
675525 |
+++ b/daemon/gdm-session-worker.c
|
|
|
675525 |
@@ -1743,72 +1743,69 @@ gdm_session_worker_get_environment (GdmSessionWorker *worker)
|
|
|
675525 |
static gboolean
|
|
|
675525 |
run_script (GdmSessionWorker *worker,
|
|
|
675525 |
const char *dir)
|
|
|
675525 |
{
|
|
|
675525 |
/* scripts are for non-program sessions only */
|
|
|
675525 |
if (worker->priv->is_program_session) {
|
|
|
675525 |
return TRUE;
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
return gdm_run_script (dir,
|
|
|
675525 |
worker->priv->username,
|
|
|
675525 |
worker->priv->x11_display_name,
|
|
|
675525 |
worker->priv->display_is_local? NULL : worker->priv->hostname,
|
|
|
675525 |
worker->priv->x11_authority_file);
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
static void
|
|
|
675525 |
session_worker_child_watch (GPid pid,
|
|
|
675525 |
int status,
|
|
|
675525 |
GdmSessionWorker *worker)
|
|
|
675525 |
{
|
|
|
675525 |
g_debug ("GdmSessionWorker: child (pid:%d) done (%s:%d)",
|
|
|
675525 |
(int) pid,
|
|
|
675525 |
WIFEXITED (status) ? "status"
|
|
|
675525 |
: WIFSIGNALED (status) ? "signal"
|
|
|
675525 |
: "unknown",
|
|
|
675525 |
WIFEXITED (status) ? WEXITSTATUS (status)
|
|
|
675525 |
: WIFSIGNALED (status) ? WTERMSIG (status)
|
|
|
675525 |
: -1);
|
|
|
675525 |
|
|
|
675525 |
-
|
|
|
675525 |
gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS);
|
|
|
675525 |
|
|
|
675525 |
gdm_dbus_worker_emit_session_exited (GDM_DBUS_WORKER (worker),
|
|
|
675525 |
worker->priv->service,
|
|
|
675525 |
status);
|
|
|
675525 |
-
|
|
|
675525 |
killpg (pid, SIGHUP);
|
|
|
675525 |
|
|
|
675525 |
worker->priv->child_pid = -1;
|
|
|
675525 |
worker->priv->child_watch_id = 0;
|
|
|
675525 |
- run_script (worker, GDMCONFDIR "/PostSession");
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
static void
|
|
|
675525 |
gdm_session_worker_watch_child (GdmSessionWorker *worker)
|
|
|
675525 |
{
|
|
|
675525 |
g_debug ("GdmSession worker: watching pid %d", worker->priv->child_pid);
|
|
|
675525 |
worker->priv->child_watch_id = g_child_watch_add (worker->priv->child_pid,
|
|
|
675525 |
(GChildWatchFunc)session_worker_child_watch,
|
|
|
675525 |
worker);
|
|
|
675525 |
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
static gboolean
|
|
|
675525 |
_is_loggable_file (const char* filename)
|
|
|
675525 |
{
|
|
|
675525 |
struct stat file_info;
|
|
|
675525 |
|
|
|
675525 |
if (g_lstat (filename, &file_info) < 0) {
|
|
|
675525 |
return FALSE;
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
return S_ISREG (file_info.st_mode) && g_access (filename, R_OK | W_OK) == 0;
|
|
|
675525 |
}
|
|
|
675525 |
|
|
|
675525 |
static void
|
|
|
675525 |
rotate_logs (const char *path,
|
|
|
675525 |
guint n_copies)
|
|
|
675525 |
{
|
|
|
675525 |
int i;
|
|
|
675525 |
|
|
|
675525 |
--
|
|
|
675525 |
2.21.0
|
|
|
675525 |
|