gdm r5639 - in trunk: . daemon
- From: mccann svn gnome org
- To: svn-commits-list gnome org
- Subject: gdm r5639 - in trunk: . daemon
- Date: Mon, 28 Jan 2008 21:28:43 +0000 (GMT)
Author: mccann
Date: Mon Jan 28 21:28:43 2008
New Revision: 5639
URL: http://svn.gnome.org/viewvc/gdm?rev=5639&view=rev
Log:
2008-01-28 William Jon McCann <mccann jhu edu>
* daemon/gdm-display.c: (gdm_display_get_seat_id),
(gdm_display_class_init):
* daemon/gdm-display.h:
* daemon/gdm-display.xml:
* daemon/gdm-local-display-factory.c:
(gdm_local_display_factory_create_transient_display),
(gdm_local_display_factory_create_product_display),
(create_display):
* daemon/gdm-simple-slave.c: (on_session_authorized),
(try_migrate_session), (start_session_timeout),
(queue_start_session), (on_session_accredited),
(on_session_accreditation_failed):
* daemon/gdm-slave.c: (gdm_slave_real_start),
(_get_uid_and_gid_for_user), (x11_session_is_on_seat),
(_get_primary_user_session_id), (activate_session_id),
(gdm_slave_switch_to_user_session),
(_gdm_slave_set_display_seat_id), (gdm_slave_set_property),
(gdm_slave_get_property), (gdm_slave_class_init):
* daemon/gdm-slave.h:
Initial session migration support. We still need to
make the slave die after if it is a transient display.
Modified:
trunk/ChangeLog
trunk/daemon/gdm-display.c
trunk/daemon/gdm-display.h
trunk/daemon/gdm-display.xml
trunk/daemon/gdm-local-display-factory.c
trunk/daemon/gdm-simple-slave.c
trunk/daemon/gdm-slave.c
trunk/daemon/gdm-slave.h
Modified: trunk/daemon/gdm-display.c
==============================================================================
--- trunk/daemon/gdm-display.c (original)
+++ trunk/daemon/gdm-display.c Mon Jan 28 21:28:43 2008
@@ -355,6 +355,20 @@
return TRUE;
}
+gboolean
+gdm_display_get_seat_id (GdmDisplay *display,
+ char **seat_id,
+ GError **error)
+{
+ g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+ if (seat_id != NULL) {
+ *seat_id = g_strdup (display->priv->seat_id);
+ }
+
+ return TRUE;
+}
+
static gboolean
finish_idle (GdmDisplay *display)
{
@@ -800,13 +814,6 @@
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
- PROP_SEAT_ID,
- g_param_spec_string ("seat-id",
- "seat id",
- "seat id",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (object_class,
PROP_REMOTE_HOSTNAME,
g_param_spec_string ("remote-hostname",
"remote-hostname",
@@ -830,6 +837,13 @@
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
+ PROP_SEAT_ID,
+ g_param_spec_string ("seat-id",
+ "seat id",
+ "seat id",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+ g_object_class_install_property (object_class,
PROP_X11_COOKIE,
g_param_spec_string ("x11-cookie",
"cookie",
Modified: trunk/daemon/gdm-display.h
==============================================================================
--- trunk/daemon/gdm-display.h (original)
+++ trunk/daemon/gdm-display.h Mon Jan 28 21:28:43 2008
@@ -101,6 +101,9 @@
gboolean gdm_display_get_x11_display_name (GdmDisplay *display,
char **x11_display,
GError **error);
+gboolean gdm_display_get_seat_id (GdmDisplay *display,
+ char **seat_id,
+ GError **error);
gboolean gdm_display_is_local (GdmDisplay *display,
gboolean *local,
GError **error);
Modified: trunk/daemon/gdm-display.xml
==============================================================================
--- trunk/daemon/gdm-display.xml (original)
+++ trunk/daemon/gdm-display.xml Mon Jan 28 21:28:43 2008
@@ -16,6 +16,9 @@
<method name="GetX11AuthorityFile">
<arg name="filename" direction="out" type="s"/>
</method>
+ <method name="GetSeatId">
+ <arg name="filename" direction="out" type="s"/>
+ </method>
<method name="GetRemoteHostname">
<arg name="hostname" direction="out" type="s"/>
</method>
Modified: trunk/daemon/gdm-local-display-factory.c
==============================================================================
--- trunk/daemon/gdm-local-display-factory.c (original)
+++ trunk/daemon/gdm-local-display-factory.c Mon Jan 28 21:28:43 2008
@@ -39,6 +39,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"
@@ -209,7 +211,7 @@
}
/* FIXME: don't hardcode seat1? */
- g_object_set (display, "seat-id", "org.freedesktop.ConsoleKit.Seat1", NULL);
+ g_object_set (display, "seat-id", CK_SEAT1_PATH, NULL);
store_display (factory, num, display);
@@ -261,7 +263,7 @@
}
/* FIXME: don't hardcode seat1? */
- g_object_set (display, "seat-id", "org.freedesktop.ConsoleKit.Seat1", NULL);
+ g_object_set (display, "seat-id", CK_SEAT1_PATH, NULL);
store_display (factory, num, display);
@@ -309,7 +311,7 @@
}
/* FIXME: don't hardcode seat1? */
- g_object_set (display, "seat-id", "org.freedesktop.ConsoleKit.Seat1", NULL);
+ g_object_set (display, "seat-id", CK_SEAT1_PATH, NULL);
store_display (factory, num, display);
Modified: trunk/daemon/gdm-simple-slave.c
==============================================================================
--- trunk/daemon/gdm-simple-slave.c (original)
+++ trunk/daemon/gdm-simple-slave.c Mon Jan 28 21:28:43 2008
@@ -66,6 +66,7 @@
guint error_watch_id;
guint greeter_reset_id;
+ guint start_session_id;
int ping_interval;
@@ -76,7 +77,6 @@
GdmGreeterServer *greeter_server;
GdmGreeterSession *greeter;
GdmSessionDirect *session;
- DBusGConnection *connection;
};
enum {
@@ -209,7 +209,6 @@
{
int flag;
- /* FIXME: check for migration? */
flag = GDM_SESSION_CRED_ESTABLISH;
gdm_session_accredit (session, flag);
@@ -225,11 +224,39 @@
queue_greeter_reset (slave);
}
-static void
-on_session_accredited (GdmSession *session,
- GdmSimpleSlave *slave)
+static gboolean
+try_migrate_session (GdmSimpleSlave *slave)
+{
+ char *username;
+ gboolean res;
+
+ g_debug ("GdmSimpleSlave: trying to migrate session");
+
+ username = gdm_session_direct_get_username (slave->priv->session);
+
+ /* try to switch to an existing session */
+ res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username);
+ g_free (username);
+
+ return res;
+}
+
+
+static gboolean
+start_session_timeout (GdmSimpleSlave *slave)
{
- char *auth_file;
+
+ char *auth_file;
+ gboolean migrated;
+
+ g_debug ("GdmSimpleSlave: accredited");
+
+ migrated = try_migrate_session (slave);
+ g_debug ("GdmSimpleSlave: migrated: %d", migrated);
+ if (migrated) {
+ queue_greeter_reset (slave);
+ goto out;
+ }
gdm_greeter_session_stop (slave->priv->greeter);
gdm_greeter_server_stop (slave->priv->greeter_server);
@@ -239,13 +266,33 @@
g_assert (auth_file != NULL);
- g_object_set (session,
+ g_object_set (slave->priv->session,
"user-x11-authority-file", auth_file,
NULL);
g_free (auth_file);
- gdm_session_start_session (session);
+ gdm_session_start_session (GDM_SESSION (slave->priv->session));
+ out:
+ slave->priv->start_session_id = 0;
+ return FALSE;
+}
+
+static void
+queue_start_session (GdmSimpleSlave *slave)
+{
+ if (slave->priv->start_session_id > 0) {
+ return;
+ }
+
+ slave->priv->start_session_id = g_idle_add ((GSourceFunc)start_session_timeout, slave);
+}
+
+static void
+on_session_accredited (GdmSession *session,
+ GdmSimpleSlave *slave)
+{
+ queue_start_session (slave);
}
static void
@@ -253,7 +300,17 @@
const char *message,
GdmSimpleSlave *slave)
{
- gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable establish credentials"));
+ gboolean migrated;
+
+ g_debug ("GdmSimpleSlave: accreditation failed");
+
+ migrated = try_migrate_session (slave);
+
+ /* If we switched to another session we don't care if
+ accreditation fails */
+ if (! migrated) {
+ gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable establish credentials"));
+ }
queue_greeter_reset (slave);
}
Modified: trunk/daemon/gdm-slave.c
==============================================================================
--- trunk/daemon/gdm-slave.c (original)
+++ trunk/daemon/gdm-slave.c Mon Jan 28 21:28:43 2008
@@ -53,6 +53,15 @@
#define GDM_SLAVE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SLAVE, GdmSlavePrivate))
+#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"
+
#define GDM_DBUS_NAME "org.gnome.DisplayManager"
#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display"
@@ -74,6 +83,7 @@
char *display_hostname;
gboolean display_is_local;
gboolean display_is_parented;
+ char *display_seat_id;
char *display_x11_authority_file;
char *parent_display_name;
char *parent_display_x11_authority_file;
@@ -93,6 +103,7 @@
PROP_DISPLAY_NUMBER,
PROP_DISPLAY_HOSTNAME,
PROP_DISPLAY_IS_LOCAL,
+ PROP_DISPLAY_SEAT_ID,
PROP_DISPLAY_X11_AUTHORITY_FILE
};
@@ -555,6 +566,24 @@
return FALSE;
}
+ error = NULL;
+ res = dbus_g_proxy_call (slave->priv->display_proxy,
+ "GetSeatId",
+ &error,
+ G_TYPE_INVALID,
+ G_TYPE_STRING, &slave->priv->display_seat_id,
+ G_TYPE_INVALID);
+ if (! res) {
+ if (error != NULL) {
+ g_warning ("Failed to get value: %s", error->message);
+ g_error_free (error);
+ } else {
+ g_warning ("Failed to get value");
+ }
+
+ return FALSE;
+ }
+
return TRUE;
}
@@ -650,6 +679,317 @@
return res;
}
+static gboolean
+_get_uid_and_gid_for_user (const char *username,
+ uid_t *uid,
+ gid_t *gid)
+{
+ struct passwd *passwd_entry;
+
+ g_assert (username != NULL);
+
+ errno = 0;
+ passwd_entry = getpwnam (username);
+
+ if (passwd_entry == NULL) {
+ return FALSE;
+ }
+
+ if (uid != NULL) {
+ *uid = passwd_entry->pw_uid;
+ }
+
+ if (gid != NULL) {
+ *gid = passwd_entry->pw_gid;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+x11_session_is_on_seat (GdmSlave *slave,
+ const char *session_id,
+ const char *seat_id)
+{
+ DBusGProxy *proxy;
+ GError *error;
+ char *sid;
+ gboolean res;
+ gboolean ret;
+ char *x11_display_device;
+ char *x11_display;
+
+ ret = FALSE;
+
+ if (seat_id == NULL || seat_id[0] == '\0' || session_id == NULL || session_id[0] == '\0') {
+ return FALSE;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (slave->priv->connection,
+ CK_NAME,
+ session_id,
+ CK_SESSION_INTERFACE);
+ if (proxy == NULL) {
+ g_warning ("Failed to connect to the ConsoleKit seat object");
+ goto out;
+ }
+
+ sid = NULL;
+ error = NULL;
+ res = dbus_g_proxy_call (proxy,
+ "GetSeatId",
+ &error,
+ G_TYPE_INVALID,
+ DBUS_TYPE_G_OBJECT_PATH, &sid,
+ G_TYPE_INVALID);
+ if (! res) {
+ g_debug ("Failed to identify the current seat: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ if (sid == NULL || sid[0] == '\0' || strcmp (sid, seat_id) != 0) {
+ g_debug ("GdmSlave: session not on current seat: %s", seat_id);
+ goto out;
+ }
+
+ x11_display = NULL;
+ error = NULL;
+ res = dbus_g_proxy_call (proxy,
+ "GetX11Display",
+ &error,
+ G_TYPE_INVALID,
+ G_TYPE_STRING, &x11_display,
+ G_TYPE_INVALID);
+ if (! res) {
+ g_error_free (error);
+ goto out;
+ }
+
+ /* don't try to switch to our own session */
+ if (x11_display == NULL || x11_display[0] == '\0'
+ || strcmp (slave->priv->display_name, x11_display) == 0) {
+ g_free (x11_display);
+ goto out;
+ }
+ g_free (x11_display);
+
+ x11_display_device = NULL;
+ error = NULL;
+ res = dbus_g_proxy_call (proxy,
+ "GetX11DisplayDevice",
+ &error,
+ G_TYPE_INVALID,
+ G_TYPE_STRING, &x11_display_device,
+ G_TYPE_INVALID);
+ if (! res) {
+ g_error_free (error);
+ goto out;
+ }
+
+ if (x11_display_device == NULL || x11_display_device[0] == '\0') {
+ g_free (x11_display_device);
+ goto out;
+ }
+ g_free (x11_display_device);
+
+ ret = TRUE;
+
+ out:
+ if (proxy != NULL) {
+ g_object_unref (proxy);
+ }
+
+ return ret;
+}
+
+static char *
+_get_primary_user_session_id (GdmSlave *slave,
+ const char *username)
+{
+ gboolean res;
+ gboolean ret;
+ gboolean can_activate_sessions;
+ GError *error;
+ DBusGProxy *manager_proxy;
+ DBusGProxy *seat_proxy;
+ GPtrArray *sessions;
+ char *primary_ssid;
+ int i;
+ uid_t uid;
+
+ if (slave->priv->display_seat_id == NULL || slave->priv->display_seat_id[0] == '\0') {
+ g_debug ("GdmSlave: display seat id is not set; can't switch sessions");
+ return FALSE;
+ }
+
+ ret = FALSE;
+ manager_proxy = NULL;
+ primary_ssid = NULL;
+ sessions = NULL;
+
+ g_debug ("GdmSlave: getting proxy for seat: %s", slave->priv->display_seat_id);
+
+ seat_proxy = dbus_g_proxy_new_for_name (slave->priv->connection,
+ CK_NAME,
+ slave->priv->display_seat_id,
+ CK_SEAT_INTERFACE);
+
+ g_debug ("GdmSlave: checking if seat can activate sessions");
+
+ error = NULL;
+ res = dbus_g_proxy_call (seat_proxy,
+ "CanActivateSessions",
+ &error,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &can_activate_sessions,
+ G_TYPE_INVALID);
+ if (! res) {
+ g_warning ("unable to determine if seat can activate sessions: %s",
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ if (! can_activate_sessions) {
+ g_debug ("GdmSlave: seat is unable to activate sessions");
+ goto out;
+ }
+
+ manager_proxy = dbus_g_proxy_new_for_name (slave->priv->connection,
+ CK_NAME,
+ CK_MANAGER_PATH,
+ CK_MANAGER_INTERFACE);
+
+ if (! _get_uid_and_gid_for_user (username, &uid, NULL)) {
+ g_debug ("GdmSlave: unable to determine uid for user: %s", username);
+ goto out;
+ }
+
+ error = NULL;
+ res = dbus_g_proxy_call (manager_proxy,
+ "GetSessionsForUnixUser",
+ &error,
+ G_TYPE_UINT, uid,
+ G_TYPE_INVALID,
+ dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &sessions,
+ G_TYPE_INVALID);
+ if (! res) {
+ g_warning ("unable to determine sessions for user: %s",
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ for (i = 0; i < sessions->len; i++) {
+ char *ssid;
+
+ ssid = g_ptr_array_index (sessions, i);
+
+ if (! x11_session_is_on_seat (slave, ssid, slave->priv->display_seat_id)) {
+ goto next;
+ }
+
+ /* FIXME: better way to choose? */
+ if (primary_ssid == NULL) {
+ primary_ssid = g_strdup (ssid);
+ }
+
+ next:
+ g_free (ssid);
+ }
+ g_ptr_array_free (sessions, TRUE);
+
+ out:
+
+ if (seat_proxy != NULL) {
+ g_object_unref (seat_proxy);
+ }
+ if (manager_proxy != NULL) {
+ g_object_unref (manager_proxy);
+ }
+
+ return primary_ssid;
+}
+
+static gboolean
+activate_session_id (GdmSlave *slave,
+ const char *seat_id,
+ const char *session_id)
+{
+ DBusError local_error;
+ DBusMessage *message;
+ DBusMessage *reply;
+ gboolean ret;
+
+ ret = FALSE;
+
+ dbus_error_init (&local_error);
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ seat_id,
+ "org.freedesktop.ConsoleKit.Seat",
+ "ActivateSession");
+ if (message == NULL) {
+ goto out;
+ }
+
+ if (! dbus_message_append_args (message,
+ DBUS_TYPE_OBJECT_PATH, &session_id,
+ DBUS_TYPE_INVALID)) {
+ goto out;
+ }
+
+
+ dbus_error_init (&local_error);
+ reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (slave->priv->connection),
+ message,
+ -1,
+ &local_error);
+ if (reply == NULL) {
+ if (dbus_error_is_set (&local_error)) {
+ g_warning ("Unable to activate session: %s", local_error.message);
+ dbus_error_free (&local_error);
+ goto out;
+ }
+ }
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+gboolean
+gdm_slave_switch_to_user_session (GdmSlave *slave,
+ const char *username)
+{
+ gboolean res;
+ gboolean ret;
+ char *ssid_to_activate;
+
+ ret = FALSE;
+
+ ssid_to_activate = _get_primary_user_session_id (slave, username);
+ if (ssid_to_activate == NULL) {
+ g_debug ("GdmSlave: unable to determine session to activate");
+ goto out;
+ }
+
+ g_debug ("GdmSlave: Activating session: '%s'", ssid_to_activate);
+
+ res = activate_session_id (slave, slave->priv->display_seat_id, ssid_to_activate);
+ if (! res) {
+ g_debug ("GdmSlave: unable to activate session: %s", ssid_to_activate);
+ goto out;
+ }
+
+ ret = TRUE;
+
+ out:
+ g_free (ssid_to_activate);
+
+ return ret;
+}
+
static void
_gdm_slave_set_display_id (GdmSlave *slave,
const char *id)
@@ -690,6 +1030,14 @@
}
static void
+_gdm_slave_set_display_seat_id (GdmSlave *slave,
+ const char *id)
+{
+ g_free (slave->priv->display_seat_id);
+ slave->priv->display_seat_id = g_strdup (id);
+}
+
+static void
_gdm_slave_set_display_is_local (GdmSlave *slave,
gboolean is)
{
@@ -719,6 +1067,9 @@
case PROP_DISPLAY_HOSTNAME:
_gdm_slave_set_display_hostname (self, g_value_get_string (value));
break;
+ case PROP_DISPLAY_SEAT_ID:
+ _gdm_slave_set_display_seat_id (self, g_value_get_string (value));
+ break;
case PROP_DISPLAY_X11_AUTHORITY_FILE:
_gdm_slave_set_display_x11_authority_file (self, g_value_get_string (value));
break;
@@ -754,6 +1105,9 @@
case PROP_DISPLAY_HOSTNAME:
g_value_set_string (value, self->priv->display_hostname);
break;
+ case PROP_DISPLAY_SEAT_ID:
+ g_value_set_string (value, self->priv->display_seat_id);
+ break;
case PROP_DISPLAY_X11_AUTHORITY_FILE:
g_value_set_string (value, self->priv->display_x11_authority_file);
break;
@@ -864,6 +1218,13 @@
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
+ PROP_DISPLAY_SEAT_ID,
+ g_param_spec_string ("display-seat-id",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class,
PROP_DISPLAY_X11_AUTHORITY_FILE,
g_param_spec_string ("display-x11-authority-file",
"",
Modified: trunk/daemon/gdm-slave.h
==============================================================================
--- trunk/daemon/gdm-slave.h (original)
+++ trunk/daemon/gdm-slave.h Mon Jan 28 21:28:43 2008
@@ -60,6 +60,10 @@
gboolean gdm_slave_add_user_authorization (GdmSlave *slave,
const char *username,
char **filename);
+
+gboolean gdm_slave_switch_to_user_session (GdmSlave *slave,
+ const char *username);
+
gboolean gdm_slave_connect_to_x11_display (GdmSlave *slave);
void gdm_slave_set_busy_cursor (GdmSlave *slave);
gboolean gdm_slave_run_script (GdmSlave *slave,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]