]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - src/lightdm.c
Re-enable SIGPIPE for children so they have default behaviour
[sojka/lightdm.git] / src / lightdm.c
index 40db4f816ac2de97c7d669691586fb2607e176a4..fd62314cfe406d44aa2a164e1ba0e974bd7a02f0 100644 (file)
@@ -33,6 +33,7 @@
 #include "shared-data-manager.h"
 #include "user-list.h"
 #include "login1.h"
+#include "log-file.h"
 
 static gchar *config_path = NULL;
 static GMainLoop *loop = NULL;
@@ -68,6 +69,8 @@ typedef struct
 
 #define LIGHTDM_BUS_NAME "org.freedesktop.DisplayManager"
 
+static gboolean update_login1_seat (Login1Seat *login1_seat);
+
 static void
 log_cb (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer data)
 {
@@ -122,7 +125,8 @@ log_cb (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message,
 static void
 log_init (void)
 {
-    gchar *log_dir, *path, *old_path;
+    gchar *log_dir, *path;
+    gboolean backup_logs;
 
     log_timer = g_timer_new ();
 
@@ -131,13 +135,8 @@ log_init (void)
     path = g_build_filename (log_dir, "lightdm.log", NULL);
     g_free (log_dir);
 
-    /* Move old file out of the way */
-    old_path = g_strdup_printf ("%s.old", path);
-    rename (path, old_path);
-    g_free (old_path);
-
-    /* Create new file and log to it */
-    log_fd = open (path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+    backup_logs = config_get_boolean (config_get_instance (), "LightDM", "backup-logs");
+    log_fd = log_file_open (path, backup_logs ? LOG_MODE_BACKUP_AND_TRUNCATE : LOG_MODE_APPEND);
     fcntl (log_fd, F_SETFD, FD_CLOEXEC);
     g_log_set_default_handler (log_cb, NULL);
 
@@ -145,40 +144,71 @@ log_init (void)
     g_free (path);
 }
 
+static GList*
+get_config_sections (const gchar *seat_name)
+{
+    gchar **groups, **i;
+    GList *config_sections = NULL;
+
+    /* Load seat defaults first */
+    config_sections = g_list_append (config_sections, g_strdup ("Seat:*"));
+
+    groups = config_get_groups (config_get_instance ());
+    for (i = groups; *i; i++)
+    {
+        if (g_str_has_prefix (*i, "Seat:") && strcmp (*i, "Seat:*") != 0)
+        {
+            const gchar *seat_name_glob = *i + strlen ("Seat:");
+            if (g_pattern_match_simple (seat_name_glob, seat_name ? seat_name : ""))
+                config_sections = g_list_append (config_sections, g_strdup (*i));
+        }
+    }
+    g_strfreev (groups);
+
+    return config_sections;
+}
+
 static void
-set_seat_properties (Seat *seat, const gchar *config_section)
+set_seat_properties (Seat *seat, const gchar *seat_name)
 {
+    GList *sections, *link;
     gchar **keys;
     gint i;
 
-    keys = config_get_keys (config_get_instance (), "SeatDefaults");
-    for (i = 0; keys && keys[i]; i++)
+    sections = get_config_sections (seat_name);
+    for (link = sections; link; link = link->next)
     {
-        gchar *value = config_get_string (config_get_instance (), "SeatDefaults", keys[i]);
-        seat_set_property (seat, keys[i], value);
-        g_free (value);
-    }
-    g_strfreev (keys);
+        const gchar *section = link->data;
+        keys = config_get_keys (config_get_instance (), section);
 
-    if (config_section)
-    {
-        keys = config_get_keys (config_get_instance (), config_section);
+        l_debug (seat, "Loading properties from config section %s", section);
         for (i = 0; keys && keys[i]; i++)
         {
-            gchar *value = config_get_string (config_get_instance (), config_section, keys[i]);
+            gchar *value = config_get_string (config_get_instance (), section, keys[i]);
             seat_set_property (seat, keys[i], value);
             g_free (value);
         }
         g_strfreev (keys);
     }
+    g_list_free_full (sections, g_free);
 }
 
 static void
 signal_cb (Process *process, int signum)
 {
-    g_debug ("Caught %s signal, shutting down", g_strsignal (signum));
-    display_manager_stop (display_manager);
-    // FIXME: Stop XDMCP server
+    switch (signum)
+    {
+    case SIGINT:
+    case SIGTERM:
+        g_debug ("Caught %s signal, shutting down", g_strsignal (signum));
+        display_manager_stop (display_manager);
+        // FIXME: Stop XDMCP server
+        break;
+    case SIGUSR1:
+    case SIGUSR2:
+    case SIGHUP:
+        break;
+    }
 }
 
 static void
@@ -188,6 +218,17 @@ display_manager_stopped_cb (DisplayManager *display_manager)
     g_main_loop_quit (loop);
 }
 
+static Seat *
+create_seat (const gchar *module_name, const gchar *name)
+{
+    if (strcmp (module_name, "xlocal") == 0) {
+        g_warning ("Seat type 'xlocal' is deprecated, use 'type=local' instead");
+        return seat_new ("local", name);
+    }
+    else
+        return seat_new (module_name, name);
+}
+
 static void
 display_manager_seat_removed_cb (DisplayManager *display_manager, Seat *seat)
 {
@@ -207,7 +248,7 @@ display_manager_seat_removed_cb (DisplayManager *display_manager, Seat *seat)
 
         if (!next_seat)
         {
-            next_seat = seat_new (*iter, seat_get_name (seat));
+            next_seat = create_seat (*iter, seat_get_name (seat));
             g_string_assign (next_types, *iter);
         }
         else
@@ -221,11 +262,7 @@ display_manager_seat_removed_cb (DisplayManager *display_manager, Seat *seat)
 
     if (next_seat)
     {
-        gchar *config_section;
-
-        config_section = get_config_section (seat_get_name (seat));
-        set_seat_properties (next_seat, config_section);
-        g_free (config_section);
+        set_seat_properties (next_seat, seat_get_name (seat));
 
         // We set this manually on default seat.  Let's port it over if needed.
         if (seat_get_boolean_property (seat, "exit-on-failure"))
@@ -328,7 +365,7 @@ handle_display_manager_call (GDBusConnection       *connection,
 
         g_debug ("Adding local X seat :%d", display_number);
 
-        seat = seat_new ("xremote", "xremote0"); // FIXME: What to use for a name?
+        seat = create_seat ("xremote", "xremote0"); // FIXME: What to use for a name?
         if (seat)
         {
             gchar *display_number_string;
@@ -567,7 +604,7 @@ emit_object_value_changed (GDBusConnection *bus, const gchar *path, const gchar
                                         g_variant_new ("(sa{sv}as)", interface_name, &builder, NULL),
                                         &error))
         g_warning ("Failed to emit PropertiesChanged signal: %s", error->message);
-    g_clear_error (&error); 
+    g_clear_error (&error);
 }
 
 static void
@@ -583,7 +620,7 @@ emit_object_signal (GDBusConnection *bus, const gchar *path, const gchar *signal
                                         g_variant_new ("(o)", object_path),
                                         &error))
         g_warning ("Failed to emit %s signal on %s: %s", signal_name, path, error->message);
-    g_clear_error (&error); 
+    g_clear_error (&error);
 }
 
 static void
@@ -591,11 +628,6 @@ seat_bus_entry_free (gpointer data)
 {
     SeatBusEntry *entry = data;
 
-    g_dbus_connection_unregister_object (bus, entry->bus_id);
-
-    emit_object_value_changed (bus, "/org/freedesktop/DisplayManager", "org.freedesktop.DisplayManager", "Seats", get_seat_list ());
-    emit_object_signal (bus, "/org/freedesktop/DisplayManager", "SeatRemoved", entry->path);
-
     g_free (entry->path);
     g_free (entry);
 }
@@ -605,14 +637,6 @@ session_bus_entry_free (gpointer data)
 {
     SessionBusEntry *entry = data;
 
-    g_dbus_connection_unregister_object (bus, entry->bus_id);
-
-    emit_object_value_changed (bus, "/org/freedesktop/DisplayManager", "org.freedesktop.DisplayManager", "Sessions", get_session_list (NULL));
-    emit_object_signal (bus, "/org/freedesktop/DisplayManager", "SessionRemoved", entry->path);
-
-    emit_object_value_changed (bus, entry->seat_path, "org.freedesktop.DisplayManager.Seat", "Sessions", get_session_list (entry->seat_path));
-    emit_object_signal (bus, entry->seat_path, "SessionRemoved", entry->path);
-
     g_free (entry->path);
     g_free (entry->seat_path);
     g_free (entry);
@@ -639,7 +663,6 @@ running_user_session_cb (Seat *seat, Session *session)
     session_set_env (session, "XDG_SESSION_PATH", path);
     g_object_set_data_full (G_OBJECT (session), "XDG_SESSION_PATH", path, g_free);
 
-    seat_entry = g_hash_table_lookup (seat_bus_entries, seat);
     session_entry = session_bus_entry_new (g_object_get_data (G_OBJECT (session), "XDG_SESSION_PATH"), seat_entry ? seat_entry->path : NULL);
     g_hash_table_insert (session_bus_entries, g_object_ref (session), session_entry);
 
@@ -665,8 +688,28 @@ running_user_session_cb (Seat *seat, Session *session)
 static void
 session_removed_cb (Seat *seat, Session *session)
 {
+    SessionBusEntry *entry;
+    gchar *seat_path = NULL;
+
     g_signal_handlers_disconnect_matched (session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
+
+    entry = g_hash_table_lookup (session_bus_entries, session);
+    if (entry)
+    {
+        g_dbus_connection_unregister_object (bus, entry->bus_id);
+        emit_object_signal (bus, "/org/freedesktop/DisplayManager", "SessionRemoved", entry->path);
+        emit_object_signal (bus, entry->seat_path, "SessionRemoved", entry->path);
+        seat_path = g_strdup (entry->seat_path);
+    }
+
     g_hash_table_remove (session_bus_entries, session);
+
+    if (seat_path)
+    {
+        emit_object_value_changed (bus, "/org/freedesktop/DisplayManager", "org.freedesktop.DisplayManager", "Sessions", get_session_list (NULL));
+        emit_object_value_changed (bus, seat_path, "org.freedesktop.DisplayManager.Seat", "Sessions", get_session_list (seat_path));
+        g_free (seat_path);
+    }
 }
 
 static void
@@ -703,14 +746,25 @@ seat_added_cb (DisplayManager *display_manager, Seat *seat)
     emit_object_value_changed (bus, "/org/freedesktop/DisplayManager", "org.freedesktop.DisplayManager", "Seats", get_seat_list ());
     emit_object_signal (bus, "/org/freedesktop/DisplayManager", "SeatAdded", entry->path);
 
-    g_signal_connect (seat, "running-user-session", G_CALLBACK (running_user_session_cb), NULL);
-    g_signal_connect (seat, "session-removed", G_CALLBACK (session_removed_cb), NULL);
+    g_signal_connect (seat, SEAT_SIGNAL_RUNNING_USER_SESSION, G_CALLBACK (running_user_session_cb), NULL);
+    g_signal_connect (seat, SEAT_SIGNAL_SESSION_REMOVED, G_CALLBACK (session_removed_cb), NULL);
 }
 
 static void
 seat_removed_cb (DisplayManager *display_manager, Seat *seat)
 {
+    SeatBusEntry *entry;
+
+    entry = g_hash_table_lookup (seat_bus_entries, seat);
+    if (entry)
+    {
+        g_dbus_connection_unregister_object (bus, entry->bus_id);
+        emit_object_signal (bus, "/org/freedesktop/DisplayManager", "SeatRemoved", entry->path);
+    }
+
     g_hash_table_remove (seat_bus_entries, seat);
+  
+    emit_object_value_changed (bus, "/org/freedesktop/DisplayManager", "org.freedesktop.DisplayManager", "Seats", get_seat_list ());
 }
 
 static gboolean
@@ -836,8 +890,8 @@ bus_acquired_cb (GDBusConnection *connection,
     seat_bus_entries = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, seat_bus_entry_free);
     session_bus_entries = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, session_bus_entry_free);
 
-    g_signal_connect (display_manager, "seat-added", G_CALLBACK (seat_added_cb), NULL);
-    g_signal_connect (display_manager, "seat-removed", G_CALLBACK (seat_removed_cb), NULL);
+    g_signal_connect (display_manager, DISPLAY_MANAGER_SIGNAL_SEAT_ADDED, G_CALLBACK (seat_added_cb), NULL);
+    g_signal_connect (display_manager, DISPLAY_MANAGER_SIGNAL_SEAT_REMOVED, G_CALLBACK (seat_removed_cb), NULL);
     for (link = display_manager_get_seats (display_manager); link; link = link->next)
         seat_added_cb (display_manager, (Seat *) link->data);
 
@@ -846,7 +900,7 @@ bus_acquired_cb (GDBusConnection *connection,
     /* Start the XDMCP server */
     if (config_get_boolean (config_get_instance (), "XDMCPServer", "enabled"))
     {
-        gchar *key_name, *key = NULL;
+        gchar *key_name, *key = NULL, *listen_address, *hostname;
 
         xdmcp_server = xdmcp_server_new ();
         if (config_has_key (config_get_instance (), "XDMCPServer", "port"))
@@ -856,7 +910,13 @@ bus_acquired_cb (GDBusConnection *connection,
             if (port > 0)
                 xdmcp_server_set_port (xdmcp_server, port);
         }
-        g_signal_connect (xdmcp_server, "new-session", G_CALLBACK (xdmcp_session_cb), NULL);
+        listen_address = config_get_string (config_get_instance (), "XDMCPServer", "listen-address");
+        xdmcp_server_set_listen_address (xdmcp_server, listen_address);
+        g_free (listen_address);
+        hostname = config_get_string (config_get_instance (), "XDMCPServer", "hostname");
+        xdmcp_server_set_hostname (xdmcp_server, hostname);
+        g_free (hostname);
+        g_signal_connect (xdmcp_server, XDMCP_SERVER_SIGNAL_NEW_SESSION, G_CALLBACK (xdmcp_session_cb), NULL);
 
         key_name = config_get_string (config_get_instance (), "XDMCPServer", "key");
         if (key_name)
@@ -871,7 +931,7 @@ bus_acquired_cb (GDBusConnection *connection,
             keys = g_key_file_new ();
             result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error);
             if (error)
-                g_debug ("Error getting key %s", error->message);
+                g_warning ("Unable to load keys from %s: %s", path, error->message);
             g_clear_error (&error);
 
             if (result)
@@ -879,7 +939,7 @@ bus_acquired_cb (GDBusConnection *connection,
                 if (g_key_file_has_key (keys, "keyring", key_name, NULL))
                     key = g_key_file_get_string (keys, "keyring", key_name, NULL);
                 else
-                    g_debug ("Key %s not defined", key_name);
+                    g_warning ("Key %s not defined", key_name);
             }
             g_free (path);
             g_key_file_free (keys);
@@ -888,9 +948,18 @@ bus_acquired_cb (GDBusConnection *connection,
             xdmcp_server_set_key (xdmcp_server, key);
         g_free (key_name);
         g_free (key);
-
-        g_debug ("Starting XDMCP server on UDP/IP port %d", xdmcp_server_get_port (xdmcp_server));
-        xdmcp_server_start (xdmcp_server);
+      
+        if (key_name && !key)
+        {
+            exit_code = EXIT_FAILURE;
+            display_manager_stop (display_manager);
+            return;
+        }
+        else
+        {
+            g_debug ("Starting XDMCP server on UDP/IP port %d", xdmcp_server_get_port (xdmcp_server));
+            xdmcp_server_start (xdmcp_server);
+        }
     }
 
     /* Start the VNC server */
@@ -901,6 +970,8 @@ bus_acquired_cb (GDBusConnection *connection,
         path = g_find_program_in_path ("Xvnc");
         if (path)
         {
+            gchar *listen_address;
+
             vnc_server = vnc_server_new ();
             if (config_has_key (config_get_instance (), "VNCServer", "port"))
             {
@@ -909,7 +980,10 @@ bus_acquired_cb (GDBusConnection *connection,
                 if (port > 0)
                     vnc_server_set_port (vnc_server, port);
             }
-            g_signal_connect (vnc_server, "new-connection", G_CALLBACK (vnc_connection_cb), NULL);
+            listen_address = config_get_string (config_get_instance (), "VNCServer", "listen-address");
+            vnc_server_set_listen_address (vnc_server, listen_address);
+            g_free (listen_address);
+            g_signal_connect (vnc_server, VNC_SERVER_SIGNAL_NEW_CONNECTION, G_CALLBACK (vnc_connection_cb), NULL);
 
             g_debug ("Starting VNC server on TCP/IP port %d", vnc_server_get_port (vnc_server));
             vnc_server_start (vnc_server);
@@ -934,112 +1008,171 @@ name_lost_cb (GDBusConnection *connection,
     exit (EXIT_FAILURE);
 }
 
-static gchar*
-get_config_section (const gchar *seat_name)
-{
-    gchar **groups, **i;
-    gchar *config_section = NULL;
-
-    groups = config_get_groups (config_get_instance ());
-    for (i = groups; !config_section && *i; i++)
-    {
-        if (g_str_has_prefix (*i, "Seat:"))
-        {
-            const gchar *seat_name_suffix = *i + strlen ("Seat:");
-            gchar *seat_name_globbing;
-            gboolean matches;
-
-            if (g_str_has_suffix (seat_name_suffix, "*"))
-                seat_name_globbing = g_strndup (seat_name_suffix, strlen(seat_name_suffix) - 1);
-            else
-                seat_name_globbing = g_strdup (seat_name_suffix);
-            
-            matches = g_str_has_prefix (seat_name, seat_name_globbing);
-            g_free (seat_name_globbing);
-
-            if (matches)
-            {
-                config_section = g_strdup (*i);
-                break;
-            }
-        }
-    }
-    g_strfreev (groups);
-    return config_section;
-}
-
 static gboolean
 add_login1_seat (Login1Seat *login1_seat)
 {
     const gchar *seat_name = login1_seat_get_id (login1_seat);
     gchar **types = NULL, **type;
-    gchar *config_section;
+    GList *config_sections = NULL, *link;
     Seat *seat = NULL;
     gboolean is_seat0, started = FALSE;
 
     g_debug ("New seat added from logind: %s", seat_name);
     is_seat0 = strcmp (seat_name, "seat0") == 0;
 
-    config_section = get_config_section (seat_name);
-    if (config_section)
+    config_sections = get_config_sections (seat_name);
+    for (link = g_list_last (config_sections); link; link = link->prev)
     {
-        g_debug ("Loading properties from config section %s", config_section);
+        gchar *config_section = link->data;
         types = config_get_string_list (config_get_instance (), config_section, "type");
+        if (types)
+            break;
     }
+    g_list_free_full (config_sections, g_free);
 
-    if (!types)
-        types = config_get_string_list (config_get_instance (), "SeatDefaults", "type");
     for (type = types; !seat && type && *type; type++)
-        seat = seat_new (*type, seat_name);
+        seat = create_seat (*type, seat_name);
     g_strfreev (types);
 
     if (seat)
     {
-        set_seat_properties (seat, NULL);
+        set_seat_properties (seat, seat_name);
 
         if (!login1_seat_get_can_multi_session (login1_seat))
         {
             g_debug ("Seat %s has property CanMultiSession=no", seat_name);
-            seat_set_property (seat, "allow-user-switching", "false");
+            /* XXX: uncomment this line after bug #1371250 is closed.
+            seat_set_property (seat, "allow-user-switching", "false"); */
         }
 
-        if (config_section)
-            set_seat_properties (seat, config_section);
-
         if (is_seat0)
             seat_set_property (seat, "exit-on-failure", "true");
     }
     else
-        g_debug ("Unable to create seat: %s", seat_name);
-
-    if (seat)
     {
-        started = display_manager_add_seat (display_manager, seat);
-        if (!started)
-            g_debug ("Failed to start seat: %s", seat_name);
+        g_debug ("Unable to create seat: %s", seat_name);
+        return FALSE;
     }
 
-    g_free (config_section);
+    started = display_manager_add_seat (display_manager, seat);
+    if (!started)
+        g_debug ("Failed to start seat: %s", seat_name);
     g_object_unref (seat);
-  
+
     return started;
 }
 
 static void
-login1_service_seat_added_cb (Login1Service *service, Login1Seat *login1_seat)
+remove_login1_seat (Login1Seat *login1_seat)
 {
-    add_login1_seat (login1_seat);
+    Seat *seat;
+
+    seat = display_manager_get_seat (display_manager, login1_seat_get_id (login1_seat));
+    if (seat)
+        seat_stop (seat);
 }
 
 static void
-login1_service_seat_removed_cb (Login1Service *service, Login1Seat *login1_seat)
+seat_stopped_cb (Seat *seat, Login1Seat *login1_seat)
 {
-    Seat *seat;
+    update_login1_seat (login1_seat);
+    g_signal_handlers_disconnect_matched (seat, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, login1_seat);
+}
+
+static gboolean
+update_login1_seat (Login1Seat *login1_seat)
+{
+    if (!config_get_boolean (config_get_instance (), "LightDM", "logind-check-graphical") ||
+        login1_seat_get_can_graphical (login1_seat))
+    {
+        Seat *seat;
+
+        /* Wait for existing seat to stop or ignore if we already have a valid seat */
+        seat = display_manager_get_seat (display_manager, login1_seat_get_id (login1_seat));
+        if (seat)
+        {
+            if (seat_get_is_stopping (seat))
+                g_signal_connect (seat, SEAT_SIGNAL_STOPPED, G_CALLBACK (seat_stopped_cb), login1_seat);
+            return TRUE;
+        }
 
-    g_debug ("Seat removed from logind: %s", login1_seat_get_id (login1_seat));
+        return add_login1_seat (login1_seat);
+    }
+    else
+    {
+        remove_login1_seat (login1_seat);
+        return TRUE;
+    }
+}
+
+static void
+login1_can_graphical_changed_cb (Login1Seat *login1_seat)
+{
+    g_debug ("Seat %s changes graphical state to %s", login1_seat_get_id (login1_seat), login1_seat_get_can_graphical (login1_seat) ? "true" : "false");
+    update_login1_seat (login1_seat);
+}
+
+static void
+login1_active_session_changed_cb (Login1Seat *login1_seat, const gchar *login1_session_id)
+{
+    g_debug ("Seat %s changes active session to %s", login1_seat_get_id (login1_seat), login1_session_id);
+
+    Seat *seat;
     seat = display_manager_get_seat (display_manager, login1_seat_get_id (login1_seat));
+
     if (seat)
-        seat_stop (seat);
+    {
+        Session *active_session;
+
+        active_session = seat_get_expected_active_session (seat);
+        if (active_session != NULL &&
+            g_strcmp0 (login1_session_id, session_get_login1_session_id (active_session)) == 0)
+        {
+            // Session is already active
+            g_debug ("Session %s is already active", login1_session_id);
+            return;
+        }
+
+        active_session = seat_find_session_by_login1_id (seat, login1_session_id);
+        if (active_session != NULL)
+        {
+            g_debug ("Activating session %s", login1_session_id);
+            seat_set_externally_activated_session (seat, active_session);
+            return;
+
+        }
+    }
+}
+
+static gboolean
+login1_add_seat (Login1Seat *login1_seat)
+{
+    if (config_get_boolean (config_get_instance (), "LightDM", "logind-check-graphical"))
+        g_signal_connect (login1_seat, "can-graphical-changed", G_CALLBACK (login1_can_graphical_changed_cb), NULL);
+
+    g_signal_connect (login1_seat, LOGIN1_SIGNAL_ACTIVE_SESION_CHANGED, G_CALLBACK (login1_active_session_changed_cb), NULL);
+
+    return update_login1_seat (login1_seat);
+}
+
+static void
+login1_service_seat_added_cb (Login1Service *service, Login1Seat *login1_seat)
+{
+    if (login1_seat_get_can_graphical (login1_seat))
+        g_debug ("Seat %s added from logind", login1_seat_get_id (login1_seat));
+    else
+        g_debug ("Seat %s added from logind without graphical output", login1_seat_get_id (login1_seat));
+
+    login1_add_seat (login1_seat);
+}
+
+static void
+login1_service_seat_removed_cb (Login1Service *service, Login1Seat *login1_seat)
+{
+    g_debug ("Seat %s removed from logind", login1_seat_get_id (login1_seat));
+    g_signal_handlers_disconnect_matched (login1_seat, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, login1_can_graphical_changed_cb, NULL);
+    g_signal_handlers_disconnect_matched (login1_seat, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, login1_active_session_changed_cb, NULL);
+    remove_login1_seat (login1_seat);
 }
 
 int
@@ -1092,6 +1225,12 @@ main (int argc, char **argv)
     };
     GError *error = NULL;
 
+    /* Disable the SIGPIPE handler - this is a stupid Unix hangover behaviour.
+     * We will handle piples / sockets being closed instead of having the whole daemon be killed...
+     * http://stackoverflow.com/questions/8369506/why-does-sigpipe-exist
+     */
+    signal (SIGPIPE, SIG_IGN);
+
     /* When lightdm starts sessions it needs to run itself in a new mode */
     if (argc >= 2 && strcmp (argv[1], "--session-child") == 0)
         return session_child_run (argc, argv);
@@ -1103,7 +1242,7 @@ main (int argc, char **argv)
 
     messages = g_list_append (messages, g_strdup_printf ("Starting Light Display Manager %s, UID=%i PID=%i", VERSION, getuid (), getpid ()));
 
-    g_signal_connect (process_get_current (), "got-signal", G_CALLBACK (signal_cb), NULL);
+    g_signal_connect (process_get_current (), PROCESS_SIGNAL_GOT_SIGNAL, G_CALLBACK (signal_cb), NULL);
 
     option_context = g_option_context_new (/* Arguments and description for --help test */
                                            _("- Display Manager"));
@@ -1273,36 +1412,40 @@ main (int argc, char **argv)
         config_set_string (config_get_instance (), "LightDM", "greeter-user", GREETER_USER);
     if (!config_has_key (config_get_instance (), "LightDM", "lock-memory"))
         config_set_boolean (config_get_instance (), "LightDM", "lock-memory", TRUE);
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "type"))
-        config_set_string (config_get_instance (), "SeatDefaults", "type", "xlocal");
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "pam-service"))
-        config_set_string (config_get_instance (), "SeatDefaults", "pam-service", "lightdm");
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "pam-autologin-service"))
-        config_set_string (config_get_instance (), "SeatDefaults", "pam-autologin-service", "lightdm-autologin");
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "pam-greeter-service"))
-        config_set_string (config_get_instance (), "SeatDefaults", "pam-greeter-service", "lightdm-greeter");
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "xserver-command"))
-        config_set_string (config_get_instance (), "SeatDefaults", "xserver-command", "X");
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "xserver-share"))
-        config_set_boolean (config_get_instance (), "SeatDefaults", "xserver-share", TRUE);
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "unity-compositor-command"))
-        config_set_string (config_get_instance (), "SeatDefaults", "unity-compositor-command", "unity-system-compositor");
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "start-session"))
-        config_set_boolean (config_get_instance (), "SeatDefaults", "start-session", TRUE);
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "allow-user-switching"))
-        config_set_boolean (config_get_instance (), "SeatDefaults", "allow-user-switching", TRUE);
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "allow-guest"))
-        config_set_boolean (config_get_instance (), "SeatDefaults", "allow-guest", TRUE);
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "greeter-allow-guest"))
-        config_set_boolean (config_get_instance (), "SeatDefaults", "greeter-allow-guest", TRUE);
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "greeter-show-remote-login"))
-        config_set_boolean (config_get_instance (), "SeatDefaults", "greeter-show-remote-login", TRUE);
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "greeter-session"))
-        config_set_string (config_get_instance (), "SeatDefaults", "greeter-session", GREETER_SESSION);
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "user-session"))
-        config_set_string (config_get_instance (), "SeatDefaults", "user-session", USER_SESSION);
-    if (!config_has_key (config_get_instance (), "SeatDefaults", "session-wrapper"))
-        config_set_string (config_get_instance (), "SeatDefaults", "session-wrapper", "lightdm-session");
+    if (!config_has_key (config_get_instance (), "LightDM", "backup-logs"))
+        config_set_boolean (config_get_instance (), "LightDM", "backup-logs", TRUE);
+    if (!config_has_key (config_get_instance (), "Seat:*", "type"))
+        config_set_string (config_get_instance (), "Seat:*", "type", "local");
+    if (!config_has_key (config_get_instance (), "Seat:*", "pam-service"))
+        config_set_string (config_get_instance (), "Seat:*", "pam-service", "lightdm");
+    if (!config_has_key (config_get_instance (), "Seat:*", "pam-autologin-service"))
+        config_set_string (config_get_instance (), "Seat:*", "pam-autologin-service", "lightdm-autologin");
+    if (!config_has_key (config_get_instance (), "Seat:*", "pam-greeter-service"))
+        config_set_string (config_get_instance (), "Seat:*", "pam-greeter-service", "lightdm-greeter");
+    if (!config_has_key (config_get_instance (), "Seat:*", "xserver-command"))
+        config_set_string (config_get_instance (), "Seat:*", "xserver-command", "X");
+    if (!config_has_key (config_get_instance (), "Seat:*", "xmir-command"))
+        config_set_string (config_get_instance (), "Seat:*", "xmir-command", "Xmir");
+    if (!config_has_key (config_get_instance (), "Seat:*", "xserver-share"))
+        config_set_boolean (config_get_instance (), "Seat:*", "xserver-share", TRUE);
+    if (!config_has_key (config_get_instance (), "Seat:*", "unity-compositor-command"))
+        config_set_string (config_get_instance (), "Seat:*", "unity-compositor-command", "unity-system-compositor");
+    if (!config_has_key (config_get_instance (), "Seat:*", "start-session"))
+        config_set_boolean (config_get_instance (), "Seat:*", "start-session", TRUE);
+    if (!config_has_key (config_get_instance (), "Seat:*", "allow-user-switching"))
+        config_set_boolean (config_get_instance (), "Seat:*", "allow-user-switching", TRUE);
+    if (!config_has_key (config_get_instance (), "Seat:*", "allow-guest"))
+        config_set_boolean (config_get_instance (), "Seat:*", "allow-guest", TRUE);
+    if (!config_has_key (config_get_instance (), "Seat:*", "greeter-allow-guest"))
+        config_set_boolean (config_get_instance (), "Seat:*", "greeter-allow-guest", TRUE);
+    if (!config_has_key (config_get_instance (), "Seat:*", "greeter-show-remote-login"))
+        config_set_boolean (config_get_instance (), "Seat:*", "greeter-show-remote-login", TRUE);
+    if (!config_has_key (config_get_instance (), "Seat:*", "greeter-session"))
+        config_set_string (config_get_instance (), "Seat:*", "greeter-session", DEFAULT_GREETER_SESSION);
+    if (!config_has_key (config_get_instance (), "Seat:*", "user-session"))
+        config_set_string (config_get_instance (), "Seat:*", "user-session", DEFAULT_USER_SESSION);
+    if (!config_has_key (config_get_instance (), "Seat:*", "session-wrapper"))
+        config_set_string (config_get_instance (), "Seat:*", "session-wrapper", "lightdm-session");
     if (!config_has_key (config_get_instance (), "LightDM", "log-directory"))
         config_set_string (config_get_instance (), "LightDM", "log-directory", default_log_dir);
     g_free (default_log_dir);
