X-Git-Url: http://rtime.felk.cvut.cz/gitweb/sojka/lightdm.git/blobdiff_plain/424284df710c033c2c87e5d2dd4baea2f59ff2a3..f22dda3f1c7c3abf299b8dba7891d5b1a905779d:/src/greeter.c diff --git a/src/greeter.c b/src/greeter.c index 4ed18c2f..e2ae19f9 100644 --- a/src/greeter.c +++ b/src/greeter.c @@ -1,7 +1,6 @@ /* - * Copyright (C) 2010-2011 Robert Ancell. - * Author: Robert Ancell - * + * Copyright (C) 2010-2016 Canonical Ltd. + * * 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 3 of the License, or (at your option) any later @@ -13,12 +12,11 @@ #include #include -#include -#include #include #include "greeter.h" #include "configuration.h" +#include "shared-data-manager.h" enum { PROP_0, @@ -27,6 +25,7 @@ enum { enum { CONNECTED, + DISCONNECTED, CREATE_SESSION, START_SESSION, LAST_SIGNAL @@ -43,11 +42,11 @@ struct GreeterPrivate guint8 *read_buffer; gsize n_read; gboolean use_secure_memory; - + /* Hints for the greeter */ GHashTable *hints; - /* Default session to use */ + /* Default session to use */ gchar *default_session; /* Sequence number of current PAM session */ @@ -62,6 +61,9 @@ struct GreeterPrivate /* PAM session being constructed by the greeter */ Session *authentication_session; + /* TRUE if a the greeter can handle a reset; else we will just kill it instead */ + gboolean resettable; + /* TRUE if a user has been authenticated and the session requested to start */ gboolean start_session; @@ -72,12 +74,14 @@ struct GreeterPrivate gboolean guest_account_authenticated; /* Communication channels to communicate with */ + int to_greeter_input; + int from_greeter_output; GIOChannel *to_greeter_channel; GIOChannel *from_greeter_channel; guint from_greeter_watch; }; -G_DEFINE_TYPE (Greeter, greeter, SESSION_TYPE); +G_DEFINE_TYPE (Greeter, greeter, G_TYPE_OBJECT); /* Messages from the greeter to the server */ typedef enum @@ -89,7 +93,8 @@ typedef enum GREETER_MESSAGE_START_SESSION, GREETER_MESSAGE_CANCEL_AUTHENTICATION, GREETER_MESSAGE_SET_LANGUAGE, - GREETER_MESSAGE_AUTHENTICATE_REMOTE + GREETER_MESSAGE_AUTHENTICATE_REMOTE, + GREETER_MESSAGE_ENSURE_SHARED_DIR, } GreeterMessage; /* Messages from the server to the greeter */ @@ -98,7 +103,10 @@ typedef enum SERVER_MESSAGE_CONNECTED = 0, SERVER_MESSAGE_PROMPT_AUTHENTICATION, SERVER_MESSAGE_END_AUTHENTICATION, - SERVER_MESSAGE_SESSION_RESULT + SERVER_MESSAGE_SESSION_RESULT, + SERVER_MESSAGE_SHARED_DIR_RESULT, + SERVER_MESSAGE_IDLE, + SERVER_MESSAGE_RESET, } ServerMessage; static gboolean read_cb (GIOChannel *source, GIOCondition condition, gpointer data); @@ -109,9 +117,43 @@ greeter_new (void) return g_object_new (GREETER_TYPE, NULL); } +void +greeter_set_file_descriptors (Greeter *greeter, int to_greeter_fd, int from_greeter_fd) +{ + GError *error = NULL; + + g_return_if_fail (greeter != NULL); + g_return_if_fail (greeter->priv->to_greeter_input < 0); + g_return_if_fail (greeter->priv->from_greeter_output < 0); + + greeter->priv->to_greeter_input = to_greeter_fd; + greeter->priv->to_greeter_channel = g_io_channel_unix_new (greeter->priv->to_greeter_input); + g_io_channel_set_encoding (greeter->priv->to_greeter_channel, NULL, &error); + if (error) + g_warning ("Failed to set encoding on to greeter channel to binary: %s\n", error->message); + g_clear_error (&error); + greeter->priv->from_greeter_output = from_greeter_fd; + greeter->priv->from_greeter_channel = g_io_channel_unix_new (greeter->priv->from_greeter_output); + g_io_channel_set_encoding (greeter->priv->from_greeter_channel, NULL, &error); + if (error) + g_warning ("Failed to set encoding on from greeter channel to binary: %s\n", error->message); + g_clear_error (&error); + g_io_channel_set_buffered (greeter->priv->from_greeter_channel, FALSE); + greeter->priv->from_greeter_watch = g_io_add_watch (greeter->priv->from_greeter_channel, G_IO_IN | G_IO_HUP, read_cb, greeter); +} + +void +greeter_stop (Greeter *greeter) +{ + /* Stop any events occurring after we've stopped */ + if (greeter->priv->authentication_session) + g_signal_handlers_disconnect_matched (greeter->priv->authentication_session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, greeter); +} + void greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const gchar *autologin_pam_service) { + g_return_if_fail (greeter != NULL); g_free (greeter->priv->pam_service); greeter->priv->pam_service = g_strdup (pam_service); g_free (greeter->priv->autologin_pam_service); @@ -121,12 +163,21 @@ greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const gcha void greeter_set_allow_guest (Greeter *greeter, gboolean allow_guest) { + g_return_if_fail (greeter != NULL); greeter->priv->allow_guest = allow_guest; } +void +greeter_clear_hints (Greeter *greeter) +{ + g_return_if_fail (greeter != NULL); + g_hash_table_remove_all (greeter->priv->hints); +} + void greeter_set_hint (Greeter *greeter, const gchar *name, const gchar *value) { + g_return_if_fail (greeter != NULL); g_hash_table_insert (greeter->priv->hints, g_strdup (name), g_strdup (value)); } @@ -169,13 +220,31 @@ int_length (void) static void write_message (Greeter *greeter, guint8 *message, gsize message_length) { + gchar *data; + gsize data_length; GError *error = NULL; - g_io_channel_write_chars (greeter->priv->to_greeter_channel, (gchar *) message, message_length, NULL, &error); + data = (gchar *) message; + data_length = message_length; + while (data_length > 0) + { + GIOStatus status; + gsize n_written; + + status = g_io_channel_write_chars (greeter->priv->to_greeter_channel, data, data_length, &n_written, &error); + if (error) + g_warning ("Error writing to greeter: %s", error->message); + g_clear_error (&error); + if (status != G_IO_STATUS_NORMAL) + return; + data_length -= n_written; + data += n_written; + } + + g_io_channel_flush (greeter->priv->to_greeter_channel, &error); if (error) - l_warning (greeter, "Error writing to greeter: %s", error->message); + g_warning ("Failed to flush data to greeter: %s", error->message); g_clear_error (&error); - g_io_channel_flush (greeter->priv->to_greeter_channel, NULL); } static void @@ -194,7 +263,7 @@ static void write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset) { gint length; - + if (value) length = strlen (value); else @@ -226,7 +295,7 @@ string_length (const gchar *value) } static void -handle_connect (Greeter *greeter, const gchar *version) +handle_connect (Greeter *greeter, const gchar *version, gboolean resettable) { guint8 message[MAX_MESSAGE_LENGTH]; gsize offset = 0; @@ -234,7 +303,9 @@ handle_connect (Greeter *greeter, const gchar *version) GHashTableIter iter; gpointer key, value; - l_debug (greeter, "Greeter connected version=%s", version); + g_debug ("Greeter connected version=%s resettable=%s", version, resettable ? "true" : "false"); + + greeter->priv->resettable = resettable; length = string_length (VERSION); g_hash_table_iter_init (&iter, greeter->priv->hints); @@ -269,11 +340,11 @@ pam_messages_cb (Session *session, Greeter *greeter) messages_length = session_get_messages_length (session); /* Respond to d-bus query with messages */ - l_debug (greeter, "Prompt greeter with %d message(s)", messages_length); + g_debug ("Prompt greeter with %d message(s)", messages_length); size = int_length () + string_length (session_get_username (session)) + int_length (); for (i = 0; i < messages_length; i++) size += int_length () + string_length (messages[i].msg); - + write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_PROMPT_AUTHENTICATION, size, &offset); write_int (message, MAX_MESSAGE_LENGTH, greeter->priv->authentication_sequence_number, &offset); write_string (message, MAX_MESSAGE_LENGTH, session_get_username (session), &offset); @@ -309,7 +380,42 @@ send_end_authentication (Greeter *greeter, guint32 sequence_number, const gchar write_int (message, MAX_MESSAGE_LENGTH, sequence_number, &offset); write_string (message, MAX_MESSAGE_LENGTH, username, &offset); write_int (message, MAX_MESSAGE_LENGTH, result, &offset); - write_message (greeter, message, offset); + write_message (greeter, message, offset); +} + +void +greeter_idle (Greeter *greeter) +{ + guint8 message[MAX_MESSAGE_LENGTH]; + gsize offset = 0; + + write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_IDLE, 0, &offset); + write_message (greeter, message, offset); +} + +void +greeter_reset (Greeter *greeter) +{ + guint8 message[MAX_MESSAGE_LENGTH]; + gsize offset = 0; + guint32 length = 0; + GHashTableIter iter; + gpointer key, value; + + g_return_if_fail (greeter != NULL); + + g_hash_table_iter_init (&iter, greeter->priv->hints); + while (g_hash_table_iter_next (&iter, &key, &value)) + length += string_length (key) + string_length (value); + + write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_RESET, length, &offset); + g_hash_table_iter_init (&iter, greeter->priv->hints); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + write_string (message, MAX_MESSAGE_LENGTH, key, &offset); + write_string (message, MAX_MESSAGE_LENGTH, value, &offset); + } + write_message (greeter, message, offset); } static void @@ -317,16 +423,16 @@ authentication_complete_cb (Session *session, Greeter *greeter) { int result; - l_debug (greeter, "Authenticate result for user %s: %s", session_get_username (session), session_get_authentication_result_string (session)); + g_debug ("Authenticate result for user %s: %s", session_get_username (session), session_get_authentication_result_string (session)); result = session_get_authentication_result (session); if (session_get_is_authenticated (session)) { if (session_get_user (session)) - l_debug (greeter, "User %s authorized", session_get_username (session)); + g_debug ("User %s authorized", session_get_username (session)); else { - l_debug (greeter, "User %s authorized, but no account of that name exists", session_get_username (session)); + g_debug ("User %s authorized, but no account of that name exists", session_get_username (session)); result = PAM_USER_UNKNOWN; } } @@ -343,8 +449,7 @@ reset_session (Greeter *greeter) { g_signal_handlers_disconnect_matched (greeter->priv->authentication_session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, greeter); session_stop (greeter->priv->authentication_session); - g_object_unref (greeter->priv->authentication_session); - greeter->priv->authentication_session = NULL; + g_clear_object (&greeter->priv->authentication_session); } greeter->priv->guest_account_authenticated = FALSE; @@ -358,18 +463,18 @@ handle_login (Greeter *greeter, guint32 sequence_number, const gchar *username) if (username[0] == '\0') { - l_debug (greeter, "Greeter start authentication"); + g_debug ("Greeter start authentication"); username = NULL; } else - l_debug (greeter, "Greeter start authentication for %s", username); + g_debug ("Greeter start authentication for %s", username); reset_session (greeter); if (greeter->priv->active_username) g_free (greeter->priv->active_username); greeter->priv->active_username = g_strdup (username); - g_object_notify (G_OBJECT (greeter), "active-username"); + g_object_notify (G_OBJECT (greeter), GREETER_PROPERTY_ACTIVE_USERNAME); greeter->priv->authentication_sequence_number = sequence_number; g_signal_emit (greeter, signals[CREATE_SESSION], 0, &greeter->priv->authentication_session); @@ -379,8 +484,8 @@ handle_login (Greeter *greeter, guint32 sequence_number, const gchar *username) return; } - g_signal_connect (G_OBJECT (greeter->priv->authentication_session), "got-messages", G_CALLBACK (pam_messages_cb), greeter); - g_signal_connect (G_OBJECT (greeter->priv->authentication_session), "authentication-complete", G_CALLBACK (authentication_complete_cb), greeter); + g_signal_connect (G_OBJECT (greeter->priv->authentication_session), SESSION_SIGNAL_GOT_MESSAGES, G_CALLBACK (pam_messages_cb), greeter); + g_signal_connect (G_OBJECT (greeter->priv->authentication_session), SESSION_SIGNAL_AUTHENTICATION_COMPLETE, G_CALLBACK (authentication_complete_cb), greeter); /* Use non-interactive service for autologin user */ autologin_username = g_hash_table_lookup (greeter->priv->hints, "autologin-user"); @@ -406,18 +511,18 @@ handle_login (Greeter *greeter, guint32 sequence_number, const gchar *username) static void handle_login_as_guest (Greeter *greeter, guint32 sequence_number) { - l_debug (greeter, "Greeter start authentication for guest account"); + g_debug ("Greeter start authentication for guest account"); reset_session (greeter); if (!greeter->priv->allow_guest) { - l_debug (greeter, "Guest account is disabled"); + g_debug ("Guest account is disabled"); send_end_authentication (greeter, sequence_number, "", PAM_USER_UNKNOWN); return; } - greeter->priv->guest_account_authenticated = TRUE; + greeter->priv->guest_account_authenticated = TRUE; send_end_authentication (greeter, sequence_number, "", PAM_SUCCESS); } @@ -463,11 +568,11 @@ handle_login_remote (Greeter *greeter, const gchar *session_name, const gchar *u if (username[0] == '\0') { - l_debug (greeter, "Greeter start authentication for remote session %s", session_name); + g_debug ("Greeter start authentication for remote session %s", session_name); username = NULL; } else - l_debug (greeter, "Greeter start authentication for remote session %s as user %s", session_name, username); + g_debug ("Greeter start authentication for remote session %s as user %s", session_name, username); reset_session (greeter); @@ -483,8 +588,8 @@ handle_login_remote (Greeter *greeter, const gchar *session_name, const gchar *u g_signal_emit (greeter, signals[CREATE_SESSION], 0, &greeter->priv->authentication_session); if (greeter->priv->authentication_session) { - g_signal_connect (G_OBJECT (greeter->priv->authentication_session), "got-messages", G_CALLBACK (pam_messages_cb), greeter); - g_signal_connect (G_OBJECT (greeter->priv->authentication_session), "authentication-complete", G_CALLBACK (authentication_complete_cb), greeter); + g_signal_connect (G_OBJECT (greeter->priv->authentication_session), SESSION_SIGNAL_GOT_MESSAGES, G_CALLBACK (pam_messages_cb), greeter); + g_signal_connect (G_OBJECT (greeter->priv->authentication_session), SESSION_SIGNAL_AUTHENTICATION_COMPLETE, G_CALLBACK (authentication_complete_cb), greeter); /* Run the session process */ session_set_pam_service (greeter->priv->authentication_session, service); @@ -532,7 +637,7 @@ handle_continue_authentication (Greeter *greeter, gchar **secrets) return; } - l_debug (greeter, "Continue authentication"); + g_debug ("Continue authentication"); /* Build response */ response = calloc (messages_length, sizeof (struct pam_response)); @@ -562,7 +667,7 @@ handle_cancel_authentication (Greeter *greeter) if (greeter->priv->authentication_session == NULL) return; - l_debug (greeter, "Cancel authentication"); + g_debug ("Cancel authentication"); reset_session (greeter); } @@ -587,15 +692,15 @@ handle_start_session (Greeter *greeter, const gchar *session) if (greeter->priv->guest_account_authenticated || session_get_is_authenticated (greeter->priv->authentication_session)) { if (session) - l_debug (greeter, "Greeter requests session %s", session); + g_debug ("Greeter requests session %s", session); else - l_debug (greeter, "Greeter requests default session"); + g_debug ("Greeter requests default session"); greeter->priv->start_session = TRUE; g_signal_emit (greeter, signals[START_SESSION], 0, session_type, session, &result); } else { - l_debug (greeter, "Ignoring start session request, user is not authorized"); + g_debug ("Ignoring start session request, user is not authorized"); result = FALSE; } @@ -611,22 +716,40 @@ handle_set_language (Greeter *greeter, const gchar *language) if (!greeter->priv->guest_account_authenticated && !session_get_is_authenticated (greeter->priv->authentication_session)) { - l_debug (greeter, "Ignoring set language request, user is not authorized"); + g_debug ("Ignoring set language request, user is not authorized"); return; } // FIXME: Could use this if (greeter->priv->guest_account_authenticated) { - l_debug (greeter, "Ignoring set language request for guest user"); + g_debug ("Ignoring set language request for guest user"); return; } - l_debug (greeter, "Greeter sets language %s", language); + g_debug ("Greeter sets language %s", language); user = session_get_user (greeter->priv->authentication_session); user_set_language (user, language); } +static void +handle_ensure_shared_dir (Greeter *greeter, const gchar *username) +{ + gchar *dir; + guint8 message[MAX_MESSAGE_LENGTH]; + gsize offset = 0; + + g_debug ("Greeter requests data directory for user %s", username); + + dir = shared_data_manager_ensure_user_dir (shared_data_manager_get_instance (), username); + + write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_SHARED_DIR_RESULT, string_length (dir), &offset); + write_string (message, MAX_MESSAGE_LENGTH, dir, &offset); + write_message (greeter, message, offset); + + g_free (dir); +} + static guint32 read_int (Greeter *greeter, gsize *offset) { @@ -634,7 +757,7 @@ read_int (Greeter *greeter, gsize *offset) guint8 *buffer; if (greeter->priv->n_read - *offset < sizeof (guint32)) { - l_warning (greeter, "Not enough space for int, need %zu, got %zu", sizeof (guint32), greeter->priv->n_read - *offset); + g_warning ("Not enough space for int, need %zu, got %zu", sizeof (guint32), greeter->priv->n_read - *offset); return 0; } buffer = greeter->priv->read_buffer + *offset; @@ -654,7 +777,7 @@ get_message_length (Greeter *greeter) if (HEADER_SIZE + payload_length < HEADER_SIZE) { - l_warning (greeter, "Payload length of %u octets too long", payload_length); + g_warning ("Payload length of %u octets too long", payload_length); return HEADER_SIZE; } @@ -670,7 +793,7 @@ read_string_full (Greeter *greeter, gsize *offset, void* (*alloc_fn)(size_t n)) length = read_int (greeter, offset); if (greeter->priv->n_read - *offset < length) { - l_warning (greeter, "Not enough space for string, need %u, got %zu", length, greeter->priv->n_read - *offset); + g_warning ("Not enough space for string, need %u, got %zu", length, greeter->priv->n_read - *offset); return g_strdup (""); } @@ -703,19 +826,21 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data) Greeter *greeter = data; gsize n_to_read, n_read, offset; GIOStatus status; - int id, i; + int id, length, i; guint32 sequence_number, n_secrets, max_secrets; gchar *version, *username, *session_name, *language; gchar **secrets; + gboolean resettable = FALSE; GError *error = NULL; if (condition == G_IO_HUP) { - l_debug (greeter, "Greeter closed communication channel"); + g_debug ("Greeter closed communication channel"); greeter->priv->from_greeter_watch = 0; + g_signal_emit (greeter, signals[DISCONNECTED], 0); return FALSE; } - + n_to_read = HEADER_SIZE; if (greeter->priv->n_read >= HEADER_SIZE) { @@ -733,9 +858,16 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data) &n_read, &error); if (error) - l_warning (greeter, "Error reading from greeter: %s", error->message); + g_warning ("Error reading from greeter: %s", error->message); g_clear_error (&error); - if (status != G_IO_STATUS_NORMAL) + if (status == G_IO_STATUS_EOF) + { + g_debug ("Greeter closed communication channel"); + greeter->priv->from_greeter_watch = 0; + g_signal_emit (greeter, signals[DISCONNECTED], 0); + return FALSE; + } + else if (status != G_IO_STATUS_NORMAL) return TRUE; greeter->priv->n_read += n_read; @@ -751,17 +883,19 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data) greeter->priv->read_buffer = secure_realloc (greeter, greeter->priv->read_buffer, n_to_read); read_cb (source, condition, greeter); return TRUE; - } + } } - + offset = 0; id = read_int (greeter, &offset); - read_int (greeter, &offset); + length = HEADER_SIZE + read_int (greeter, &offset); switch (id) { case GREETER_MESSAGE_CONNECT: version = read_string (greeter, &offset); - handle_connect (greeter, version); + if (offset < length) + resettable = read_int (greeter, &offset) != 0; + handle_connect (greeter, version, resettable); g_free (version); break; case GREETER_MESSAGE_AUTHENTICATE: @@ -785,7 +919,7 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data) max_secrets = (G_MAXUINT32 - 1) / sizeof (gchar *); if (n_secrets > max_secrets) { - l_warning (greeter, "Array length of %u elements too long", n_secrets); + g_warning ("Array length of %u elements too long", n_secrets); greeter->priv->from_greeter_watch = 0; return FALSE; } @@ -811,8 +945,13 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data) handle_set_language (greeter, language); g_free (language); break; + case GREETER_MESSAGE_ENSURE_SHARED_DIR: + username = read_string (greeter, &offset); + handle_ensure_shared_dir (greeter, username); + g_free (username); + break; default: - l_warning (greeter, "Unknown message from greeter: %d", id); + g_warning ("Unknown message from greeter: %d", id); break; } @@ -835,6 +974,13 @@ greeter_get_authentication_session (Greeter *greeter) return greeter->priv->authentication_session; } +gboolean +greeter_get_resettable (Greeter *greeter) +{ + g_return_val_if_fail (greeter != NULL, FALSE); + return greeter->priv->resettable; +} + gboolean greeter_get_start_session (Greeter *greeter) { @@ -849,48 +995,6 @@ greeter_get_active_username (Greeter *greeter) return greeter->priv->active_username; } -static gboolean -greeter_start (Session *session) -{ - Greeter *greeter = GREETER (session); - int to_greeter_pipe[2], from_greeter_pipe[2]; - gboolean result = FALSE; - gchar *value; - - /* Create a pipe to talk with the greeter */ - if (pipe (to_greeter_pipe) != 0 || pipe (from_greeter_pipe) != 0) - { - g_warning ("Failed to create pipes: %s", strerror (errno)); - return FALSE; - } - greeter->priv->to_greeter_channel = g_io_channel_unix_new (to_greeter_pipe[1]); - g_io_channel_set_encoding (greeter->priv->to_greeter_channel, NULL, NULL); - greeter->priv->from_greeter_channel = g_io_channel_unix_new (from_greeter_pipe[0]); - g_io_channel_set_encoding (greeter->priv->from_greeter_channel, NULL, NULL); - g_io_channel_set_buffered (greeter->priv->from_greeter_channel, FALSE); - greeter->priv->from_greeter_watch = g_io_add_watch (greeter->priv->from_greeter_channel, G_IO_IN | G_IO_HUP, read_cb, greeter); - - /* Let the greeter session know how to communicate with the daemon */ - value = g_strdup_printf ("%d", from_greeter_pipe[1]); - session_set_env (SESSION (greeter), "LIGHTDM_TO_SERVER_FD", value); - g_free (value); - value = g_strdup_printf ("%d", to_greeter_pipe[0]); - session_set_env (SESSION (greeter), "LIGHTDM_FROM_SERVER_FD", value); - g_free (value); - - /* Don't allow the daemon end of the pipes to be accessed in child processes */ - fcntl (to_greeter_pipe[1], F_SETFD, FD_CLOEXEC); - fcntl (from_greeter_pipe[0], F_SETFD, FD_CLOEXEC); - - result = SESSION_CLASS (greeter_parent_class)->start (session); - - /* Close the session ends of the pipe */ - close (to_greeter_pipe[0]); - close (from_greeter_pipe[1]); - - return result; -} - static Session * greeter_real_create_session (Greeter *greeter) { @@ -903,18 +1007,6 @@ greeter_real_start_session (Greeter *greeter, SessionType type, const gchar *ses return FALSE; } -static void -greeter_stop (Session *session) -{ - Greeter *greeter = GREETER (session); - - /* Stop any events occurring after we've stopped */ - if (greeter->priv->authentication_session) - g_signal_handlers_disconnect_matched (greeter->priv->authentication_session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, greeter); - - SESSION_CLASS (greeter_parent_class)->stop (session); -} - static void greeter_init (Greeter *greeter) { @@ -922,14 +1014,14 @@ greeter_init (Greeter *greeter) greeter->priv->read_buffer = secure_malloc (greeter, HEADER_SIZE); greeter->priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); greeter->priv->use_secure_memory = config_get_boolean (config_get_instance (), "LightDM", "lock-memory"); + greeter->priv->to_greeter_input = -1; + greeter->priv->from_greeter_output = -1; } static void greeter_finalize (GObject *object) { - Greeter *self; - - self = GREETER (object); + Greeter *self = GREETER (object); g_free (self->priv->pam_service); g_free (self->priv->autologin_pam_service); @@ -942,6 +1034,8 @@ greeter_finalize (GObject *object) g_signal_handlers_disconnect_matched (self->priv->authentication_session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self); g_object_unref (self->priv->authentication_session); } + close (self->priv->to_greeter_input); + close (self->priv->from_greeter_output); if (self->priv->to_greeter_channel) g_io_channel_unref (self->priv->to_greeter_channel); if (self->priv->from_greeter_channel) @@ -982,19 +1076,16 @@ greeter_get_property (GObject *object, static void greeter_class_init (GreeterClass *klass) { - SessionClass *session_class = SESSION_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); klass->create_session = greeter_real_create_session; klass->start_session = greeter_real_start_session; - session_class->start = greeter_start; - session_class->stop = greeter_stop; object_class->finalize = greeter_finalize; object_class->get_property = greeter_get_property; object_class->set_property = greeter_set_property; signals[CONNECTED] = - g_signal_new ("connected", + g_signal_new (GREETER_SIGNAL_CONNECTED, G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GreeterClass, connected), @@ -1002,8 +1093,17 @@ greeter_class_init (GreeterClass *klass) NULL, G_TYPE_NONE, 0); + signals[DISCONNECTED] = + g_signal_new (GREETER_SIGNAL_DISCONNECTED, + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GreeterClass, disconnected), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + signals[CREATE_SESSION] = - g_signal_new ("create-session", + g_signal_new (GREETER_SIGNAL_CREATE_SESSION, G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GreeterClass, create_session), @@ -1013,7 +1113,7 @@ greeter_class_init (GreeterClass *klass) SESSION_TYPE, 0); signals[START_SESSION] = - g_signal_new ("start-session", + g_signal_new (GREETER_SIGNAL_START_SESSION, G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GreeterClass, start_session), @@ -1024,8 +1124,8 @@ greeter_class_init (GreeterClass *klass) g_object_class_install_property (object_class, PROP_ACTIVE_USERNAME, - g_param_spec_string ("active-username", - "active-username", + g_param_spec_string (GREETER_PROPERTY_ACTIVE_USERNAME, + GREETER_PROPERTY_ACTIVE_USERNAME, "Active username", NULL, G_PARAM_READABLE));