diff options
author | Ray Strode <rstrode@redhat.com> | 2012-07-09 21:17:25 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2012-07-13 15:25:41 -0400 |
commit | 11bc17e07f673d2b27b8153d8c46d5ec26582208 (patch) | |
tree | 5405be3aa5c0c4eda7b720dc59cb627fcbb4761b | |
parent | e8ab501afbb3cf4ac418775587847959150d84d7 (diff) | |
download | gdm-11bc17e07f673d2b27b8153d8c46d5ec26582208.tar.gz |
daemon: drop display-id arg to GdmSessionDirect
It's not used anywhere, and so there's no reason to pass it along.
-rw-r--r-- | daemon/Makefile.am | 11 | ||||
-rw-r--r-- | daemon/gdm-session-direct.c | 3105 | ||||
-rw-r--r-- | daemon/gdm-session-direct.h | 66 | ||||
-rw-r--r-- | daemon/gdm-session.c | 3537 | ||||
-rw-r--r-- | daemon/gdm-session.h | 197 | ||||
-rw-r--r-- | daemon/gdm-simple-slave.c | 38 | ||||
-rw-r--r-- | daemon/gdm-welcome-session.c | 14 | ||||
-rw-r--r-- | daemon/test-session.c | 31 | ||||
-rw-r--r-- | po/POTFILES.in | 2 |
9 files changed, 3305 insertions, 3696 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 7bb68f22..6116ebe8 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -67,9 +67,6 @@ test_session_SOURCES = \ test-session.c \ gdm-session.c \ gdm-session.h \ - gdm-session-private.h \ - gdm-session-direct.c \ - gdm-session-direct.h \ gdm-session-record.c \ gdm-session-record.h \ gdm-session-worker-job.c\ @@ -107,9 +104,6 @@ gdm_simple_slave_SOURCES = \ gdm-server.h \ gdm-session.c \ gdm-session.h \ - gdm-session-private.h \ - gdm-session-direct.c \ - gdm-session-direct.h \ gdm-session-record.c \ gdm-session-record.h \ gdm-session-worker-job.c \ @@ -141,9 +135,6 @@ gdm_xdmcp_chooser_slave_SOURCES = \ gdm-chooser-server.h \ gdm-session.c \ gdm-session.h \ - gdm-session-direct.c \ - gdm-session-direct.h \ - gdm-session-private.h \ gdm-session-record.c \ gdm-session-record.h \ gdm-session-worker-job.c \ @@ -286,7 +277,7 @@ EXTRA_DIST = \ gdm-slave.xml \ gdm-simple-slave.xml \ gdm-xdmcp-chooser-slave.xml \ - gdm-session-direct.xml \ + gdm-session.xml \ gdm-manager.xml \ gdm-display.xml \ gdm-xdmcp-greeter-display.xml \ diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c deleted file mode 100644 index 579da945..00000000 --- a/daemon/gdm-session-direct.c +++ /dev/null @@ -1,3105 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2006 Ray Strode <rstrode@redhat.com> - * Copyright (C) 2007 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, 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 <dirent.h> -#include <errno.h> -#include <fcntl.h> - -#include <stdlib.h> -#include <string.h> -#include <sys/resource.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#include <pwd.h> -#include <grp.h> - -#include <locale.h> - -#include <glib.h> -#include <glib/gi18n.h> -#include <glib/gstdio.h> -#include <glib-object.h> - -#ifdef HAVE_LIBXKLAVIER -#include <libxklavier/xklavier.h> -#include <X11/Xlib.h> /* for Display */ -#endif - -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-lowlevel.h> - -#include "gdm-session-direct.h" -#include "gdm-session.h" -#include "gdm-session-private.h" - -#include "gdm-session-record.h" -#include "gdm-session-worker-job.h" -#include "gdm-common.h" - -#define GDM_SESSION_DBUS_PATH "/org/gnome/DisplayManager/Session" -#define GDM_SESSION_DBUS_INTERFACE "org.gnome.DisplayManager.Session" -#define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel" - -#ifndef GDM_SESSION_DEFAULT_PATH -#define GDM_SESSION_DEFAULT_PATH "/usr/local/bin:/usr/bin:/bin" -#endif - -typedef struct -{ - GdmSessionDirect *session; - GdmSessionWorkerJob *job; - GPid worker_pid; - char *service_name; - DBusConnection *worker_connection; - DBusMessage *message_pending_reply; - guint32 is_stopping : 1; -} GdmSessionConversation; - -struct _GdmSessionDirectPrivate -{ - /* per open scope */ - char *selected_program; - char *selected_session; - char *saved_session; - char *selected_language; - char *saved_language; - char *selected_user; - char *user_x11_authority_file; - - GHashTable *conversations; - - GdmSessionConversation *session_conversation; - - GList *pending_connections; - - GPid session_pid; - - /* object lifetime scope */ - char *display_id; - char *display_name; - char *display_hostname; - char *display_device; - char *display_seat_id; - char *display_x11_authority_file; - gboolean display_is_local; - - char *fallback_session_name; - - DBusServer *server; - char *server_address; - GHashTable *environment; - DBusGConnection *connection; -}; - -enum { - PROP_0, - PROP_DISPLAY_ID, - PROP_DISPLAY_NAME, - PROP_DISPLAY_HOSTNAME, - PROP_DISPLAY_IS_LOCAL, - PROP_DISPLAY_DEVICE, - PROP_DISPLAY_SEAT_ID, - PROP_DISPLAY_X11_AUTHORITY_FILE, - PROP_USER_X11_AUTHORITY_FILE, -}; - -static void gdm_session_iface_init (GdmSessionIface *iface); - -G_DEFINE_TYPE_WITH_CODE (GdmSessionDirect, - gdm_session_direct, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (GDM_TYPE_SESSION, - gdm_session_iface_init)) - -static gboolean -send_dbus_message (GdmSessionConversation *conversation, - DBusMessage *message) -{ - gboolean is_connected; - gboolean sent; - - g_return_val_if_fail (message != NULL, FALSE); - - if (conversation->worker_connection == NULL) { - g_warning ("There is no valid connection"); - return FALSE; - } - - is_connected = dbus_connection_get_is_connected (conversation->worker_connection); - if (! is_connected) { - g_warning ("Not connected!"); - return FALSE; - } - - sent = dbus_connection_send (conversation->worker_connection, message, NULL); - - return sent; -} - -static void -send_dbus_string_signal (GdmSessionConversation *conversation, - const char *name, - const char *text) -{ - DBusMessage *message; - DBusMessageIter iter; - - g_return_if_fail (conversation != NULL); - - message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, - GDM_SESSION_DBUS_INTERFACE, - name); - - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &text); - - if (! send_dbus_message (conversation, message)) { - g_debug ("GdmSessionDirect: Could not send %s signal", - name ? name : "(null)"); - } - - dbus_message_unref (message); -} - -static void -send_dbus_void_signal (GdmSessionConversation *conversation, - const char *name) -{ - DBusMessage *message; - - g_return_if_fail (conversation != NULL); - - message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, - GDM_SESSION_DBUS_INTERFACE, - name); - - if (! send_dbus_message (conversation, message)) { - g_debug ("GdmSessionDirect: Could not send %s signal", name); - } - - dbus_message_unref (message); -} - -static GdmSessionConversation * -find_conversation_by_name (GdmSessionDirect *session, - const char *service_name) -{ - GdmSessionConversation *conversation; - - conversation = g_hash_table_lookup (session->priv->conversations, service_name); - - if (conversation == NULL) { - g_warning ("Tried to look up non-existent conversation %s", service_name); - } - - return conversation; -} - -static void -on_authentication_failed (GdmSession *session, - const char *service_name, - const char *message) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GdmSessionConversation *conversation; - - conversation = find_conversation_by_name (impl, service_name); - if (conversation != NULL) { - gdm_session_record_failed (conversation->worker_pid, - impl->priv->selected_user, - impl->priv->display_hostname, - impl->priv->display_name, - impl->priv->display_device); - } -} - -static void -on_session_started (GdmSession *session, - const char *service_name) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GdmSessionConversation *conversation; - - conversation = find_conversation_by_name (impl, service_name); - if (conversation != NULL) { - gdm_session_record_login (conversation->worker_pid, - impl->priv->selected_user, - impl->priv->display_hostname, - impl->priv->display_name, - impl->priv->display_device); - } -} - -static void -on_session_start_failed (GdmSession *session, - const char *service_name, - const char *message) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GdmSessionConversation *conversation; - - conversation = find_conversation_by_name (impl, service_name); - if (conversation != NULL) { - gdm_session_record_login (conversation->worker_pid, - impl->priv->selected_user, - impl->priv->display_hostname, - impl->priv->display_name, - impl->priv->display_device); - } -} - -static void -on_session_exited (GdmSession *session, - int exit_code) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - - gdm_session_record_logout (impl->priv->session_pid, - impl->priv->selected_user, - impl->priv->display_hostname, - impl->priv->display_name, - impl->priv->display_device); -} - -static DBusHandlerResult -gdm_session_direct_handle_service_unavailable (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - - g_debug ("GdmSessionDirect: Emitting 'service-unavailable' signal"); - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - _gdm_session_service_unavailable (GDM_SESSION (session), conversation->service_name); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_setup_complete (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - - g_debug ("GdmSessionDirect: Emitting 'setup-complete' signal"); - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - _gdm_session_setup_complete (GDM_SESSION (session), conversation->service_name); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_setup_failed (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'setup-failed' signal"); - - _gdm_session_setup_failed (GDM_SESSION (session), conversation->service_name, text); - - return DBUS_HANDLER_RESULT_HANDLED; -} - - -static DBusHandlerResult -gdm_session_direct_handle_reset_complete (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - - g_debug ("GdmSessionDirect: Emitting 'reset-complete' signal"); - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - _gdm_session_reset_complete (GDM_SESSION (session)); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_reset_failed (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'reset-failed' signal"); - - _gdm_session_reset_failed (GDM_SESSION (session), text); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_authenticated (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - - g_debug ("GdmSessionDirect: Emitting 'authenticated' signal"); - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - _gdm_session_authenticated (GDM_SESSION (session), conversation->service_name); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_authentication_failed (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'authentication-failed' signal"); - - _gdm_session_authentication_failed (GDM_SESSION (session), conversation->service_name, text); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_authorized (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - - g_debug ("GdmSessionDirect: Emitting 'authorized' signal"); - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - _gdm_session_authorized (GDM_SESSION (session), conversation->service_name); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_authorization_failed (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'authorization-failed' signal"); - - _gdm_session_authorization_failed (GDM_SESSION (session), conversation->service_name, text); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_accredited (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - - g_debug ("GdmSessionDirect: Emitting 'accredited' signal"); - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - _gdm_session_accredited (GDM_SESSION (session), conversation->service_name); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_accreditation_failed (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'accreditation-failed' signal"); - - _gdm_session_accreditation_failed (GDM_SESSION (session), conversation->service_name, text); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static const char ** -get_system_session_dirs (void) -{ - static const char *search_dirs[] = { - "/etc/X11/sessions/", - DMCONFDIR "/Sessions/", - DATADIR "/xsessions/", - DATADIR "/gdm/BuiltInSessions/", - NULL - }; - - return search_dirs; -} - -static gboolean -is_prog_in_path (const char *prog) -{ - char *f; - gboolean ret; - - f = g_find_program_in_path (prog); - ret = (f != NULL); - g_free (f); - return ret; -} - -static gboolean -get_session_command_for_file (const char *file, - char **command) -{ - GKeyFile *key_file; - GError *error; - char *exec; - gboolean ret; - gboolean res; - - exec = NULL; - ret = FALSE; - if (command != NULL) { - *command = NULL; - } - - key_file = g_key_file_new (); - - g_debug ("GdmSessionDirect: looking for session file '%s'", file); - - error = NULL; - res = g_key_file_load_from_dirs (key_file, - file, - get_system_session_dirs (), - NULL, - G_KEY_FILE_NONE, - &error); - if (! res) { - g_debug ("GdmSessionDirect: File '%s' not found: %s", file, error->message); - g_error_free (error); - if (command != NULL) { - *command = NULL; - } - goto out; - } - - error = NULL; - res = g_key_file_get_boolean (key_file, - G_KEY_FILE_DESKTOP_GROUP, - G_KEY_FILE_DESKTOP_KEY_HIDDEN, - &error); - if (error == NULL && res) { - g_debug ("GdmSessionDirect: Session %s is marked as hidden", file); - goto out; - } - - exec = g_key_file_get_string (key_file, - G_KEY_FILE_DESKTOP_GROUP, - G_KEY_FILE_DESKTOP_KEY_TRY_EXEC, - NULL); - if (exec != NULL) { - res = is_prog_in_path (exec); - g_free (exec); - exec = NULL; - - if (! res) { - g_debug ("GdmSessionDirect: Command not found: %s", - G_KEY_FILE_DESKTOP_KEY_TRY_EXEC); - goto out; - } - } - - error = NULL; - exec = g_key_file_get_string (key_file, - G_KEY_FILE_DESKTOP_GROUP, - G_KEY_FILE_DESKTOP_KEY_EXEC, - &error); - if (error != NULL) { - g_debug ("GdmSessionDirect: %s key not found: %s", - G_KEY_FILE_DESKTOP_KEY_EXEC, - error->message); - g_error_free (error); - goto out; - } - - if (command != NULL) { - *command = g_strdup (exec); - } - ret = TRUE; - -out: - g_free (exec); - - return ret; -} - -static gboolean -get_session_command_for_name (const char *name, - char **command) -{ - gboolean res; - char *filename; - - filename = g_strdup_printf ("%s.desktop", name); - res = get_session_command_for_file (filename, command); - g_free (filename); - - /* - * The GDM Xsession script honors "custom" as a valid session. If the - * session is one of these, no file is needed, then just run the - * command as "custom". - */ - if (!res && strcmp (name, GDM_CUSTOM_SESSION) == 0) { - g_debug ("No custom desktop file, but accepting it anyway."); - if (command != NULL) { - *command = g_strdup (GDM_CUSTOM_SESSION); - } - res = TRUE; - } - - return res; -} - -static const char * -get_default_language_name (GdmSessionDirect *session) -{ - if (session->priv->saved_language != NULL) { - return session->priv->saved_language; - } - - return setlocale (LC_MESSAGES, NULL); -} - -static const char * -get_fallback_session_name (GdmSessionDirect *session_direct) -{ - const char **search_dirs; - int i; - char *name; - GSequence *sessions; - GSequenceIter *session; - - if (session_direct->priv->fallback_session_name != NULL) { - /* verify that the cached version still exists */ - if (get_session_command_for_name (session_direct->priv->fallback_session_name, NULL)) { - goto out; - } - } - - name = g_strdup ("gnome"); - if (get_session_command_for_name (name, NULL)) { - g_free (session_direct->priv->fallback_session_name); - session_direct->priv->fallback_session_name = name; - goto out; - } - g_free (name); - - sessions = g_sequence_new (g_free); - - search_dirs = get_system_session_dirs (); - for (i = 0; search_dirs[i] != NULL; i++) { - GDir *dir; - const char *base_name; - - dir = g_dir_open (search_dirs[i], 0, NULL); - - if (dir == NULL) { - continue; - } - - do { - base_name = g_dir_read_name (dir); - - if (base_name == NULL) { - break; - } - - if (!g_str_has_suffix (base_name, ".desktop")) { - continue; - } - - if (get_session_command_for_file (base_name, NULL)) { - - g_sequence_insert_sorted (sessions, g_strdup (base_name), (GCompareDataFunc) g_strcmp0, NULL); - } - } while (base_name != NULL); - - g_dir_close (dir); - } - - name = NULL; - session = g_sequence_get_begin_iter (sessions); - do { - if (g_sequence_get (session)) { - char *base_name; - - g_free (name); - base_name = g_sequence_get (session); - name = g_strndup (base_name, - strlen (base_name) - - strlen (".desktop")); - - break; - } - session = g_sequence_iter_next (session); - } while (!g_sequence_iter_is_end (session)); - - g_free (session_direct->priv->fallback_session_name); - session_direct->priv->fallback_session_name = name; - - g_sequence_free (sessions); - - out: - return session_direct->priv->fallback_session_name; -} - -static const char * -get_default_session_name (GdmSessionDirect *session) -{ - if (session->priv->saved_session != NULL) { - return session->priv->saved_session; - } - - return get_fallback_session_name (session); -} - -static void -gdm_session_direct_defaults_changed (GdmSessionDirect *session) -{ - _gdm_session_default_language_name_changed (GDM_SESSION (session), - get_default_language_name (session)); - _gdm_session_default_session_name_changed (GDM_SESSION (session), - get_default_session_name (session)); -} - -static void -gdm_session_direct_select_user (GdmSession *session, - const char *text) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - - g_debug ("GdmSessionDirect: Setting user: '%s'", text); - - g_free (impl->priv->selected_user); - impl->priv->selected_user = g_strdup (text); - - g_free (impl->priv->saved_session); - impl->priv->saved_session = NULL; - - g_free (impl->priv->saved_language); - impl->priv->saved_language = NULL; -} - -static DBusHandlerResult -gdm_session_direct_handle_username_changed (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: changing username from '%s' to '%s'", - session->priv->selected_user != NULL ? session->priv->selected_user : "<unset>", - (strlen (text)) ? text : "<unset>"); - - gdm_session_direct_select_user (GDM_SESSION (session), (strlen (text) > 0) ? g_strdup (text) : NULL); - - _gdm_session_selected_user_changed (GDM_SESSION (session), session->priv->selected_user); - - gdm_session_direct_defaults_changed (session); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static void -cancel_pending_query (GdmSessionConversation *conversation) -{ - DBusMessage *reply; - - if (conversation->message_pending_reply == NULL) { - return; - } - - g_debug ("GdmSessionDirect: Cancelling pending query"); - - reply = dbus_message_new_error (conversation->message_pending_reply, - GDM_SESSION_DBUS_ERROR_CANCEL, - "Operation cancelled"); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_connection_flush (conversation->worker_connection); - - dbus_message_unref (reply); - dbus_message_unref (conversation->message_pending_reply); - conversation->message_pending_reply = NULL; -} - -static void -answer_pending_query (GdmSessionConversation *conversation, - const char *answer) -{ - DBusMessage *reply; - DBusMessageIter iter; - - reply = dbus_message_new_method_return (conversation->message_pending_reply); - dbus_message_iter_init_append (reply, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &answer); - - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - dbus_message_unref (conversation->message_pending_reply); - conversation->message_pending_reply = NULL; -} - -static void -set_pending_query (GdmSessionConversation *conversation, - DBusMessage *message) -{ - g_assert (conversation->message_pending_reply == NULL); - - conversation->message_pending_reply = dbus_message_ref (message); -} - -static DBusHandlerResult -gdm_session_direct_handle_info_query (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - set_pending_query (conversation, message); - - g_debug ("GdmSessionDirect: Emitting 'info-query' signal"); - _gdm_session_info_query (GDM_SESSION (session), conversation->service_name, text); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_secret_info_query (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - set_pending_query (conversation, message); - - g_debug ("GdmSessionDirect: Emitting 'secret-info-query' signal"); - _gdm_session_secret_info_query (GDM_SESSION (session), conversation->service_name, text); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_info (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'info' signal"); - _gdm_session_info (GDM_SESSION (session), conversation->service_name, text); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_cancel_pending_query (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - - g_debug ("GdmSessionDirect: worker cancelling pending query"); - - cancel_pending_query (conversation); - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_problem (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'problem' signal"); - _gdm_session_problem (GDM_SESSION (session), conversation->service_name, text); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_session_opened (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - - g_debug ("GdmSessionDirect: Handling SessionOpened"); - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - g_debug ("GdmSessionDirect: Emitting 'session-opened' signal"); - - _gdm_session_session_opened (GDM_SESSION (session), conversation->service_name); - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_open_failed (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'session-open-failed' signal"); - _gdm_session_session_open_failed (GDM_SESSION (session), conversation->service_name, text); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_session_started (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - int pid; - - pid = 0; - - g_debug ("GdmSessionDirect: Handling SessionStarted"); - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_INT32, &pid, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'session-started' signal with pid '%d'", - pid); - - session->priv->session_pid = pid; - session->priv->session_conversation = conversation; - - _gdm_session_session_started (GDM_SESSION (session), conversation->service_name, pid); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_start_failed (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *text; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &text, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'session-start-failed' signal"); - _gdm_session_session_start_failed (GDM_SESSION (session), conversation->service_name, text); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_session_exited (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - int code; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_INT32, &code, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'session-exited' signal with exit code '%d'", - code); - - session->priv->session_conversation = NULL; - _gdm_session_session_exited (GDM_SESSION (session), code); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_session_died (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - int code; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_INT32, &code, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - g_debug ("GdmSessionDirect: Emitting 'session-died' signal with signal number '%d'", - code); - - session->priv->session_conversation = NULL; - _gdm_session_session_died (GDM_SESSION (session), code); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_saved_language_name_read (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *language_name; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &language_name, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - if (strcmp (language_name, - get_default_language_name (session)) != 0) { - g_free (session->priv->saved_language); - session->priv->saved_language = g_strdup (language_name); - - _gdm_session_default_language_name_changed (GDM_SESSION (session), - language_name); - } - - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -gdm_session_direct_handle_saved_session_name_read (GdmSessionDirect *session, - GdmSessionConversation *conversation, - DBusMessage *message) -{ - DBusMessage *reply; - DBusError error; - const char *session_name; - - dbus_error_init (&error); - if (! dbus_message_get_args (message, &error, - DBUS_TYPE_STRING, &session_name, - DBUS_TYPE_INVALID)) { - g_warning ("ERROR: %s", error.message); - } - - reply = dbus_message_new_method_return (message); - dbus_connection_send (conversation->worker_connection, reply, NULL); - dbus_message_unref (reply); - - if (! get_session_command_for_name (session_name, NULL)) { - /* ignore sessions that don't exist */ - g_debug ("GdmSessionDirect: not using invalid .dmrc session: %s", session_name); - g_free (session->priv->saved_session); - session->priv->saved_session = NULL; - goto out; - } - - if (strcmp (session_name, - get_default_session_name (session)) != 0) { - g_free (session->priv->saved_session); - session->priv->saved_session = g_strdup (session_name); - - _gdm_session_default_session_name_changed (GDM_SESSION (session), - session_name); - } - out: - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -session_worker_message (DBusConnection *connection, - DBusMessage *message, - void *user_data) -{ - GdmSessionConversation *conversation = user_data; - GdmSessionDirect *session; - - session = conversation->session; - - if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "InfoQuery")) { - return gdm_session_direct_handle_info_query (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SecretInfoQuery")) { - return gdm_session_direct_handle_secret_info_query (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Info")) { - return gdm_session_direct_handle_info (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Problem")) { - return gdm_session_direct_handle_problem (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "CancelPendingQuery")) { - return gdm_session_direct_handle_cancel_pending_query (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "ServiceUnavailable")) { - return gdm_session_direct_handle_service_unavailable (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SetupComplete")) { - return gdm_session_direct_handle_setup_complete (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SetupFailed")) { - return gdm_session_direct_handle_setup_failed (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "ResetComplete")) { - return gdm_session_direct_handle_reset_complete (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "ResetFailed")) { - return gdm_session_direct_handle_reset_failed (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Authenticated")) { - return gdm_session_direct_handle_authenticated (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AuthenticationFailed")) { - return gdm_session_direct_handle_authentication_failed (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Authorized")) { - return gdm_session_direct_handle_authorized (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AuthorizationFailed")) { - return gdm_session_direct_handle_authorization_failed (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Accredited")) { - return gdm_session_direct_handle_accredited (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AccreditationFailed")) { - return gdm_session_direct_handle_accreditation_failed (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "UsernameChanged")) { - return gdm_session_direct_handle_username_changed (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionOpened")) { - return gdm_session_direct_handle_session_opened (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "OpenFailed")) { - return gdm_session_direct_handle_open_failed (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionStarted")) { - return gdm_session_direct_handle_session_started (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "StartFailed")) { - return gdm_session_direct_handle_start_failed (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionExited")) { - return gdm_session_direct_handle_session_exited (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionDied")) { - return gdm_session_direct_handle_session_died (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedLanguageNameRead")) { - return gdm_session_direct_handle_saved_language_name_read (session, conversation, message); - } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedSessionNameRead")) { - return gdm_session_direct_handle_saved_session_name_read (session, conversation, message); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult -do_introspect (DBusConnection *connection, - DBusMessage *message) -{ - DBusMessage *reply; - GString *xml; - char *xml_string; - - g_debug ("GdmSessionDirect: Do introspect"); - - /* standard header */ - xml = g_string_new ("<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" - "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n" - "<node>\n" - " <interface name=\"org.freedesktop.DBus.Introspectable\">\n" - " <method name=\"Introspect\">\n" - " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n" - " </method>\n" - " </interface>\n"); - - /* interface */ - xml = g_string_append (xml, - " <interface name=\"org.gnome.DisplayManager.Session\">\n" - " <method name=\"SetupComplete\">\n" - " </method>\n" - " <method name=\"SetupFailed\">\n" - " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" - " </method>\n" - " <method name=\"ResetComplete\">\n" - " </method>\n" - " <method name=\"ResetFailed\">\n" - " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" - " </method>\n" - " <method name=\"Authenticated\">\n" - " </method>\n" - " <method name=\"AuthenticationFailed\">\n" - " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" - " </method>\n" - " <method name=\"Authorized\">\n" - " </method>\n" - " <method name=\"AuthorizationFailed\">\n" - " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" - " </method>\n" - " <method name=\"Accredited\">\n" - " </method>\n" - " <method name=\"AccreditationFailed\">\n" - " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" - " </method>\n" - " <method name=\"CancelPendingQuery\">\n" - " </method>\n" - " <method name=\"InfoQuery\">\n" - " <arg name=\"query\" direction=\"in\" type=\"s\"/>\n" - " <arg name=\"answer\" direction=\"out\" type=\"s\"/>\n" - " </method>\n" - " <method name=\"SecretInfoQuery\">\n" - " <arg name=\"query\" direction=\"in\" type=\"s\"/>\n" - " <arg name=\"answer\" direction=\"out\" type=\"s\"/>\n" - " </method>\n" - " <method name=\"Info\">\n" - " <arg name=\"text\" direction=\"in\" type=\"s\"/>\n" - " </method>\n" - " <method name=\"Problem\">\n" - " <arg name=\"text\" direction=\"in\" type=\"s\"/>\n" - " </method>\n" - " <method name=\"UsernameChanged\">\n" - " <arg name=\"text\" direction=\"in\" type=\"s\"/>\n" - " </method>\n" - " <method name=\"StartFailed\">\n" - " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" - " </method>\n" - " <method name=\"SessionStarted\">\n" - " <arg name=\"pid\" direction=\"in\" type=\"i\"/>\n" - " <arg name=\"environment\" direction=\"in\" type=\"as\"/>\n" - " </method>\n" - " <method name=\"SessionExited\">\n" - " <arg name=\"code\" direction=\"in\" type=\"i\"/>\n" - " </method>\n" - " <method name=\"SessionDied\">\n" - " <arg name=\"signal\" direction=\"in\" type=\"i\"/>\n" - " </method>\n" - " <signal name=\"Reset\">\n" - " </signal>\n" - " <signal name=\"Setup\">\n" - " <arg name=\"service_name\" type=\"s\"/>\n" - " <arg name=\"x11_display_name\" type=\"s\"/>\n" - " <arg name=\"display_device\" type=\"s\"/>\n" - " <arg name=\"display_seat\" type=\"s\"/>\n" - " <arg name=\"hostname\" type=\"s\"/>\n" - " <arg name=\"x11_authority_file\" type=\"s\"/>\n" - " </signal>\n" - " <signal name=\"SetupForUser\">\n" - " <arg name=\"service_name\" type=\"s\"/>\n" - " <arg name=\"x11_display_name\" type=\"s\"/>\n" - " <arg name=\"display_device\" type=\"s\"/>\n" - " <arg name=\"display_seat\" type=\"s\"/>\n" - " <arg name=\"hostname\" type=\"s\"/>\n" - " <arg name=\"x11_authority_file\" type=\"s\"/>\n" - " <arg name=\"username\" type=\"s\"/>\n" - " </signal>\n" - " <signal name=\"SetupForProgram\">\n" - " <arg name=\"service_name\" type=\"s\"/>\n" - " <arg name=\"x11_display_name\" type=\"s\"/>\n" - " <arg name=\"display_device\" type=\"s\"/>\n" - " <arg name=\"display_seat\" type=\"s\"/>\n" - " <arg name=\"hostname\" type=\"s\"/>\n" - " <arg name=\"x11_authority_file\" type=\"s\"/>\n" - " <arg name=\"log_file\" type=\"s\"/>\n" - " </signal>\n" - " <signal name=\"Authenticate\">\n" - " </signal>\n" - " <signal name=\"Authorize\">\n" - " </signal>\n" - " <signal name=\"EstablishCredentials\">\n" - " </signal>\n" - " <signal name=\"RefreshCredentials\">\n" - " </signal>\n" - " <signal name=\"SetEnvironmentVariable\">\n" - " <arg name=\"name\" type=\"s\"/>\n" - " <arg name=\"value\" type=\"s\"/>\n" - " </signal>\n" - " <signal name=\"SetLanguageName\">\n" - " <arg name=\"language_name\" type=\"s\"/>\n" - " </signal>\n" - " <signal name=\"SetSessionName\">\n" - " <arg name=\"session_name\" type=\"s\"/>\n" - " </signal>\n" - " <signal name=\"SetSessionType\">\n" - " <arg name=\"session_type\" type=\"s\"/>\n" - " </signal>\n" - " <signal name=\"StartProgram\">\n" - " <arg name=\"command\" type=\"s\"/>\n" - " </signal>\n" - " </interface>\n"); - - reply = dbus_message_new_method_return (message); - - xml = g_string_append (xml, "</node>\n"); - xml_string = g_string_free (xml, FALSE); - - dbus_message_append_args (reply, - DBUS_TYPE_STRING, &xml_string, - DBUS_TYPE_INVALID); - - g_free (xml_string); - - if (reply == NULL) { - g_error ("No memory"); - } - - if (! dbus_connection_send (connection, reply, NULL)) { - g_error ("No memory"); - } - - dbus_message_unref (reply); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult -session_message_handler (DBusConnection *connection, - DBusMessage *message, - void *user_data) -{ - const char *dbus_destination = dbus_message_get_destination (message); - const char *dbus_path = dbus_message_get_path (message); - const char *dbus_interface = dbus_message_get_interface (message); - const char *dbus_member = dbus_message_get_member (message); - - g_debug ("session_message_handler: destination=%s obj_path=%s interface=%s method=%s", - dbus_destination ? dbus_destination : "(null)", - dbus_path ? dbus_path : "(null)", - dbus_interface ? dbus_interface : "(null)", - dbus_member ? dbus_member : "(null)"); - - if (dbus_message_is_method_call (message, "org.freedesktop.DBus", "AddMatch")) { - DBusMessage *reply; - - reply = dbus_message_new_method_return (message); - - if (reply == NULL) { - g_error ("No memory"); - } - - if (! dbus_connection_send (connection, reply, NULL)) { - g_error ("No memory"); - } - - dbus_message_unref (reply); - - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") && - strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0) { - - g_debug ("GdmSessionDirect: Disconnected"); - - /*dbus_connection_unref (connection);*/ - - return DBUS_HANDLER_RESULT_HANDLED; - } else if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Introspectable", "Introspect")) { - return do_introspect (connection, message); - } else { - return session_worker_message (connection, message, user_data); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -/* Note: Use abstract sockets like dbus does by default on Linux. Abstract - * sockets are only available on Linux. - */ -static char * -generate_address (void) -{ - char *path; -#if defined (__linux__) - int i; - char tmp[9]; - - for (i = 0; i < 8; i++) { - if (g_random_int_range (0, 2) == 0) { - tmp[i] = g_random_int_range ('a', 'z' + 1); - } else { - tmp[i] = g_random_int_range ('A', 'Z' + 1); - } - } - tmp[8] = '\0'; - - path = g_strdup_printf ("unix:abstract=/tmp/gdm-session-%s", tmp); -#else - path = g_strdup ("unix:tmpdir=/tmp"); -#endif - - return path; -} - -static void -session_unregister_handler (DBusConnection *connection, - void *user_data) -{ - g_debug ("session_unregister_handler"); -} - -static GdmSessionConversation * -find_conversation_by_pid (GdmSessionDirect *session, - GPid pid) -{ - GHashTableIter iter; - gpointer key, value; - - g_hash_table_iter_init (&iter, session->priv->conversations); - while (g_hash_table_iter_next (&iter, &key, &value)) { - GdmSessionConversation *conversation; - - conversation = (GdmSessionConversation *) value; - - if (conversation->worker_pid == pid) { - return conversation; - } - } - - return NULL; -} - -static dbus_bool_t -allow_user_function (DBusConnection *connection, - unsigned long uid, - void *data) -{ - if (0 == uid) { - return TRUE; - } - - g_debug ("GdmSessionDirect: User not allowed"); - - return FALSE; -} - -static gboolean -register_worker (GdmSessionDirect *session, - DBusConnection *connection) -{ - GdmSessionConversation *conversation; - DBusObjectPathVTable vtable = { &session_unregister_handler, - &session_message_handler, - NULL, NULL, NULL, NULL }; - GList *connection_node; - gulong pid; - - g_debug ("GdmSessionDirect: Authenticating new connection"); - - connection_node = g_list_find (session->priv->pending_connections, connection); - - if (connection_node == NULL) { - g_debug ("GdmSessionDirect: Ignoring connection that we aren't tracking"); - return FALSE; - } - - session->priv->pending_connections = - g_list_delete_link (session->priv->pending_connections, - connection_node); - - if (!dbus_connection_get_unix_process_id (connection, &pid)) { - g_warning ("GdmSessionDirect: Unable to read pid on new worker connection"); - dbus_connection_unref (connection); - return FALSE; - } - - conversation = find_conversation_by_pid (session, (GPid) pid); - - if (conversation == NULL) { - g_warning ("GdmSessionDirect: New worker connection is from unknown source"); - dbus_connection_unref (connection); - return FALSE; - } - - conversation->worker_connection = connection; - - g_debug ("GdmSessionDirect: worker connection is %p", connection); - - dbus_connection_register_object_path (connection, - GDM_SESSION_DBUS_PATH, - &vtable, - conversation); - - g_debug ("GdmSessionDirect: Emitting conversation-started signal"); - _gdm_session_conversation_started (GDM_SESSION (session), - conversation->service_name); - - g_debug ("GdmSessionDirect: Conversation started"); - - return TRUE; -} - -static DBusHandlerResult -on_message (DBusConnection *connection, - DBusMessage *message, - void *user_data) -{ - GdmSessionDirect *session = GDM_SESSION_DIRECT (user_data); - - g_debug ("GdmSessionDirect: got message"); - - if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Hello")) { - DBusMessage *reply; - - if (register_worker (session, connection)) { - reply = dbus_message_new_method_return (message); - } else { - reply = dbus_message_new_error (message, DBUS_ERROR_FAILED, ""); - } - - dbus_connection_send (connection, reply, NULL); - return DBUS_HANDLER_RESULT_HANDLED; - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static void -handle_connection (DBusServer *server, - DBusConnection *new_connection, - void *user_data) -{ - GdmSessionDirect *session = GDM_SESSION_DIRECT (user_data); - g_debug ("GdmSessionDirect: Handing new connection"); - - /* add to the list of pending connections. We won't be able to - * associate it with a specific worker conversation until we have - * authenticated the connection (from the Hello handler). - */ - session->priv->pending_connections = - g_list_prepend (session->priv->pending_connections, - dbus_connection_ref (new_connection)); - dbus_connection_setup_with_g_main (new_connection, NULL); - dbus_connection_set_exit_on_disconnect (new_connection, FALSE); - - dbus_connection_set_unix_user_function (new_connection, - allow_user_function, - session, - NULL); - dbus_connection_add_filter (new_connection, on_message, session, NULL); -} - -static gboolean -setup_server (GdmSessionDirect *session) -{ - DBusError error; - gboolean ret; - char *address; - const char *auth_mechanisms[] = {"EXTERNAL", NULL}; - - ret = FALSE; - - g_debug ("GdmSessionDirect: Creating D-Bus server for session"); - - address = generate_address (); - - dbus_error_init (&error); - session->priv->server = dbus_server_listen (address, &error); - g_free (address); - - if (session->priv->server == NULL) { - g_warning ("Cannot create D-BUS server for the session: %s", error.message); - /* FIXME: should probably fail if we can't create the socket */ - goto out; - } - - dbus_server_setup_with_g_main (session->priv->server, NULL); - dbus_server_set_auth_mechanisms (session->priv->server, auth_mechanisms); - dbus_server_set_new_connection_function (session->priv->server, - handle_connection, - session, - NULL); - ret = TRUE; - - g_free (session->priv->server_address); - session->priv->server_address = dbus_server_get_address (session->priv->server); - - g_debug ("GdmSessionDirect: D-Bus server listening on %s", session->priv->server_address); - - out: - - return ret; -} - -static void -free_conversation (GdmSessionConversation *conversation) -{ - if (conversation->job != NULL) { - g_warning ("Freeing conversation '%s' with active job", conversation->service_name); - } - - g_free (conversation->service_name); - g_free (conversation); -} - -static void -gdm_session_direct_init (GdmSessionDirect *session) -{ - session->priv = G_TYPE_INSTANCE_GET_PRIVATE (session, - GDM_TYPE_SESSION_DIRECT, - GdmSessionDirectPrivate); - - g_signal_connect (session, - "authentication-failed", - G_CALLBACK (on_authentication_failed), - NULL); - g_signal_connect (session, - "session-started", - G_CALLBACK (on_session_started), - NULL); - g_signal_connect (session, - "session-start-failed", - G_CALLBACK (on_session_start_failed), - NULL); - g_signal_connect (session, - "session-exited", - G_CALLBACK (on_session_exited), - NULL); - - session->priv->conversations = g_hash_table_new_full (g_str_hash, - g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) - free_conversation); - session->priv->environment = g_hash_table_new_full (g_str_hash, - g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_free); - - setup_server (session); - -} - -static void -worker_started (GdmSessionWorkerJob *job, - GdmSessionConversation *conversation) -{ - g_debug ("GdmSessionDirect: Worker job started"); -} - -static void -worker_exited (GdmSessionWorkerJob *job, - int code, - GdmSessionConversation *conversation) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (conversation->session); - - g_debug ("GdmSessionDirect: Worker job exited: %d", code); - - g_object_ref (conversation->job); - if (conversation->session->priv->session_conversation == conversation) { - _gdm_session_session_exited (GDM_SESSION (conversation->session), code); - } - - g_hash_table_steal (impl->priv->conversations, conversation->service_name); - - g_debug ("GdmSessionDirect: Emitting conversation-stopped signal"); - _gdm_session_conversation_stopped (GDM_SESSION (conversation->session), - conversation->service_name); - g_object_unref (conversation->job); - - if (conversation->is_stopping) { - g_object_unref (conversation->job); - conversation->job = NULL; - } - - free_conversation (conversation); -} - -static void -worker_died (GdmSessionWorkerJob *job, - int signum, - GdmSessionConversation *conversation) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (conversation->session); - - g_debug ("GdmSessionDirect: Worker job died: %d", signum); - - g_object_ref (conversation->job); - if (conversation->session->priv->session_conversation == conversation) { - _gdm_session_session_died (GDM_SESSION (conversation->session), signum); - } - - g_hash_table_steal (impl->priv->conversations, conversation->service_name); - - g_debug ("GdmSessionDirect: Emitting conversation-stopped signal"); - _gdm_session_conversation_stopped (GDM_SESSION (conversation->session), - conversation->service_name); - g_object_unref (conversation->job); - - if (conversation->is_stopping) { - g_object_unref (conversation->job); - conversation->job = NULL; - } - - free_conversation (conversation); -} - -static GdmSessionConversation * -start_conversation (GdmSessionDirect *session, - const char *service_name) -{ - GdmSessionConversation *conversation; - char *job_name; - - conversation = g_new0 (GdmSessionConversation, 1); - conversation->session = session; - conversation->service_name = g_strdup (service_name); - conversation->worker_pid = -1; - conversation->job = gdm_session_worker_job_new (); - gdm_session_worker_job_set_server_address (conversation->job, session->priv->server_address); - g_signal_connect (conversation->job, - "started", - G_CALLBACK (worker_started), - conversation); - g_signal_connect (conversation->job, - "exited", - G_CALLBACK (worker_exited), - conversation); - g_signal_connect (conversation->job, - "died", - G_CALLBACK (worker_died), - conversation); - - job_name = g_strdup_printf ("gdm-session-worker [pam/%s]", service_name); - if (!gdm_session_worker_job_start (conversation->job, job_name)) { - g_object_unref (conversation->job); - g_free (conversation->service_name); - g_free (conversation); - g_free (job_name); - return NULL; - } - - g_free (job_name); - - conversation->worker_pid = gdm_session_worker_job_get_pid (conversation->job); - - return conversation; -} - -static void -stop_conversation (GdmSessionConversation *conversation) -{ - GdmSessionDirect *session; - - session = conversation->session; - - if (conversation->worker_connection != NULL) { - dbus_connection_remove_filter (conversation->worker_connection, on_message, session); - - dbus_connection_close (conversation->worker_connection); - conversation->worker_connection = NULL; - } - - conversation->is_stopping = TRUE; - gdm_session_worker_job_stop (conversation->job); -} - -static void -stop_conversation_now (GdmSessionConversation *conversation) -{ - GdmSessionDirect *session; - - session = conversation->session; - - if (conversation->worker_connection != NULL) { - dbus_connection_remove_filter (conversation->worker_connection, on_message, session); - - dbus_connection_close (conversation->worker_connection); - conversation->worker_connection = NULL; - } - - gdm_session_worker_job_stop_now (conversation->job); - g_object_unref (conversation->job); - conversation->job = NULL; -} - -static void -gdm_session_direct_start_conversation (GdmSession *session, - const char *service_name) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GdmSessionConversation *conversation; - - g_return_if_fail (session != NULL); - - conversation = g_hash_table_lookup (impl->priv->conversations, - service_name); - - if (conversation != NULL) { - if (!conversation->is_stopping) { - g_warning ("GdmSessionDirect: conversation %s started more than once", service_name); - return; - } - g_debug ("GdmSessionDirect: stopping old conversation %s", service_name); - gdm_session_worker_job_stop_now (conversation->job); - g_object_unref (conversation->job); - conversation->job = NULL; - } - - g_debug ("GdmSessionDirect: starting conversation %s", service_name); - - conversation = start_conversation (impl, service_name); - - g_hash_table_insert (impl->priv->conversations, - g_strdup (service_name), conversation); -} - -static void -gdm_session_direct_stop_conversation (GdmSession *session, - const char *service_name) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GdmSessionConversation *conversation; - - g_return_if_fail (session != NULL); - - g_debug ("GdmSessionDirect: stopping conversation %s", service_name); - - conversation = find_conversation_by_name (impl, service_name); - - if (conversation != NULL) { - stop_conversation (conversation); - } -} - -static void -send_setup (GdmSessionDirect *session, - const char *service_name) -{ - DBusMessage *message; - DBusMessageIter iter; - const char *display_name; - const char *display_device; - const char *display_seat_id; - const char *display_hostname; - const char *display_x11_authority_file; - GdmSessionConversation *conversation; - - g_assert (service_name != NULL); - - if (session->priv->display_name != NULL) { - display_name = session->priv->display_name; - } else { - display_name = ""; - } - if (session->priv->display_hostname != NULL) { - display_hostname = session->priv->display_hostname; - } else { - display_hostname = ""; - } - if (session->priv->display_device != NULL) { - display_device = session->priv->display_device; - } else { - display_device = ""; - } - if (session->priv->display_seat_id != NULL) { - display_seat_id = session->priv->display_seat_id; - } else { - display_seat_id = ""; - } - if (session->priv->display_x11_authority_file != NULL) { - display_x11_authority_file = session->priv->display_x11_authority_file; - } else { - display_x11_authority_file = ""; - } - - g_debug ("GdmSessionDirect: Beginning setup"); - - message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, - GDM_SESSION_DBUS_INTERFACE, - "Setup"); - - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file); - - conversation = find_conversation_by_name (session, service_name); - if (conversation != NULL && ! send_dbus_message (conversation, message)) { - g_debug ("GdmSessionDirect: Could not send %s signal", "Setup"); - } - - dbus_message_unref (message); -} - -static void -send_setup_for_user (GdmSessionDirect *session, - const char *service_name) -{ - DBusMessage *message; - DBusMessageIter iter; - const char *display_name; - const char *display_device; - const char *display_seat_id; - const char *display_hostname; - const char *display_x11_authority_file; - const char *selected_user; - GdmSessionConversation *conversation; - - g_assert (service_name != NULL); - - if (session->priv->display_name != NULL) { - display_name = session->priv->display_name; - } else { - display_name = ""; - } - if (session->priv->display_hostname != NULL) { - display_hostname = session->priv->display_hostname; - } else { - display_hostname = ""; - } - if (session->priv->display_device != NULL) { - display_device = session->priv->display_device; - } else { - display_device = ""; - } - if (session->priv->display_seat_id != NULL) { - display_seat_id = session->priv->display_seat_id; - } else { - display_seat_id = ""; - } - if (session->priv->display_x11_authority_file != NULL) { - display_x11_authority_file = session->priv->display_x11_authority_file; - } else { - display_x11_authority_file = ""; - } - if (session->priv->selected_user != NULL) { - selected_user = session->priv->selected_user; - } else { - selected_user = ""; - } - - g_debug ("GdmSessionDirect: Beginning setup for user %s", session->priv->selected_user); - - message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, - GDM_SESSION_DBUS_INTERFACE, - "SetupForUser"); - - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &selected_user); - - conversation = find_conversation_by_name (session, service_name); - if (conversation != NULL && ! send_dbus_message (conversation, message)) { - g_debug ("GdmSessionDirect: Could not send %s signal", "SetupForUser"); - } - - dbus_message_unref (message); -} - -static void -send_setup_for_program (GdmSessionDirect *session, - const char *service_name, - const char *log_file) -{ - DBusMessage *message; - DBusMessageIter iter; - const char *display_name; - const char *display_device; - const char *display_seat_id; - const char *display_hostname; - const char *display_x11_authority_file; - GdmSessionConversation *conversation; - - g_assert (service_name != NULL); - - if (session->priv->display_name != NULL) { - display_name = session->priv->display_name; - } else { - display_name = ""; - } - if (session->priv->display_hostname != NULL) { - display_hostname = session->priv->display_hostname; - } else { - display_hostname = ""; - } - if (session->priv->display_device != NULL) { - display_device = session->priv->display_device; - } else { - display_device = ""; - } - if (session->priv->display_seat_id != NULL) { - display_seat_id = session->priv->display_seat_id; - } else { - display_seat_id = ""; - } - if (session->priv->display_x11_authority_file != NULL) { - display_x11_authority_file = session->priv->display_x11_authority_file; - } else { - display_x11_authority_file = ""; - } - - g_debug ("GdmSessionDirect: Beginning setup for session for program with log '%s'", log_file); - - message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, - GDM_SESSION_DBUS_INTERFACE, - "SetupForProgram"); - - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &log_file); - - conversation = find_conversation_by_name (session, service_name); - if (conversation != NULL && ! send_dbus_message (conversation, message)) { - g_debug ("GdmSessionDirect: Could not send %s signal", "SetupForProgram"); - } - - dbus_message_unref (message); -} - -static void -gdm_session_direct_setup (GdmSession *session, - const char *service_name) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - - g_return_if_fail (session != NULL); - - send_setup (impl, service_name); - gdm_session_direct_defaults_changed (impl); -} - -static void -gdm_session_direct_setup_for_user (GdmSession *session, - const char *service_name, - const char *username) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - - g_return_if_fail (session != NULL); - g_return_if_fail (username != NULL); - - gdm_session_direct_select_user (session, username); - - send_setup_for_user (impl, service_name); - gdm_session_direct_defaults_changed (impl); -} - -static void -gdm_session_direct_setup_for_program (GdmSession *session, - const char *service_name, - const char *log_file) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - - g_return_if_fail (session != NULL); - - send_setup_for_program (impl, service_name, log_file); -} - -static void -gdm_session_direct_authenticate (GdmSession *session, - const char *service_name) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GdmSessionConversation *conversation; - - g_return_if_fail (session != NULL); - - conversation = find_conversation_by_name (impl, service_name); - if (conversation != NULL) { - send_dbus_void_signal (conversation, "Authenticate"); - } -} - -static void -gdm_session_direct_authorize (GdmSession *session, - const char *service_name) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GdmSessionConversation *conversation; - - g_return_if_fail (session != NULL); - - conversation = find_conversation_by_name (impl, service_name); - if (conversation != NULL) { - send_dbus_void_signal (conversation, "Authorize"); - } -} - -static void -gdm_session_direct_accredit (GdmSession *session, - const char *service_name, - int cred_flag) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GdmSessionConversation *conversation; - - g_return_if_fail (session != NULL); - - conversation = find_conversation_by_name (impl, service_name); - if (conversation == NULL) { - return; - } - - switch (cred_flag) { - case GDM_SESSION_CRED_ESTABLISH: - send_dbus_void_signal (conversation, "EstablishCredentials"); - break; - case GDM_SESSION_CRED_REFRESH: - send_dbus_void_signal (conversation, "RefreshCredentials"); - break; - default: - g_assert_not_reached (); - } -} - -static void -send_environment_variable (const char *key, - const char *value, - GdmSessionConversation *conversation) -{ - DBusMessage *message; - DBusMessageIter iter; - - message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, - GDM_SESSION_DBUS_INTERFACE, - "SetEnvironmentVariable"); - - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value); - - if (! send_dbus_message (conversation, message)) { - g_debug ("GdmSessionDirect: Could not send %s signal", "SetEnvironmentVariable"); - } - - dbus_message_unref (message); -} - -static void -send_environment (GdmSessionDirect *session, - GdmSessionConversation *conversation) -{ - - g_hash_table_foreach (session->priv->environment, - (GHFunc) send_environment_variable, - conversation); -} - -static const char * -get_language_name (GdmSessionDirect *session) -{ - if (session->priv->selected_language != NULL) { - return session->priv->selected_language; - } - - return get_default_language_name (session); -} - -static const char * -get_session_name (GdmSessionDirect *session) -{ - /* FIXME: test the session names before we use them? */ - - if (session->priv->selected_session != NULL) { - return session->priv->selected_session; - } - - return get_default_session_name (session); -} - -static char * -get_session_command (GdmSessionDirect *session) -{ - gboolean res; - char *command; - const char *session_name; - - session_name = get_session_name (session); - - command = NULL; - res = get_session_command_for_name (session_name, &command); - if (! res) { - g_critical ("Cannot find a command for specified session: %s", session_name); - exit (1); - } - - return command; -} - -static void -gdm_session_direct_set_environment_variable (GdmSession *session, - const char *key, - const char *value) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - - g_return_if_fail (key != NULL); - g_return_if_fail (value != NULL); - - g_hash_table_replace (impl->priv->environment, - g_strdup (key), - g_strdup (value)); -} - -static void -setup_session_environment (GdmSessionDirect *session_direct) -{ - GdmSession *session = GDM_SESSION (session_direct); - const char *locale; - - gdm_session_direct_set_environment_variable (session, - "GDMSESSION", - get_session_name (session_direct)); - gdm_session_direct_set_environment_variable (session, - "DESKTOP_SESSION", - get_session_name (session_direct)); - - locale = get_language_name (session_direct); - - if (locale != NULL && locale[0] != '\0') { - gdm_session_direct_set_environment_variable (session, - "LANG", - locale); - gdm_session_direct_set_environment_variable (session, - "GDM_LANG", - locale); - } - - gdm_session_direct_set_environment_variable (session, - "DISPLAY", - session_direct->priv->display_name); - - if (session_direct->priv->user_x11_authority_file != NULL) { - gdm_session_direct_set_environment_variable (session, - "XAUTHORITY", - session_direct->priv->user_x11_authority_file); - } - - if (g_getenv ("WINDOWPATH") != NULL) { - gdm_session_direct_set_environment_variable (session, - "WINDOWPATH", - g_getenv ("WINDOWPATH")); - } - - - /* FIXME: We do this here and in the session worker. We should consolidate - * somehow. - */ - gdm_session_direct_set_environment_variable (session, - "PATH", - strcmp (BINDIR, "/usr/bin") == 0? - GDM_SESSION_DEFAULT_PATH : - BINDIR ":" GDM_SESSION_DEFAULT_PATH); - -} - -static void -gdm_session_direct_open_session (GdmSession *session, - const char *service_name) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GdmSessionConversation *conversation; - - g_return_if_fail (session != NULL); - - conversation = find_conversation_by_name (impl, service_name); - - send_dbus_string_signal (conversation, "OpenSession", service_name); -} - -static void -stop_all_other_conversations (GdmSessionDirect *session, - GdmSessionConversation *conversation_to_keep, - gboolean now) -{ - GHashTableIter iter; - gpointer key, value; - - if (session->priv->conversations == NULL) { - return; - } - - if (conversation_to_keep == NULL) { - g_debug ("GdmSessionDirect: Stopping all conversations"); - } else { - g_debug ("GdmSessionDirect: Stopping all conversations " - "except for %s", conversation_to_keep->service_name); - } - - g_hash_table_iter_init (&iter, session->priv->conversations); - while (g_hash_table_iter_next (&iter, &key, &value)) { - GdmSessionConversation *conversation; - - conversation = (GdmSessionConversation *) value; - - if (conversation == conversation_to_keep) { - if (now) { - g_hash_table_iter_steal (&iter); - g_free (key); - } - } else { - if (now) { - stop_conversation_now (conversation); - } else { - stop_conversation (conversation); - } - } - } - - if (now) { - g_hash_table_remove_all (session->priv->conversations); - - if (conversation_to_keep != NULL) { - g_hash_table_insert (session->priv->conversations, - g_strdup (conversation_to_keep->service_name), - conversation_to_keep); - } - - if (session->priv->session_conversation != conversation_to_keep) { - session->priv->session_conversation = NULL; - } - } - -} - -static void -gdm_session_direct_start_session (GdmSession *session, - const char *service_name) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GdmSessionConversation *conversation; - char *command; - char *program; - - g_return_if_fail (session != NULL); - g_return_if_fail (impl->priv->session_conversation == NULL); - - conversation = find_conversation_by_name (impl, service_name); - - if (conversation == NULL) { - g_warning ("GdmSessionDirect: Tried to start session of " - "nonexistent conversation %s", service_name); - return; - } - - stop_all_other_conversations (impl, conversation, FALSE); - - if (impl->priv->selected_program == NULL) { - command = get_session_command (impl); - - if (gdm_session_direct_bypasses_xsession (impl)) { - program = g_strdup (command); - } else { - program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command); - } - - g_free (command); - } else { - program = g_strdup (impl->priv->selected_program); - } - - setup_session_environment (impl); - send_environment (impl, conversation); - - send_dbus_string_signal (conversation, "StartProgram", program); - g_free (program); -} - -static void -stop_all_conversations (GdmSessionDirect *session) -{ - stop_all_other_conversations (session, NULL, TRUE); -} - -static void -gdm_session_direct_close (GdmSession *session) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - - g_return_if_fail (session != NULL); - - g_debug ("GdmSessionDirect: Closing session"); - - if (impl->priv->session_conversation != NULL) { - gdm_session_record_logout (impl->priv->session_pid, - impl->priv->selected_user, - impl->priv->display_hostname, - impl->priv->display_name, - impl->priv->display_device); - } - - stop_all_conversations (impl); - - g_list_foreach (impl->priv->pending_connections, - (GFunc) dbus_connection_unref, NULL); - g_list_free (impl->priv->pending_connections); - impl->priv->pending_connections = NULL; - - g_free (impl->priv->selected_user); - impl->priv->selected_user = NULL; - - g_free (impl->priv->selected_session); - impl->priv->selected_session = NULL; - - g_free (impl->priv->saved_session); - impl->priv->saved_session = NULL; - - g_free (impl->priv->selected_language); - impl->priv->selected_language = NULL; - - g_free (impl->priv->saved_language); - impl->priv->saved_language = NULL; - - g_free (impl->priv->user_x11_authority_file); - impl->priv->user_x11_authority_file = NULL; - - g_hash_table_remove_all (impl->priv->environment); - - impl->priv->session_pid = -1; - impl->priv->session_conversation = NULL; -} - -static void -gdm_session_direct_answer_query (GdmSession *session, - const char *service_name, - const char *text) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GdmSessionConversation *conversation; - - g_return_if_fail (session != NULL); - - conversation = find_conversation_by_name (impl, service_name); - - answer_pending_query (conversation, text); -} - -static void -gdm_session_direct_cancel (GdmSession *session) -{ - g_return_if_fail (session != NULL); - - stop_all_conversations (GDM_SESSION_DIRECT (session)); -} - -char * -gdm_session_direct_get_username (GdmSessionDirect *session) -{ - g_return_val_if_fail (session != NULL, NULL); - - return g_strdup (session->priv->selected_user); -} - -char * -gdm_session_direct_get_display_device (GdmSessionDirect *session) -{ - g_return_val_if_fail (session != NULL, NULL); - - return g_strdup (session->priv->display_device); -} - -char * -gdm_session_direct_get_display_seat_id (GdmSessionDirect *session) -{ - g_return_val_if_fail (session != NULL, NULL); - - return g_strdup (session->priv->display_seat_id); -} - -gboolean -gdm_session_direct_bypasses_xsession (GdmSessionDirect *session_direct) -{ - GError *error; - GKeyFile *key_file; - gboolean res; - gboolean bypasses_xsession = FALSE; - char *filename; - - g_return_val_if_fail (session_direct != NULL, FALSE); - g_return_val_if_fail (GDM_IS_SESSION_DIRECT (session_direct), FALSE); - - filename = g_strdup_printf ("%s.desktop", get_session_name (session_direct)); - - key_file = g_key_file_new (); - error = NULL; - res = g_key_file_load_from_dirs (key_file, - filename, - get_system_session_dirs (), - NULL, - G_KEY_FILE_NONE, - &error); - if (! res) { - g_debug ("GdmSessionDirect: File '%s' not found: %s", filename, error->message); - goto out; - } - - error = NULL; - res = g_key_file_has_key (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-BypassXsession", NULL); - if (!res) { - goto out; - } else { - bypasses_xsession = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-BypassXsession", &error); - if (error) { - bypasses_xsession = FALSE; - g_error_free (error); - goto out; - } - if (bypasses_xsession) { - g_debug ("GdmSessionDirect: Session %s bypasses Xsession wrapper script", filename); - } - } - -out: - g_free (filename); - return bypasses_xsession; -} - -static void -gdm_session_direct_select_program (GdmSession *session, - const char *text) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - - g_free (impl->priv->selected_program); - - impl->priv->selected_program = g_strdup (text); -} - -static void -gdm_session_direct_select_session_type (GdmSession *session, - const char *text) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GHashTableIter iter; - gpointer key, value; - - g_hash_table_iter_init (&iter, impl->priv->conversations); - while (g_hash_table_iter_next (&iter, &key, &value)) { - GdmSessionConversation *conversation; - - conversation = (GdmSessionConversation *) value; - - send_dbus_string_signal (conversation, "SetSessionType", - text); - } -} -static void -gdm_session_direct_select_session (GdmSession *session, - const char *text) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GHashTableIter iter; - gpointer key, value; - - g_free (impl->priv->selected_session); - - if (strcmp (text, "__previous") == 0) { - impl->priv->selected_session = NULL; - } else { - impl->priv->selected_session = g_strdup (text); - } - - g_hash_table_iter_init (&iter, impl->priv->conversations); - while (g_hash_table_iter_next (&iter, &key, &value)) { - GdmSessionConversation *conversation; - - conversation = (GdmSessionConversation *) value; - - send_dbus_string_signal (conversation, "SetSessionName", - get_session_name (impl)); - } -} - -static void -gdm_session_direct_select_language (GdmSession *session, - const char *text) -{ - GdmSessionDirect *impl = GDM_SESSION_DIRECT (session); - GHashTableIter iter; - gpointer key, value; - - g_free (impl->priv->selected_language); - - if (strcmp (text, "__previous") == 0) { - impl->priv->selected_language = NULL; - } else { - impl->priv->selected_language = g_strdup (text); - } - - g_hash_table_iter_init (&iter, impl->priv->conversations); - while (g_hash_table_iter_next (&iter, &key, &value)) { - GdmSessionConversation *conversation; - - conversation = (GdmSessionConversation *) value; - - send_dbus_string_signal (conversation, "SetLanguageName", - get_language_name (impl)); - } -} - -static void -_gdm_session_direct_set_display_id (GdmSessionDirect *session, - const char *id) -{ - g_free (session->priv->display_id); - session->priv->display_id = g_strdup (id); -} - -/* At some point we may want to read these right from - * the slave but for now I don't want the dependency */ -static void -_gdm_session_direct_set_display_name (GdmSessionDirect *session, - const char *name) -{ - g_free (session->priv->display_name); - session->priv->display_name = g_strdup (name); -} - -static void -_gdm_session_direct_set_display_hostname (GdmSessionDirect *session, - const char *name) -{ - g_free (session->priv->display_hostname); - session->priv->display_hostname = g_strdup (name); -} - -static void -_gdm_session_direct_set_display_device (GdmSessionDirect *session, - const char *name) -{ - g_debug ("GdmSessionDirect: Setting display device: %s", name); - g_free (session->priv->display_device); - session->priv->display_device = g_strdup (name); -} - -static void -_gdm_session_direct_set_display_seat_id (GdmSessionDirect *session, - const char *name) -{ - g_free (session->priv->display_seat_id); - session->priv->display_seat_id = g_strdup (name); -} - -static void -_gdm_session_direct_set_user_x11_authority_file (GdmSessionDirect *session, - const char *name) -{ - g_free (session->priv->user_x11_authority_file); - session->priv->user_x11_authority_file = g_strdup (name); -} - -static void -_gdm_session_direct_set_display_x11_authority_file (GdmSessionDirect *session, - const char *name) -{ - g_free (session->priv->display_x11_authority_file); - session->priv->display_x11_authority_file = g_strdup (name); -} - -static void -_gdm_session_direct_set_display_is_local (GdmSessionDirect *session, - gboolean is) -{ - session->priv->display_is_local = is; -} - -static void -gdm_session_direct_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GdmSessionDirect *self; - - self = GDM_SESSION_DIRECT (object); - - switch (prop_id) { - case PROP_DISPLAY_ID: - _gdm_session_direct_set_display_id (self, g_value_get_string (value)); - break; - case PROP_DISPLAY_NAME: - _gdm_session_direct_set_display_name (self, g_value_get_string (value)); - break; - case PROP_DISPLAY_HOSTNAME: - _gdm_session_direct_set_display_hostname (self, g_value_get_string (value)); - break; - case PROP_DISPLAY_DEVICE: - _gdm_session_direct_set_display_device (self, g_value_get_string (value)); - break; - case PROP_DISPLAY_SEAT_ID: - _gdm_session_direct_set_display_seat_id (self, g_value_get_string (value)); - break; - case PROP_USER_X11_AUTHORITY_FILE: - _gdm_session_direct_set_user_x11_authority_file (self, g_value_get_string (value)); - break; - case PROP_DISPLAY_X11_AUTHORITY_FILE: - _gdm_session_direct_set_display_x11_authority_file (self, g_value_get_string (value)); - break; - case PROP_DISPLAY_IS_LOCAL: - _gdm_session_direct_set_display_is_local (self, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_session_direct_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GdmSessionDirect *self; - - self = GDM_SESSION_DIRECT (object); - - switch (prop_id) { - case PROP_DISPLAY_ID: - g_value_set_string (value, self->priv->display_id); - break; - case PROP_DISPLAY_NAME: - g_value_set_string (value, self->priv->display_name); - break; - case PROP_DISPLAY_HOSTNAME: - g_value_set_string (value, self->priv->display_hostname); - break; - case PROP_DISPLAY_DEVICE: - g_value_set_string (value, self->priv->display_device); - break; - case PROP_DISPLAY_SEAT_ID: - g_value_set_string (value, self->priv->display_seat_id); - break; - case PROP_USER_X11_AUTHORITY_FILE: - g_value_set_string (value, self->priv->user_x11_authority_file); - break; - case PROP_DISPLAY_X11_AUTHORITY_FILE: - g_value_set_string (value, self->priv->display_x11_authority_file); - break; - case PROP_DISPLAY_IS_LOCAL: - g_value_set_boolean (value, self->priv->display_is_local); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_session_direct_dispose (GObject *object) -{ - GdmSessionDirect *session; - - session = GDM_SESSION_DIRECT (object); - - g_debug ("GdmSessionDirect: Disposing session"); - - gdm_session_direct_close (GDM_SESSION (session)); - - g_free (session->priv->display_id); - session->priv->display_id = NULL; - - g_free (session->priv->display_name); - session->priv->display_name = NULL; - - g_free (session->priv->display_hostname); - session->priv->display_hostname = NULL; - - g_free (session->priv->display_device); - session->priv->display_device = NULL; - - g_free (session->priv->display_seat_id); - session->priv->display_seat_id = NULL; - - g_free (session->priv->display_x11_authority_file); - session->priv->display_x11_authority_file = NULL; - - g_free (session->priv->server_address); - session->priv->server_address = NULL; - - if (session->priv->server != NULL) { - dbus_server_disconnect (session->priv->server); - dbus_server_unref (session->priv->server); - session->priv->server = NULL; - } - - if (session->priv->environment != NULL) { - g_hash_table_destroy (session->priv->environment); - session->priv->environment = NULL; - } - - G_OBJECT_CLASS (gdm_session_direct_parent_class)->dispose (object); -} - -static void -gdm_session_direct_finalize (GObject *object) -{ - GdmSessionDirect *session; - GObjectClass *parent_class; - - session = GDM_SESSION_DIRECT (object); - - g_free (session->priv->selected_user); - g_free (session->priv->selected_session); - g_free (session->priv->saved_session); - g_free (session->priv->selected_language); - g_free (session->priv->saved_language); - - g_free (session->priv->fallback_session_name); - - parent_class = G_OBJECT_CLASS (gdm_session_direct_parent_class); - - if (parent_class->finalize != NULL) - parent_class->finalize (object); -} - -static GObject * -gdm_session_direct_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - GdmSessionDirect *session; - - session = GDM_SESSION_DIRECT (G_OBJECT_CLASS (gdm_session_direct_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - - return G_OBJECT (session); -} - -static void -gdm_session_iface_init (GdmSessionIface *iface) -{ - iface->start_conversation = gdm_session_direct_start_conversation; - iface->stop_conversation = gdm_session_direct_stop_conversation; - iface->setup = gdm_session_direct_setup; - iface->setup_for_user = gdm_session_direct_setup_for_user; - iface->setup_for_program = gdm_session_direct_setup_for_program; - iface->set_environment_variable = gdm_session_direct_set_environment_variable; - iface->authenticate = gdm_session_direct_authenticate; - iface->authorize = gdm_session_direct_authorize; - iface->accredit = gdm_session_direct_accredit; - iface->open_session = gdm_session_direct_open_session; - iface->close = gdm_session_direct_close; - - iface->cancel = gdm_session_direct_cancel; - iface->start_session = gdm_session_direct_start_session; - iface->answer_query = gdm_session_direct_answer_query; - iface->select_program = gdm_session_direct_select_program; - iface->select_session_type = gdm_session_direct_select_session_type; - iface->select_session = gdm_session_direct_select_session; - iface->select_language = gdm_session_direct_select_language; - iface->select_user = gdm_session_direct_select_user; -} - -static void -gdm_session_direct_class_init (GdmSessionDirectClass *session_class) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (session_class); - - object_class->get_property = gdm_session_direct_get_property; - object_class->set_property = gdm_session_direct_set_property; - object_class->constructor = gdm_session_direct_constructor; - object_class->dispose = gdm_session_direct_dispose; - object_class->finalize = gdm_session_direct_finalize; - - g_type_class_add_private (session_class, sizeof (GdmSessionDirectPrivate)); - - g_object_class_install_property (object_class, - PROP_DISPLAY_ID, - g_param_spec_string ("display-id", - "display id", - "display id", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_DISPLAY_NAME, - g_param_spec_string ("display-name", - "display name", - "display name", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_DISPLAY_HOSTNAME, - g_param_spec_string ("display-hostname", - "display hostname", - "display hostname", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_DISPLAY_IS_LOCAL, - g_param_spec_boolean ("display-is-local", - "display is local", - "display is local", - TRUE, - 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", - "display x11 authority file", - "display x11 authority file", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - /* not construct only */ - g_object_class_install_property (object_class, - PROP_USER_X11_AUTHORITY_FILE, - g_param_spec_string ("user-x11-authority-file", - "", - "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_DISPLAY_DEVICE, - g_param_spec_string ("display-device", - "display device", - "display device", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - g_object_class_install_property (object_class, - PROP_DISPLAY_SEAT_ID, - g_param_spec_string ("display-seat-id", - "display seat id", - "display seat id", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); -} - -GdmSessionDirect * -gdm_session_direct_new (const char *display_id, - const char *display_name, - const char *display_hostname, - const char *display_device, - const char *display_seat_id, - const char *display_x11_authority_file, - gboolean display_is_local) -{ - GdmSessionDirect *session; - - session = g_object_new (GDM_TYPE_SESSION_DIRECT, - "display-id", display_id, - "display-name", display_name, - "display-hostname", display_hostname, - "display-device", display_device, - "display-seat-id", display_seat_id, - "display-x11-authority-file", display_x11_authority_file, - "display-is-local", display_is_local, - NULL); - - return session; -} diff --git a/daemon/gdm-session-direct.h b/daemon/gdm-session-direct.h deleted file mode 100644 index 254d6680..00000000 --- a/daemon/gdm-session-direct.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2006 Ray Strode <rstrode@redhat.com> - * - * 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, 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_SESSION_DIRECT_H -#define __GDM_SESSION_DIRECT_H - -#include <glib-object.h> -#include "gdm-session.h" - -G_BEGIN_DECLS - -#define GDM_TYPE_SESSION_DIRECT (gdm_session_direct_get_type ()) -#define GDM_SESSION_DIRECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_SESSION_DIRECT, GdmSessionDirect)) -#define GDM_SESSION_DIRECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_SESSION_DIRECT, GdmSessionDirectClass)) -#define GDM_IS_SESSION_DIRECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_SESSION_DIRECT)) -#define GDM_IS_SESSION_DIRECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_SESSION_DIRECT)) -#define GDM_SESSION_DIRECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SESSION_DIRECT, GdmSessionDirectClass)) - -typedef struct _GdmSessionDirectPrivate GdmSessionDirectPrivate; - -typedef struct -{ - GObject parent; - GdmSessionDirectPrivate *priv; -} GdmSessionDirect; - -typedef struct -{ - GObjectClass parent_class; -} GdmSessionDirectClass; - -GType gdm_session_direct_get_type (void); - -GdmSessionDirect * gdm_session_direct_new (const char *display_id, - const char *display_name, - const char *display_hostname, - const char *display_device, - const char *display_seat_id, - const char *display_x11_authority_file, - gboolean display_is_local) G_GNUC_MALLOC; - -char * gdm_session_direct_get_username (GdmSessionDirect *session_direct); -char * gdm_session_direct_get_display_device (GdmSessionDirect *session_direct); -char * gdm_session_direct_get_display_seat_id (GdmSessionDirect *session_direct); -gboolean gdm_session_direct_bypasses_xsession (GdmSessionDirect *session_direct); - -G_END_DECLS - -#endif /* GDM_SESSION_DIRECT_H */ diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c index b91ec634..044a8a7f 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c @@ -1,11 +1,12 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * + * Copyright (C) 2006 Ray Strode <rstrode@redhat.com> * Copyright (C) 2007 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. + * the Free Software Foundation; either version 2, 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 @@ -14,19 +15,114 @@ * * 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. - * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. */ #include "config.h" +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> + +#include <stdlib.h> +#include <string.h> +#include <sys/resource.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <pwd.h> +#include <grp.h> + +#include <locale.h> + #include <glib.h> #include <glib/gi18n.h> +#include <glib/gstdio.h> #include <glib-object.h> +#ifdef HAVE_LIBXKLAVIER +#include <libxklavier/xklavier.h> +#include <X11/Xlib.h> /* for Display */ +#endif + +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + #include "gdm-session.h" #include "gdm-session-private.h" +#include "gdm-session-record.h" +#include "gdm-session-worker-job.h" +#include "gdm-common.h" + +#define GDM_SESSION_DBUS_PATH "/org/gnome/DisplayManager/Session" +#define GDM_SESSION_DBUS_INTERFACE "org.gnome.DisplayManager.Session" +#define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel" + +#ifndef GDM_SESSION_DEFAULT_PATH +#define GDM_SESSION_DEFAULT_PATH "/usr/local/bin:/usr/bin:/bin" +#endif + +typedef struct +{ + GdmSession *session; + GdmSessionWorkerJob *job; + GPid worker_pid; + char *service_name; + DBusConnection *worker_connection; + DBusMessage *message_pending_reply; + guint32 is_stopping : 1; +} GdmSessionConversation; + +struct _GdmSessionPrivate +{ + /* per open scope */ + char *selected_program; + char *selected_session; + char *saved_session; + char *selected_language; + char *saved_language; + char *selected_user; + char *user_x11_authority_file; + + GHashTable *conversations; + + GdmSessionConversation *session_conversation; + + GList *pending_connections; + + GPid session_pid; + + /* object lifetime scope */ + char *display_id; + char *display_name; + char *display_hostname; + char *display_device; + char *display_seat_id; + char *display_x11_authority_file; + gboolean display_is_local; + + char *fallback_session_name; + + DBusServer *server; + char *server_address; + GHashTable *environment; + DBusGConnection *connection; +}; + +enum { + PROP_0, + PROP_DISPLAY_NAME, + PROP_DISPLAY_HOSTNAME, + PROP_DISPLAY_IS_LOCAL, + PROP_DISPLAY_DEVICE, + PROP_DISPLAY_SEAT_ID, + PROP_DISPLAY_X11_AUTHORITY_FILE, + PROP_USER_X11_AUTHORITY_FILE, +}; + enum { CONVERSATION_STARTED = 0, CONVERSATION_STOPPED, @@ -59,209 +155,3080 @@ enum { static guint signals [LAST_SIGNAL] = { 0, }; -static void gdm_session_class_init (gpointer g_iface); +G_DEFINE_TYPE (GdmSession, + gdm_session, + G_TYPE_OBJECT); + +static gboolean +send_dbus_message (GdmSessionConversation *conversation, + DBusMessage *message) +{ + gboolean is_connected; + gboolean sent; + + g_return_val_if_fail (message != NULL, FALSE); + + if (conversation->worker_connection == NULL) { + g_warning ("There is no valid connection"); + return FALSE; + } + + is_connected = dbus_connection_get_is_connected (conversation->worker_connection); + if (! is_connected) { + g_warning ("Not connected!"); + return FALSE; + } + + sent = dbus_connection_send (conversation->worker_connection, message, NULL); + + return sent; +} + +static void +send_dbus_string_signal (GdmSessionConversation *conversation, + const char *name, + const char *text) +{ + DBusMessage *message; + DBusMessageIter iter; + + g_return_if_fail (conversation != NULL); + + message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, + GDM_SESSION_DBUS_INTERFACE, + name); + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &text); + + if (! send_dbus_message (conversation, message)) { + g_debug ("GdmSession: Could not send %s signal", + name ? name : "(null)"); + } + + dbus_message_unref (message); +} + +static void +send_dbus_void_signal (GdmSessionConversation *conversation, + const char *name) +{ + DBusMessage *message; + + g_return_if_fail (conversation != NULL); + + message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, + GDM_SESSION_DBUS_INTERFACE, + name); + + if (! send_dbus_message (conversation, message)) { + g_debug ("GdmSession: Could not send %s signal", name); + } + + dbus_message_unref (message); +} + +static void +emit_service_unavailable (GdmSession *self, + const char *service_name) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [SERVICE_UNAVAILABLE], 0, service_name); +} + +static void +emit_setup_complete (GdmSession *self, + const char *service_name) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [SETUP_COMPLETE], 0, service_name); +} + +static void +emit_setup_failed (GdmSession *self, + const char *service_name, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [SETUP_FAILED], 0, service_name, text); +} + +static void +emit_reset_complete (GdmSession *self) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [RESET_COMPLETE], 0); +} + +static void +emit_reset_failed (GdmSession *self, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [RESET_FAILED], 0, text); +} + +static void +emit_authenticated (GdmSession *self, + const char *service_name) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [AUTHENTICATED], 0, service_name); +} + +static void +emit_authentication_failed (GdmSession *self, + const char *service_name, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [AUTHENTICATION_FAILED], 0, service_name, text); +} + +static void +emit_authorized (GdmSession *self, + const char *service_name) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [AUTHORIZED], 0, service_name); +} + +static void +emit_authorization_failed (GdmSession *self, + const char *service_name, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [AUTHORIZATION_FAILED], 0, service_name, text); +} + +static void +emit_accredited (GdmSession *self, + const char *service_name) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [ACCREDITED], 0, service_name); +} + +static void +emit_accreditation_failed (GdmSession *self, + const char *service_name, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [ACCREDITATION_FAILED], 0, service_name, text); +} + +static void +emit_info_query (GdmSession *self, + const char *service_name, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [INFO_QUERY], 0, service_name, text); +} + +static void +emit_secret_info_query (GdmSession *self, + const char *service_name, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [SECRET_INFO_QUERY], 0, service_name, text); +} + +static void +emit_info (GdmSession *self, + const char *service_name, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [INFO], 0, service_name, text); +} + +static void +emit_problem (GdmSession *self, + const char *service_name, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [PROBLEM], 0, service_name, text); +} + +static void +emit_session_opened (GdmSession *self, + const char *service_name) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [SESSION_OPENED], 0, service_name); +} + +static void +emit_session_open_failed (GdmSession *self, + const char *service_name, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [SESSION_OPEN_FAILED], 0, service_name, text); +} + +static void +emit_session_started (GdmSession *self, + const char *service_name, + int pid) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [SESSION_STARTED], 0, service_name, pid); +} + +static void +emit_session_start_failed (GdmSession *self, + const char *service_name, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [SESSION_START_FAILED], 0, service_name, text); +} + +static void +emit_session_exited (GdmSession *self, + int exit_code) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [SESSION_EXITED], 0, exit_code); +} + +static void +emit_session_died (GdmSession *self, + int signal_number) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [SESSION_DIED], 0, signal_number); +} + +static void +emit_conversation_started (GdmSession *self, + const char *service_name) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [CONVERSATION_STARTED], 0, service_name); +} + +static void +emit_conversation_stopped (GdmSession *self, + const char *service_name) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [CONVERSATION_STOPPED], 0, service_name); +} + +static void +emit_default_language_name_changed (GdmSession *self, + const char *language_name) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [DEFAULT_LANGUAGE_NAME_CHANGED], 0, language_name); +} + +static void +emit_default_session_name_changed (GdmSession *self, + const char *session_name) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [DEFAULT_SESSION_NAME_CHANGED], 0, session_name); +} + +static void +emit_selected_user_changed (GdmSession *self, + const char *text) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + g_signal_emit (self, signals [SELECTED_USER_CHANGED], 0, text); +} + +static GdmSessionConversation * +find_conversation_by_name (GdmSession *self, + const char *service_name) +{ + GdmSessionConversation *conversation; + + conversation = g_hash_table_lookup (self->priv->conversations, service_name); + + if (conversation == NULL) { + g_warning ("Tried to look up non-existent conversation %s", service_name); + } + + return conversation; +} + +static void +on_authentication_failed (GdmSession *self, + const char *service_name, + const char *message) +{ + GdmSessionConversation *conversation; + + conversation = find_conversation_by_name (self, service_name); + if (conversation != NULL) { + gdm_session_record_failed (conversation->worker_pid, + self->priv->selected_user, + self->priv->display_hostname, + self->priv->display_name, + self->priv->display_device); + } +} + +static void +on_session_started (GdmSession *self, + const char *service_name) +{ + GdmSessionConversation *conversation; + + conversation = find_conversation_by_name (self, service_name); + if (conversation != NULL) { + gdm_session_record_login (conversation->worker_pid, + self->priv->selected_user, + self->priv->display_hostname, + self->priv->display_name, + self->priv->display_device); + } +} + +static void +on_session_start_failed (GdmSession *self, + const char *service_name, + const char *message) +{ + GdmSessionConversation *conversation; + + conversation = find_conversation_by_name (self, service_name); + if (conversation != NULL) { + gdm_session_record_login (conversation->worker_pid, + self->priv->selected_user, + self->priv->display_hostname, + self->priv->display_name, + self->priv->display_device); + } +} + +static void +on_session_exited (GdmSession *self, + int exit_code) +{ + + gdm_session_record_logout (self->priv->session_pid, + self->priv->selected_user, + self->priv->display_hostname, + self->priv->display_name, + self->priv->display_device); +} + + +static DBusHandlerResult +gdm_session_handle_service_unavailable (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + + g_debug ("GdmSession: Emitting 'service-unavailable' signal"); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + emit_service_unavailable (self, conversation->service_name); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_setup_complete (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + + g_debug ("GdmSession: Emitting 'setup-complete' signal"); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + emit_setup_complete (self, conversation->service_name); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_setup_failed (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'setup-failed' signal"); + + emit_setup_failed (self, conversation->service_name, text); + + return DBUS_HANDLER_RESULT_HANDLED; +} + + +static DBusHandlerResult +gdm_session_handle_reset_complete (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + + g_debug ("GdmSession: Emitting 'reset-complete' signal"); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + emit_reset_complete (self); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_reset_failed (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'reset-failed' signal"); + + emit_reset_failed (self, text); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_authenticated (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + + g_debug ("GdmSession: Emitting 'authenticated' signal"); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + emit_authenticated (self, conversation->service_name); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_authentication_failed (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'authentication-failed' signal"); -GType -gdm_session_get_type (void) + emit_authentication_failed (self, conversation->service_name, text); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_authorized (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + + g_debug ("GdmSession: Emitting 'authorized' signal"); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + emit_authorized (self, conversation->service_name); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_authorization_failed (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'authorization-failed' signal"); + + emit_authorization_failed (self, conversation->service_name, text); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_accredited (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) { - static GType session_type = 0; + DBusMessage *reply; + + g_debug ("GdmSession: Emitting 'accredited' signal"); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); - if (!session_type) { - session_type = g_type_register_static_simple (G_TYPE_INTERFACE, - "GdmSession", - sizeof (GdmSessionIface), - (GClassInitFunc) gdm_session_class_init, - 0, NULL, 0); + emit_accredited (self, conversation->service_name); + + return DBUS_HANDLER_RESULT_HANDLED; +} - g_type_interface_add_prerequisite (session_type, G_TYPE_OBJECT); +static DBusHandlerResult +gdm_session_handle_accreditation_failed (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); } - return session_type; + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'accreditation-failed' signal"); + + emit_accreditation_failed (self, conversation->service_name, text); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static const char ** +get_system_session_dirs (void) +{ + static const char *search_dirs[] = { + "/etc/X11/sessions/", + DMCONFDIR "/Sessions/", + DATADIR "/xsessions/", + DATADIR "/gdm/BuiltInSessions/", + NULL + }; + + return search_dirs; +} + +static gboolean +is_prog_in_path (const char *prog) +{ + char *f; + gboolean ret; + + f = g_find_program_in_path (prog); + ret = (f != NULL); + g_free (f); + return ret; +} + +static gboolean +get_session_command_for_file (const char *file, + char **command) +{ + GKeyFile *key_file; + GError *error; + char *exec; + gboolean ret; + gboolean res; + + exec = NULL; + ret = FALSE; + if (command != NULL) { + *command = NULL; + } + + key_file = g_key_file_new (); + + g_debug ("GdmSession: looking for session file '%s'", file); + + error = NULL; + res = g_key_file_load_from_dirs (key_file, + file, + get_system_session_dirs (), + NULL, + G_KEY_FILE_NONE, + &error); + if (! res) { + g_debug ("GdmSession: File '%s' not found: %s", file, error->message); + g_error_free (error); + if (command != NULL) { + *command = NULL; + } + goto out; + } + + error = NULL; + res = g_key_file_get_boolean (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_HIDDEN, + &error); + if (error == NULL && res) { + g_debug ("GdmSession: Session %s is marked as hidden", file); + goto out; + } + + exec = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TRY_EXEC, + NULL); + if (exec != NULL) { + res = is_prog_in_path (exec); + g_free (exec); + exec = NULL; + + if (! res) { + g_debug ("GdmSession: Command not found: %s", + G_KEY_FILE_DESKTOP_KEY_TRY_EXEC); + goto out; + } + } + + error = NULL; + exec = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_EXEC, + &error); + if (error != NULL) { + g_debug ("GdmSession: %s key not found: %s", + G_KEY_FILE_DESKTOP_KEY_EXEC, + error->message); + g_error_free (error); + goto out; + } + + if (command != NULL) { + *command = g_strdup (exec); + } + ret = TRUE; + +out: + g_free (exec); + + return ret; +} + +static gboolean +get_session_command_for_name (const char *name, + char **command) +{ + gboolean res; + char *filename; + + filename = g_strdup_printf ("%s.desktop", name); + res = get_session_command_for_file (filename, command); + g_free (filename); + + /* + * The GDM Xsession script honors "custom" as a valid session. If the + * session is one of these, no file is needed, then just run the + * command as "custom". + */ + if (!res && strcmp (name, GDM_CUSTOM_SESSION) == 0) { + g_debug ("No custom desktop file, but accepting it anyway."); + if (command != NULL) { + *command = g_strdup (GDM_CUSTOM_SESSION); + } + res = TRUE; + } + + return res; +} + +static const char * +get_default_language_name (GdmSession *self) +{ + if (self->priv->saved_language != NULL) { + return self->priv->saved_language; + } + + return setlocale (LC_MESSAGES, NULL); +} + +static const char * +get_fallback_session_name (GdmSession *self) +{ + const char **search_dirs; + int i; + char *name; + GSequence *sessions; + GSequenceIter *session; + + if (self->priv->fallback_session_name != NULL) { + /* verify that the cached version still exists */ + if (get_session_command_for_name (self->priv->fallback_session_name, NULL)) { + goto out; + } + } + + name = g_strdup ("gnome"); + if (get_session_command_for_name (name, NULL)) { + g_free (self->priv->fallback_session_name); + self->priv->fallback_session_name = name; + goto out; + } + g_free (name); + + sessions = g_sequence_new (g_free); + + search_dirs = get_system_session_dirs (); + for (i = 0; search_dirs[i] != NULL; i++) { + GDir *dir; + const char *base_name; + + dir = g_dir_open (search_dirs[i], 0, NULL); + + if (dir == NULL) { + continue; + } + + do { + base_name = g_dir_read_name (dir); + + if (base_name == NULL) { + break; + } + + if (!g_str_has_suffix (base_name, ".desktop")) { + continue; + } + + if (get_session_command_for_file (base_name, NULL)) { + + g_sequence_insert_sorted (sessions, g_strdup (base_name), (GCompareDataFunc) g_strcmp0, NULL); + } + } while (base_name != NULL); + + g_dir_close (dir); + } + + name = NULL; + session = g_sequence_get_begin_iter (sessions); + do { + if (g_sequence_get (session)) { + char *base_name; + + g_free (name); + base_name = g_sequence_get (session); + name = g_strndup (base_name, + strlen (base_name) - + strlen (".desktop")); + + break; + } + session = g_sequence_iter_next (session); + } while (!g_sequence_iter_is_end (session)); + + g_free (self->priv->fallback_session_name); + self->priv->fallback_session_name = name; + + g_sequence_free (sessions); + + out: + return self->priv->fallback_session_name; +} + +static const char * +get_default_session_name (GdmSession *self) +{ + if (self->priv->saved_session != NULL) { + return self->priv->saved_session; + } + + return get_fallback_session_name (self); +} + +static void +gdm_session_defaults_changed (GdmSession *self) +{ + emit_default_language_name_changed (self, + get_default_language_name (self)); + emit_default_session_name_changed (self, + get_default_session_name (self)); } void -gdm_session_start_conversation (GdmSession *session, - const char *service_name) +gdm_session_select_user (GdmSession *self, + const char *text) +{ + + g_debug ("GdmSession: Setting user: '%s'", text); + + g_free (self->priv->selected_user); + self->priv->selected_user = g_strdup (text); + + g_free (self->priv->saved_session); + self->priv->saved_session = NULL; + + g_free (self->priv->saved_language); + self->priv->saved_language = NULL; +} + +static DBusHandlerResult +gdm_session_handle_username_changed (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: changing username from '%s' to '%s'", + self->priv->selected_user != NULL ? self->priv->selected_user : "<unset>", + (strlen (text)) ? text : "<unset>"); + + gdm_session_select_user (self, (strlen (text) > 0) ? g_strdup (text) : NULL); + + emit_selected_user_changed (self, self->priv->selected_user); + + gdm_session_defaults_changed (self); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static void +cancel_pending_query (GdmSessionConversation *conversation) { - g_return_if_fail (GDM_IS_SESSION (session)); + DBusMessage *reply; + + if (conversation->message_pending_reply == NULL) { + return; + } + + g_debug ("GdmSession: Cancelling pending query"); + + reply = dbus_message_new_error (conversation->message_pending_reply, + GDM_SESSION_DBUS_ERROR_CANCEL, + "Operation cancelled"); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_connection_flush (conversation->worker_connection); + + dbus_message_unref (reply); + dbus_message_unref (conversation->message_pending_reply); + conversation->message_pending_reply = NULL; +} + +static void +answer_pending_query (GdmSessionConversation *conversation, + const char *answer) +{ + DBusMessage *reply; + DBusMessageIter iter; + + reply = dbus_message_new_method_return (conversation->message_pending_reply); + dbus_message_iter_init_append (reply, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &answer); + + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + dbus_message_unref (conversation->message_pending_reply); + conversation->message_pending_reply = NULL; +} + +static void +set_pending_query (GdmSessionConversation *conversation, + DBusMessage *message) +{ + g_assert (conversation->message_pending_reply == NULL); + + conversation->message_pending_reply = dbus_message_ref (message); +} + +static DBusHandlerResult +gdm_session_handle_info_query (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + set_pending_query (conversation, message); + + g_debug ("GdmSession: Emitting 'info-query' signal"); + emit_info_query (self, conversation->service_name, text); - GDM_SESSION_GET_IFACE (session)->start_conversation (session, service_name); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_secret_info_query (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + set_pending_query (conversation, message); + + g_debug ("GdmSession: Emitting 'secret-info-query' signal"); + emit_secret_info_query (self, conversation->service_name, text); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_info (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'info' signal"); + emit_info (self, conversation->service_name, text); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_cancel_pending_query (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + + g_debug ("GdmSession: worker cancelling pending query"); + + cancel_pending_query (conversation); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_problem (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'problem' signal"); + emit_problem (self, conversation->service_name, text); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_session_opened (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + + g_debug ("GdmSession: Handling SessionOpened"); + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + g_debug ("GdmSession: Emitting 'session-opened' signal"); + + emit_session_opened (self, conversation->service_name); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_open_failed (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'session-open-failed' signal"); + emit_session_open_failed (self, conversation->service_name, text); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_session_started (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + int pid; + + pid = 0; + + g_debug ("GdmSession: Handling SessionStarted"); + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'session-started' signal with pid '%d'", + pid); + + self->priv->session_pid = pid; + self->priv->session_conversation = conversation; + + emit_session_started (self, conversation->service_name, pid); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_start_failed (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'session-start-failed' signal"); + emit_session_start_failed (self, conversation->service_name, text); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_session_exited (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + int code; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_INT32, &code, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'session-exited' signal with exit code '%d'", + code); + + self->priv->session_conversation = NULL; + emit_session_exited (self, code); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_session_died (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + int code; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_INT32, &code, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + g_debug ("GdmSession: Emitting 'session-died' signal with signal number '%d'", + code); + + self->priv->session_conversation = NULL; + emit_session_died (self, code); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_saved_language_name_read (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *language_name; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &language_name, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + if (strcmp (language_name, + get_default_language_name (self)) != 0) { + g_free (self->priv->saved_language); + self->priv->saved_language = g_strdup (language_name); + + emit_default_language_name_changed (self, language_name); + } + + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +gdm_session_handle_saved_session_name_read (GdmSession *self, + GdmSessionConversation *conversation, + DBusMessage *message) +{ + DBusMessage *reply; + DBusError error; + const char *session_name; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &session_name, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + reply = dbus_message_new_method_return (message); + dbus_connection_send (conversation->worker_connection, reply, NULL); + dbus_message_unref (reply); + + if (! get_session_command_for_name (session_name, NULL)) { + /* ignore sessions that don't exist */ + g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name); + g_free (self->priv->saved_session); + self->priv->saved_session = NULL; + goto out; + } + + if (strcmp (session_name, + get_default_session_name (self)) != 0) { + g_free (self->priv->saved_session); + self->priv->saved_session = g_strdup (session_name); + + emit_default_session_name_changed (self, session_name); + } + out: + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +session_worker_message (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + GdmSessionConversation *conversation = user_data; + GdmSession *session; + + session = conversation->session; + + if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "InfoQuery")) { + return gdm_session_handle_info_query (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SecretInfoQuery")) { + return gdm_session_handle_secret_info_query (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Info")) { + return gdm_session_handle_info (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Problem")) { + return gdm_session_handle_problem (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "CancelPendingQuery")) { + return gdm_session_handle_cancel_pending_query (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "ServiceUnavailable")) { + return gdm_session_handle_service_unavailable (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SetupComplete")) { + return gdm_session_handle_setup_complete (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SetupFailed")) { + return gdm_session_handle_setup_failed (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "ResetComplete")) { + return gdm_session_handle_reset_complete (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "ResetFailed")) { + return gdm_session_handle_reset_failed (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Authenticated")) { + return gdm_session_handle_authenticated (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AuthenticationFailed")) { + return gdm_session_handle_authentication_failed (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Authorized")) { + return gdm_session_handle_authorized (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AuthorizationFailed")) { + return gdm_session_handle_authorization_failed (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Accredited")) { + return gdm_session_handle_accredited (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AccreditationFailed")) { + return gdm_session_handle_accreditation_failed (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "UsernameChanged")) { + return gdm_session_handle_username_changed (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionOpened")) { + return gdm_session_handle_session_opened (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "OpenFailed")) { + return gdm_session_handle_open_failed (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionStarted")) { + return gdm_session_handle_session_started (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "StartFailed")) { + return gdm_session_handle_start_failed (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionExited")) { + return gdm_session_handle_session_exited (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionDied")) { + return gdm_session_handle_session_died (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedLanguageNameRead")) { + return gdm_session_handle_saved_language_name_read (session, conversation, message); + } else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedSessionNameRead")) { + return gdm_session_handle_saved_session_name_read (session, conversation, message); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult +do_introspect (DBusConnection *connection, + DBusMessage *message) +{ + DBusMessage *reply; + GString *xml; + char *xml_string; + + g_debug ("GdmSession: Do introspect"); + + /* standard header */ + xml = g_string_new ("<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" + "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n" + "<node>\n" + " <interface name=\"org.freedesktop.DBus.Introspectable\">\n" + " <method name=\"Introspect\">\n" + " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n" + " </method>\n" + " </interface>\n"); + + /* interface */ + xml = g_string_append (xml, + " <interface name=\"org.gnome.DisplayManager.Session\">\n" + " <method name=\"SetupComplete\">\n" + " </method>\n" + " <method name=\"SetupFailed\">\n" + " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" + " </method>\n" + " <method name=\"ResetComplete\">\n" + " </method>\n" + " <method name=\"ResetFailed\">\n" + " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" + " </method>\n" + " <method name=\"Authenticated\">\n" + " </method>\n" + " <method name=\"AuthenticationFailed\">\n" + " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" + " </method>\n" + " <method name=\"Authorized\">\n" + " </method>\n" + " <method name=\"AuthorizationFailed\">\n" + " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" + " </method>\n" + " <method name=\"Accredited\">\n" + " </method>\n" + " <method name=\"AccreditationFailed\">\n" + " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" + " </method>\n" + " <method name=\"CancelPendingQuery\">\n" + " </method>\n" + " <method name=\"InfoQuery\">\n" + " <arg name=\"query\" direction=\"in\" type=\"s\"/>\n" + " <arg name=\"answer\" direction=\"out\" type=\"s\"/>\n" + " </method>\n" + " <method name=\"SecretInfoQuery\">\n" + " <arg name=\"query\" direction=\"in\" type=\"s\"/>\n" + " <arg name=\"answer\" direction=\"out\" type=\"s\"/>\n" + " </method>\n" + " <method name=\"Info\">\n" + " <arg name=\"text\" direction=\"in\" type=\"s\"/>\n" + " </method>\n" + " <method name=\"Problem\">\n" + " <arg name=\"text\" direction=\"in\" type=\"s\"/>\n" + " </method>\n" + " <method name=\"UsernameChanged\">\n" + " <arg name=\"text\" direction=\"in\" type=\"s\"/>\n" + " </method>\n" + " <method name=\"StartFailed\">\n" + " <arg name=\"message\" direction=\"in\" type=\"s\"/>\n" + " </method>\n" + " <method name=\"SessionStarted\">\n" + " <arg name=\"pid\" direction=\"in\" type=\"i\"/>\n" + " <arg name=\"environment\" direction=\"in\" type=\"as\"/>\n" + " </method>\n" + " <method name=\"SessionExited\">\n" + " <arg name=\"code\" direction=\"in\" type=\"i\"/>\n" + " </method>\n" + " <method name=\"SessionDied\">\n" + " <arg name=\"signal\" direction=\"in\" type=\"i\"/>\n" + " </method>\n" + " <signal name=\"Reset\">\n" + " </signal>\n" + " <signal name=\"Setup\">\n" + " <arg name=\"service_name\" type=\"s\"/>\n" + " <arg name=\"x11_display_name\" type=\"s\"/>\n" + " <arg name=\"display_device\" type=\"s\"/>\n" + " <arg name=\"display_seat\" type=\"s\"/>\n" + " <arg name=\"hostname\" type=\"s\"/>\n" + " <arg name=\"x11_authority_file\" type=\"s\"/>\n" + " </signal>\n" + " <signal name=\"SetupForUser\">\n" + " <arg name=\"service_name\" type=\"s\"/>\n" + " <arg name=\"x11_display_name\" type=\"s\"/>\n" + " <arg name=\"display_device\" type=\"s\"/>\n" + " <arg name=\"display_seat\" type=\"s\"/>\n" + " <arg name=\"hostname\" type=\"s\"/>\n" + " <arg name=\"x11_authority_file\" type=\"s\"/>\n" + " <arg name=\"username\" type=\"s\"/>\n" + " </signal>\n" + " <signal name=\"SetupForProgram\">\n" + " <arg name=\"service_name\" type=\"s\"/>\n" + " <arg name=\"x11_display_name\" type=\"s\"/>\n" + " <arg name=\"display_device\" type=\"s\"/>\n" + " <arg name=\"display_seat\" type=\"s\"/>\n" + " <arg name=\"hostname\" type=\"s\"/>\n" + " <arg name=\"x11_authority_file\" type=\"s\"/>\n" + " <arg name=\"log_file\" type=\"s\"/>\n" + " </signal>\n" + " <signal name=\"Authenticate\">\n" + " </signal>\n" + " <signal name=\"Authorize\">\n" + " </signal>\n" + " <signal name=\"EstablishCredentials\">\n" + " </signal>\n" + " <signal name=\"RefreshCredentials\">\n" + " </signal>\n" + " <signal name=\"SetEnvironmentVariable\">\n" + " <arg name=\"name\" type=\"s\"/>\n" + " <arg name=\"value\" type=\"s\"/>\n" + " </signal>\n" + " <signal name=\"SetLanguageName\">\n" + " <arg name=\"language_name\" type=\"s\"/>\n" + " </signal>\n" + " <signal name=\"SetSessionName\">\n" + " <arg name=\"session_name\" type=\"s\"/>\n" + " </signal>\n" + " <signal name=\"SetSessionType\">\n" + " <arg name=\"session_type\" type=\"s\"/>\n" + " </signal>\n" + " <signal name=\"StartProgram\">\n" + " <arg name=\"command\" type=\"s\"/>\n" + " </signal>\n" + " </interface>\n"); + + reply = dbus_message_new_method_return (message); + + xml = g_string_append (xml, "</node>\n"); + xml_string = g_string_free (xml, FALSE); + + dbus_message_append_args (reply, + DBUS_TYPE_STRING, &xml_string, + DBUS_TYPE_INVALID); + + g_free (xml_string); + + if (reply == NULL) { + g_error ("No memory"); + } + + if (! dbus_connection_send (connection, reply, NULL)) { + g_error ("No memory"); + } + + dbus_message_unref (reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +session_message_handler (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + const char *dbus_destination = dbus_message_get_destination (message); + const char *dbus_path = dbus_message_get_path (message); + const char *dbus_interface = dbus_message_get_interface (message); + const char *dbus_member = dbus_message_get_member (message); + + g_debug ("session_message_handler: destination=%s obj_path=%s interface=%s method=%s", + dbus_destination ? dbus_destination : "(null)", + dbus_path ? dbus_path : "(null)", + dbus_interface ? dbus_interface : "(null)", + dbus_member ? dbus_member : "(null)"); + + if (dbus_message_is_method_call (message, "org.freedesktop.DBus", "AddMatch")) { + DBusMessage *reply; + + reply = dbus_message_new_method_return (message); + + if (reply == NULL) { + g_error ("No memory"); + } + + if (! dbus_connection_send (connection, reply, NULL)) { + g_error ("No memory"); + } + + dbus_message_unref (reply); + + return DBUS_HANDLER_RESULT_HANDLED; + } else if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") && + strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0) { + + g_debug ("GdmSession: Disconnected"); + + /*dbus_connection_unref (connection);*/ + + return DBUS_HANDLER_RESULT_HANDLED; + } else if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + return do_introspect (connection, message); + } else { + return session_worker_message (connection, message, user_data); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +/* Note: Use abstract sockets like dbus does by default on Linux. Abstract + * sockets are only available on Linux. + */ +static char * +generate_address (void) +{ + char *path; +#if defined (__linux__) + int i; + char tmp[9]; + + for (i = 0; i < 8; i++) { + if (g_random_int_range (0, 2) == 0) { + tmp[i] = g_random_int_range ('a', 'z' + 1); + } else { + tmp[i] = g_random_int_range ('A', 'Z' + 1); + } + } + tmp[8] = '\0'; + + path = g_strdup_printf ("unix:abstract=/tmp/gdm-session-%s", tmp); +#else + path = g_strdup ("unix:tmpdir=/tmp"); +#endif + + return path; +} + +static void +session_unregister_handler (DBusConnection *connection, + void *user_data) +{ + g_debug ("session_unregister_handler"); +} + +static GdmSessionConversation * +find_conversation_by_pid (GdmSession *self, + GPid pid) +{ + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, self->priv->conversations); + while (g_hash_table_iter_next (&iter, &key, &value)) { + GdmSessionConversation *conversation; + + conversation = (GdmSessionConversation *) value; + + if (conversation->worker_pid == pid) { + return conversation; + } + } + + return NULL; +} + +static dbus_bool_t +allow_user_function (DBusConnection *connection, + unsigned long uid, + void *data) +{ + if (0 == uid) { + return TRUE; + } + + g_debug ("GdmSession: User not allowed"); + + return FALSE; +} + +static gboolean +register_worker (GdmSession *self, + DBusConnection *connection) +{ + GdmSessionConversation *conversation; + DBusObjectPathVTable vtable = { &session_unregister_handler, + &session_message_handler, + NULL, NULL, NULL, NULL }; + GList *connection_node; + gulong pid; + + g_debug ("GdmSession: Authenticating new connection"); + + connection_node = g_list_find (self->priv->pending_connections, connection); + + if (connection_node == NULL) { + g_debug ("GdmSession: Ignoring connection that we aren't tracking"); + return FALSE; + } + + self->priv->pending_connections = + g_list_delete_link (self->priv->pending_connections, + connection_node); + + if (!dbus_connection_get_unix_process_id (connection, &pid)) { + g_warning ("GdmSession: Unable to read pid on new worker connection"); + dbus_connection_unref (connection); + return FALSE; + } + + conversation = find_conversation_by_pid (self, (GPid) pid); + + if (conversation == NULL) { + g_warning ("GdmSession: New worker connection is from unknown source"); + dbus_connection_unref (connection); + return FALSE; + } + + conversation->worker_connection = connection; + + g_debug ("GdmSession: worker connection is %p", connection); + + dbus_connection_register_object_path (connection, + GDM_SESSION_DBUS_PATH, + &vtable, + conversation); + + g_debug ("GdmSession: Emitting conversation-started signal"); + emit_conversation_started (self, conversation->service_name); + + g_debug ("GdmSession: Conversation started"); + + return TRUE; +} + +static DBusHandlerResult +on_message (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + GdmSession *self = GDM_SESSION (user_data); + + g_debug ("GdmSession: got message"); + + if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Hello")) { + DBusMessage *reply; + + if (register_worker (self, connection)) { + reply = dbus_message_new_method_return (message); + } else { + reply = dbus_message_new_error (message, DBUS_ERROR_FAILED, ""); + } + + dbus_connection_send (connection, reply, NULL); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void +handle_connection (DBusServer *server, + DBusConnection *new_connection, + void *user_data) +{ + GdmSession *self = GDM_SESSION (user_data); + g_debug ("GdmSession: Handing new connection"); + + /* add to the list of pending connections. We won't be able to + * associate it with a specific worker conversation until we have + * authenticated the connection (from the Hello handler). + */ + self->priv->pending_connections = + g_list_prepend (self->priv->pending_connections, + dbus_connection_ref (new_connection)); + dbus_connection_setup_with_g_main (new_connection, NULL); + dbus_connection_set_exit_on_disconnect (new_connection, FALSE); + + dbus_connection_set_unix_user_function (new_connection, + allow_user_function, + self, + NULL); + dbus_connection_add_filter (new_connection, on_message, self, NULL); +} + +static gboolean +setup_server (GdmSession *self) +{ + DBusError error; + gboolean ret; + char *address; + const char *auth_mechanisms[] = {"EXTERNAL", NULL}; + + ret = FALSE; + + g_debug ("GdmSession: Creating D-Bus server for session"); + + address = generate_address (); + + dbus_error_init (&error); + self->priv->server = dbus_server_listen (address, &error); + g_free (address); + + if (self->priv->server == NULL) { + g_warning ("Cannot create D-BUS server for the session: %s", error.message); + /* FIXME: should probably fail if we can't create the socket */ + goto out; + } + + dbus_server_setup_with_g_main (self->priv->server, NULL); + dbus_server_set_auth_mechanisms (self->priv->server, auth_mechanisms); + dbus_server_set_new_connection_function (self->priv->server, + handle_connection, + self, + NULL); + ret = TRUE; + + g_free (self->priv->server_address); + self->priv->server_address = dbus_server_get_address (self->priv->server); + + g_debug ("GdmSession: D-Bus server listening on %s", self->priv->server_address); + + out: + + return ret; +} + +static void +free_conversation (GdmSessionConversation *conversation) +{ + if (conversation->job != NULL) { + g_warning ("Freeing conversation '%s' with active job", conversation->service_name); + } + + g_free (conversation->service_name); + g_free (conversation); +} + +static void +gdm_session_init (GdmSession *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + GDM_TYPE_SESSION, + GdmSessionPrivate); + + g_signal_connect (self, + "authentication-failed", + G_CALLBACK (on_authentication_failed), + NULL); + g_signal_connect (self, + "session-started", + G_CALLBACK (on_session_started), + NULL); + g_signal_connect (self, + "session-start-failed", + G_CALLBACK (on_session_start_failed), + NULL); + g_signal_connect (self, + "session-exited", + G_CALLBACK (on_session_exited), + NULL); + + self->priv->conversations = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) + free_conversation); + self->priv->environment = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); + + setup_server (self); + +} + +static void +worker_started (GdmSessionWorkerJob *job, + GdmSessionConversation *conversation) +{ + g_debug ("GdmSession: Worker job started"); +} + +static void +worker_exited (GdmSessionWorkerJob *job, + int code, + GdmSessionConversation *conversation) +{ + + g_debug ("GdmSession: Worker job exited: %d", code); + + g_object_ref (conversation->job); + if (conversation->session->priv->session_conversation == conversation) { + emit_session_exited (GDM_SESSION (conversation->session), code); + } + + g_hash_table_steal (conversation->session->priv->conversations, conversation->service_name); + + g_debug ("GdmSession: Emitting conversation-stopped signal"); + emit_conversation_stopped (GDM_SESSION (conversation->session), + conversation->service_name); + g_object_unref (conversation->job); + + if (conversation->is_stopping) { + g_object_unref (conversation->job); + conversation->job = NULL; + } + + free_conversation (conversation); +} + +static void +worker_died (GdmSessionWorkerJob *job, + int signum, + GdmSessionConversation *conversation) +{ + + g_debug ("GdmSession: Worker job died: %d", signum); + + g_object_ref (conversation->job); + if (conversation->session->priv->session_conversation == conversation) { + emit_session_died (GDM_SESSION (conversation->session), signum); + } + + g_hash_table_steal (conversation->session->priv->conversations, conversation->service_name); + + g_debug ("GdmSession: Emitting conversation-stopped signal"); + emit_conversation_stopped (GDM_SESSION (conversation->session), + conversation->service_name); + g_object_unref (conversation->job); + + if (conversation->is_stopping) { + g_object_unref (conversation->job); + conversation->job = NULL; + } + + free_conversation (conversation); +} + +static GdmSessionConversation * +start_conversation (GdmSession *self, + const char *service_name) +{ + GdmSessionConversation *conversation; + char *job_name; + + conversation = g_new0 (GdmSessionConversation, 1); + conversation->session = self; + conversation->service_name = g_strdup (service_name); + conversation->worker_pid = -1; + conversation->job = gdm_session_worker_job_new (); + gdm_session_worker_job_set_server_address (conversation->job, self->priv->server_address); + g_signal_connect (conversation->job, + "started", + G_CALLBACK (worker_started), + conversation); + g_signal_connect (conversation->job, + "exited", + G_CALLBACK (worker_exited), + conversation); + g_signal_connect (conversation->job, + "died", + G_CALLBACK (worker_died), + conversation); + + job_name = g_strdup_printf ("gdm-session-worker [pam/%s]", service_name); + if (!gdm_session_worker_job_start (conversation->job, job_name)) { + g_object_unref (conversation->job); + g_free (conversation->service_name); + g_free (conversation); + g_free (job_name); + return NULL; + } + + g_free (job_name); + + conversation->worker_pid = gdm_session_worker_job_get_pid (conversation->job); + + return conversation; +} + +static void +stop_conversation (GdmSessionConversation *conversation) +{ + GdmSession *session; + + session = conversation->session; + + if (conversation->worker_connection != NULL) { + dbus_connection_remove_filter (conversation->worker_connection, on_message, session); + + dbus_connection_close (conversation->worker_connection); + conversation->worker_connection = NULL; + } + + conversation->is_stopping = TRUE; + gdm_session_worker_job_stop (conversation->job); +} + +static void +stop_conversation_now (GdmSessionConversation *conversation) +{ + GdmSession *session; + + session = conversation->session; + + if (conversation->worker_connection != NULL) { + dbus_connection_remove_filter (conversation->worker_connection, on_message, session); + + dbus_connection_close (conversation->worker_connection); + conversation->worker_connection = NULL; + } + + gdm_session_worker_job_stop_now (conversation->job); + g_object_unref (conversation->job); + conversation->job = NULL; } void -gdm_session_stop_conversation (GdmSession *session, - const char *service_name) +gdm_session_start_conversation (GdmSession *self, + const char *service_name) { - g_return_if_fail (GDM_IS_SESSION (session)); + GdmSessionConversation *conversation; + + g_return_if_fail (GDM_IS_SESSION (self)); + + conversation = g_hash_table_lookup (self->priv->conversations, + service_name); + + if (conversation != NULL) { + if (!conversation->is_stopping) { + g_warning ("GdmSession: conversation %s started more than once", service_name); + return; + } + g_debug ("GdmSession: stopping old conversation %s", service_name); + gdm_session_worker_job_stop_now (conversation->job); + g_object_unref (conversation->job); + conversation->job = NULL; + } - GDM_SESSION_GET_IFACE (session)->stop_conversation (session, service_name); + g_debug ("GdmSession: starting conversation %s", service_name); + + conversation = start_conversation (self, service_name); + + g_hash_table_insert (self->priv->conversations, + g_strdup (service_name), conversation); } void -gdm_session_close (GdmSession *session) +gdm_session_stop_conversation (GdmSession *self, + const char *service_name) +{ + GdmSessionConversation *conversation; + + g_return_if_fail (GDM_IS_SESSION (self)); + + g_debug ("GdmSession: stopping conversation %s", service_name); + + conversation = find_conversation_by_name (self, service_name); + + if (conversation != NULL) { + stop_conversation (conversation); + } +} + +static void +send_setup (GdmSession *self, + const char *service_name) +{ + DBusMessage *message; + DBusMessageIter iter; + const char *display_name; + const char *display_device; + const char *display_seat_id; + const char *display_hostname; + const char *display_x11_authority_file; + GdmSessionConversation *conversation; + + g_assert (service_name != NULL); + + if (self->priv->display_name != NULL) { + display_name = self->priv->display_name; + } else { + display_name = ""; + } + if (self->priv->display_hostname != NULL) { + display_hostname = self->priv->display_hostname; + } else { + display_hostname = ""; + } + if (self->priv->display_device != NULL) { + display_device = self->priv->display_device; + } else { + display_device = ""; + } + if (self->priv->display_seat_id != NULL) { + display_seat_id = self->priv->display_seat_id; + } else { + display_seat_id = ""; + } + if (self->priv->display_x11_authority_file != NULL) { + display_x11_authority_file = self->priv->display_x11_authority_file; + } else { + display_x11_authority_file = ""; + } + + g_debug ("GdmSession: Beginning setup"); + + message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, + GDM_SESSION_DBUS_INTERFACE, + "Setup"); + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file); + + conversation = find_conversation_by_name (self, service_name); + if (conversation != NULL && ! send_dbus_message (conversation, message)) { + g_debug ("GdmSession: Could not send %s signal", "Setup"); + } + + dbus_message_unref (message); +} + +static void +send_setup_for_user (GdmSession *self, + const char *service_name) +{ + DBusMessage *message; + DBusMessageIter iter; + const char *display_name; + const char *display_device; + const char *display_seat_id; + const char *display_hostname; + const char *display_x11_authority_file; + const char *selected_user; + GdmSessionConversation *conversation; + + g_assert (service_name != NULL); + + if (self->priv->display_name != NULL) { + display_name = self->priv->display_name; + } else { + display_name = ""; + } + if (self->priv->display_hostname != NULL) { + display_hostname = self->priv->display_hostname; + } else { + display_hostname = ""; + } + if (self->priv->display_device != NULL) { + display_device = self->priv->display_device; + } else { + display_device = ""; + } + if (self->priv->display_seat_id != NULL) { + display_seat_id = self->priv->display_seat_id; + } else { + display_seat_id = ""; + } + if (self->priv->display_x11_authority_file != NULL) { + display_x11_authority_file = self->priv->display_x11_authority_file; + } else { + display_x11_authority_file = ""; + } + if (self->priv->selected_user != NULL) { + selected_user = self->priv->selected_user; + } else { + selected_user = ""; + } + + g_debug ("GdmSession: Beginning setup for user %s", self->priv->selected_user); + + message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, + GDM_SESSION_DBUS_INTERFACE, + "SetupForUser"); + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &selected_user); + + conversation = find_conversation_by_name (self, service_name); + if (conversation != NULL && ! send_dbus_message (conversation, message)) { + g_debug ("GdmSession: Could not send %s signal", "SetupForUser"); + } + + dbus_message_unref (message); +} + +static void +send_setup_for_program (GdmSession *self, + const char *service_name, + const char *log_file) { - g_return_if_fail (GDM_IS_SESSION (session)); + DBusMessage *message; + DBusMessageIter iter; + const char *display_name; + const char *display_device; + const char *display_seat_id; + const char *display_hostname; + const char *display_x11_authority_file; + GdmSessionConversation *conversation; + + g_assert (service_name != NULL); + + if (self->priv->display_name != NULL) { + display_name = self->priv->display_name; + } else { + display_name = ""; + } + if (self->priv->display_hostname != NULL) { + display_hostname = self->priv->display_hostname; + } else { + display_hostname = ""; + } + if (self->priv->display_device != NULL) { + display_device = self->priv->display_device; + } else { + display_device = ""; + } + if (self->priv->display_seat_id != NULL) { + display_seat_id = self->priv->display_seat_id; + } else { + display_seat_id = ""; + } + if (self->priv->display_x11_authority_file != NULL) { + display_x11_authority_file = self->priv->display_x11_authority_file; + } else { + display_x11_authority_file = ""; + } + + g_debug ("GdmSession: Beginning setup for session for program with log '%s'", log_file); + + message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, + GDM_SESSION_DBUS_INTERFACE, + "SetupForProgram"); + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &log_file); - GDM_SESSION_GET_IFACE (session)->close (session); + conversation = find_conversation_by_name (self, service_name); + if (conversation != NULL && ! send_dbus_message (conversation, message)) { + g_debug ("GdmSession: Could not send %s signal", "SetupForProgram"); + } + + dbus_message_unref (message); } void -gdm_session_setup (GdmSession *session, +gdm_session_setup (GdmSession *self, const char *service_name) { - g_return_if_fail (GDM_IS_SESSION (session)); - GDM_SESSION_GET_IFACE (session)->setup (session, service_name); + g_return_if_fail (GDM_IS_SESSION (self)); + + send_setup (self, service_name); + gdm_session_defaults_changed (self); } void -gdm_session_setup_for_user (GdmSession *session, +gdm_session_setup_for_user (GdmSession *self, const char *service_name, const char *username) { - g_return_if_fail (GDM_IS_SESSION (session)); - GDM_SESSION_GET_IFACE (session)->setup_for_user (session, service_name, username); + g_return_if_fail (GDM_IS_SESSION (self)); + g_return_if_fail (username != NULL); + + gdm_session_select_user (self, username); + + send_setup_for_user (self, service_name); + gdm_session_defaults_changed (self); } void -gdm_session_setup_for_program (GdmSession *session, +gdm_session_setup_for_program (GdmSession *self, const char *service_name, const char *log_file) { - g_return_if_fail (GDM_IS_SESSION (session)); - GDM_SESSION_GET_IFACE (session)->setup_for_program (session, service_name, log_file); + g_return_if_fail (GDM_IS_SESSION (self)); + + send_setup_for_program (self, service_name, log_file); +} + +void +gdm_session_authenticate (GdmSession *self, + const char *service_name) +{ + GdmSessionConversation *conversation; + + g_return_if_fail (GDM_IS_SESSION (self)); + + conversation = find_conversation_by_name (self, service_name); + if (conversation != NULL) { + send_dbus_void_signal (conversation, "Authenticate"); + } +} + +void +gdm_session_authorize (GdmSession *self, + const char *service_name) +{ + GdmSessionConversation *conversation; + + g_return_if_fail (GDM_IS_SESSION (self)); + + conversation = find_conversation_by_name (self, service_name); + if (conversation != NULL) { + send_dbus_void_signal (conversation, "Authorize"); + } +} + +void +gdm_session_accredit (GdmSession *self, + const char *service_name, + int cred_flag) +{ + GdmSessionConversation *conversation; + + g_return_if_fail (GDM_IS_SESSION (self)); + + conversation = find_conversation_by_name (self, service_name); + if (conversation == NULL) { + return; + } + + switch (cred_flag) { + case GDM_SESSION_CRED_ESTABLISH: + send_dbus_void_signal (conversation, "EstablishCredentials"); + break; + case GDM_SESSION_CRED_REFRESH: + send_dbus_void_signal (conversation, "RefreshCredentials"); + break; + default: + g_assert_not_reached (); + } +} + +static void +send_environment_variable (const char *key, + const char *value, + GdmSessionConversation *conversation) +{ + DBusMessage *message; + DBusMessageIter iter; + + message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH, + GDM_SESSION_DBUS_INTERFACE, + "SetEnvironmentVariable"); + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value); + + if (! send_dbus_message (conversation, message)) { + g_debug ("GdmSession: Could not send %s signal", "SetEnvironmentVariable"); + } + + dbus_message_unref (message); +} + +static void +send_environment (GdmSession *self, + GdmSessionConversation *conversation) +{ + + g_hash_table_foreach (self->priv->environment, + (GHFunc) send_environment_variable, + conversation); +} + +static const char * +get_language_name (GdmSession *self) +{ + if (self->priv->selected_language != NULL) { + return self->priv->selected_language; + } + + return get_default_language_name (self); +} + +static const char * +get_session_name (GdmSession *self) +{ + /* FIXME: test the session names before we use them? */ + + if (self->priv->selected_session != NULL) { + return self->priv->selected_session; + } + + return get_default_session_name (self); +} + +static char * +get_session_command (GdmSession *self) +{ + gboolean res; + char *command; + const char *session_name; + + session_name = get_session_name (self); + + command = NULL; + res = get_session_command_for_name (session_name, &command); + if (! res) { + g_critical ("Cannot find a command for specified session: %s", session_name); + exit (1); + } + + return command; } void -gdm_session_set_environment_variable (GdmSession *session, +gdm_session_set_environment_variable (GdmSession *self, const char *key, const char *value) { - g_return_if_fail (GDM_IS_SESSION (session)); - GDM_SESSION_GET_IFACE (session)->set_environment_variable (session, key, value); + g_return_if_fail (key != NULL); + g_return_if_fail (value != NULL); + + g_hash_table_replace (self->priv->environment, + g_strdup (key), + g_strdup (value)); +} + +static void +setup_session_environment (GdmSession *self) +{ + const char *locale; + + gdm_session_set_environment_variable (self, + "GDMSESSION", + get_session_name (self)); + gdm_session_set_environment_variable (self, + "DESKTOP_SESSION", + get_session_name (self)); + + locale = get_language_name (self); + + if (locale != NULL && locale[0] != '\0') { + gdm_session_set_environment_variable (self, + "LANG", + locale); + gdm_session_set_environment_variable (self, + "GDM_LANG", + locale); + } + + gdm_session_set_environment_variable (self, + "DISPLAY", + self->priv->display_name); + + if (self->priv->user_x11_authority_file != NULL) { + gdm_session_set_environment_variable (self, + "XAUTHORITY", + self->priv->user_x11_authority_file); + } + + if (g_getenv ("WINDOWPATH") != NULL) { + gdm_session_set_environment_variable (self, + "WINDOWPATH", + g_getenv ("WINDOWPATH")); + } + + + /* FIXME: We do this here and in the session worker. We should consolidate + * somehow. + */ + gdm_session_set_environment_variable (self, + "PATH", + strcmp (BINDIR, "/usr/bin") == 0? + GDM_SESSION_DEFAULT_PATH : + BINDIR ":" GDM_SESSION_DEFAULT_PATH); + } void -gdm_session_authenticate (GdmSession *session, +gdm_session_open_session (GdmSession *self, const char *service_name) { - g_return_if_fail (GDM_IS_SESSION (session)); + GdmSessionConversation *conversation; + + g_return_if_fail (GDM_IS_SESSION (self)); + + conversation = find_conversation_by_name (self, service_name); + + send_dbus_string_signal (conversation, "OpenSession", service_name); +} + +static void +stop_all_other_conversations (GdmSession *self, + GdmSessionConversation *conversation_to_keep, + gboolean now) +{ + GHashTableIter iter; + gpointer key, value; + + if (self->priv->conversations == NULL) { + return; + } + + if (conversation_to_keep == NULL) { + g_debug ("GdmSession: Stopping all conversations"); + } else { + g_debug ("GdmSession: Stopping all conversations " + "except for %s", conversation_to_keep->service_name); + } + + g_hash_table_iter_init (&iter, self->priv->conversations); + while (g_hash_table_iter_next (&iter, &key, &value)) { + GdmSessionConversation *conversation; + + conversation = (GdmSessionConversation *) value; + + if (conversation == conversation_to_keep) { + if (now) { + g_hash_table_iter_steal (&iter); + g_free (key); + } + } else { + if (now) { + stop_conversation_now (conversation); + } else { + stop_conversation (conversation); + } + } + } + + if (now) { + g_hash_table_remove_all (self->priv->conversations); + + if (conversation_to_keep != NULL) { + g_hash_table_insert (self->priv->conversations, + g_strdup (conversation_to_keep->service_name), + conversation_to_keep); + } + + if (self->priv->session_conversation != conversation_to_keep) { + self->priv->session_conversation = NULL; + } + } - GDM_SESSION_GET_IFACE (session)->authenticate (session, service_name); } void -gdm_session_authorize (GdmSession *session, - const char *service_name) +gdm_session_start_session (GdmSession *self, + const char *service_name) { - g_return_if_fail (GDM_IS_SESSION (session)); + GdmSessionConversation *conversation; + char *command; + char *program; + + g_return_if_fail (GDM_IS_SESSION (self)); + g_return_if_fail (self->priv->session_conversation == NULL); + + conversation = find_conversation_by_name (self, service_name); - GDM_SESSION_GET_IFACE (session)->authorize (session, service_name); + if (conversation == NULL) { + g_warning ("GdmSession: Tried to start session of " + "nonexistent conversation %s", service_name); + return; + } + + stop_all_other_conversations (self, conversation, FALSE); + + if (self->priv->selected_program == NULL) { + command = get_session_command (self); + + if (gdm_session_bypasses_xsession (self)) { + program = g_strdup (command); + } else { + program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command); + } + + g_free (command); + } else { + program = g_strdup (self->priv->selected_program); + } + + setup_session_environment (self); + send_environment (self, conversation); + + send_dbus_string_signal (conversation, "StartProgram", program); + g_free (program); +} + +static void +stop_all_conversations (GdmSession *self) +{ + stop_all_other_conversations (self, NULL, TRUE); } void -gdm_session_accredit (GdmSession *session, - const char *service_name, - int flag) +gdm_session_close (GdmSession *self) { - g_return_if_fail (GDM_IS_SESSION (session)); - GDM_SESSION_GET_IFACE (session)->accredit (session, service_name, flag); + g_return_if_fail (GDM_IS_SESSION (self)); + + g_debug ("GdmSession: Closing session"); + + if (self->priv->session_conversation != NULL) { + gdm_session_record_logout (self->priv->session_pid, + self->priv->selected_user, + self->priv->display_hostname, + self->priv->display_name, + self->priv->display_device); + } + + stop_all_conversations (self); + + g_list_foreach (self->priv->pending_connections, + (GFunc) dbus_connection_unref, NULL); + g_list_free (self->priv->pending_connections); + self->priv->pending_connections = NULL; + + g_free (self->priv->selected_user); + self->priv->selected_user = NULL; + + g_free (self->priv->selected_session); + self->priv->selected_session = NULL; + + g_free (self->priv->saved_session); + self->priv->saved_session = NULL; + + g_free (self->priv->selected_language); + self->priv->selected_language = NULL; + + g_free (self->priv->saved_language); + self->priv->saved_language = NULL; + + g_free (self->priv->user_x11_authority_file); + self->priv->user_x11_authority_file = NULL; + + g_hash_table_remove_all (self->priv->environment); + + self->priv->session_pid = -1; + self->priv->session_conversation = NULL; } void -gdm_session_answer_query (GdmSession *session, +gdm_session_answer_query (GdmSession *self, const char *service_name, const char *text) { - g_return_if_fail (GDM_IS_SESSION (session)); + GdmSessionConversation *conversation; + + g_return_if_fail (GDM_IS_SESSION (self)); + + conversation = find_conversation_by_name (self, service_name); + + answer_pending_query (conversation, text); +} + +void +gdm_session_cancel (GdmSession *self) +{ + g_return_if_fail (GDM_IS_SESSION (self)); + + stop_all_conversations (self); +} + +char * +gdm_session_get_username (GdmSession *self) +{ + g_return_val_if_fail (GDM_IS_SESSION (self), NULL); + + return g_strdup (self->priv->selected_user); +} + +char * +gdm_session_get_display_device (GdmSession *self) +{ + g_return_val_if_fail (GDM_IS_SESSION (self), NULL); + + return g_strdup (self->priv->display_device); +} + +char * +gdm_session_get_display_seat_id (GdmSession *self) +{ + g_return_val_if_fail (GDM_IS_SESSION (self), NULL); + + return g_strdup (self->priv->display_seat_id); +} + +gboolean +gdm_session_bypasses_xsession (GdmSession *self) +{ + GError *error; + GKeyFile *key_file; + gboolean res; + gboolean bypasses_xsession = FALSE; + char *filename; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); + + filename = g_strdup_printf ("%s.desktop", get_session_name (self)); + + key_file = g_key_file_new (); + error = NULL; + res = g_key_file_load_from_dirs (key_file, + filename, + get_system_session_dirs (), + NULL, + G_KEY_FILE_NONE, + &error); + if (! res) { + g_debug ("GdmSession: File '%s' not found: %s", filename, error->message); + goto out; + } + + error = NULL; + res = g_key_file_has_key (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-BypassXsession", NULL); + if (!res) { + goto out; + } else { + bypasses_xsession = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-BypassXsession", &error); + if (error) { + bypasses_xsession = FALSE; + g_error_free (error); + goto out; + } + if (bypasses_xsession) { + g_debug ("GdmSession: Session %s bypasses Xsession wrapper script", filename); + } + } - GDM_SESSION_GET_IFACE (session)->answer_query (session, service_name, text); +out: + g_free (filename); + return bypasses_xsession; } void -gdm_session_select_program (GdmSession *session, +gdm_session_select_program (GdmSession *self, const char *text) { - g_return_if_fail (GDM_IS_SESSION (session)); - GDM_SESSION_GET_IFACE (session)->select_program (session, text); + g_free (self->priv->selected_program); + + self->priv->selected_program = g_strdup (text); } void -gdm_session_select_session_type (GdmSession *session, +gdm_session_select_session_type (GdmSession *self, const char *text) { - g_return_if_fail (GDM_IS_SESSION (session)); + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, self->priv->conversations); + while (g_hash_table_iter_next (&iter, &key, &value)) { + GdmSessionConversation *conversation; - GDM_SESSION_GET_IFACE (session)->select_session_type (session, text); + conversation = (GdmSessionConversation *) value; + + send_dbus_string_signal (conversation, "SetSessionType", + text); + } } + void -gdm_session_select_session (GdmSession *session, +gdm_session_select_session (GdmSession *self, const char *text) { - g_return_if_fail (GDM_IS_SESSION (session)); + GHashTableIter iter; + gpointer key, value; + + g_free (self->priv->selected_session); - GDM_SESSION_GET_IFACE (session)->select_session (session, text); + if (strcmp (text, "__previous") == 0) { + self->priv->selected_session = NULL; + } else { + self->priv->selected_session = g_strdup (text); + } + + g_hash_table_iter_init (&iter, self->priv->conversations); + while (g_hash_table_iter_next (&iter, &key, &value)) { + GdmSessionConversation *conversation; + + conversation = (GdmSessionConversation *) value; + + send_dbus_string_signal (conversation, "SetSessionName", + get_session_name (self)); + } } void -gdm_session_select_language (GdmSession *session, +gdm_session_select_language (GdmSession *self, const char *text) { - g_return_if_fail (GDM_IS_SESSION (session)); + GHashTableIter iter; + gpointer key, value; + + g_free (self->priv->selected_language); + + if (strcmp (text, "__previous") == 0) { + self->priv->selected_language = NULL; + } else { + self->priv->selected_language = g_strdup (text); + } - GDM_SESSION_GET_IFACE (session)->select_language (session, text); + g_hash_table_iter_init (&iter, self->priv->conversations); + while (g_hash_table_iter_next (&iter, &key, &value)) { + GdmSessionConversation *conversation; + + conversation = (GdmSessionConversation *) value; + + send_dbus_string_signal (conversation, "SetLanguageName", + get_language_name (self)); + } } -void -gdm_session_select_user (GdmSession *session, - const char *text) +/* At some point we may want to read these right from + * the slave but for now I don't want the dependency */ +static void +set_display_name (GdmSession *self, + const char *name) { - g_return_if_fail (GDM_IS_SESSION (session)); + g_free (self->priv->display_name); + self->priv->display_name = g_strdup (name); +} - GDM_SESSION_GET_IFACE (session)->select_user (session, text); +static void +set_display_hostname (GdmSession *self, + const char *name) +{ + g_free (self->priv->display_hostname); + self->priv->display_hostname = g_strdup (name); } -void -gdm_session_cancel (GdmSession *session) +static void +set_display_device (GdmSession *self, + const char *name) { - g_return_if_fail (GDM_IS_SESSION (session)); + g_debug ("GdmSession: Setting display device: %s", name); + g_free (self->priv->display_device); + self->priv->display_device = g_strdup (name); +} - GDM_SESSION_GET_IFACE (session)->cancel (session); +static void +set_display_seat_id (GdmSession *self, + const char *name) +{ + g_free (self->priv->display_seat_id); + self->priv->display_seat_id = g_strdup (name); } -void -gdm_session_open_session (GdmSession *session, - const char *service_name) +static void +set_user_x11_authority_file (GdmSession *self, + const char *name) { - g_return_if_fail (GDM_IS_SESSION (session)); + g_free (self->priv->user_x11_authority_file); + self->priv->user_x11_authority_file = g_strdup (name); +} - GDM_SESSION_GET_IFACE (session)->open_session (session, service_name); +static void +set_display_x11_authority_file (GdmSession *self, + const char *name) +{ + g_free (self->priv->display_x11_authority_file); + self->priv->display_x11_authority_file = g_strdup (name); } -void -gdm_session_start_session (GdmSession *session, - const char *service_name) +static void +set_display_is_local (GdmSession *self, + gboolean is_local) +{ + self->priv->display_is_local = is_local; +} + +static void +gdm_session_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdmSession *self; + + self = GDM_SESSION (object); + + switch (prop_id) { + case PROP_DISPLAY_NAME: + set_display_name (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_HOSTNAME: + set_display_hostname (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_DEVICE: + set_display_device (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_SEAT_ID: + set_display_seat_id (self, g_value_get_string (value)); + break; + case PROP_USER_X11_AUTHORITY_FILE: + set_user_x11_authority_file (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_X11_AUTHORITY_FILE: + set_display_x11_authority_file (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_IS_LOCAL: + set_display_is_local (self, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdm_session_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdmSession *self; + + self = GDM_SESSION (object); + + switch (prop_id) { + case PROP_DISPLAY_NAME: + g_value_set_string (value, self->priv->display_name); + break; + case PROP_DISPLAY_HOSTNAME: + g_value_set_string (value, self->priv->display_hostname); + break; + case PROP_DISPLAY_DEVICE: + g_value_set_string (value, self->priv->display_device); + break; + case PROP_DISPLAY_SEAT_ID: + g_value_set_string (value, self->priv->display_seat_id); + break; + case PROP_USER_X11_AUTHORITY_FILE: + g_value_set_string (value, self->priv->user_x11_authority_file); + break; + case PROP_DISPLAY_X11_AUTHORITY_FILE: + g_value_set_string (value, self->priv->display_x11_authority_file); + break; + case PROP_DISPLAY_IS_LOCAL: + g_value_set_boolean (value, self->priv->display_is_local); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdm_session_dispose (GObject *object) +{ + GdmSession *self; + + self = GDM_SESSION (object); + + g_debug ("GdmSession: Disposing session"); + + gdm_session_close (self); + + g_free (self->priv->display_id); + self->priv->display_id = NULL; + + g_free (self->priv->display_name); + self->priv->display_name = NULL; + + g_free (self->priv->display_hostname); + self->priv->display_hostname = NULL; + + g_free (self->priv->display_device); + self->priv->display_device = NULL; + + g_free (self->priv->display_seat_id); + self->priv->display_seat_id = NULL; + + g_free (self->priv->display_x11_authority_file); + self->priv->display_x11_authority_file = NULL; + + g_free (self->priv->server_address); + self->priv->server_address = NULL; + + if (self->priv->server != NULL) { + dbus_server_disconnect (self->priv->server); + dbus_server_unref (self->priv->server); + self->priv->server = NULL; + } + + if (self->priv->environment != NULL) { + g_hash_table_destroy (self->priv->environment); + self->priv->environment = NULL; + } + + G_OBJECT_CLASS (gdm_session_parent_class)->dispose (object); +} + +static void +gdm_session_finalize (GObject *object) { - g_return_if_fail (GDM_IS_SESSION (session)); + GdmSession *self; + GObjectClass *parent_class; + + self = GDM_SESSION (object); + + g_free (self->priv->selected_user); + g_free (self->priv->selected_session); + g_free (self->priv->saved_session); + g_free (self->priv->selected_language); + g_free (self->priv->saved_language); - GDM_SESSION_GET_IFACE (session)->start_session (session, service_name); + g_free (self->priv->fallback_session_name); + + parent_class = G_OBJECT_CLASS (gdm_session_parent_class); + + if (parent_class->finalize != NULL) + parent_class->finalize (object); +} + +static GObject * +gdm_session_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GdmSession *self; + + self = GDM_SESSION (G_OBJECT_CLASS (gdm_session_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + return G_OBJECT (self); } static void -gdm_session_class_init (gpointer g_iface) +gdm_session_class_init (GdmSessionClass *session_class) { - GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (session_class); + + object_class->get_property = gdm_session_get_property; + object_class->set_property = gdm_session_set_property; + object_class->constructor = gdm_session_constructor; + object_class->dispose = gdm_session_dispose; + object_class->finalize = gdm_session_finalize; + + g_type_class_add_private (session_class, sizeof (GdmSessionPrivate)); signals [CONVERSATION_STARTED] = g_signal_new ("conversation-started", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, conversation_started), + G_STRUCT_OFFSET (GdmSessionClass, conversation_started), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -269,9 +3236,9 @@ gdm_session_class_init (gpointer g_iface) 1, G_TYPE_STRING); signals [CONVERSATION_STOPPED] = g_signal_new ("conversation-stopped", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, conversation_stopped), + G_STRUCT_OFFSET (GdmSessionClass, conversation_stopped), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -279,9 +3246,9 @@ gdm_session_class_init (gpointer g_iface) 1, G_TYPE_STRING); signals [SERVICE_UNAVAILABLE] = g_signal_new ("service-unavailable", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, service_unavailable), + G_STRUCT_OFFSET (GdmSessionClass, service_unavailable), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -290,9 +3257,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING); signals [SETUP_COMPLETE] = g_signal_new ("setup-complete", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, setup_complete), + G_STRUCT_OFFSET (GdmSessionClass, setup_complete), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -301,9 +3268,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING); signals [SETUP_FAILED] = g_signal_new ("setup-failed", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, setup_failed), + G_STRUCT_OFFSET (GdmSessionClass, setup_failed), NULL, NULL, g_cclosure_marshal_generic, @@ -312,9 +3279,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING, G_TYPE_STRING); signals [RESET_COMPLETE] = g_signal_new ("reset-complete", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, reset_complete), + G_STRUCT_OFFSET (GdmSessionClass, reset_complete), NULL, NULL, g_cclosure_marshal_VOID__VOID, @@ -322,9 +3289,9 @@ gdm_session_class_init (gpointer g_iface) 0); signals [RESET_FAILED] = g_signal_new ("reset-failed", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, reset_failed), + G_STRUCT_OFFSET (GdmSessionClass, reset_failed), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -333,9 +3300,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING); signals [AUTHENTICATED] = g_signal_new ("authenticated", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, authenticated), + G_STRUCT_OFFSET (GdmSessionClass, authenticated), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -343,9 +3310,9 @@ gdm_session_class_init (gpointer g_iface) 1, G_TYPE_STRING); signals [AUTHENTICATION_FAILED] = g_signal_new ("authentication-failed", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, authentication_failed), + G_STRUCT_OFFSET (GdmSessionClass, authentication_failed), NULL, NULL, g_cclosure_marshal_generic, @@ -354,9 +3321,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING, G_TYPE_STRING); signals [AUTHORIZED] = g_signal_new ("authorized", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, authorized), + G_STRUCT_OFFSET (GdmSessionClass, authorized), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -364,9 +3331,9 @@ gdm_session_class_init (gpointer g_iface) 1, G_TYPE_STRING); signals [AUTHORIZATION_FAILED] = g_signal_new ("authorization-failed", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, authorization_failed), + G_STRUCT_OFFSET (GdmSessionClass, authorization_failed), NULL, NULL, g_cclosure_marshal_generic, @@ -375,9 +3342,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING, G_TYPE_STRING); signals [ACCREDITED] = g_signal_new ("accredited", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, accredited), + G_STRUCT_OFFSET (GdmSessionClass, accredited), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -385,9 +3352,9 @@ gdm_session_class_init (gpointer g_iface) 1, G_TYPE_STRING); signals [ACCREDITATION_FAILED] = g_signal_new ("accreditation-failed", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, accreditation_failed), + G_STRUCT_OFFSET (GdmSessionClass, accreditation_failed), NULL, NULL, g_cclosure_marshal_generic, @@ -397,9 +3364,9 @@ gdm_session_class_init (gpointer g_iface) signals [INFO_QUERY] = g_signal_new ("info-query", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, info_query), + G_STRUCT_OFFSET (GdmSessionClass, info_query), NULL, NULL, g_cclosure_marshal_generic, @@ -408,9 +3375,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING, G_TYPE_STRING); signals [SECRET_INFO_QUERY] = g_signal_new ("secret-info-query", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, secret_info_query), + G_STRUCT_OFFSET (GdmSessionClass, secret_info_query), NULL, NULL, g_cclosure_marshal_generic, @@ -419,9 +3386,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING, G_TYPE_STRING); signals [INFO] = g_signal_new ("info", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, info), + G_STRUCT_OFFSET (GdmSessionClass, info), NULL, NULL, g_cclosure_marshal_generic, @@ -430,9 +3397,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING, G_TYPE_STRING); signals [PROBLEM] = g_signal_new ("problem", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, problem), + G_STRUCT_OFFSET (GdmSessionClass, problem), NULL, NULL, g_cclosure_marshal_generic, @@ -441,9 +3408,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING, G_TYPE_STRING); signals [SESSION_OPENED] = g_signal_new ("session-opened", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, session_opened), + G_STRUCT_OFFSET (GdmSessionClass, session_opened), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -452,9 +3419,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING); signals [SESSION_OPEN_FAILED] = g_signal_new ("session-open-failed", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, session_open_failed), + G_STRUCT_OFFSET (GdmSessionClass, session_open_failed), NULL, NULL, g_cclosure_marshal_generic, @@ -463,9 +3430,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING, G_TYPE_STRING); signals [SESSION_STARTED] = g_signal_new ("session-started", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, session_started), + G_STRUCT_OFFSET (GdmSessionClass, session_started), NULL, NULL, g_cclosure_marshal_generic, @@ -474,9 +3441,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING, G_TYPE_INT); signals [SESSION_START_FAILED] = g_signal_new ("session-start-failed", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, session_start_failed), + G_STRUCT_OFFSET (GdmSessionClass, session_start_failed), NULL, NULL, g_cclosure_marshal_generic, @@ -485,9 +3452,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING, G_TYPE_STRING); signals [SESSION_EXITED] = g_signal_new ("session-exited", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, session_exited), + G_STRUCT_OFFSET (GdmSessionClass, session_exited), NULL, NULL, g_cclosure_marshal_VOID__INT, @@ -496,9 +3463,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_INT); signals [SESSION_DIED] = g_signal_new ("session-died", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, session_died), + G_STRUCT_OFFSET (GdmSessionClass, session_died), NULL, NULL, g_cclosure_marshal_VOID__INT, @@ -507,9 +3474,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_INT); signals [SELECTED_USER_CHANGED] = g_signal_new ("selected-user-changed", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, selected_user_changed), + G_STRUCT_OFFSET (GdmSessionClass, selected_user_changed), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -518,9 +3485,9 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING); signals [DEFAULT_LANGUAGE_NAME_CHANGED] = g_signal_new ("default-language-name-changed", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, default_language_name_changed), + G_STRUCT_OFFSET (GdmSessionClass, default_language_name_changed), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -529,239 +3496,87 @@ gdm_session_class_init (gpointer g_iface) G_TYPE_STRING); signals [DEFAULT_SESSION_NAME_CHANGED] = g_signal_new ("default-session-name-changed", - iface_type, + GDM_TYPE_SESSION, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSessionIface, default_session_name_changed), + G_STRUCT_OFFSET (GdmSessionClass, default_session_name_changed), NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); -} - -void -_gdm_session_service_unavailable (GdmSession *session, - const char *service_name) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - - g_signal_emit (session, signals [SERVICE_UNAVAILABLE], 0, service_name); -} - -void -_gdm_session_setup_complete (GdmSession *session, - const char *service_name) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - - g_signal_emit (session, signals [SETUP_COMPLETE], 0, service_name); -} - -void -_gdm_session_setup_failed (GdmSession *session, - const char *service_name, - const char *text) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [SETUP_FAILED], 0, service_name, text); -} - -void -_gdm_session_reset_complete (GdmSession *session) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - - g_signal_emit (session, signals [RESET_COMPLETE], 0); -} - -void -_gdm_session_reset_failed (GdmSession *session, - const char *text) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [RESET_FAILED], 0, text); -} - -void -_gdm_session_authenticated (GdmSession *session, - const char *service_name) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - - g_signal_emit (session, signals [AUTHENTICATED], 0, service_name); -} - -void -_gdm_session_authentication_failed (GdmSession *session, - const char *service_name, - const char *text) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [AUTHENTICATION_FAILED], 0, service_name, text); -} - -void -_gdm_session_authorized (GdmSession *session, - const char *service_name) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - - g_signal_emit (session, signals [AUTHORIZED], 0, service_name); -} - -void -_gdm_session_authorization_failed (GdmSession *session, - const char *service_name, - const char *text) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [AUTHORIZATION_FAILED], 0, service_name, text); -} - -void -_gdm_session_accredited (GdmSession *session, - const char *service_name) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [ACCREDITED], 0, service_name); + g_object_class_install_property (object_class, + PROP_DISPLAY_NAME, + g_param_spec_string ("display-name", + "display name", + "display name", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_DISPLAY_HOSTNAME, + g_param_spec_string ("display-hostname", + "display hostname", + "display hostname", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_DISPLAY_IS_LOCAL, + g_param_spec_boolean ("display-is-local", + "display is local", + "display is local", + TRUE, + 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", + "display x11 authority file", + "display x11 authority file", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /* not construct only */ + g_object_class_install_property (object_class, + PROP_USER_X11_AUTHORITY_FILE, + g_param_spec_string ("user-x11-authority-file", + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_DISPLAY_DEVICE, + g_param_spec_string ("display-device", + "display device", + "display device", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (object_class, + PROP_DISPLAY_SEAT_ID, + g_param_spec_string ("display-seat-id", + "display seat id", + "display seat id", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); } -void -_gdm_session_accreditation_failed (GdmSession *session, - const char *service_name, - const char *text) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [ACCREDITATION_FAILED], 0, service_name, text); -} - -void -_gdm_session_info_query (GdmSession *session, - const char *service_name, - const char *text) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [INFO_QUERY], 0, service_name, text); -} - -void -_gdm_session_secret_info_query (GdmSession *session, - const char *service_name, - const char *text) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [SECRET_INFO_QUERY], 0, service_name, text); -} - -void -_gdm_session_info (GdmSession *session, - const char *service_name, - const char *text) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [INFO], 0, service_name, text); -} - -void -_gdm_session_problem (GdmSession *session, - const char *service_name, - const char *text) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [PROBLEM], 0, service_name, text); -} - -void -_gdm_session_session_opened (GdmSession *session, - const char *service_name) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [SESSION_OPENED], 0, service_name); -} - -void -_gdm_session_session_open_failed (GdmSession *session, - const char *service_name, - const char *text) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [SESSION_OPEN_FAILED], 0, service_name, text); -} - -void -_gdm_session_session_started (GdmSession *session, - const char *service_name, - int pid) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [SESSION_STARTED], 0, service_name, pid); -} - -void -_gdm_session_session_start_failed (GdmSession *session, - const char *service_name, - const char *text) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [SESSION_START_FAILED], 0, service_name, text); -} - -void -_gdm_session_session_exited (GdmSession *session, - int exit_code) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [SESSION_EXITED], 0, exit_code); -} - -void -_gdm_session_session_died (GdmSession *session, - int signal_number) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [SESSION_DIED], 0, signal_number); -} - -void -_gdm_session_conversation_started (GdmSession *session, - const char *service_name) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [CONVERSATION_STARTED], 0, service_name); -} - -void -_gdm_session_conversation_stopped (GdmSession *session, - const char *service_name) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [CONVERSATION_STOPPED], 0, service_name); -} - -void -_gdm_session_default_language_name_changed (GdmSession *session, - const char *language_name) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - - g_signal_emit (session, signals [DEFAULT_LANGUAGE_NAME_CHANGED], 0, language_name); -} - -void -_gdm_session_default_session_name_changed (GdmSession *session, - const char *session_name) -{ - g_return_if_fail (GDM_IS_SESSION (session)); - - g_signal_emit (session, signals [DEFAULT_SESSION_NAME_CHANGED], 0, session_name); -} - -void -_gdm_session_selected_user_changed (GdmSession *session, - const char *text) +GdmSession * +gdm_session_new (const char *display_name, + const char *display_hostname, + const char *display_device, + const char *display_seat_id, + const char *display_x11_authority_file, + gboolean display_is_local) { - g_return_if_fail (GDM_IS_SESSION (session)); - g_signal_emit (session, signals [SELECTED_USER_CHANGED], 0, text); + GdmSession *self; + + self = g_object_new (GDM_TYPE_SESSION, + "display-name", display_name, + "display-hostname", display_hostname, + "display-device", display_device, + "display-seat-id", display_seat_id, + "display-x11-authority-file", display_x11_authority_file, + "display-is-local", display_is_local, + NULL); + + return self; } diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h index 479d8e3f..1961be09 100644 --- a/daemon/gdm-session.h +++ b/daemon/gdm-session.h @@ -1,11 +1,11 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * - * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> + * Copyright (C) 2006 Ray Strode <rstrode@redhat.com> * * 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. + * the Free Software Foundation; either version 2, 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 @@ -14,11 +14,10 @@ * * 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. - * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. */ - #ifndef __GDM_SESSION_H #define __GDM_SESSION_H @@ -26,69 +25,29 @@ G_BEGIN_DECLS -#define GDM_TYPE_SESSION (gdm_session_get_type ()) -#define GDM_SESSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_SESSION, GdmSession)) -#define GDM_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_SESSION, GdmSessionClass)) -#define GDM_IS_SESSION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_SESSION)) -#define GDM_SESSION_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), GDM_TYPE_SESSION, GdmSessionIface)) +#define GDM_TYPE_SESSION (gdm_session_get_type ()) +#define GDM_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_SESSION, GdmSession)) +#define GDM_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_SESSION, GdmSessionClass)) +#define GDM_IS_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_SESSION)) +#define GDM_IS_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_SESSION)) +#define GDM_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SESSION, GdmSessionClass)) -typedef struct _GdmSession GdmSession; /* Dummy typedef */ -typedef struct _GdmSessionIface GdmSessionIface; +typedef struct _GdmSessionPrivate GdmSessionPrivate; enum { GDM_SESSION_CRED_ESTABLISH = 0, GDM_SESSION_CRED_REFRESH, }; -struct _GdmSessionIface +typedef struct { - GTypeInterface base_iface; + GObject parent; + GdmSessionPrivate *priv; +} GdmSession; - /* Methods */ - void (* start_conversation) (GdmSession *session, - const char *service_name); - void (* stop_conversation) (GdmSession *session, - const char *service_name); - void (* service_unavailable) (GdmSession *session, - const char *service_name); - void (* setup) (GdmSession *session, - const char *service_name); - void (* setup_for_user) (GdmSession *session, - const char *service_name, - const char *username); - void (* setup_for_program) (GdmSession *session, - const char *service_name, - const char *log_file); - void (* set_environment_variable) (GdmSession *session, - const char *key, - const char *value); - void (* reset) (GdmSession *session); - void (* authenticate) (GdmSession *session, - const char *service_name); - void (* authorize) (GdmSession *session, - const char *service_name); - void (* accredit) (GdmSession *session, - const char *service_name, - int cred_flag); - void (* open_session) (GdmSession *session, - const char *service_name); - void (* answer_query) (GdmSession *session, - const char *service_name, - const char *text); - void (* select_language) (GdmSession *session, - const char *text); - void (* select_program) (GdmSession *session, - const char *text); - void (* select_session_type) (GdmSession *session, - const char *session_type); - void (* select_session) (GdmSession *session, - const char *text); - void (* select_user) (GdmSession *session, - const char *text); - void (* start_session) (GdmSession *session, - const char *service_name); - void (* close) (GdmSession *session); - void (* cancel) (GdmSession *session); +typedef struct +{ + GObjectClass parent_class; /* Signals */ void (* setup_complete) (GdmSession *session, @@ -146,6 +105,8 @@ struct _GdmSessionIface const char *service_name); void (* conversation_stopped) (GdmSession *session, const char *service_name); + void (* service_unavailable) (GdmSession *session, + const char *service_name); void (* selected_user_changed) (GdmSession *session, const char *text); @@ -153,54 +114,74 @@ struct _GdmSessionIface const char *text); void (* default_session_name_changed) (GdmSession *session, const char *text); -}; - -GType gdm_session_get_type (void) G_GNUC_CONST; - -void gdm_session_start_conversation (GdmSession *session, - const char *service_name); -void gdm_session_stop_conversation (GdmSession *session, - const char *service_name); -void gdm_session_setup (GdmSession *session, - const char *service_name); -void gdm_session_setup_for_user (GdmSession *session, - const char *service_name, - const char *username); -void gdm_session_setup_for_program (GdmSession *session, - const char *service_name, - const char *log_file); -void gdm_session_set_environment_variable (GdmSession *session, - const char *key, - const char *value); -void gdm_session_reset (GdmSession *session); -void gdm_session_authenticate (GdmSession *session, - const char *service_name); -void gdm_session_authorize (GdmSession *session, - const char *service_name); -void gdm_session_accredit (GdmSession *session, - const char *service_name, - int cred_flag); -void gdm_session_open_session (GdmSession *session, - const char *service_name); -void gdm_session_start_session (GdmSession *session, - const char *service_name); -void gdm_session_close (GdmSession *session); - -void gdm_session_answer_query (GdmSession *session, - const char *service_name, - 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_language (GdmSession *session, - const char *language); -void gdm_session_select_user (GdmSession *session, - const char *username); -void gdm_session_cancel (GdmSession *session); +} GdmSessionClass; + +GType gdm_session_get_type (void); + +GdmSession *gdm_session_new (const char *display_name, + const char *display_hostname, + const char *display_device, + const char *display_seat_id, + const char *display_x11_authority_file, + gboolean display_is_local); + +char *gdm_session_get_username (GdmSession *session); +char *gdm_session_get_display_device (GdmSession *session); +char *gdm_session_get_display_seat_id (GdmSession *session); +gboolean gdm_session_bypasses_xsession (GdmSession *session); + +void gdm_session_start_conversation (GdmSession *session, + const char *service_name); +void gdm_session_stop_conversation (GdmSession *session, + const char *service_name); +void gdm_session_setup (GdmSession *session, + const char *service_name); +void gdm_session_setup_for_user (GdmSession *session, + const char *service_name, + const char *username); +void gdm_session_setup_for_program (GdmSession *session, + const char *service_name, + const char *log_file); +void gdm_session_set_environment_variable (GdmSession *session, + const char *key, + const char *value); +void gdm_session_reset (GdmSession *session); +void gdm_session_authenticate (GdmSession *session, + const char *service_name); +void gdm_session_authorize (GdmSession *session, + const char *service_name); +void gdm_session_accredit (GdmSession *session, + const char *service_name, + int cred_flag); +void gdm_session_open_session (GdmSession *session, + const char *service_name); +void gdm_session_start_session (GdmSession *session, + const char *service_name); +void gdm_session_close (GdmSession *session); + +void gdm_session_answer_query (GdmSession *session, + const char *service_name, + 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_language (GdmSession *session, + const char *language); +void gdm_session_select_user (GdmSession *session, + const char *username); +void gdm_session_cancel (GdmSession *session); + +/* Exported methods */ +gboolean gdm_session_restart (GdmSession *session, + GError **error); +gboolean gdm_session_stop (GdmSession *session, + GError **error); +gboolean gdm_session_detach (GdmSession *session, + GError **error); G_END_DECLS -#endif /* __GDM_SESSION_H */ +#endif /* GDM_SESSION_H */ diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c index 4dea4d29..42fa6af3 100644 --- a/daemon/gdm-simple-slave.c +++ b/daemon/gdm-simple-slave.c @@ -50,7 +50,6 @@ #include "gdm-server.h" #include "gdm-session.h" -#include "gdm-session-direct.h" #include "gdm-greeter-server.h" #include "gdm-greeter-session.h" #include "gdm-settings-direct.h" @@ -79,7 +78,7 @@ struct GdmSimpleSlavePrivate guint connection_attempts; GdmServer *server; - GdmSessionDirect *session; + GdmSession *session; GdmGreeterServer *greeter_server; GdmGreeterSession *greeter; @@ -122,7 +121,7 @@ on_session_started (GdmSession *session, g_debug ("GdmSimpleSlave: session started %d", pid); /* Run the PreSession script. gdmslave suspends until script has terminated */ - username = gdm_session_direct_get_username (slave->priv->session); + username = gdm_session_get_username (slave->priv->session); if (username != NULL) { gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/PreSession", username); } @@ -132,7 +131,7 @@ on_session_started (GdmSession *session, * Note that error return status from PreSession script should * be ignored in the case of a X-GDM-BypassXsession session, which can * be checked by calling: - * gdm_session_direct_bypasses_xsession (session) + * gdm_session_bypasses_xsession (session) */ } @@ -144,8 +143,8 @@ gdm_simple_slave_grant_console_permissions (GdmSimpleSlave *slave) char *display_device; struct passwd *passwd_entry; - username = gdm_session_direct_get_username (slave->priv->session); - display_device = gdm_session_direct_get_display_device (slave->priv->session); + username = gdm_session_get_username (slave->priv->session); + display_device = gdm_session_get_display_device (slave->priv->session); if (username != NULL) { gdm_get_pwent_for_name (username, &passwd_entry); @@ -179,8 +178,8 @@ gdm_simple_slave_revoke_console_permissions (GdmSimpleSlave *slave) char *username; char *display_device; - username = gdm_session_direct_get_username (slave->priv->session); - display_device = gdm_session_direct_get_display_device (slave->priv->session); + username = gdm_session_get_username (slave->priv->session); + display_device = gdm_session_get_display_device (slave->priv->session); /* * Only do logindevperm processing if /dev/console or a device @@ -238,7 +237,7 @@ add_user_authorization (GdmSimpleSlave *slave, char *username; gboolean ret; - username = gdm_session_direct_get_username (slave->priv->session); + username = gdm_session_get_username (slave->priv->session); ret = gdm_slave_add_user_authorization (GDM_SLAVE (slave), username, filename); @@ -376,7 +375,7 @@ on_session_authorized (GdmSession *session, char *username; int cred_flag; - username = gdm_session_direct_get_username (slave->priv->session); + username = gdm_session_get_username (slave->priv->session); ssid = gdm_slave_get_primary_session_id_for_user (GDM_SLAVE (slave), username); if (ssid != NULL && ssid [0] != '\0') { @@ -414,7 +413,7 @@ try_migrate_session (GdmSimpleSlave *slave) g_debug ("GdmSimpleSlave: trying to migrate session"); - username = gdm_session_direct_get_username (slave->priv->session); + username = gdm_session_get_username (slave->priv->session); /* try to switch to an existing session */ res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username); @@ -438,7 +437,7 @@ stop_greeter (GdmSimpleSlave *slave) /* Run the PostLogin script. gdmslave suspends until script has terminated */ username = NULL; if (slave->priv->session != NULL) { - username = gdm_session_direct_get_username (slave->priv->session); + username = gdm_session_get_username (slave->priv->session); } if (username != NULL) { @@ -768,13 +767,12 @@ create_new_session (GdmSimpleSlave *slave) display_device = gdm_server_get_display_device (slave->priv->server); } - slave->priv->session = gdm_session_direct_new (display_id, - display_name, - display_hostname, - display_device, - display_seat_id, - display_x11_authority_file, - display_is_local); + slave->priv->session = gdm_session_new (display_name, + display_hostname, + display_device, + display_seat_id, + display_x11_authority_file, + display_is_local); g_free (display_id); g_free (display_name); g_free (display_device); @@ -1626,7 +1624,7 @@ gdm_simple_slave_stop (GdmSlave *slave) /* Run the PostSession script. gdmslave suspends until script * has terminated */ - username = gdm_session_direct_get_username (GDM_SIMPLE_SLAVE (slave)->priv->session); + username = gdm_session_get_username (GDM_SIMPLE_SLAVE (slave)->priv->session); if (username != NULL) { gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/PostSession", username); } diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c index 3431edba..503f4f8c 100644 --- a/daemon/gdm-welcome-session.c +++ b/daemon/gdm-welcome-session.c @@ -47,7 +47,6 @@ #include "gdm-common.h" #include "gdm-session.h" -#include "gdm-session-direct.h" #include "gdm-welcome-session.h" #define DBUS_LAUNCH_COMMAND BINDIR "/dbus-launch" @@ -830,13 +829,12 @@ gdm_welcome_session_start (GdmWelcomeSession *welcome_session) return FALSE; } - welcome_session->priv->session = GDM_SESSION (gdm_session_direct_new (NULL, - welcome_session->priv->x11_display_name, - welcome_session->priv->x11_display_hostname, - welcome_session->priv->x11_display_device, - welcome_session->priv->x11_display_seat_id, - welcome_session->priv->x11_authority_file, - welcome_session->priv->x11_display_is_local)); + welcome_session->priv->session = gdm_session_new (welcome_session->priv->x11_display_name, + welcome_session->priv->x11_display_hostname, + welcome_session->priv->x11_display_device, + welcome_session->priv->x11_display_seat_id, + welcome_session->priv->x11_authority_file, + welcome_session->priv->x11_display_is_local); g_signal_connect (GDM_SESSION (welcome_session->priv->session), "conversation-started", diff --git a/daemon/test-session.c b/daemon/test-session.c index f75d5ed9..23eca7af 100644 --- a/daemon/test-session.c +++ b/daemon/test-session.c @@ -28,7 +28,7 @@ #include <glib.h> -#include "gdm-session-direct.h" +#include "gdm-session.h" static GMainLoop *loop; @@ -124,7 +124,7 @@ on_session_accredited (GdmSession *session, { char *username; - username = gdm_session_direct_get_username (GDM_SESSION_DIRECT (session)); + username = gdm_session_get_username (GDM_SESSION (session)); g_print ("%s%ssuccessfully accredited\n", username ? username : "", username ? " " : ""); @@ -247,7 +247,7 @@ on_secret_info_query (GdmSession *session, } static void -import_environment (GdmSessionDirect *session) +import_environment (GdmSession *session) { } @@ -255,23 +255,22 @@ int main (int argc, char *argv[]) { - GdmSessionDirect *session; - char *username; + GdmSession *session; + char *username; g_log_set_always_fatal (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING); g_type_init (); do { - g_debug ("creating instance of GdmSessionDirect object..."); - session = gdm_session_direct_new ("/org/gnome/DisplayManager/Display1", - ":0", - g_get_host_name (), - ttyname (STDIN_FILENO), - "", - getenv("XAUTHORITY"), - TRUE); - g_debug ("GdmSessionDirect object created successfully"); + g_debug ("creating instance of GdmSession object..."); + session = gdm_session_new (":0", + g_get_host_name (), + ttyname (STDIN_FILENO), + "", + getenv("XAUTHORITY"), + TRUE); + g_debug ("GdmSession object created successfully"); if (argc <= 1) { username = NULL; @@ -362,8 +361,8 @@ main (int argc, g_main_loop_run (loop); g_main_loop_unref (loop); - g_message ("destroying previously created GdmSessionDirect object..."); + g_message ("destroying previously created GdmSession object..."); g_object_unref (session); - g_message ("GdmSessionDirect object destroyed successfully"); + g_message ("GdmSession object destroyed successfully"); } while (1); } diff --git a/po/POTFILES.in b/po/POTFILES.in index 3e779fc9..cbbbaca5 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -25,8 +25,6 @@ daemon/gdm-manager.c daemon/gdm-server.c daemon/gdm-session-auditor.c daemon/gdm-session.c -daemon/gdm-session-direct.c -daemon/gdm-session-settings.c daemon/gdm-session-settings.c daemon/gdm-session-worker.c daemon/gdm-session-worker-job.c |