Commit 512bbbcb authored by William Jon McCann's avatar William Jon McCann Committed by William Jon McCann

Add ConsoleKit support. Fixes #365375.

2006-10-31  William Jon McCann  <mccann@jhu.edu>

	* configure.ac:
	* daemon/Makefile.am:
	* daemon/gdm.c: (main):
	* daemon/gdmconsolekit.c: (add_param_int), (add_param_boolean),
	(add_param_string), (get_string), (unlock_ck_session),
	(open_ck_session), (close_ck_session):
	* daemon/gdmconsolekit.h:
	* daemon/slave.c: (gdm_slave_check_user_wants_to_log_in),
	(session_child_run), (gdm_slave_session_start):
	* docs/C/gdm.xml:
	Add ConsoleKit support.  Fixes #365375.
parent 0eb03f54
2006-10-31 William Jon McCann <mccann@jhu.edu>
* configure.ac:
* daemon/Makefile.am:
* daemon/gdm.c: (main):
* daemon/gdmconsolekit.c: (add_param_int), (add_param_boolean),
(add_param_string), (get_string), (unlock_ck_session),
(open_ck_session), (close_ck_session):
* daemon/gdmconsolekit.h:
* daemon/slave.c: (gdm_slave_check_user_wants_to_log_in),
(session_child_run), (gdm_slave_session_start):
* docs/C/gdm.xml:
Add ConsoleKit support. Fixes #365375.
2006-10-31 Brian Cameron <brian.cameron@sun.com>
* gui/greeter/greeter_item_customlist.c: Fix custom lists so
......
......@@ -10,6 +10,7 @@ IT_PROG_INTLTOOL([0.35.0])
GNOME_DOC_INIT
DBUS_REQUIRED=0.30
GLIB_REQUIRED=2.8.0
GTK_REQUIRED=2.6.0
PANGO_REQUIRED=1.3.0
......@@ -71,6 +72,10 @@ AC_ARG_WITH(dmx,
AC_ARG_WITH(selinux, [ --with-selinux Add SELinux support])
AC_ARG_WITH(console-kit,
[ --with-console-kit=[auto/yes/no] Add ConsoleKit support [default=auto]],,
with_console_kit=auto)
# On Solaris, Xnest is only shipped in /usr/openwin/, but your
# should use "--with-post-path=/usr/openwin/bin" for full
# Xserver support (such as access to Xnest and other X executables
......@@ -156,7 +161,7 @@ PKG_CHECK_MODULES(VICIOUS, gtk+-2.0 >= $GTK_REQUIRED libglade-2.0 >= $LIBGLADE_R
AC_SUBST(VICIOUS_CFLAGS)
AC_SUBST(VICIOUS_LIBS)
PKG_CHECK_MODULES(DAEMON, gtk+-2.0 >= $GTK_REQUIRED)
PKG_CHECK_MODULES(DAEMON, gtk+-2.0 >= $GTK_REQUIRED dbus-glib-1 >= $DBUS_REQUIRED)
AC_SUBST(DAEMON_CFLAGS)
AC_SUBST(DAEMON_LIBS)
......@@ -776,6 +781,17 @@ if test "x$with_selinux" = "xyes" ; then
EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lselinux -lattr"
fi
#
# ConsoleKit support
#
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)
#
# Subst the extra libs
#
......@@ -1215,6 +1231,13 @@ else
echo "Solaris Trusted Extensions support : NO"
fi
dnl <= ConsoleKit support =>
if test "x$use_console_kit" = "xyes" ; then
echo "ConsoleKit support : YES"
else
echo "ConsoleKit support : NO"
fi
dnl <= Authentication scheme =>
echo "Authentication scheme : $VRFY"
......
......@@ -73,6 +73,12 @@ gdm_binary_SOURCES = \
getvt.c \
getvt.h
if WITH_CONSOLE_KIT
gdm_binary_SOURCES += \
gdmconsolekit.c \
gdmconsolekit.h
endif
EXTRA_gdm_binary_SOURCES = verify-pam.c verify-crypt.c verify-shadow.c
# Note that these libs are in LDFLAGS because they should come before
......
......@@ -46,6 +46,7 @@
#include <X11/Xauth.h>
#include <glib/gi18n.h>
#include <glib-object.h>
/* Needed for signal handling */
#include <vicious.h>
......@@ -1534,6 +1535,8 @@ main (int argc, char *argv[])
/* Initialize runtime environment */
umask (022);
g_type_init ();
ctx = g_option_context_new (_("- The GNOME login manager"));
g_option_context_add_main_entries (ctx, options, _("main options"));
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "config.h"
#include <pwd.h>
#define DBUS_API_SUBJECT_TO_CHANGE
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "misc.h" /* for gdm_debug */
#include "gdmconsolekit.h"
#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_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
#define CK_TYPE_PARAMETER_STRUCT (dbus_g_type_get_struct ("GValueArray", \
G_TYPE_STRING, \
G_TYPE_VALUE, \
G_TYPE_INVALID))
#define CK_TYPE_PARAMETER_LIST (dbus_g_type_get_collection ("GPtrArray", \
CK_TYPE_PARAMETER_STRUCT))
static void
add_param_int (GPtrArray *parameters,
const char *key,
int value)
{
GValue val = { 0, };
GValue param_val = { 0, };
g_value_init (&val, G_TYPE_INT);
g_value_set_int (&val, value);
g_value_init (&param_val, CK_TYPE_PARAMETER_STRUCT);
g_value_take_boxed (&param_val,
dbus_g_type_specialized_construct (CK_TYPE_PARAMETER_STRUCT));
dbus_g_type_struct_set (&param_val,
0, key,
1, &val,
G_MAXUINT);
g_ptr_array_add (parameters, g_value_get_boxed (&param_val));
}
static void
add_param_boolean (GPtrArray *parameters,
const char *key,
gboolean value)
{
GValue val = { 0, };
GValue param_val = { 0, };
g_value_init (&val, G_TYPE_BOOLEAN);
g_value_set_boolean (&val, value);
g_value_init (&param_val, CK_TYPE_PARAMETER_STRUCT);
g_value_take_boxed (&param_val,
dbus_g_type_specialized_construct (CK_TYPE_PARAMETER_STRUCT));
dbus_g_type_struct_set (&param_val,
0, key,
1, &val,
G_MAXUINT);
g_ptr_array_add (parameters, g_value_get_boxed (&param_val));
}
static void
add_param_string (GPtrArray *parameters,
const char *key,
const char *value)
{
GValue val = { 0, };
GValue param_val = { 0, };
g_value_init (&val, G_TYPE_STRING);
g_value_set_string (&val, value);
g_value_init (&param_val, CK_TYPE_PARAMETER_STRUCT);
g_value_take_boxed (&param_val,
dbus_g_type_specialized_construct (CK_TYPE_PARAMETER_STRUCT));
dbus_g_type_struct_set (&param_val,
0, key,
1, &val,
G_MAXUINT);
g_ptr_array_add (parameters, g_value_get_boxed (&param_val));
}
static gboolean
get_string (DBusGProxy *proxy,
const char *method,
char **str)
{
GError *error;
gboolean res;
error = NULL;
res = dbus_g_proxy_call (proxy,
method,
&error,
G_TYPE_INVALID,
G_TYPE_STRING, str,
G_TYPE_INVALID);
if (! res) {
g_warning ("%s failed: %s", method, error->message);
g_error_free (error);
}
return res;
}
void
unlock_ck_session (const char *user,
const char *x11_display)
{
DBusGConnection *connection;
DBusGProxy *proxy;
GError *error;
gboolean res;
struct passwd *pwent;
GPtrArray *sessions;
int i;
gdm_debug ("Unlocking ConsoleKit session for %s on %s", user, x11_display);
error = NULL;
connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (connection == NULL) {
gdm_debug ("Failed to connect to the D-Bus daemon: %s", error->message);
g_error_free (error);
return;
}
proxy = dbus_g_proxy_new_for_name (connection,
CK_NAME,
CK_MANAGER_PATH,
CK_MANAGER_INTERFACE);
if (proxy == NULL) {
return;
}
pwent = getpwnam (user);
error = NULL;
res = dbus_g_proxy_call (proxy,
"GetSessionsForUser",
&error,
G_TYPE_UINT,
pwent->pw_uid,
G_TYPE_INVALID,
dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
&sessions,
G_TYPE_INVALID);
if (! res) {
g_warning ("Failed to get list of sessions: %s", error->message);
g_error_free (error);
goto out;
}
for (i = 0; i < sessions->len; i++) {
char *ssid;
DBusGProxy *session_proxy;
ssid = g_ptr_array_index (sessions, i);
session_proxy = dbus_g_proxy_new_for_name (connection,
CK_NAME,
ssid,
CK_SESSION_INTERFACE);
if (session_proxy != NULL) {
char *xdisplay;
get_string (session_proxy, "GetX11Display", &xdisplay);
if (xdisplay != NULL
&& x11_display != NULL
&& strcmp (xdisplay, x11_display) == 0) {
res = dbus_g_proxy_call (session_proxy,
"Unlock",
&error,
G_TYPE_INVALID,
G_TYPE_INVALID);
if (! res) {
g_warning ("Unable to unlock %s: %s", ssid, error->message);
g_error_free (error);
}
}
}
g_object_unref (session_proxy);
g_free (ssid);
}
g_ptr_array_free (sessions, TRUE);
out:
g_object_unref (proxy);
}
char *
open_ck_session (struct passwd *pwent,
GdmDisplay *d,
const char *session)
{
DBusGConnection *connection;
DBusGProxy *proxy;
GError *error;
gboolean res;
char *cookie;
GPtrArray *parameters;
cookie = NULL;
gdm_debug ("Opening ConsoleKit session for %s", pwent->pw_name);
error = NULL;
connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (connection == NULL) {
gdm_debug ("Failed to connect to the D-Bus daemon: %s", error->message);
g_error_free (error);
return NULL;
}
proxy = dbus_g_proxy_new_for_name (connection,
CK_NAME,
CK_MANAGER_PATH,
CK_MANAGER_INTERFACE);
if (proxy == NULL) {
return NULL;
}
parameters = g_ptr_array_sized_new (10);
add_param_int (parameters, "user", pwent->pw_uid);
add_param_string (parameters, "x11-display", d->name);
add_param_string (parameters, "host-name", d->hostname);
add_param_boolean (parameters, "is-local", d->attached);
/* FIXME: this isn't really a reliable value to use */
add_param_string (parameters, "session-type", session);
if (d->vt > 0) {
char *device;
/* FIXME: how does xorg construct this */
device = g_strdup_printf ("/dev/tty%d", d->vt);
add_param_string (parameters, "display-device", device);
g_free (device);
}
error = NULL;
res = dbus_g_proxy_call (proxy,
"OpenSessionWithParameters",
&error,
CK_TYPE_PARAMETER_LIST,
parameters,
G_TYPE_INVALID,
G_TYPE_STRING,
&cookie,
G_TYPE_INVALID);
if (! res) {
g_warning ("OpenSession failed: %s", error->message);
g_error_free (error);
}
g_object_unref (proxy);
g_ptr_array_free (parameters, TRUE);
return cookie;
}
void
close_ck_session (const char *cookie)
{
DBusGConnection *connection;
DBusGProxy *proxy;
GError *error;
gboolean res;
error = NULL;
connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (connection == NULL) {
gdm_debug ("Failed to connect to the D-Bus daemon: %s", error->message);
g_error_free (error);
return;
}
proxy = dbus_g_proxy_new_for_name (connection,
CK_NAME,
CK_MANAGER_PATH,
CK_MANAGER_INTERFACE);
if (proxy == NULL) {
return;
}
error = NULL;
res = dbus_g_proxy_call (proxy,
"CloseSession",
&error,
G_TYPE_STRING,
&cookie,
G_TYPE_INVALID,
G_TYPE_INVALID);
if (! res) {
g_warning ("CloseSession failed: %s", error->message);
g_error_free (error);
}
g_object_unref (proxy);
}
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GDM_CONSOLE_KIT_H
#define __GDM_CONSOLE_KIT_H
G_BEGIN_DECLS
char * open_ck_session (struct passwd *pwent,
GdmDisplay *display,
const char *session);
void close_ck_session (const char *cookie);
void unlock_ck_session (const char *user,
const char *x11_display);
G_END_DECLS
#endif /* __GDM_CONSOLE_KIT_H */
......@@ -90,6 +90,10 @@
#include "cookie.h"
#include "gdmconfig.h"
#ifdef WITH_CONSOLE_KIT
#include "gdmconsolekit.h"
#endif
/* Some per slave globals */
static GdmDisplay *d = 0;
static gchar *login = NULL;
......@@ -1234,6 +1238,10 @@ gdm_slave_check_user_wants_to_log_in (const char *user)
*/
gdm_sleep_no_signal (1);
#ifdef WITH_CONSOLE_KIT
unlock_ck_session (user, migrate_to);
#endif
gdm_slave_send_string (GDM_SOP_MIGRATE, migrate_to);
g_free (migrate_to);
......@@ -3344,6 +3352,9 @@ session_child_run (struct passwd *pwent,
gboolean failsafe,
const char *home_dir,
gboolean home_dir_ok,
#ifdef WITH_CONSOLE_KIT
const char *ck_session_cookie,
#endif
const char *session,
const char *save_session,
const char *language,
......@@ -3434,6 +3445,9 @@ session_child_run (struct passwd *pwent,
g_setenv ("USER", pwent->pw_name, TRUE);
g_setenv ("USERNAME", pwent->pw_name, TRUE);
g_setenv ("HOME", home_dir, TRUE);
#ifdef WITH_CONSOLE_KIT
g_setenv ("XDG_SESSION_COOKIE", ck_session_cookie, TRUE);
#endif
g_setenv ("GDMSESSION", session, TRUE);
g_setenv ("DESKTOP_SESSION", session, TRUE);
g_setenv ("SHELL", pwent->pw_shell, TRUE);
......@@ -3580,7 +3594,7 @@ session_child_run (struct passwd *pwent,
gdm_close_all_descriptors (3 /* from */, -1 /* except */, -1 /* except2 */);
openlog ("gdm", LOG_PID, LOG_DAEMON);
argv[0] = NULL;
argv[1] = NULL;
argv[2] = NULL;
......@@ -3930,6 +3944,9 @@ gdm_slave_session_start (void)
const char *home_dir = NULL;
char *save_session = NULL, *session = NULL, *language = NULL, *usrsess, *usrlang;
char *gnome_session = NULL;
#ifdef WITH_CONSOLE_KIT
char *ck_session_cookie;
#endif
char *tmp;
gboolean savesess = FALSE, savelang = FALSE;
gboolean usrcfgok = FALSE, authok = FALSE;
......@@ -4242,6 +4259,10 @@ gdm_slave_session_start (void)
* could reset time or do other crazy things */
session_start_time = time (NULL);
#ifdef WITH_CONSOLE_KIT
ck_session_cookie = open_ck_session (pwent, d, session);
#endif
/* Start user process */
gdm_sigchld_block_push ();
gdm_sigterm_block_push ();
......@@ -4266,6 +4287,9 @@ gdm_slave_session_start (void)
failsafe,
home_dir,
home_dir_ok,
#ifdef WITH_CONSOLE_KIT
ck_session_cookie,
#endif
session,
save_session,
language,
......@@ -4353,6 +4377,11 @@ gdm_slave_session_start (void)
FALSE /* no_shutdown_check */);
gdm_debug ("gdm_slave_session_start: Session ended OK (now all finished)");
#ifdef WITH_CONSOLE_KIT
close_ck_session (ck_session_cookie);
g_free (ck_session_cookie);
#endif
}
......
......@@ -1005,6 +1005,46 @@ gdm: .your.domain
</sect2>
</sect1>
<sect1 id="consolekit">
<title>Support for ConsoleKit</title>
<para>
GDM includes support for publishing user login information with the user and login
session accounting framework known as ConsoleKit. ConsoleKit is able to keep track
of all the users currently logged in. In this respect, it can be used as a replacement
for the utmp or utmpx files that are available on most Unix-like operating systems.
</para>
<para>
When GDM is about to create a new login process for a user it will call a privileged
method of ConsoleKit in order to open a new session for this user. At this time
GDM also provides ConsoleKit with information about this user session such as: the user ID,
the X11 Display name that will be associated with the session, the host-name from which the
session originates (useful in the case of an XDMCP session), whether or not this session
is local, etc. As the entity that initiates the user process, GDM is in a unique position
know and to be trusted to provide these bits of information about the user session. The use
of this privileged method is restricted by the use of D-Bus system message bus security policy.
</para>
<para>
In the case where a user with an existing session and has authenticated at GDM and requests to
resume that existing session GDM calls a privileged method of ConsoleKit to unlock that
session. The exact details of what happens when the session receives this unlock signal is
undefined and session-specific. However, most sessions will unlock a screensaver in response.
</para>
<para>
When the user chooses to log out, or if GDM or the session quit unexpectedly the user session
will be unregistered from ConsoleKit.
</para>
<para>
If support for ConsoleKit is not desired it can be disabled at build time using the
--with-console-kit=no option when running configure.
</para>
</sect1>
<sect1 id="gdmsetupusage">
<title>Using gdmsetup To Configure GDM</title>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment