mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2025-08-08 06:47:09 +02:00
2817 lines
96 KiB
Diff
2817 lines
96 KiB
Diff
From f4a1a8c560796804e0ec763ab50f5e56e2ff05c4 Mon Sep 17 00:00:00 2001
|
|
From: William Pitcock <nenolod@dereferenced.org>
|
|
Date: Tue, 6 Jun 2017 00:29:44 +0000
|
|
Subject: [PATCH 3/3] reintroduce ConsoleKit support
|
|
|
|
---
|
|
common/gdm-common.c | 335 +++++++++++++++++-
|
|
common/gdm-common.h | 3 +
|
|
common/gdm-log.c | 22 ++
|
|
configure.ac | 64 +++-
|
|
daemon/Makefile.am | 10 +
|
|
daemon/gdm-launch-environment.c | 7 +-
|
|
daemon/gdm-local-display-factory.c | 35 +-
|
|
daemon/gdm-manager.c | 679 +++++++++++++++++++++++++++----------
|
|
daemon/gdm-server.c | 69 +++-
|
|
daemon/gdm-session-worker-job.c | 2 +
|
|
daemon/gdm-session-worker.c | 314 +++++++++++++++--
|
|
daemon/gdm-session-worker.xml | 3 +
|
|
daemon/gdm-session.c | 25 ++
|
|
daemon/gdm-session.h | 2 +
|
|
libgdm/gdm-user-switching.c | 349 ++++++++++++++++++-
|
|
15 files changed, 1653 insertions(+), 266 deletions(-)
|
|
|
|
diff --git a/common/gdm-common.c b/common/gdm-common.c
|
|
index 31fc810a..2ad134a6 100644
|
|
--- a/common/gdm-common.c
|
|
+++ b/common/gdm-common.c
|
|
@@ -39,12 +39,25 @@
|
|
#include "mkdtemp.h"
|
|
#endif
|
|
|
|
+#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);
|
|
|
|
const char *
|
|
@@ -343,10 +356,301 @@ create_transient_display (GDBusConnection *connection,
|
|
return TRUE;
|
|
}
|
|
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+
|
|
+static gboolean
|
|
+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;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+activate_session_id_for_ck (GDBusConnection *connection,
|
|
+ const char *seat_id,
|
|
+ const char *session_id)
|
|
+{
|
|
+ GError *local_error = NULL;
|
|
+ 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
|
|
+
|
|
static gboolean
|
|
-activate_session_id (GDBusConnection *connection,
|
|
- const char *seat_id,
|
|
- const char *session_id)
|
|
+activate_session_id_for_systemd (GDBusConnection *connection,
|
|
+ const char *seat_id,
|
|
+ const char *session_id)
|
|
{
|
|
GError *local_error = NULL;
|
|
GVariant *reply;
|
|
@@ -373,8 +677,8 @@ activate_session_id (GDBusConnection *connection,
|
|
}
|
|
|
|
static gboolean
|
|
-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;
|
|
@@ -442,8 +746,8 @@ out:
|
|
}
|
|
|
|
static gboolean
|
|
-goto_login_session (GDBusConnection *connection,
|
|
- GError **error)
|
|
+goto_login_session_for_systemd (GDBusConnection *connection,
|
|
+ GError **error)
|
|
{
|
|
gboolean ret;
|
|
int res;
|
|
@@ -497,9 +801,9 @@ goto_login_session (GDBusConnection *connection,
|
|
return FALSE;
|
|
}
|
|
|
|
- res = 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 = activate_session_id (connection, seat_id, session_id);
|
|
+ res = activate_session_id_for_systemd (connection, seat_id, session_id);
|
|
|
|
if (res) {
|
|
ret = TRUE;
|
|
@@ -518,6 +822,7 @@ goto_login_session (GDBusConnection *connection,
|
|
|
|
return ret;
|
|
}
|
|
+#endif
|
|
|
|
gboolean
|
|
gdm_goto_login_session (GError **error)
|
|
@@ -533,7 +838,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
|
|
diff --git a/common/gdm-common.h b/common/gdm-common.h
|
|
index 8d83a124..4ffb9a25 100644
|
|
--- a/common/gdm-common.h
|
|
+++ b/common/gdm-common.h
|
|
@@ -31,6 +31,9 @@
|
|
expr; \
|
|
} while G_UNLIKELY (errno == EINTR);
|
|
|
|
+/* check if logind is running */
|
|
+#define LOGIND_RUNNING() (access("/run/systemd/seats/", F_OK) >= 0)
|
|
+
|
|
GQuark gdm_common_error_quark (void);
|
|
#define GDM_COMMON_ERROR gdm_common_error_quark()
|
|
|
|
diff --git a/common/gdm-log.c b/common/gdm-log.c
|
|
index 8a2d0154..22d8c7d6 100644
|
|
--- a/common/gdm-log.c
|
|
+++ b/common/gdm-log.c
|
|
@@ -30,7 +30,9 @@
|
|
#include <unistd.h>
|
|
|
|
#include <syslog.h>
|
|
+#ifdef WITH_SYSTEMD
|
|
#include <systemd/sd-daemon.h>
|
|
+#endif
|
|
|
|
#include <glib.h>
|
|
#include <glib/gstdio.h>
|
|
@@ -133,7 +135,27 @@ gdm_log_init (void)
|
|
|
|
initialized = TRUE;
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
+ is_sd_booted = sd_booted () > 0;
|
|
+#endif
|
|
+
|
|
g_log_set_default_handler (gdm_log_default_handler, NULL);
|
|
+
|
|
+ /* Only set up syslog if !systemd, otherwise with systemd
|
|
+ * enabled, we keep the default GLib log handler which goes to
|
|
+ * stderr, which is routed to the appropriate place in the
|
|
+ * systemd service file.
|
|
+ */
|
|
+ if (!is_sd_booted) {
|
|
+ prg_name = g_get_prgname ();
|
|
+
|
|
+ options = LOG_PID;
|
|
+#ifdef LOG_PERROR
|
|
+ options |= LOG_PERROR;
|
|
+#endif
|
|
+
|
|
+ openlog (prg_name, options, LOG_DAEMON);
|
|
+ }
|
|
}
|
|
|
|
void
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 602969bd..07a56ce4 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -257,7 +257,15 @@ AC_ARG_WITH(tcp-wrappers,
|
|
[Use TCP Wrappers @<:@default=auto@:>@]),,
|
|
with_tcp_wrappers=auto)
|
|
|
|
-
|
|
+AC_ARG_WITH(console-kit,
|
|
+ AS_HELP_STRING([--with-console-kit],
|
|
+ [Add ConsoleKit support @<:@default=auto@:>@]),,
|
|
+ with_console_kit=no)
|
|
+
|
|
+AC_ARG_WITH(systemd,
|
|
+ AS_HELP_STRING([--with-systemd],
|
|
+ [Add systemd support @<:@default=auto@:>@]),
|
|
+ [with_systemd=$withval], [with_systemd=auto])
|
|
AC_ARG_WITH([systemdsystemunitdir],
|
|
AS_HELP_STRING([--with-systemdsystemunitdir=DIR],
|
|
[Directory for systemd service files]),
|
|
@@ -640,14 +648,8 @@ dnl ---------------------------------------------------------------------------
|
|
dnl - Check for utmp stuff
|
|
dnl ---------------------------------------------------------------------------
|
|
|
|
-AC_CHECK_HEADERS(utmp.h utmpx.h libutil.h sys/param.h)
|
|
-AC_CHECK_FUNCS([getutxent updwtmpx updwtmp])
|
|
-AC_CHECK_LIB(util, login, [
|
|
- AC_DEFINE(HAVE_LOGIN, 1, [Define if have login])
|
|
- EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lutil" ])
|
|
-AC_CHECK_LIB(util, logout, [
|
|
- AC_DEFINE(HAVE_LOGOUT, 1, [Define if have logout])
|
|
- EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lutil" ])
|
|
+AC_CHECK_HEADERS(utmp.h utmpx.h util.h sys/param.h)
|
|
+AC_CHECK_FUNCS([getutxent getttyent updwtmpx updwtmp])
|
|
AC_CHECK_LIB(util, logwtmp, [
|
|
AC_DEFINE(HAVE_LOGWTMP, 1, [Define if have logwtmp])
|
|
EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lutil" ])
|
|
@@ -896,12 +898,42 @@ AC_SUBST(XINERAMA_LIBS)
|
|
CPPFLAGS="$xinerama_save_cppflags"
|
|
|
|
dnl ---------------------------------------------------------------------------
|
|
+dnl - Check for ConsoleKit support
|
|
+dnl ---------------------------------------------------------------------------
|
|
+
|
|
+use_console_kit=no
|
|
+if test "x$with_console_kit" != "xno" ; then
|
|
+ use_console_kit=yes
|
|
+ AC_DEFINE(WITH_CONSOLE_KIT, 1, [Define to enable ConsoleKit support])
|
|
+fi
|
|
+AM_CONDITIONAL(WITH_CONSOLE_KIT, test x$use_console_kit = xyes)
|
|
+AC_SUBST(WITH_CONSOLE_KIT)
|
|
+
|
|
+dnl ---------------------------------------------------------------------------
|
|
dnl - Check for systemd support
|
|
dnl ---------------------------------------------------------------------------
|
|
|
|
PKG_CHECK_MODULES(SYSTEMD,
|
|
- [libsystemd])
|
|
+ [libsystemd-login >= 186 libsystemd-daemon],
|
|
+ [have_systemd=yes], [have_systemd=no])
|
|
|
|
+if test "x$with_systemd" = "xauto" ; then
|
|
+ if test x$have_systemd = xno ; then
|
|
+ use_systemd=no
|
|
+ else
|
|
+ use_systemd=yes
|
|
+ fi
|
|
+else
|
|
+ use_systemd="$with_systemd"
|
|
+fi
|
|
+
|
|
+if test "x$use_systemd" != "xno" ; then
|
|
+ if test "x$have_systemd" = "xno"; then
|
|
+ AC_MSG_ERROR([Systemd support explicitly required, but systemd not found])
|
|
+ fi
|
|
+
|
|
+ AC_DEFINE(WITH_SYSTEMD, 1, [Define to enable systemd support])
|
|
+fi
|
|
AC_SUBST(SYSTEMD_CFLAGS)
|
|
AC_SUBST(SYSTEMD_LIBS)
|
|
|
|
@@ -1094,6 +1126,14 @@ fi
|
|
AC_SUBST(GDM_CUSTOM_CONF)
|
|
AC_SUBST(GDM_OLD_CONF, '${gdmconfdir}/gdm.conf')
|
|
|
|
+AC_ARG_WITH(consolekit-directory,
|
|
+ [AC_HELP_STRING([--with-consolekit-directory],
|
|
+ [Specify the directory of ck-get-x11-display-device @<:@default=libexecdir@:>@])],,
|
|
+ [with_consolekit_directory="\${libexecdir}"])
|
|
+
|
|
+CONSOLEKIT_DIR=$with_consolekit_directory
|
|
+AC_SUBST(CONSOLEKIT_DIR)
|
|
+
|
|
AC_ARG_WITH(gnome-settings-daemon-directory,
|
|
[AC_HELP_STRING([--with-gnome-settings-daemon-directory],
|
|
[Specify the directory of gnome-settings-daemon used by the chooser @<:@default=libexecdir@:>@])],,
|
|
@@ -1582,6 +1622,7 @@ echo "
|
|
dmconfdir: ${dmconfdir}
|
|
localstatedir: ${localstatedir}
|
|
datadir: ${datadir}
|
|
+ consolekit location: ${with_consolekit_directory}
|
|
gnome-settings-daemon location: ${with_gnome_settings_daemon_directory}
|
|
gnome-session-check-accel location: ${with_check_accelerated_directory}
|
|
source code location: ${srcdir}
|
|
@@ -1612,6 +1653,8 @@ echo \
|
|
" Xinerama support: ${XINERAMA_SUPPORT}
|
|
XDMCP support: ${XDMCP_SUPPORT}
|
|
SELinux support: ${use_selinux}
|
|
+ ConsoleKit support: ${use_console_kit}
|
|
+ systemd support: ${use_systemd}
|
|
systemd unit dir: ${with_systemdsystemunitdir}
|
|
plymouth support: ${use_plymouth}
|
|
wayland support: ${enable_wayland_support}
|
|
@@ -1620,3 +1663,4 @@ echo \
|
|
Enable documentation: ${enable_documentation}
|
|
Install GDM's Xsession: ${enable_gdm_xsession}
|
|
"
|
|
+
|
|
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
|
|
index ab5dda06..e3cf73a6 100644
|
|
--- a/daemon/Makefile.am
|
|
+++ b/daemon/Makefile.am
|
|
@@ -20,6 +20,7 @@ AM_CPPFLAGS = \
|
|
-DGDM_SCREENSHOT_DIR=\"$(GDM_SCREENSHOT_DIR)\" \
|
|
-DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \
|
|
-DGDM_SESSION_DEFAULT_PATH=\"$(GDM_SESSION_DEFAULT_PATH)\" \
|
|
+ -DCONSOLEKIT_DIR=\"$(CONSOLEKIT_DIR)\" \
|
|
$(DISABLE_DEPRECATED_CFLAGS) \
|
|
$(DAEMON_CFLAGS) \
|
|
$(XLIB_CFLAGS) \
|
|
@@ -264,6 +265,11 @@ EXTRA_gdm_SOURCES = \
|
|
$(XDMCP_SOURCES) \
|
|
$(NULL)
|
|
|
|
+CONSOLE_KIT_SOURCES = \
|
|
+ $(NULL)
|
|
+
|
|
+EXTRA_gdm_SOURCES += $(CONSOLE_KIT_SOURCES)
|
|
+
|
|
gdm_LDADD = \
|
|
$(top_builddir)/common/libgdmcommon.la \
|
|
$(XLIB_LIBS) \
|
|
@@ -275,6 +281,10 @@ gdm_LDADD = \
|
|
$(EXTRA_DAEMON_LIBS) \
|
|
$(NULL)
|
|
|
|
+if WITH_CONSOLE_KIT
|
|
+gdm_SOURCES += $(CONSOLE_KIT_SOURCES)
|
|
+endif
|
|
+
|
|
CLEANFILES = \
|
|
gdm-display-glue.c \
|
|
gdm-local-display-factory-glue.c \
|
|
diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c
|
|
index 5fd346ff..88183265 100644
|
|
--- a/daemon/gdm-launch-environment.c
|
|
+++ b/daemon/gdm-launch-environment.c
|
|
@@ -50,7 +50,7 @@
|
|
#include "gdm-settings-direct.h"
|
|
#include "gdm-settings-keys.h"
|
|
|
|
-#define INITIAL_SETUP_USERNAME "gnome-initial-setup"
|
|
+#define INITIAL_SETUP_USERNAME "_gnome-initial-setup"
|
|
#define GDM_SESSION_MODE "gdm"
|
|
#define INITIAL_SETUP_SESSION_MODE "initial-setup"
|
|
#define GNOME_SESSION_SESSIONS_PATH DATADIR "/gnome-session/sessions"
|
|
@@ -197,6 +197,9 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment,
|
|
char *seat_id;
|
|
|
|
seat_id = launch_environment->priv->x11_display_seat_id;
|
|
+ if (g_str_has_prefix (seat_id, "/org/freedesktop/ConsoleKit/")) {
|
|
+ seat_id += strlen ("/org/freedesktop/ConsoleKit/");
|
|
+ }
|
|
|
|
g_hash_table_insert (hash, g_strdup ("GDM_SEAT_ID"), g_strdup (seat_id));
|
|
}
|
|
@@ -224,6 +227,8 @@ on_session_setup_complete (GdmSession *session,
|
|
gdm_session_set_environment_variable (launch_environment->priv->session, key, value);
|
|
}
|
|
g_hash_table_destroy (hash);
|
|
+
|
|
+ gdm_session_select_session_type (launch_environment->priv->session, "LoginWindow");
|
|
}
|
|
|
|
static void
|
|
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
|
|
index 7a4643d0..b31310c7 100644
|
|
--- a/daemon/gdm-local-display-factory.c
|
|
+++ b/daemon/gdm-local-display-factory.c
|
|
@@ -42,6 +42,8 @@
|
|
|
|
#define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate))
|
|
|
|
+#define CK_SEAT1_PATH "/org/freedesktop/ConsoleKit/Seat1"
|
|
+
|
|
#define GDM_DBUS_PATH "/org/gnome/DisplayManager"
|
|
#define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory"
|
|
#define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.LocalDisplayFactory"
|
|
@@ -57,8 +59,10 @@ struct GdmLocalDisplayFactoryPrivate
|
|
/* FIXME: this needs to be per seat? */
|
|
guint num_failures;
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
guint seat_new_id;
|
|
guint seat_removed_id;
|
|
+#endif
|
|
};
|
|
|
|
enum {
|
|
@@ -206,8 +210,10 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact
|
|
|
|
g_debug ("GdmLocalDisplayFactory: Creating transient display");
|
|
|
|
-#ifdef ENABLE_USER_DISPLAY_SERVER
|
|
- display = gdm_local_display_new ();
|
|
+#if defined ENABLE_USER_DISPLAY_SERVER && defined WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING() > 0) {
|
|
+ display = gdm_local_display_new ();
|
|
+ }
|
|
#else
|
|
if (display == NULL) {
|
|
guint32 num;
|
|
@@ -289,7 +295,7 @@ on_display_status_changed (GdmDisplay *display,
|
|
/* reset num failures */
|
|
factory->priv->num_failures = 0;
|
|
|
|
- gdm_local_display_factory_sync_seats (factory);
|
|
+ create_display (factory, seat_id, session_type, is_initial);
|
|
}
|
|
break;
|
|
case GDM_DISPLAY_FAILED:
|
|
@@ -368,7 +374,7 @@ create_display (GdmLocalDisplayFactory *factory,
|
|
|
|
g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
|
|
|
|
-#ifdef ENABLE_USER_DISPLAY_SERVER
|
|
+#if defined ENABLE_USER_DISPLAY_SERVER && defined WITH_SYSTEMD
|
|
if (g_strcmp0 (seat_id, "seat0") == 0) {
|
|
display = gdm_local_display_new ();
|
|
if (session_type != NULL) {
|
|
@@ -400,6 +406,8 @@ create_display (GdmLocalDisplayFactory *factory,
|
|
return display;
|
|
}
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
+
|
|
static void
|
|
delete_display (GdmLocalDisplayFactory *factory,
|
|
const char *seat_id) {
|
|
@@ -536,6 +544,7 @@ gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory)
|
|
factory->priv->seat_removed_id = 0;
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
static void
|
|
on_display_added (GdmDisplayStore *display_store,
|
|
@@ -576,6 +585,7 @@ static gboolean
|
|
gdm_local_display_factory_start (GdmDisplayFactory *base_factory)
|
|
{
|
|
GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory);
|
|
+ GdmDisplay *display;
|
|
GdmDisplayStore *store;
|
|
|
|
g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
|
|
@@ -594,8 +604,17 @@ gdm_local_display_factory_start (GdmDisplayFactory *base_factory)
|
|
factory,
|
|
0);
|
|
|
|
- gdm_local_display_factory_start_monitor (factory);
|
|
- return gdm_local_display_factory_sync_seats (factory);
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ gdm_local_display_factory_start_monitor (factory);
|
|
+ return gdm_local_display_factory_sync_seats (factory);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ /* On ConsoleKit just create Seat1, and that's it. */
|
|
+ display = create_display (factory, CK_SEAT1_PATH, NULL, TRUE);
|
|
+
|
|
+ return display != NULL;
|
|
}
|
|
|
|
static gboolean
|
|
@@ -606,7 +625,9 @@ gdm_local_display_factory_stop (GdmDisplayFactory *base_factory)
|
|
|
|
g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
gdm_local_display_factory_stop_monitor (factory);
|
|
+#endif
|
|
|
|
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
|
|
|
|
@@ -762,7 +783,9 @@ gdm_local_display_factory_finalize (GObject *object)
|
|
|
|
g_hash_table_destroy (factory->priv->used_display_numbers);
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
gdm_local_display_factory_stop_monitor (factory);
|
|
+#endif
|
|
|
|
G_OBJECT_CLASS (gdm_local_display_factory_parent_class)->finalize (object);
|
|
}
|
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
index d080b308..f5439855 100644
|
|
--- a/daemon/gdm-manager.c
|
|
+++ b/daemon/gdm-manager.c
|
|
@@ -36,7 +36,9 @@
|
|
|
|
#include <act/act-user-manager.h>
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
#include <systemd/sd-login.h>
|
|
+#endif
|
|
|
|
#include "gdm-common.h"
|
|
|
|
@@ -61,7 +63,16 @@
|
|
#define GDM_MANAGER_PATH GDM_DBUS_PATH "/Manager"
|
|
#define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays"
|
|
|
|
-#define INITIAL_SETUP_USERNAME "gnome-initial-setup"
|
|
+#define INITIAL_SETUP_USERNAME "_gnome-initial-setup"
|
|
+
|
|
+#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"
|
|
|
|
typedef struct
|
|
{
|
|
@@ -206,9 +217,10 @@ plymouth_quit_without_transition (void)
|
|
}
|
|
#endif
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
static char *
|
|
-get_session_id_for_pid (pid_t pid,
|
|
- GError **error)
|
|
+get_session_id_for_pid_systemd (pid_t pid,
|
|
+ GError **error)
|
|
{
|
|
char *session, *gsession;
|
|
int ret;
|
|
@@ -233,11 +245,61 @@ get_session_id_for_pid (pid_t pid,
|
|
return NULL;
|
|
}
|
|
}
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+static char *
|
|
+get_session_id_for_pid_consolekit (GDBusConnection *connection,
|
|
+ pid_t pid,
|
|
+ GError **error)
|
|
+{
|
|
+ GVariant *reply;
|
|
+ char *retval;
|
|
+
|
|
+ reply = g_dbus_connection_call_sync (connection,
|
|
+ "org.freedesktop.ConsoleKit",
|
|
+ "/org/freedesktop/ConsoleKit/Manager",
|
|
+ "org.freedesktop.ConsoleKit.Manager",
|
|
+ "GetSessionForUnixProcess",
|
|
+ g_variant_new ("(u)", pid),
|
|
+ G_VARIANT_TYPE ("(o)"),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL, error);
|
|
+ if (reply == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ g_variant_get (reply, "(o)", &retval);
|
|
+ g_variant_unref (reply);
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+#endif
|
|
+
|
|
+static char *
|
|
+get_session_id_for_pid (GDBusConnection *connection,
|
|
+ pid_t pid,
|
|
+ GError **error)
|
|
+{
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ return get_session_id_for_pid_systemd (pid, error);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+ return get_session_id_for_pid_consolekit (connection, pid, error);
|
|
+#endif
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
static gboolean
|
|
-get_uid_for_session_id (const char *session_id,
|
|
- uid_t *uid,
|
|
- GError **error)
|
|
+get_uid_for_systemd_session_id (const char *session_id,
|
|
+ uid_t *uid,
|
|
+ GError **error)
|
|
{
|
|
int ret;
|
|
|
|
@@ -254,6 +316,60 @@ get_uid_for_session_id (const char *session_id,
|
|
|
|
return TRUE;
|
|
}
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+static gboolean
|
|
+get_uid_for_consolekit_session_id (GDBusConnection *connection,
|
|
+ const char *session_id,
|
|
+ uid_t *out_uid,
|
|
+ GError **error)
|
|
+{
|
|
+ GVariant *reply;
|
|
+ guint32 uid;
|
|
+
|
|
+ reply = g_dbus_connection_call_sync (connection,
|
|
+ "org.freedesktop.ConsoleKit",
|
|
+ session_id,
|
|
+ "org.freedesktop.ConsoleKit.Session",
|
|
+ "GetUnixUser",
|
|
+ NULL,
|
|
+ G_VARIANT_TYPE ("(u)"),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ error);
|
|
+ if (reply == NULL) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ g_variant_get (reply, "(u)", &uid);
|
|
+ g_variant_unref (reply);
|
|
+
|
|
+ *out_uid = (uid_t) uid;
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+#endif
|
|
+
|
|
+static gboolean
|
|
+get_uid_for_session_id (GDBusConnection *connection,
|
|
+ const char *session_id,
|
|
+ uid_t *uid,
|
|
+ GError **error)
|
|
+{
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ return get_uid_for_systemd_session_id (session_id, uid, error);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+ return get_uid_for_consolekit_session_id (connection, session_id, uid, error);
|
|
+#endif
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
|
|
static gboolean
|
|
lookup_by_session_id (const char *id,
|
|
@@ -267,10 +383,50 @@ lookup_by_session_id (const char *id,
|
|
return g_strcmp0 (current, looking_for) == 0;
|
|
}
|
|
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
static gboolean
|
|
-is_login_session (GdmManager *self,
|
|
- const char *session_id,
|
|
- GError **error)
|
|
+is_consolekit_login_session (GdmManager *self,
|
|
+ GDBusConnection *connection,
|
|
+ const char *session_id,
|
|
+ GError **error)
|
|
+{
|
|
+ GVariant *reply;
|
|
+ char *session_type = NULL;
|
|
+
|
|
+ reply = g_dbus_connection_call_sync (connection,
|
|
+ "org.freedesktop.ConsoleKit",
|
|
+ session_id,
|
|
+ "org.freedesktop.ConsoleKit.Session",
|
|
+ "GetSessionType",
|
|
+ NULL,
|
|
+ G_VARIANT_TYPE ("(s)"),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ error);
|
|
+ if (reply == NULL) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ g_variant_get (reply, "(s)", &session_type);
|
|
+ g_variant_unref (reply);
|
|
+
|
|
+ if (g_strcmp0 (session_type, "LoginWindow") != 0) {
|
|
+ g_free (session_type);
|
|
+
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ g_free (session_type);
|
|
+ return TRUE;
|
|
+}
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_SYSTEMD
|
|
+static gboolean
|
|
+is_systemd_login_session (GdmManager *self,
|
|
+ const char *session_id,
|
|
+ GError **error)
|
|
{
|
|
char *session_class = NULL;
|
|
int ret;
|
|
@@ -295,11 +451,32 @@ is_login_session (GdmManager *self,
|
|
g_free (session_class);
|
|
return TRUE;
|
|
}
|
|
+#endif
|
|
|
|
static gboolean
|
|
-activate_session_id (GdmManager *manager,
|
|
- const char *seat_id,
|
|
- const char *session_id)
|
|
+is_login_session (GdmManager *self,
|
|
+ GDBusConnection *connection,
|
|
+ const char *session_id,
|
|
+ GError **error)
|
|
+{
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ return is_systemd_login_session (self, session_id, error);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+ return is_consolekit_login_session (self, connection, session_id, error);
|
|
+#endif
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+#ifdef WITH_SYSTEMD
|
|
+static gboolean
|
|
+activate_session_id_for_systemd (GdmManager *manager,
|
|
+ const char *seat_id,
|
|
+ const char *session_id)
|
|
{
|
|
GError *error = NULL;
|
|
GVariant *reply;
|
|
@@ -326,15 +503,74 @@ activate_session_id (GdmManager *manager,
|
|
|
|
return TRUE;
|
|
}
|
|
+#endif
|
|
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
static gboolean
|
|
-session_unlock (GdmManager *manager,
|
|
- const char *ssid)
|
|
+activate_session_id_for_ck (GdmManager *manager,
|
|
+ const char *seat_id,
|
|
+ const char *session_id)
|
|
{
|
|
GError *error = NULL;
|
|
GVariant *reply;
|
|
|
|
- g_debug ("Unlocking session %s", ssid);
|
|
+ reply = g_dbus_connection_call_sync (manager->priv->connection,
|
|
+ CK_NAME,
|
|
+ seat_id,
|
|
+ "org.freedesktop.ConsoleKit.Seat",
|
|
+ "ActivateSession",
|
|
+ g_variant_new ("(o)", session_id),
|
|
+ NULL, /* expected reply */
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ &error);
|
|
+ if (reply == NULL) {
|
|
+ g_debug ("GdmManager: ConsoleKit %s raised:\n %s\n\n",
|
|
+ g_dbus_error_get_remote_error (error), error->message);
|
|
+ g_error_free (error);
|
|
+
|
|
+ /* It is very likely that the "error" just reported is
|
|
+ * that the session is already active. Unfortunately,
|
|
+ * ConsoleKit doesn't use proper error codes and it
|
|
+ * translates the error message, so we have no real way
|
|
+ * to detect this case...
|
|
+ */
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ g_variant_unref (reply);
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+#endif
|
|
+
|
|
+static gboolean
|
|
+activate_session_id (GdmManager *manager,
|
|
+ const char *seat_id,
|
|
+ const char *session_id)
|
|
+{
|
|
+
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ return activate_session_id_for_systemd (manager, seat_id, session_id);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+ return activate_session_id_for_ck (manager, seat_id, session_id);
|
|
+#else
|
|
+ return FALSE;
|
|
+#endif
|
|
+}
|
|
+
|
|
+#ifdef WITH_SYSTEMD
|
|
+static gboolean
|
|
+session_unlock_for_systemd (GdmManager *manager,
|
|
+ const char *ssid)
|
|
+{
|
|
+ GError *error = NULL;
|
|
+ GVariant *reply;
|
|
|
|
reply = g_dbus_connection_call_sync (manager->priv->connection,
|
|
"org.freedesktop.login1",
|
|
@@ -358,6 +594,59 @@ session_unlock (GdmManager *manager,
|
|
|
|
return TRUE;
|
|
}
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+static gboolean
|
|
+session_unlock_for_ck (GdmManager *manager,
|
|
+ const char *ssid)
|
|
+{
|
|
+ GError *error = NULL;
|
|
+ GVariant *reply;
|
|
+
|
|
+ reply = g_dbus_connection_call_sync (manager->priv->connection,
|
|
+ CK_NAME,
|
|
+ ssid,
|
|
+ CK_SESSION_INTERFACE,
|
|
+ "Unlock",
|
|
+ NULL, /* parameters */
|
|
+ NULL, /* expected reply */
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ &error);
|
|
+ if (reply == NULL) {
|
|
+ g_debug ("GdmManager: ConsoleKit %s raised:\n %s\n\n",
|
|
+ g_dbus_error_get_remote_error (error), error->message);
|
|
+ g_error_free (error);
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ g_variant_unref (reply);
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+#endif
|
|
+
|
|
+static gboolean
|
|
+session_unlock (GdmManager *manager,
|
|
+ const char *ssid)
|
|
+{
|
|
+
|
|
+ g_debug ("Unlocking session %s", ssid);
|
|
+
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ return session_unlock_for_systemd (manager, ssid);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+ return session_unlock_for_ck (manager, ssid);
|
|
+#else
|
|
+ return TRUE;
|
|
+#endif
|
|
+}
|
|
|
|
static GdmSession *
|
|
find_session_for_user_on_seat (GdmManager *manager,
|
|
@@ -389,10 +678,43 @@ find_session_for_user_on_seat (GdmManager *manager,
|
|
return NULL;
|
|
}
|
|
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+static gboolean
|
|
+is_consolekit_remote_session (GdmManager *self,
|
|
+ GDBusConnection *connection,
|
|
+ const char *session_id,
|
|
+ GError **error)
|
|
+{
|
|
+ GVariant *reply;
|
|
+ gboolean is_remote;
|
|
+
|
|
+ reply = g_dbus_connection_call_sync (connection,
|
|
+ "org.freedesktop.ConsoleKit",
|
|
+ session_id,
|
|
+ "org.freedesktop.ConsoleKit.Session",
|
|
+ "IsLocal",
|
|
+ NULL,
|
|
+ G_VARIANT_TYPE ("(b)"),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ error);
|
|
+ if (reply == NULL) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ g_variant_get (reply, "(b)", &is_remote);
|
|
+ g_variant_unref (reply);
|
|
+
|
|
+ return is_remote;
|
|
+}
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_SYSTEMD
|
|
static gboolean
|
|
-is_remote_session (GdmManager *self,
|
|
- const char *session_id,
|
|
- GError **error)
|
|
+is_systemd_remote_session (GdmManager *self,
|
|
+ const char *session_id,
|
|
+ GError **error)
|
|
{
|
|
char *seat;
|
|
int ret;
|
|
@@ -418,10 +740,31 @@ is_remote_session (GdmManager *self,
|
|
|
|
return is_remote;
|
|
}
|
|
+#endif
|
|
+
|
|
+static gboolean
|
|
+is_remote_session (GdmManager *self,
|
|
+ GDBusConnection *connection,
|
|
+ const char *session_id,
|
|
+ GError **error)
|
|
+{
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ return is_systemd_remote_session (self, session_id, error);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+ return is_consolekit_remote_session (self, connection, session_id, error);
|
|
+#endif
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
static char *
|
|
-get_seat_id_for_session_id (const char *session_id,
|
|
- GError **error)
|
|
+get_seat_id_for_systemd_session_id (const char *session_id,
|
|
+ GError **error)
|
|
{
|
|
int ret;
|
|
char *seat, *out_seat;
|
|
@@ -446,10 +789,61 @@ get_seat_id_for_session_id (const char *session_id,
|
|
|
|
return out_seat;
|
|
}
|
|
+#endif
|
|
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
static char *
|
|
-get_tty_for_session_id (const char *session_id,
|
|
- GError **error)
|
|
+get_seat_id_for_consolekit_session_id (GDBusConnection *connection,
|
|
+ const char *session_id,
|
|
+ GError **error)
|
|
+{
|
|
+ GVariant *reply;
|
|
+ char *retval;
|
|
+
|
|
+ reply = g_dbus_connection_call_sync (connection,
|
|
+ "org.freedesktop.ConsoleKit",
|
|
+ session_id,
|
|
+ "org.freedesktop.ConsoleKit.Session",
|
|
+ "GetSeatId",
|
|
+ NULL,
|
|
+ G_VARIANT_TYPE ("(o)"),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ error);
|
|
+ if (reply == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ g_variant_get (reply, "(o)", &retval);
|
|
+ g_variant_unref (reply);
|
|
+
|
|
+ return retval;
|
|
+}
|
|
+#endif
|
|
+
|
|
+static char *
|
|
+get_seat_id_for_session_id (GDBusConnection *connection,
|
|
+ const char *session_id,
|
|
+ GError **error)
|
|
+{
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ return get_seat_id_for_systemd_session_id (session_id, error);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+ return get_seat_id_for_consolekit_session_id (connection, session_id, error);
|
|
+#endif
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+#ifdef WITH_SYSTEMD
|
|
+static char *
|
|
+get_tty_for_systemd_session_id (const char *session_id,
|
|
+ GError **error)
|
|
{
|
|
int ret;
|
|
char *tty, *out_tty;
|
|
@@ -473,6 +867,20 @@ get_tty_for_session_id (const char *session_id,
|
|
|
|
return out_tty;
|
|
}
|
|
+#endif
|
|
+
|
|
+static char *
|
|
+get_tty_for_session_id (const char *session_id,
|
|
+ GError **error)
|
|
+{
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ return get_tty_for_systemd_session_id (session_id, error);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
|
|
static void
|
|
get_display_and_details_for_bus_sender (GdmManager *self,
|
|
@@ -516,7 +924,7 @@ get_display_and_details_for_bus_sender (GdmManager *self,
|
|
goto out;
|
|
}
|
|
|
|
- session_id = get_session_id_for_pid (pid, &error);
|
|
+ session_id = get_session_id_for_pid (connection, pid, &error);
|
|
|
|
if (session_id == NULL) {
|
|
g_debug ("GdmManager: Error while retrieving session id for sender: %s",
|
|
@@ -530,7 +938,7 @@ get_display_and_details_for_bus_sender (GdmManager *self,
|
|
}
|
|
|
|
if (out_is_login_screen != NULL) {
|
|
- *out_is_login_screen = is_login_session (self, session_id, &error);
|
|
+ *out_is_login_screen = is_login_session (self, connection, session_id, &error);
|
|
|
|
if (error != NULL) {
|
|
g_debug ("GdmManager: Error while checking if sender is login screen: %s",
|
|
@@ -540,7 +948,7 @@ get_display_and_details_for_bus_sender (GdmManager *self,
|
|
}
|
|
}
|
|
|
|
- if (!get_uid_for_session_id (session_id, &session_uid, &error)) {
|
|
+ if (!get_uid_for_session_id (connection, session_id, &session_uid, &error)) {
|
|
g_debug ("GdmManager: Error while retrieving uid for session: %s",
|
|
error->message);
|
|
g_error_free (error);
|
|
@@ -557,7 +965,7 @@ get_display_and_details_for_bus_sender (GdmManager *self,
|
|
}
|
|
|
|
if (out_seat_id != NULL) {
|
|
- *out_seat_id = get_seat_id_for_session_id (session_id, &error);
|
|
+ *out_seat_id = get_seat_id_for_session_id (connection, session_id, &error);
|
|
|
|
if (error != NULL) {
|
|
g_debug ("GdmManager: Error while retrieving seat id for session: %s",
|
|
@@ -567,7 +975,7 @@ get_display_and_details_for_bus_sender (GdmManager *self,
|
|
}
|
|
|
|
if (out_is_remote != NULL) {
|
|
- *out_is_remote = is_remote_session (self, session_id, &error);
|
|
+ *out_is_remote = is_remote_session (self, connection, session_id, &error);
|
|
|
|
if (error != NULL) {
|
|
g_debug ("GdmManager: Error while retrieving remoteness for session: %s",
|
|
@@ -956,7 +1364,8 @@ on_reauthentication_client_rejected (GdmSession *session,
|
|
* same audit session, ignore it since it doesn't "own" the
|
|
* reauthentication session
|
|
*/
|
|
- client_session_id = get_session_id_for_pid (pid_of_client,
|
|
+ client_session_id = get_session_id_for_pid (self->priv->connection,
|
|
+ pid_of_client,
|
|
NULL);
|
|
session_id = g_object_get_data (G_OBJECT (session), "caller-session-id");
|
|
|
|
@@ -1168,16 +1577,20 @@ static gboolean
|
|
display_is_on_seat0 (GdmDisplay *display)
|
|
{
|
|
gboolean is_on_seat0 = TRUE;
|
|
- char *seat_id = NULL;
|
|
|
|
- g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL);
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ char *seat_id = NULL;
|
|
|
|
- if (g_strcmp0 (seat_id, "seat0") != 0) {
|
|
- is_on_seat0 = FALSE;
|
|
- }
|
|
+ g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL);
|
|
|
|
- g_free (seat_id);
|
|
+ if (g_strcmp0 (seat_id, "seat0") != 0) {
|
|
+ is_on_seat0 = FALSE;
|
|
+ }
|
|
|
|
+ g_free (seat_id);
|
|
+ }
|
|
+#endif
|
|
return is_on_seat0;
|
|
}
|
|
|
|
@@ -1315,133 +1728,6 @@ maybe_start_pending_initial_login (GdmManager *manager,
|
|
g_free (user_session_seat_id);
|
|
}
|
|
|
|
-static gboolean
|
|
-get_login_window_session_id (const char *seat_id,
|
|
- char **session_id)
|
|
-{
|
|
- gboolean ret;
|
|
- int res, i;
|
|
- char **sessions;
|
|
- char *service_id;
|
|
- char *service_class;
|
|
- char *state;
|
|
-
|
|
- res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL);
|
|
- if (res < 0) {
|
|
- g_debug ("Failed to determine sessions: %s", strerror (-res));
|
|
- return FALSE;
|
|
- }
|
|
-
|
|
- if (sessions == NULL || sessions[0] == NULL) {
|
|
- *session_id = NULL;
|
|
- ret = TRUE;
|
|
- goto out;
|
|
- }
|
|
-
|
|
- for (i = 0; sessions[i]; i ++) {
|
|
-
|
|
- res = sd_session_get_class (sessions[i], &service_class);
|
|
- if (res < 0) {
|
|
- g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res));
|
|
- ret = FALSE;
|
|
- goto out;
|
|
- }
|
|
-
|
|
- if (strcmp (service_class, "greeter") != 0) {
|
|
- free (service_class);
|
|
- continue;
|
|
- }
|
|
-
|
|
- free (service_class);
|
|
-
|
|
- ret = sd_session_get_state (sessions[i], &state);
|
|
- if (ret < 0) {
|
|
- g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res));
|
|
- ret = FALSE;
|
|
- goto out;
|
|
- }
|
|
-
|
|
- if (g_strcmp0 (state, "closing") == 0) {
|
|
- free (state);
|
|
- continue;
|
|
- }
|
|
- free (state);
|
|
-
|
|
- res = sd_session_get_service (sessions[i], &service_id);
|
|
- if (res < 0) {
|
|
- g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res));
|
|
- ret = FALSE;
|
|
- goto out;
|
|
- }
|
|
-
|
|
- if (strcmp (service_id, "gdm-launch-environment") == 0) {
|
|
- *session_id = g_strdup (sessions[i]);
|
|
- ret = TRUE;
|
|
-
|
|
- free (service_id);
|
|
- goto out;
|
|
- }
|
|
-
|
|
- free (service_id);
|
|
- }
|
|
-
|
|
- *session_id = NULL;
|
|
- ret = TRUE;
|
|
-
|
|
-out:
|
|
- if (sessions) {
|
|
- for (i = 0; sessions[i]; i ++) {
|
|
- free (sessions[i]);
|
|
- }
|
|
-
|
|
- free (sessions);
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static void
|
|
-activate_login_window_session_on_seat (GdmManager *self,
|
|
- const char *seat_id)
|
|
-{
|
|
- char *session_id;
|
|
-
|
|
- if (!get_login_window_session_id (seat_id, &session_id)) {
|
|
- return;
|
|
- }
|
|
-
|
|
- activate_session_id (self, seat_id, session_id);
|
|
-}
|
|
-
|
|
-static void
|
|
-maybe_activate_other_session (GdmManager *self,
|
|
- GdmDisplay *old_display)
|
|
-{
|
|
- char *seat_id = NULL;
|
|
- char *session_id;
|
|
- int ret;
|
|
-
|
|
- g_object_get (G_OBJECT (old_display),
|
|
- "seat-id", &seat_id,
|
|
- NULL);
|
|
-
|
|
- ret = sd_seat_get_active (seat_id, &session_id, NULL);
|
|
-
|
|
- if (ret == 0) {
|
|
- GdmDisplay *display;
|
|
-
|
|
- display = gdm_display_store_find (self->priv->display_store,
|
|
- lookup_by_session_id,
|
|
- (gpointer) session_id);
|
|
-
|
|
- if (display == NULL) {
|
|
- activate_login_window_session_on_seat (self, seat_id);
|
|
- }
|
|
- }
|
|
-
|
|
- g_free (seat_id);
|
|
-}
|
|
-
|
|
static const char *
|
|
get_username_for_greeter_display (GdmManager *manager,
|
|
GdmDisplay *display)
|
|
@@ -1684,7 +1970,6 @@ on_display_status_changed (GdmDisplay *display,
|
|
manager->priv->ran_once = TRUE;
|
|
}
|
|
maybe_start_pending_initial_login (manager, display);
|
|
- maybe_activate_other_session (manager, display);
|
|
break;
|
|
default:
|
|
break;
|
|
@@ -2014,11 +2299,57 @@ on_user_session_died (GdmSession *session,
|
|
}
|
|
|
|
static char *
|
|
+query_ck_for_display_device (GdmManager *manager,
|
|
+ GdmDisplay *display)
|
|
+{
|
|
+ char *out;
|
|
+ char *command;
|
|
+ char *display_name = NULL;
|
|
+ int status;
|
|
+ gboolean res;
|
|
+ GError *error;
|
|
+
|
|
+ g_object_get (G_OBJECT (display),
|
|
+ "x11-display-name", &display_name,
|
|
+ NULL);
|
|
+
|
|
+ error = NULL;
|
|
+ command = g_strdup_printf (CONSOLEKIT_DIR "/ck-get-x11-display-device --display %s",
|
|
+ display_name);
|
|
+ g_free (display_name);
|
|
+
|
|
+ g_debug ("GdmManager: Running helper %s", command);
|
|
+ out = NULL;
|
|
+ res = g_spawn_command_line_sync (command,
|
|
+ &out,
|
|
+ NULL,
|
|
+ &status,
|
|
+ &error);
|
|
+ if (! res) {
|
|
+ g_warning ("GdmManager: Could not run helper %s: %s", command, error->message);
|
|
+ g_error_free (error);
|
|
+ } else {
|
|
+ out = g_strstrip (out);
|
|
+ g_debug ("GdmManager: Got tty: '%s'", out);
|
|
+ }
|
|
+
|
|
+ g_free (command);
|
|
+
|
|
+ return out;
|
|
+}
|
|
+
|
|
+static char *
|
|
get_display_device (GdmManager *manager,
|
|
GdmDisplay *display)
|
|
{
|
|
- /* systemd finds the display device out on its own based on the display */
|
|
- return NULL;
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ /* systemd finds the display device out on its own based on the display */
|
|
+ return NULL;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ return query_ck_for_display_device (manager, display);
|
|
}
|
|
|
|
static void
|
|
@@ -2027,26 +2358,6 @@ on_session_reauthenticated (GdmSession *session,
|
|
GdmManager *manager)
|
|
{
|
|
gboolean fail_if_already_switched = FALSE;
|
|
-
|
|
- if (gdm_session_get_display_mode (session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) {
|
|
- const char *seat_id;
|
|
- char *session_id;
|
|
-
|
|
- seat_id = gdm_session_get_display_seat_id (session);
|
|
- if (get_login_window_session_id (seat_id, &session_id)) {
|
|
- GdmDisplay *display = gdm_display_store_find (manager->priv->display_store,
|
|
- lookup_by_session_id,
|
|
- (gpointer) session_id);
|
|
-
|
|
- if (display != NULL) {
|
|
- gdm_display_stop_greeter_session (display);
|
|
- gdm_display_unmanage (display);
|
|
- gdm_display_finish (display);
|
|
- }
|
|
- }
|
|
- g_free (session_id);
|
|
- }
|
|
-
|
|
/* There should already be a session running, so jump to its
|
|
* VT. In the event we're already on the right VT, (i.e. user
|
|
* used an unlock screen instead of a user switched login screen),
|
|
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
|
|
index 6357d344..6ecd0f70 100644
|
|
--- a/daemon/gdm-server.c
|
|
+++ b/daemon/gdm-server.c
|
|
@@ -43,7 +43,9 @@
|
|
#include <linux/vt.h>
|
|
#endif
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
#include <systemd/sd-daemon.h>
|
|
+#endif
|
|
|
|
#ifdef ENABLE_SYSTEMD_JOURNAL
|
|
#include <systemd/sd-journal.h>
|
|
@@ -122,11 +124,59 @@ static void gdm_server_finalize (GObject *object);
|
|
|
|
G_DEFINE_TYPE (GdmServer, gdm_server, G_TYPE_OBJECT)
|
|
|
|
+static char *
|
|
+_gdm_server_query_ck_for_display_device (GdmServer *server)
|
|
+{
|
|
+ char *out;
|
|
+ char *command;
|
|
+ int status;
|
|
+ gboolean res;
|
|
+ GError *error;
|
|
+
|
|
+ g_return_val_if_fail (GDM_IS_SERVER (server), NULL);
|
|
+
|
|
+ error = NULL;
|
|
+ command = g_strdup_printf (CONSOLEKIT_DIR "/ck-get-x11-display-device --display %s",
|
|
+ server->priv->display_name);
|
|
+
|
|
+ g_debug ("GdmServer: Running helper %s", command);
|
|
+ out = NULL;
|
|
+ res = g_spawn_command_line_sync (command,
|
|
+ &out,
|
|
+ NULL,
|
|
+ &status,
|
|
+ &error);
|
|
+ if (! res) {
|
|
+ g_warning ("Could not run helper: %s", error->message);
|
|
+ g_error_free (error);
|
|
+ } else {
|
|
+ out = g_strstrip (out);
|
|
+ g_debug ("GdmServer: Got tty: '%s'", out);
|
|
+ }
|
|
+
|
|
+ g_free (command);
|
|
+
|
|
+ return out;
|
|
+}
|
|
+
|
|
char *
|
|
gdm_server_get_display_device (GdmServer *server)
|
|
{
|
|
- /* systemd finds the display device out on its own based on the display */
|
|
- return NULL;
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ /* systemd finds the display device out on its own based on the display */
|
|
+ return NULL;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if (server->priv->display_device == NULL) {
|
|
+ server->priv->display_device =
|
|
+ _gdm_server_query_ck_for_display_device (server);
|
|
+
|
|
+ g_object_notify (G_OBJECT (server), "display-device");
|
|
+ }
|
|
+
|
|
+ return g_strdup (server->priv->display_device);
|
|
}
|
|
|
|
static void
|
|
@@ -226,7 +276,9 @@ gdm_server_init_command (GdmServer *server)
|
|
debug_options = "";
|
|
}
|
|
|
|
-#define X_SERVER_ARG_FORMAT " -background none -noreset -verbose %s%s"
|
|
+ #define X_SERVER_ARG_FORMAT " -background none -noreset -verbose %s%s"
|
|
+
|
|
+#ifdef WITH_SYSTEMD
|
|
|
|
/* This is a temporary hack to work around the fact that XOrg
|
|
* currently lacks support for multi-seat hotplugging for
|
|
@@ -242,6 +294,10 @@ gdm_server_init_command (GdmServer *server)
|
|
* wasn't booted using systemd, or b) the wrapper tool is
|
|
* missing, or c) we are running for the main seat 'seat0'. */
|
|
|
|
+ if (!LOGIND_RUNNING()) {
|
|
+ goto fallback;
|
|
+ }
|
|
+
|
|
#ifdef ENABLE_SYSTEMD_JOURNAL
|
|
/* For systemd, we don't have a log file but instead log to stdout,
|
|
so set it to the xserver's built-in default verbosity */
|
|
@@ -264,8 +320,9 @@ gdm_server_init_command (GdmServer *server)
|
|
return;
|
|
|
|
fallback:
|
|
- server->priv->command = g_strdup_printf (X_SERVER X_SERVER_ARG_FORMAT, verbosity, debug_options);
|
|
+#endif
|
|
|
|
+ server->priv->command = g_strdup_printf (X_SERVER X_SERVER_ARG_FORMAT, verbosity, debug_options);
|
|
}
|
|
|
|
static gboolean
|
|
@@ -315,10 +372,12 @@ gdm_server_resolve_command_line (GdmServer *server,
|
|
argv[len++] = g_strdup (server->priv->auth_file);
|
|
}
|
|
|
|
- if (server->priv->display_seat_id != NULL) {
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING() && server->priv->display_seat_id != NULL) {
|
|
argv[len++] = g_strdup ("-seat");
|
|
argv[len++] = g_strdup (server->priv->display_seat_id);
|
|
}
|
|
+#endif
|
|
|
|
/* If we were compiled with Xserver >= 1.17 we need to specify
|
|
* '-listen tcp' as the X server dosen't listen on tcp sockets
|
|
diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
|
|
index 69dca2e5..c117f709 100644
|
|
--- a/daemon/gdm-session-worker-job.c
|
|
+++ b/daemon/gdm-session-worker-job.c
|
|
@@ -36,7 +36,9 @@
|
|
#include <sys/prctl.h>
|
|
#endif
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
#include <systemd/sd-daemon.h>
|
|
+#endif
|
|
|
|
#ifdef ENABLE_SYSTEMD_JOURNAL
|
|
#include <systemd/sd-journal.h>
|
|
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
|
|
index d97b02b5..a6354163 100644
|
|
--- a/daemon/gdm-session-worker.c
|
|
+++ b/daemon/gdm-session-worker.c
|
|
@@ -28,9 +28,11 @@
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
+#ifdef WITH_SYSTEMD
|
|
#include <sys/ioctl.h>
|
|
#include <sys/vt.h>
|
|
#include <sys/kd.h>
|
|
+#endif
|
|
#include <errno.h>
|
|
#include <grp.h>
|
|
#include <pwd.h>
|
|
@@ -49,7 +51,9 @@
|
|
|
|
#include <X11/Xauth.h>
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
#include <systemd/sd-daemon.h>
|
|
+#endif
|
|
|
|
#ifdef ENABLE_SYSTEMD_JOURNAL
|
|
#include <systemd/sd-journal.h>
|
|
@@ -131,6 +135,10 @@ struct GdmSessionWorkerPrivate
|
|
|
|
int exit_code;
|
|
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+ char *session_cookie;
|
|
+#endif
|
|
+
|
|
pam_handle_t *pam_handle;
|
|
|
|
GPid child_pid;
|
|
@@ -145,6 +153,7 @@ struct GdmSessionWorkerPrivate
|
|
char *hostname;
|
|
char *username;
|
|
char *log_file;
|
|
+ char *session_type;
|
|
char *session_id;
|
|
uid_t uid;
|
|
gid_t gid;
|
|
@@ -207,6 +216,204 @@ G_DEFINE_TYPE_WITH_CODE (GdmSessionWorker,
|
|
G_IMPLEMENT_INTERFACE (GDM_DBUS_TYPE_WORKER,
|
|
worker_interface_init))
|
|
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+static gboolean
|
|
+open_ck_session (GdmSessionWorker *worker)
|
|
+{
|
|
+ GDBusConnection *system_bus;
|
|
+ GVariantBuilder builder;
|
|
+ GVariant *parameters;
|
|
+ GVariant *in_args;
|
|
+ struct passwd *pwent;
|
|
+ GVariant *reply;
|
|
+ GError *error = NULL;
|
|
+ const char *display_name;
|
|
+ const char *display_device;
|
|
+ const char *display_hostname;
|
|
+ const char *session_type;
|
|
+ gint32 uid;
|
|
+
|
|
+ g_assert (worker->priv->session_cookie == NULL);
|
|
+
|
|
+ if (worker->priv->x11_display_name != NULL) {
|
|
+ display_name = worker->priv->x11_display_name;
|
|
+ } else {
|
|
+ display_name = "";
|
|
+ }
|
|
+ if (worker->priv->hostname != NULL) {
|
|
+ display_hostname = worker->priv->hostname;
|
|
+ } else {
|
|
+ display_hostname = "";
|
|
+ }
|
|
+ if (worker->priv->display_device != NULL) {
|
|
+ display_device = worker->priv->display_device;
|
|
+ } else {
|
|
+ display_device = "";
|
|
+ }
|
|
+
|
|
+ if (worker->priv->session_type != NULL) {
|
|
+ session_type = worker->priv->session_type;
|
|
+ } else {
|
|
+ session_type = "";
|
|
+ }
|
|
+
|
|
+ g_assert (worker->priv->username != NULL);
|
|
+
|
|
+ gdm_get_pwent_for_name (worker->priv->username, &pwent);
|
|
+ if (pwent == NULL) {
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ uid = (gint32) pwent->pw_uid;
|
|
+
|
|
+ error = NULL;
|
|
+ system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
|
|
+
|
|
+ if (system_bus == NULL) {
|
|
+ g_warning ("Couldn't create connection to system bus: %s",
|
|
+ error->message);
|
|
+
|
|
+ g_error_free (error);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sv)"));
|
|
+ g_variant_builder_add_parsed (&builder, "('unix-user', <%i>)", uid);
|
|
+ g_variant_builder_add_parsed (&builder, "('x11-display-device', <%s>)", display_device);
|
|
+ g_variant_builder_add_parsed (&builder, "('x11-display', <%s>)", display_name);
|
|
+ g_variant_builder_add_parsed (&builder, "('remote-host-name', <%s>)", display_hostname);
|
|
+ g_variant_builder_add_parsed (&builder, "('is-local', <%b>)", worker->priv->display_is_local);
|
|
+ g_variant_builder_add_parsed (&builder, "('session-type', <%s>)", session_type);
|
|
+
|
|
+ parameters = g_variant_builder_end (&builder);
|
|
+ in_args = g_variant_new_tuple (¶meters, 1);
|
|
+
|
|
+ reply = g_dbus_connection_call_sync (system_bus,
|
|
+ "org.freedesktop.ConsoleKit",
|
|
+ "/org/freedesktop/ConsoleKit/Manager",
|
|
+ "org.freedesktop.ConsoleKit.Manager",
|
|
+ "OpenSessionWithParameters",
|
|
+ in_args,
|
|
+ G_VARIANT_TYPE ("(s)"),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ &error);
|
|
+
|
|
+ if (! reply) {
|
|
+ g_warning ("%s\n", error->message);
|
|
+ g_clear_error (&error);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ g_variant_get (reply, "(s)", &worker->priv->session_cookie);
|
|
+
|
|
+ g_variant_unref (reply);
|
|
+
|
|
+out:
|
|
+ return worker->priv->session_cookie != NULL;
|
|
+}
|
|
+
|
|
+static void
|
|
+close_ck_session (GdmSessionWorker *worker)
|
|
+{
|
|
+ GDBusConnection *system_bus;
|
|
+ GVariant *reply;
|
|
+ GError *error = NULL;
|
|
+ gboolean was_closed;
|
|
+
|
|
+ if (worker->priv->session_cookie == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ error = NULL;
|
|
+ system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
|
|
+
|
|
+ if (system_bus == NULL) {
|
|
+ g_warning ("Couldn't create connection to system bus: %s",
|
|
+ error->message);
|
|
+
|
|
+ g_error_free (error);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ reply = g_dbus_connection_call_sync (system_bus,
|
|
+ "org.freedesktop.ConsoleKit",
|
|
+ "/org/freedesktop/ConsoleKit/Manager",
|
|
+ "org.freedesktop.ConsoleKit.Manager",
|
|
+ "CloseSession",
|
|
+ g_variant_new ("(s)", worker->priv->session_cookie),
|
|
+ G_VARIANT_TYPE ("(b)"),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ &error);
|
|
+
|
|
+ if (! reply) {
|
|
+ g_warning ("%s", error->message);
|
|
+ g_clear_error (&error);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ g_variant_get (reply, "(b)", &was_closed);
|
|
+
|
|
+ if (!was_closed) {
|
|
+ g_warning ("Unable to close ConsoleKit session");
|
|
+ }
|
|
+
|
|
+ g_variant_unref (reply);
|
|
+
|
|
+out:
|
|
+ g_clear_pointer (&worker->priv->session_cookie,
|
|
+ (GDestroyNotify) g_free);
|
|
+}
|
|
+
|
|
+static char *
|
|
+get_ck_session_id (GdmSessionWorker *worker)
|
|
+{
|
|
+ GDBusConnection *system_bus;
|
|
+ GVariant *reply;
|
|
+ GError *error = NULL;
|
|
+ char *session_id = NULL;
|
|
+
|
|
+ error = NULL;
|
|
+ system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
|
|
+
|
|
+ if (system_bus == NULL) {
|
|
+ g_warning ("Couldn't create connection to system bus: %s",
|
|
+ error->message);
|
|
+
|
|
+ g_error_free (error);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ reply = g_dbus_connection_call_sync (system_bus,
|
|
+ "org.freedesktop.ConsoleKit",
|
|
+ "/org/freedesktop/ConsoleKit/Manager",
|
|
+ "org.freedesktop.ConsoleKit.Manager",
|
|
+ "GetSessionForCookie",
|
|
+ g_variant_new ("(s)", worker->priv->session_cookie),
|
|
+ G_VARIANT_TYPE ("(o)"),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ &error);
|
|
+
|
|
+ if (reply == NULL) {
|
|
+ g_warning ("%s", error->message);
|
|
+ g_clear_error (&error);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ g_variant_get (reply, "(o)", &session_id);
|
|
+
|
|
+ g_variant_unref (reply);
|
|
+
|
|
+out:
|
|
+ return session_id;
|
|
+}
|
|
+#endif
|
|
+
|
|
/* adapted from glib script_execute */
|
|
static void
|
|
script_execute (const gchar *file,
|
|
@@ -754,6 +961,7 @@ gdm_session_worker_stop_auditor (GdmSessionWorker *worker)
|
|
worker->priv->auditor = NULL;
|
|
}
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
static void
|
|
on_release_display (int signal)
|
|
{
|
|
@@ -879,6 +1087,7 @@ jump_to_vt (GdmSessionWorker *worker,
|
|
|
|
close (active_vt_tty_fd);
|
|
}
|
|
+#endif
|
|
|
|
static void
|
|
gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker,
|
|
@@ -909,9 +1118,11 @@ gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker,
|
|
|
|
gdm_session_worker_stop_auditor (worker);
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
if (worker->priv->login_vt != worker->priv->session_vt) {
|
|
jump_to_vt (worker, worker->priv->login_vt);
|
|
}
|
|
+#endif
|
|
|
|
worker->priv->login_vt = 0;
|
|
worker->priv->session_vt = 0;
|
|
@@ -963,32 +1174,6 @@ _get_xauth_for_pam (const char *x11_authority_file)
|
|
#endif
|
|
|
|
static gboolean
|
|
-ensure_login_vt (GdmSessionWorker *worker)
|
|
-{
|
|
- int fd;
|
|
- struct vt_stat vt_state = { 0 };
|
|
- gboolean got_login_vt = FALSE;
|
|
-
|
|
- fd = open ("/dev/tty0", O_RDWR | O_NOCTTY);
|
|
-
|
|
- if (fd < 0) {
|
|
- g_debug ("GdmSessionWorker: couldn't open VT master: %m");
|
|
- return FALSE;
|
|
- }
|
|
-
|
|
- if (ioctl (fd, VT_GETSTATE, &vt_state) < 0) {
|
|
- g_debug ("GdmSessionWorker: couldn't get current VT: %m");
|
|
- goto out;
|
|
- }
|
|
-
|
|
- worker->priv->login_vt = vt_state.v_active;
|
|
- got_login_vt = TRUE;
|
|
-out:
|
|
- close (fd);
|
|
- return got_login_vt;
|
|
-}
|
|
-
|
|
-static gboolean
|
|
gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
|
|
const char *service,
|
|
const char *username,
|
|
@@ -1002,7 +1187,6 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
|
|
{
|
|
struct pam_conv pam_conversation;
|
|
int error_code;
|
|
- char tty_string[256];
|
|
|
|
g_assert (worker->priv->pam_handle == NULL);
|
|
|
|
@@ -1063,10 +1247,12 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
|
|
}
|
|
}
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
/* set seat ID */
|
|
- if (seat_id != NULL && seat_id[0] != '\0') {
|
|
+ if (seat_id != NULL && seat_id[0] != '\0' && LOGIND_RUNNING()) {
|
|
gdm_session_worker_set_environment_variable (worker, "XDG_SEAT", seat_id);
|
|
}
|
|
+#endif
|
|
|
|
if (strcmp (service, "gdm-launch-environment") == 0) {
|
|
gdm_session_worker_set_environment_variable (worker, "XDG_SESSION_CLASS", "greeter");
|
|
@@ -1075,14 +1261,6 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
|
|
g_debug ("GdmSessionWorker: state SETUP_COMPLETE");
|
|
worker->priv->state = 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);
|
|
@@ -1629,6 +1807,26 @@ gdm_session_worker_get_environment (GdmSessionWorker *worker)
|
|
return (const char * const *) pam_getenvlist (worker->priv->pam_handle);
|
|
}
|
|
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+static void
|
|
+register_ck_session (GdmSessionWorker *worker)
|
|
+{
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ return;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ open_ck_session (worker);
|
|
+
|
|
+ if (worker->priv->session_cookie != NULL) {
|
|
+ gdm_session_worker_set_environment_variable (worker,
|
|
+ "XDG_SESSION_COOKIE",
|
|
+ worker->priv->session_cookie);
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
static gboolean
|
|
run_script (GdmSessionWorker *worker,
|
|
const char *dir)
|
|
@@ -1659,6 +1857,9 @@ session_worker_child_watch (GPid pid,
|
|
: WIFSIGNALED (status) ? WTERMSIG (status)
|
|
: -1);
|
|
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+ close_ck_session (worker);
|
|
+#endif
|
|
|
|
gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS);
|
|
|
|
@@ -1849,12 +2050,14 @@ gdm_session_worker_start_session (GdmSessionWorker *worker,
|
|
|
|
error_code = PAM_SUCCESS;
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
/* If we're in new vt mode, jump to the new vt now. There's no need to jump for
|
|
* the other two modes: in the logind case, the session will activate itself when
|
|
* ready, and in the reuse server case, we're already on the correct VT. */
|
|
if (worker->priv->display_mode == GDM_SESSION_DISPLAY_MODE_NEW_VT) {
|
|
jump_to_vt (worker, worker->priv->session_vt);
|
|
}
|
|
+#endif
|
|
|
|
if (!worker->priv->is_program_session && !run_script (worker, GDMCONFDIR "/PostLogin")) {
|
|
g_set_error (error,
|
|
@@ -1919,6 +2122,7 @@ gdm_session_worker_start_session (GdmSessionWorker *worker,
|
|
_exit (2);
|
|
}
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
/* Take control of the tty
|
|
*/
|
|
if (needs_controlling_terminal) {
|
|
@@ -1926,6 +2130,7 @@ gdm_session_worker_start_session (GdmSessionWorker *worker,
|
|
g_debug ("GdmSessionWorker: could not take control of tty: %m");
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
#ifdef HAVE_LOGINCAP
|
|
if (setusercontext (NULL, passwd_entry, passwd_entry->pw_uid, LOGIN_SETALL) < 0) {
|
|
@@ -2070,11 +2275,13 @@ gdm_session_worker_start_session (GdmSessionWorker *worker,
|
|
return TRUE;
|
|
}
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
static gboolean
|
|
set_up_for_new_vt (GdmSessionWorker *worker)
|
|
{
|
|
int fd;
|
|
char vt_string[256], tty_string[256];
|
|
+ struct vt_stat vt_state = { 0 };
|
|
int session_vt = 0;
|
|
|
|
fd = open ("/dev/tty0", O_RDWR | O_NOCTTY);
|
|
@@ -2084,6 +2291,11 @@ set_up_for_new_vt (GdmSessionWorker *worker)
|
|
return FALSE;
|
|
}
|
|
|
|
+ if (ioctl (fd, VT_GETSTATE, &vt_state) < 0) {
|
|
+ g_debug ("GdmSessionWorker: couldn't get current VT: %m");
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
if (worker->priv->display_is_initial) {
|
|
session_vt = atoi (GDM_INITIAL_VT);
|
|
} else {
|
|
@@ -2093,6 +2305,7 @@ set_up_for_new_vt (GdmSessionWorker *worker)
|
|
}
|
|
}
|
|
|
|
+ worker->priv->login_vt = vt_state.v_active;
|
|
worker->priv->session_vt = session_vt;
|
|
|
|
close (fd);
|
|
@@ -2155,6 +2368,7 @@ fail:
|
|
close (fd);
|
|
return FALSE;
|
|
}
|
|
+#endif
|
|
|
|
static gboolean
|
|
set_up_for_current_vt (GdmSessionWorker *worker,
|
|
@@ -2222,12 +2436,14 @@ set_up_for_current_vt (GdmSessionWorker *worker,
|
|
}
|
|
#endif
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
if (g_strcmp0 (worker->priv->display_seat_id, "seat0") == 0) {
|
|
g_debug ("GdmSessionWorker: setting XDG_VTNR to current vt");
|
|
set_xdg_vtnr_to_current_vt (worker);
|
|
} else {
|
|
g_debug ("GdmSessionWorker: not setting XDG_VTNR since not seat0");
|
|
}
|
|
+#endif
|
|
|
|
return TRUE;
|
|
out:
|
|
@@ -2251,6 +2467,7 @@ gdm_session_worker_open_session (GdmSessionWorker *worker,
|
|
return FALSE;
|
|
}
|
|
break;
|
|
+#ifdef WITH_SYSTEMD
|
|
case GDM_SESSION_DISPLAY_MODE_NEW_VT:
|
|
case GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED:
|
|
if (!set_up_for_new_vt (worker)) {
|
|
@@ -2261,6 +2478,7 @@ gdm_session_worker_open_session (GdmSessionWorker *worker,
|
|
return FALSE;
|
|
}
|
|
break;
|
|
+#endif
|
|
}
|
|
|
|
flags = 0;
|
|
@@ -2282,7 +2500,17 @@ gdm_session_worker_open_session (GdmSessionWorker *worker,
|
|
g_debug ("GdmSessionWorker: state SESSION_OPENED");
|
|
worker->priv->state = GDM_SESSION_WORKER_STATE_SESSION_OPENED;
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
session_id = gdm_session_worker_get_environment_variable (worker, "XDG_SESSION_ID");
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+ register_ck_session (worker);
|
|
+
|
|
+ if (session_id == NULL) {
|
|
+ session_id = get_ck_session_id (worker);
|
|
+ }
|
|
+#endif
|
|
|
|
if (session_id != NULL) {
|
|
g_free (worker->priv->session_id);
|
|
@@ -2388,6 +2616,19 @@ gdm_session_worker_handle_set_session_name (GdmDBusWorker *object,
|
|
}
|
|
|
|
static gboolean
|
|
+gdm_session_worker_handle_set_session_type (GdmDBusWorker *object,
|
|
+ GDBusMethodInvocation *invocation,
|
|
+ const char *session_type)
|
|
+{
|
|
+ GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
|
|
+ g_debug ("GdmSessionWorker: session type set to %s", session_type);
|
|
+ g_free (worker->priv->session_type);
|
|
+ worker->priv->session_type = g_strdup (session_type);
|
|
+ gdm_dbus_worker_complete_set_session_type (object, invocation);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
gdm_session_worker_handle_set_session_display_mode (GdmDBusWorker *object,
|
|
GDBusMethodInvocation *invocation,
|
|
const char *str)
|
|
@@ -3194,6 +3435,7 @@ worker_interface_init (GdmDBusWorkerIface *interface)
|
|
interface->handle_open = gdm_session_worker_handle_open;
|
|
interface->handle_set_language_name = gdm_session_worker_handle_set_language_name;
|
|
interface->handle_set_session_name = gdm_session_worker_handle_set_session_name;
|
|
+ interface->handle_set_session_type = gdm_session_worker_handle_set_session_type;
|
|
interface->handle_set_session_display_mode = gdm_session_worker_handle_set_session_display_mode;
|
|
interface->handle_set_environment_variable = gdm_session_worker_handle_set_environment_variable;
|
|
interface->handle_start_program = gdm_session_worker_handle_start_program;
|
|
diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml
|
|
index 9f6d8b35..853bc6a4 100644
|
|
--- a/daemon/gdm-session-worker.xml
|
|
+++ b/daemon/gdm-session-worker.xml
|
|
@@ -13,6 +13,9 @@
|
|
<method name="SetSessionName">
|
|
<arg name="session_name" direction="in" type="s" />
|
|
</method>
|
|
+ <method name="SetSessionType">
|
|
+ <arg name="session_type" direction="in" type="s"/>
|
|
+ </method>
|
|
<method name="SetSessionDisplayMode">
|
|
<arg name="mode" direction="in" type="s"/>
|
|
</method>
|
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
|
index ff3a1acb..5e26c5b5 100644
|
|
--- a/daemon/gdm-session.c
|
|
+++ b/daemon/gdm-session.c
|
|
@@ -3076,6 +3076,10 @@ gdm_session_bypasses_xsession (GdmSession *self)
|
|
g_return_val_if_fail (self != NULL, FALSE);
|
|
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
|
|
|
|
+ if (!LOGIND_RUNNING()) {
|
|
+ return GDM_SESSION_DISPLAY_MODE_REUSE_VT;
|
|
+ }
|
|
+
|
|
#ifdef ENABLE_WAYLAND_SUPPORT
|
|
if (gdm_session_is_wayland_session (self)) {
|
|
bypasses_xsession = TRUE;
|
|
@@ -3171,6 +3175,27 @@ gdm_session_select_program (GdmSession *self,
|
|
}
|
|
|
|
void
|
|
+gdm_session_select_session_type (GdmSession *self,
|
|
+ const char *text)
|
|
+{
|
|
+ GHashTableIter iter;
|
|
+ gpointer key, value;
|
|
+
|
|
+ g_debug ("GdmSession: selecting session type '%s'", text);
|
|
+
|
|
+ g_hash_table_iter_init (&iter, self->priv->conversations);
|
|
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = (GdmSessionConversation *) value;
|
|
+
|
|
+ gdm_dbus_worker_call_set_session_type (conversation->worker_proxy,
|
|
+ text,
|
|
+ NULL, NULL, NULL);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
gdm_session_select_session (GdmSession *self,
|
|
const char *text)
|
|
{
|
|
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
|
|
index a22c0954..44b16f64 100644
|
|
--- a/daemon/gdm-session.h
|
|
+++ b/daemon/gdm-session.h
|
|
@@ -180,6 +180,8 @@ void gdm_session_answer_query (GdmSession *session,
|
|
const char *text);
|
|
void gdm_session_select_program (GdmSession *session,
|
|
const char *command_line);
|
|
+void gdm_session_select_session_type (GdmSession *session,
|
|
+ const char *session_type);
|
|
void gdm_session_select_session (GdmSession *session,
|
|
const char *session_name);
|
|
void gdm_session_select_user (GdmSession *session,
|
|
diff --git a/libgdm/gdm-user-switching.c b/libgdm/gdm-user-switching.c
|
|
index 3d4303e3..a195d052 100644
|
|
--- a/libgdm/gdm-user-switching.c
|
|
+++ b/libgdm/gdm-user-switching.c
|
|
@@ -31,12 +31,25 @@
|
|
#include <glib-object.h>
|
|
#include <gio/gio.h>
|
|
|
|
+#ifdef WITH_SYSTEMD
|
|
#include <systemd/sd-login.h>
|
|
+#endif
|
|
|
|
#include "common/gdm-common.h"
|
|
#include "gdm-user-switching.h"
|
|
#include "gdm-client.h"
|
|
|
|
+#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
|
|
+
|
|
static gboolean
|
|
create_transient_display (GDBusConnection *connection,
|
|
GCancellable *cancellable,
|
|
@@ -67,12 +80,304 @@ create_transient_display (GDBusConnection *connection,
|
|
return TRUE;
|
|
}
|
|
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+
|
|
+static gboolean
|
|
+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;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+activate_session_id_for_ck (GDBusConnection *connection,
|
|
+ GCancellable *cancellable,
|
|
+ const char *seat_id,
|
|
+ const char *session_id,
|
|
+ GError **error)
|
|
+{
|
|
+ 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, error);
|
|
+ if (reply == NULL) {
|
|
+ g_prefix_error (error, _("Unable to activate session: "));
|
|
+ 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
|
|
-activate_session_id (GDBusConnection *connection,
|
|
- GCancellable *cancellable,
|
|
- const char *seat_id,
|
|
- const char *session_id,
|
|
- GError **error)
|
|
+goto_login_session_for_ck (GDBusConnection *connection,
|
|
+ GCancellable *cancellable,
|
|
+ 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_CLIENT_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_CLIENT_ERROR, 0, _("User unable to switch sessions."));
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ if (session_id != NULL) {
|
|
+ res = activate_session_id_for_ck (connection, cancellable, seat_id, session_id, error);
|
|
+ if (res) {
|
|
+ ret = TRUE;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (! ret && g_strcmp0 (seat_id, "/org/freedesktop/ConsoleKit/Seat1") == 0) {
|
|
+ res = create_transient_display (connection, cancellable, error);
|
|
+ if (res) {
|
|
+ ret = TRUE;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_SYSTEMD
|
|
+
|
|
+static gboolean
|
|
+activate_session_id_for_systemd (GDBusConnection *connection,
|
|
+ GCancellable *cancellable,
|
|
+ const char *seat_id,
|
|
+ const char *session_id,
|
|
+ GError **error)
|
|
{
|
|
GVariant *reply;
|
|
|
|
@@ -97,8 +402,8 @@ activate_session_id (GDBusConnection *connection,
|
|
}
|
|
|
|
static gboolean
|
|
-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;
|
|
@@ -182,9 +487,9 @@ out:
|
|
}
|
|
|
|
static gboolean
|
|
-goto_login_session (GDBusConnection *connection,
|
|
- GCancellable *cancellable,
|
|
- GError **error)
|
|
+goto_login_session_for_systemd (GDBusConnection *connection,
|
|
+ GCancellable *cancellable,
|
|
+ GError **error)
|
|
{
|
|
gboolean ret;
|
|
int res;
|
|
@@ -238,9 +543,9 @@ goto_login_session (GDBusConnection *connection,
|
|
return FALSE;
|
|
}
|
|
|
|
- res = 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 = activate_session_id (connection, cancellable, seat_id, session_id, error);
|
|
+ res = activate_session_id_for_systemd (connection, cancellable, seat_id, session_id, error);
|
|
|
|
if (res) {
|
|
ret = TRUE;
|
|
@@ -259,10 +564,11 @@ goto_login_session (GDBusConnection *connection,
|
|
|
|
return ret;
|
|
}
|
|
+#endif
|
|
|
|
gboolean
|
|
gdm_goto_login_session_sync (GCancellable *cancellable,
|
|
- GError **error)
|
|
+ GError **error)
|
|
{
|
|
GDBusConnection *connection;
|
|
gboolean retval;
|
|
@@ -271,8 +577,23 @@ gdm_goto_login_session_sync (GCancellable *cancellable,
|
|
if (!connection)
|
|
return FALSE;
|
|
|
|
- retval = goto_login_session (connection, cancellable, error);
|
|
+#ifdef WITH_SYSTEMD
|
|
+ if (LOGIND_RUNNING()) {
|
|
+ retval = goto_login_session_for_systemd (connection,
|
|
+ cancellable,
|
|
+ error);
|
|
+
|
|
+ g_object_unref (connection);
|
|
+ return retval;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#ifdef WITH_CONSOLE_KIT
|
|
+ retval = goto_login_session_for_ck (connection, cancellable, error);
|
|
|
|
g_object_unref (connection);
|
|
return retval;
|
|
+#else
|
|
+ return FALSE;
|
|
+#endif
|
|
}
|
|
--
|
|
2.13.0
|
|
|