@@ -1318,6 +1461,8 @@ main (int argc, char **argv)
         config_set_string (config_get_instance (), "LightDM", "remote-sessions-directory", REMOTE_SESSIONS_DIR);
     if (!config_has_key (config_get_instance (), "LightDM", "greeters-directory"))
         config_set_string (config_get_instance (), "LightDM", "greeters-directory", GREETERS_DIR);
+    if (!config_has_key (config_get_instance (), "XDMCPServer", "hostname"))
+        config_set_string (config_get_instance (), "XDMCPServer", "hostname", g_get_host_name ());
 
     /* Override defaults */
     if (log_dir)
@@ -1367,8 +1512,8 @@ main (int argc, char **argv)
         g_debug ("Using Xephyr for X servers");
 
     display_manager = display_manager_new ();
-    g_signal_connect (display_manager, "stopped", G_CALLBACK (display_manager_stopped_cb), NULL);
-    g_signal_connect (display_manager, "seat-removed", G_CALLBACK (display_manager_seat_removed_cb), NULL);
+    g_signal_connect (display_manager, DISPLAY_MANAGER_SIGNAL_STOPPED, G_CALLBACK (display_manager_stopped_cb), NULL);
+    g_signal_connect (display_manager, DISPLAY_MANAGER_SIGNAL_SEAT_REMOVED, G_CALLBACK (display_manager_seat_removed_cb), NULL);
 
     shared_data_manager_start (shared_data_manager_get_instance ());
 
