openbsd-ports/x11/gnome/gdm/patches/patch-common_gdm-common_c
2021-05-15 15:49:02 +00:00

575 lines
20 KiB
Plaintext

$OpenBSD: patch-common_gdm-common_c,v 1.9 2021/05/15 15:49:02 ajacoutot Exp $
REVERT - OpenBSD does not have a systemd implementation (we need ConsoleKit)
From fcba1e1a5d556ce7b52101dbd2d1ba4a19469161 Mon Sep 17 00:00:00 2001
From: Iain Lane <iain@orangesquash.org.uk>
Date: Fri, 5 Jan 2018 11:53:34 +0000
Subject: [PATCH] manager: Find user's current graphical session, not session of caller
REVERT - OpenBSD does not have a systemd implementation (we need ConsoleKit)
From 9be58c9ec9a3a411492a5182ac4b0d51fdc3a323 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 12 Jun 2015 13:48:52 -0400
Subject: require logind support
REVERT - OpenBSD does not have a systemd implementation (we need ConsoleKit)
From 1ac67f522f5690c27023d98096ca817f12f7eb88 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 12 Jun 2015 13:28:01 -0400
Subject: drop consolekit support
Index: common/gdm-common.c
--- common/gdm-common.c.orig
+++ common/gdm-common.c
@@ -36,12 +36,25 @@
#include "gdm-common.h"
+#ifdef WITH_SYSTEMD
#include <systemd/sd-login.h>
+#endif
#define GDM_DBUS_NAME "org.gnome.DisplayManager"
#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH "/org/gnome/DisplayManager/LocalDisplayFactory"
#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE "org.gnome.DisplayManager.LocalDisplayFactory"
+#ifdef WITH_CONSOLE_KIT
+#define CK_NAME "org.freedesktop.ConsoleKit"
+#define CK_PATH "/org/freedesktop/ConsoleKit"
+#define CK_INTERFACE "org.freedesktop.ConsoleKit"
+
+#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
+#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
+#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
+#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
+#endif
+
G_DEFINE_QUARK (gdm-common-error, gdm_common_error);
gboolean
@@ -352,8 +365,87 @@ create_transient_display (GDBusConnection *connection,
return TRUE;
}
+#ifdef WITH_CONSOLE_KIT
gboolean
-gdm_activate_session_by_id (GDBusConnection *connection,
+get_current_session_id (GDBusConnection *connection,
+ char **session_id)
+{
+ GError *local_error = NULL;
+ GVariant *reply;
+
+ reply = g_dbus_connection_call_sync (connection,
+ CK_NAME,
+ CK_MANAGER_PATH,
+ CK_MANAGER_INTERFACE,
+ "GetCurrentSession",
+ NULL, /* parameters */
+ G_VARIANT_TYPE ("(o)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL, &local_error);
+ if (reply == NULL) {
+ g_warning ("Unable to determine session: %s", local_error->message);
+ g_error_free (local_error);
+ return FALSE;
+ }
+
+ g_variant_get (reply, "(o)", session_id);
+ g_variant_unref (reply);
+
+ return TRUE;
+}
+
+static gboolean
+get_seat_id_for_session (GDBusConnection *connection,
+ const char *session_id,
+ char **seat_id)
+{
+ GError *local_error = NULL;
+ GVariant *reply;
+
+ reply = g_dbus_connection_call_sync (connection,
+ CK_NAME,
+ session_id,
+ CK_SESSION_INTERFACE,
+ "GetSeatId",
+ NULL, /* parameters */
+ G_VARIANT_TYPE ("(o)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL, &local_error);
+ if (reply == NULL) {
+ g_warning ("Unable to determine seat: %s", local_error->message);
+ g_error_free (local_error);
+ return FALSE;
+ }
+
+ g_variant_get (reply, "(o)", seat_id);
+ g_variant_unref (reply);
+
+ return TRUE;
+}
+
+static char *
+get_current_seat_id (GDBusConnection *connection)
+{
+ gboolean res;
+ char *session_id;
+ char *seat_id;
+
+ session_id = NULL;
+ seat_id = NULL;
+
+ res = get_current_session_id (connection, &session_id);
+ if (res) {
+ res = get_seat_id_for_session (connection, session_id, &seat_id);
+ }
+ g_free (session_id);
+
+ return seat_id;
+}
+
+gboolean
+activate_session_id_for_ck (GDBusConnection *connection,
const char *seat_id,
const char *session_id)
{
@@ -361,6 +453,217 @@ gdm_activate_session_by_id (GDBusConnection *connectio
GVariant *reply;
reply = g_dbus_connection_call_sync (connection,
+ CK_NAME,
+ seat_id,
+ CK_SEAT_INTERFACE,
+ "ActivateSession",
+ g_variant_new ("(o)", session_id),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL, &local_error);
+ if (reply == NULL) {
+ g_warning ("Unable to activate session: %s", local_error->message);
+ g_error_free (local_error);
+ return FALSE;
+ }
+
+ g_variant_unref (reply);
+
+ return TRUE;
+}
+
+static gboolean
+session_is_login_window (GDBusConnection *connection,
+ const char *session_id)
+{
+ GError *local_error = NULL;
+ GVariant *reply;
+ const char *value;
+ gboolean ret;
+
+ reply = g_dbus_connection_call_sync (connection,
+ CK_NAME,
+ session_id,
+ CK_SESSION_INTERFACE,
+ "GetSessionType",
+ NULL,
+ G_VARIANT_TYPE ("(s)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL, &local_error);
+ if (reply == NULL) {
+ g_warning ("Unable to determine session type: %s", local_error->message);
+ g_error_free (local_error);
+ return FALSE;
+ }
+
+ g_variant_get (reply, "(&s)", &value);
+
+ if (value == NULL || value[0] == '\0' || strcmp (value, "LoginWindow") != 0) {
+ ret = FALSE;
+ } else {
+ ret = TRUE;
+ }
+
+ g_variant_unref (reply);
+
+ return ret;
+}
+
+static gboolean
+seat_can_activate_sessions (GDBusConnection *connection,
+ const char *seat_id)
+{
+ GError *local_error = NULL;
+ GVariant *reply;
+ gboolean ret;
+
+ reply = g_dbus_connection_call_sync (connection,
+ CK_NAME,
+ seat_id,
+ CK_SEAT_INTERFACE,
+ "CanActivateSessions",
+ NULL,
+ G_VARIANT_TYPE ("(b)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL, &local_error);
+ if (reply == NULL) {
+ g_warning ("Unable to determine if can activate sessions: %s", local_error->message);
+ g_error_free (local_error);
+ return FALSE;
+ }
+
+ g_variant_get (reply, "(b)", &ret);
+ g_variant_unref (reply);
+
+ return ret;
+}
+
+static const char **
+seat_get_sessions (GDBusConnection *connection,
+ const char *seat_id)
+{
+ GError *local_error = NULL;
+ GVariant *reply;
+ const char **value;
+
+ reply = g_dbus_connection_call_sync (connection,
+ CK_NAME,
+ seat_id,
+ CK_SEAT_INTERFACE,
+ "GetSessions",
+ NULL,
+ G_VARIANT_TYPE ("(ao)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL, &local_error);
+ if (reply == NULL) {
+ g_warning ("Unable to list sessions: %s", local_error->message);
+ g_error_free (local_error);
+ return FALSE;
+ }
+
+ g_variant_get (reply, "(^ao)", &value);
+ g_variant_unref (reply);
+
+ return value;
+}
+
+static gboolean
+get_login_window_session_id_for_ck (GDBusConnection *connection,
+ const char *seat_id,
+ char **session_id)
+{
+ gboolean can_activate_sessions;
+ const char **sessions;
+ int i;
+
+ *session_id = NULL;
+ sessions = NULL;
+
+ g_debug ("checking if seat can activate sessions");
+
+ can_activate_sessions = seat_can_activate_sessions (connection, seat_id);
+ if (! can_activate_sessions) {
+ g_debug ("seat is unable to activate sessions");
+ return FALSE;
+ }
+
+ sessions = seat_get_sessions (connection, seat_id);
+ for (i = 0; sessions [i] != NULL; i++) {
+ const char *ssid;
+
+ ssid = sessions [i];
+
+ if (session_is_login_window (connection, ssid)) {
+ *session_id = g_strdup (ssid);
+ break;
+ }
+ }
+ g_free (sessions);
+
+ return TRUE;
+}
+
+static gboolean
+goto_login_session_for_ck (GDBusConnection *connection,
+ GError **error)
+{
+ gboolean ret;
+ gboolean res;
+ char *session_id;
+ char *seat_id;
+
+ ret = FALSE;
+
+ /* First look for any existing LoginWindow sessions on the seat.
+ If none are found, create a new one. */
+
+ seat_id = get_current_seat_id (connection);
+ if (seat_id == NULL || seat_id[0] == '\0') {
+ g_debug ("seat id is not set; can't switch sessions");
+ g_set_error (error, GDM_COMMON_ERROR, 0, _("Could not identify the current session."));
+
+ return FALSE;
+ }
+
+ res = get_login_window_session_id_for_ck (connection, seat_id, &session_id);
+ if (! res) {
+ g_set_error (error, GDM_COMMON_ERROR, 1, _("User unable to switch sessions."));
+ return FALSE;
+ }
+
+ if (session_id != NULL) {
+ res = activate_session_id_for_ck (connection, seat_id, session_id);
+ if (res) {
+ ret = TRUE;
+ }
+ }
+
+ if (! ret && g_strcmp0 (seat_id, "/org/freedesktop/ConsoleKit/Seat1") == 0) {
+ res = create_transient_display (connection, error);
+ if (res) {
+ ret = TRUE;
+ }
+ }
+
+ return ret;
+}
+#endif
+
+#ifdef WITH_SYSTEMD
+
+gboolean
+activate_session_id_for_systemd (GDBusConnection *connection,
+ const char *seat_id,
+ const char *session_id)
+{
+ GError *local_error = NULL;
+ GVariant *reply;
+
+ reply = g_dbus_connection_call_sync (connection,
"org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
@@ -382,8 +685,8 @@ gdm_activate_session_by_id (GDBusConnection *connectio
}
gboolean
-gdm_get_login_window_session_id (const char *seat_id,
- char **session_id)
+get_login_window_session_id_for_systemd (const char *seat_id,
+ char **session_id)
{
gboolean ret;
int res, i;
@@ -476,15 +779,14 @@ out:
}
static gboolean
-goto_login_session (GDBusConnection *connection,
- GError **error)
+goto_login_session_for_systemd (GDBusConnection *connection,
+ GError **error)
{
gboolean ret;
int res;
char *our_session;
char *session_id;
char *seat_id;
- GError *local_error = NULL;
ret = FALSE;
session_id = NULL;
@@ -497,8 +799,10 @@ goto_login_session (GDBusConnection *connection,
* since the data allocated is from libsystemd-logind, which
* does not use GLib's g_malloc (). */
- if (!gdm_find_display_session (0, getuid (), &our_session, &local_error)) {
- g_propagate_prefixed_error (error, local_error, _("Could not identify the current session: "));
+ res = sd_pid_get_session (0, &our_session);
+ if (res < 0) {
+ g_debug ("failed to determine own session: %s", strerror (-res));
+ g_set_error (error, GDM_COMMON_ERROR, 0, _("Could not identify the current session."));
return FALSE;
}
@@ -512,9 +816,9 @@ goto_login_session (GDBusConnection *connection,
return FALSE;
}
- res = gdm_get_login_window_session_id (seat_id, &session_id);
+ res = get_login_window_session_id_for_systemd (seat_id, &session_id);
if (res && session_id != NULL) {
- res = gdm_activate_session_by_id (connection, seat_id, session_id);
+ res = activate_session_id_for_systemd (connection, seat_id, session_id);
if (res) {
ret = TRUE;
@@ -533,6 +837,7 @@ goto_login_session (GDBusConnection *connection,
return ret;
}
+#endif
gboolean
gdm_goto_login_session (GError **error)
@@ -548,7 +853,17 @@ gdm_goto_login_session (GError **error)
return FALSE;
}
- return goto_login_session (connection, error);
+#ifdef WITH_SYSTEMD
+ if (LOGIND_RUNNING()) {
+ return goto_login_session_for_systemd (connection, error);
+ }
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+ return goto_login_session_for_ck (connection, error);
+#else
+ return FALSE;
+#endif
}
static void
@@ -823,136 +1138,4 @@ gdm_shell_expand (const char *str,
}
}
return g_string_free (s, FALSE);
-}
-
-static gboolean
-_systemd_session_is_graphical (const char *session_id)
-{
- const gchar * const graphical_session_types[] = { "wayland", "x11", "mir", NULL };
- int saved_errno;
- g_autofree gchar *type = NULL;
-
- saved_errno = sd_session_get_type (session_id, &type);
- if (saved_errno < 0) {
- g_warning ("Couldn't get type for session '%s': %s",
- session_id,
- g_strerror (-saved_errno));
- return FALSE;
- }
-
- if (!g_strv_contains (graphical_session_types, type)) {
- g_debug ("Session '%s' is not a graphical session (type: '%s')",
- session_id,
- type);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-_systemd_session_is_active (const char *session_id)
-{
- const gchar * const active_states[] = { "active", "online", NULL };
- int saved_errno;
- g_autofree gchar *state = NULL;
-
- /*
- * display sessions can be 'closing' if they are logged out but some
- * processes are lingering; we shouldn't consider these (this is
- * checking for a race condition since we specified
- * GDM_SYSTEMD_SESSION_REQUIRE_ONLINE)
- */
- saved_errno = sd_session_get_state (session_id, &state);
- if (saved_errno < 0) {
- g_warning ("Couldn't get state for session '%s': %s",
- session_id,
- g_strerror (-saved_errno));
- return FALSE;
- }
-
- if (!g_strv_contains (active_states, state)) {
- g_debug ("Session '%s' is not active or online", session_id);
- return FALSE;
- }
-
- return TRUE;
-}
-
-gboolean
-gdm_find_display_session (GPid pid,
- const uid_t uid,
- char **out_session_id,
- GError **error)
-{
- char *local_session_id = NULL;
- g_auto(GStrv) sessions = NULL;
- int n_sessions;
- int res;
-
- g_return_val_if_fail (out_session_id != NULL, FALSE);
-
- /* First try to look up the session using the pid. We need this
- * at least for the greeter, because it currently runs multiple
- * sessions under the same user.
- * See also commit 2b52d8933c8ab38e7ee83318da2363d00d8c5581
- * which added an explicit dbus-run-session for all but seat0.
- */
- res = sd_pid_get_session (pid, &local_session_id);
- if (res >= 0) {
- g_debug ("GdmCommon: Found session %s for PID %d, using", local_session_id, pid);
-
- *out_session_id = g_strdup (local_session_id);
- free (local_session_id);
-
- return TRUE;
- } else {
- if (res != -ENODATA)
- g_warning ("GdmCommon: Failed to retrieve session information for pid %d: %s",
- pid, strerror (-res));
- }
-
- g_debug ("Finding a graphical session for user %d", uid);
-
- n_sessions = sd_uid_get_sessions (uid,
- GDM_SYSTEMD_SESSION_REQUIRE_ONLINE,
- &sessions);
-
- if (n_sessions < 0) {
- g_set_error (error,
- GDM_COMMON_ERROR,
- 0,
- "Failed to get sessions for user %d",
- uid);
- return FALSE;
- }
-
- for (int i = 0; i < n_sessions; ++i) {
- g_debug ("Considering session '%s'", sessions[i]);
-
- if (!_systemd_session_is_graphical (sessions[i]))
- continue;
-
- if (!_systemd_session_is_active (sessions[i]))
- continue;
-
- /*
- * We get the sessions from newest to oldest, so take the last
- * one we find that's good
- */
- local_session_id = sessions[i];
- }
-
- if (local_session_id == NULL) {
- g_set_error (error,
- GDM_COMMON_ERROR,
- 0,
- "Could not find a graphical session for user %d",
- uid);
- return FALSE;
- }
-
- *out_session_id = g_strdup (local_session_id);
-
- return TRUE;
}