Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=17325
Since ConsoleKit 0.4.2, the sessions created by ck-launch-session are no longer marked as local and active. This means that distributions can't simply call ck-launch-session in Xsession.d anymore to get an active local ConsoleKit session. Instead, XDM must create the session directly, providing info such as the UID of the user and the tty used to log in (like GDM does). It's important that locally logged in users get active local ConsoleKit sessions because that's used by PolicyKit to determine whether certain actions are allowed or not (according to a set of policies, of course). As an example of how this can be used, UDisks can automount devices for locally logged in users without a password prompt with their default PolicyKit policy. This patch allows XDM to create a ConsoleKit session. This is disabled at build time by default, you need to enable it with --with-consolekit. It relies on a very lightweight library called libck-connector (which is distributed with ConsoleKit) to do the DBus magic required for the creation of the active local session. I did not author this patch. I fetched it from the OpenSUSE repositories[1]. It seems to have been initially created by Takashi Iwai and perhaps adapted by Stefan Dirsch[2]. [1]: https://build.opensuse.org/package/view_file?file=xdm-consolekit.diff&package=xorg-x11&project=openSUSE:11.3:Update:Test&srcmd5=5e43d91b0bf84c8a82fc23b1cb550931 [2]: https://bugs.freedesktop.org/show_bug.cgi?id=17325 Signed-off-by: Fernando Tarlá Cardoso Lemos <[email protected]> --- configure.ac | 14 ++++++++ include/dm.h | 3 ++ man/xdm.man | 6 +++ xdm/resource.c | 13 ++++++- xdm/session.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index 38717d0..6f3f9ce 100644 --- a/configure.ac +++ b/configure.ac @@ -359,6 +359,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" + 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 316dd46..d99d92b 100644 --- a/include/dm.h +++ b/include/dm.h @@ -325,6 +325,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 721dade..1d5c559 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 a2050bd..4362d59 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; @@ -196,6 +199,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]) @@ -380,7 +387,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 71e0954..62577cc 100644 --- a/xdm/session.c +++ b/xdm/session.c @@ -67,6 +67,11 @@ extern int key_setnet(struct key_netstarg *arg); # endif #endif /* USE_PAM */ +#ifdef USE_CONSOLEKIT +#include <ck-connector.h> +#include <dbus/dbus.h> +#endif + #ifdef __SCO__ # include <prot.h> #endif @@ -504,6 +509,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", (char *)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) { @@ -518,6 +614,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); @@ -600,6 +698,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 (); -- 1.7.4.1 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