@@ -1380,13 +1525,13 @@ main (int argc, char **argv)
 
         if (config_get_boolean (config_get_instance (), "LightDM", "start-default-seat"))
         {
-            g_signal_connect (login1_service_get_instance (), "seat-added", G_CALLBACK (login1_service_seat_added_cb), NULL);
-            g_signal_connect (login1_service_get_instance (), "seat-removed", G_CALLBACK (login1_service_seat_removed_cb), NULL);
+            g_signal_connect (login1_service_get_instance (), LOGIN1_SERVICE_SIGNAL_SEAT_ADDED, G_CALLBACK (login1_service_seat_added_cb), NULL);
+            g_signal_connect (login1_service_get_instance (), LOGIN1_SERVICE_SIGNAL_SEAT_REMOVED, G_CALLBACK (login1_service_seat_removed_cb), NULL);
 
             for (link = login1_service_get_seats (login1_service_get_instance ()); link; link = link->next)
             {
-                Login1Seat *seat = link->data;
-                if (!add_login1_seat (seat))
+                Login1Seat *login1_seat = link->data;
+                if (!login1_add_seat (login1_seat))
                     return EXIT_FAILURE;
             }
         }
@@ -1401,10 +1546,10 @@ main (int argc, char **argv)
 
             g_debug ("Adding default seat");
 
-            types = config_get_string_list (config_get_instance (), "SeatDefaults", "type");
+            types = config_get_string_list (config_get_instance (), "Seat:*", "type");
             for (type = types; type && *type; type++)
             {
-                seat = seat_new (*type, "seat0");
+                seat = create_seat (*type, "seat0");
                 if (seat)
                     break;
             }
@@ -1434,8 +1579,7 @@ main (int argc, char **argv)
     common_user_list_cleanup ();
 
     /* Clean up display manager */
-    g_object_unref (display_manager);
-    display_manager = NULL;
+    g_clear_object (&display_manager);
 
     /* Remove D-Bus interface */
     g_dbus_connection_unregister_object (bus, reg_id);