http://bugs.gentoo.org/360987 http://projects.archlinux.org/svntogit/packages.git/plain/trunk/xdm-consolekit.patch?h=packages/xorg-xdm http://lists.x.org/archives/xorg-devel/2011-February/019615.html http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=615020 --- configure.ac | 20 ++++++++-- include/dm.h | 3 ++ man/xdm.man | 6 +++ xdm/resource.c | 13 ++++++- xdm/session.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index d110809..db973f7 100644 --- a/configure.ac +++ b/configure.ac @@ -168,15 +168,15 @@ AS_IF([test "x$with_systemdsystemunitdir" != "xno"], [ AM_CONDITIONAL(HAVE_SYSTEMD, [test "x$with_systemdsystemunitdir" != "xno"]) # Check whether to enable systemd startup notification. -# This requires libsystemd-daemon. +# This requires libsystemd. AC_ARG_WITH([systemd-daemon], AS_HELP_STRING([--with-systemd-daemon], [Add support for systemd startup notification (default is autodetected)]), [USE_SYSTEMD_DAEMON=$withval], [USE_SYSTEMD_DAEMON=auto]) AS_IF([test "x$USE_SYSTEMD_DAEMON" != "xno"], [ - PKG_CHECK_MODULES([SYSTEMD_DAEMON], [libsystemd-daemon], + PKG_CHECK_MODULES([SYSTEMD_DAEMON], [libsystemd], [AC_DEFINE(USE_SYSTEMD_DAEMON,1,[Use systemd startup notification])], [AS_IF([test "x$USE_SYSTEMD_DAEMON" = "xyes"], - [AC_MSG_ERROR([systemd startup notification support requested, but libsystemd-daemon not found.])] + [AC_MSG_ERROR([systemd startup notification support requested, but libsystemd not found.])] )] ) ]) @@ -395,6 +395,20 @@ PKG_CHECK_MODULES(DMCP, xdmcp) PKG_CHECK_MODULES(XLIB, x11) PKG_CHECK_MODULES(AUTH, xau) +# ConsoleKit support +AC_ARG_WITH(consolekit, AC_HELP_STRING([--with-consolekit], [Use ConsoleKit]), + [USE_CONSOLEKIT=$withval], [USE_CONSOLEKIT=yes]) +if test x"$USE_CONSOLEKIT" != xno; then + PKG_CHECK_MODULES(CK_CONNECTOR, ck-connector, + [USE_CONSOLEKIT=yes], [USE_CONSOLEKIT=no]) + if test x"$USE_CONSOLEKIT" = xyes; then + AC_DEFINE([USE_CONSOLEKIT], 1, [Define to 1 to use ConsoleKit]) + XDM_CFLAGS="$XDM_CFLAGS $CK_CONNECTOR_CFLAGS -DUSE_CONSOLEKIT" + XDM_LIBS="$XDM_LIBS $CK_CONNECTOR_LIBS" + fi +fi +dnl AM_CONDITIONAL(USE_CONSOLEKIT, test$USE_CONSOLEKIT = xyes) + # # Greeter # diff --git a/include/dm.h b/include/dm.h index 9116d6f..27fdd71 100644 --- a/include/dm.h +++ b/include/dm.h @@ -327,6 +327,9 @@ extern char *randomFile; extern char *prngdSocket; extern int prngdPort; # endif +#ifdef USE_CONSOLEKIT +extern int use_consolekit; +#endif extern char *greeterLib; extern char *willing; diff --git a/man/xdm.man b/man/xdm.man index ef57d8c..de99d25 100644 --- a/man/xdm.man +++ b/man/xdm.man @@ -48,6 +48,8 @@ xdm \- X Display Manager with support for XDMCP, host chooser ] [ .B \-session .I session_program +] [ +.B \-noconsolekit ] .SH DESCRIPTION .I Xdm @@ -215,6 +217,10 @@ indicates the program to run as the session after the user has logged in. .IP "\fB\-xrm\fP \fIresource_specification\fP" Allows an arbitrary resource to be specified, as in most X Toolkit applications. +.IP "\fB\-noconsolekit\fP" +Specifies ``false'' as the value for the \fBDisplayManager.consoleKit\fP +resource. +This suppresses the session management using ConsoleKit. .SH RESOURCES At many stages the actions of .I xdm diff --git a/xdm/resource.c b/xdm/resource.c index 316ace4..725351e 100644 --- a/xdm/resource.c +++ b/xdm/resource.c @@ -65,6 +65,9 @@ char *randomDevice; char *prngdSocket; int prngdPort; #endif +#ifdef USE_CONSOLEKIT +int use_consolekit; +#endif char *greeterLib; char *willing; @@ -192,6 +195,10 @@ struct dmResources { "false"} , { "willing", "Willing", DM_STRING, &willing, ""} , +#ifdef USE_CONSOLEKIT +{ "consoleKit", "ConsoleKit", DM_BOOL, (char **) &use_consolekit, + "true"} , +#endif }; #define NUM_DM_RESOURCES (sizeof DmResources / sizeof DmResources[0]) @@ -377,7 +384,11 @@ XrmOptionDescRec optionTable [] = { {"-debug", "*debugLevel", XrmoptionSepArg, (caddr_t) NULL }, {"-xrm", NULL, XrmoptionResArg, (caddr_t) NULL }, {"-daemon", ".daemonMode", XrmoptionNoArg, "true" }, -{"-nodaemon", ".daemonMode", XrmoptionNoArg, "false" } +{"-nodaemon", ".daemonMode", XrmoptionNoArg, "false" }, +#ifdef USE_CONSOLEKIT +{"-consolekit", ".consoleKit", XrmoptionNoArg, "true" }, +{"-noconsolekit", ".consoleKit", XrmoptionNoArg, "false" } +#endif }; static int originalArgc; diff --git a/xdm/session.c b/xdm/session.c index 4fd7d0a..c16978d 100644 --- a/xdm/session.c +++ b/xdm/session.c @@ -73,6 +73,11 @@ extern int key_setnet(struct key_netstarg *arg); # endif #endif /* USE_PAM */ +#ifdef USE_CONSOLEKIT +#include +#include +#endif + #ifdef USE_SELINUX #include #include @@ -523,6 +528,97 @@ UnsecureDisplay (struct display *d, Display *dpy) } } +#ifdef USE_CONSOLEKIT + +static CkConnector *connector; + +static int openCKSession(struct verify_info *verify, struct display *d) +{ + int ret; + DBusError error; + char *remote_host_name = ""; + dbus_bool_t is_local; + char *display_name = ""; + char *display_device = ""; + char devtmp[16]; + + if (!use_consolekit) + return 1; + + is_local = d->displayType.location == Local; + if (d->peerlen > 0 && d->peer) + remote_host_name = d->peer; + if (d->name) + display_name = d->name; + /* how can we get the corresponding tty at best...? */ + if (d->windowPath) { + display_device = strchr(d->windowPath, ':'); + if (display_device && display_device[1]) + display_device++; + else + display_device = d->windowPath; + snprintf(devtmp, sizeof(devtmp), "/dev/tty%s", display_device); + display_device = devtmp; + } + + connector = ck_connector_new(); + if (!connector) { + LogOutOfMem("ck_connector"); + return 0; + } + + dbus_error_init(&error); + ret = ck_connector_open_session_with_parameters( + connector, &error, + "unix-user", &verify->uid, + "x11-display", &display_name, + "x11-display-device", &display_device, + "remote-host-name", &remote_host_name, + "is-local", &is_local, + NULL); + if (!ret) { + if (dbus_error_is_set(&error)) { + LogError("Dbus error: %s\n", error.message); + dbus_error_free(&error); + } else { + LogError("ConsoleKit error\n"); + } + LogError("console-kit-daemon not running?\n"); + ck_connector_unref(connector); + connector = NULL; + return 0; + } + + verify->userEnviron = setEnv(verify->userEnviron, + "XDG_SESSION_COOKIE", ck_connector_get_cookie(connector)); + return 1; +} + +static void closeCKSession(void) +{ + DBusError error; + + if (!connector) + return; + + dbus_error_init(&error); + if (!ck_connector_close_session(connector, &error)) { + if (dbus_error_is_set(&error)) { + LogError("Dbus error: %s\n", error.message); + dbus_error_free(&error); + } else { + LogError("ConsoleKit close error\n"); + } + LogError("console-kit-daemon not running?\n"); + } + ck_connector_unref(connector); + connector = NULL; +} +#else +#define openCKSession(v,d) 1 +#define closeCKSession() +#endif + void SessionExit (struct display *d, int status, int removeAuth) { @@ -537,6 +633,8 @@ SessionExit (struct display *d, int status, int removeAuth) } #endif + closeCKSession(); + /* make sure the server gets reset after the session is over */ if (d->serverPid >= 2 && d->resetSignal) kill (d->serverPid, d->resetSignal); @@ -614,6 +712,10 @@ StartClient ( #ifdef USE_PAM if (pamh) pam_open_session(pamh, 0); #endif + + if (!openCKSession(verify, d)) + return 0; + switch (pid = fork ()) { case 0: CleanUpChild (); -- 2.19.2