--- gdm-2.27.90/daemon/gdm-session-direct.c	2009-09-09 18:39:10.902593154 +1000
+++ gdm-2.27.90-failsafe/daemon/gdm-session-direct.c	2009-09-09 21:04:10.641171722 +1000
@@ -2032,7 +2032,14 @@
         g_return_if_fail (impl->priv->is_running == FALSE);
 
         command = get_session_command (impl);
-        program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
+
+        if (gdm_session_direct_is_failsafe(impl) == FALSE) {
+                program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
+        } else {
+                /* Failsafe session: bypass the Xsession script */
+                program = g_strdup (command);
+        }
+
         g_free (command);
 
         setup_session_environment (impl);
@@ -2123,6 +2130,55 @@
         return g_strdup (session->priv->selected_user);
 }
 
+gboolean
+gdm_session_direct_is_failsafe (GdmSessionDirect *session_direct)
+{
+        GError     *error;
+        GKeyFile   *key_file;
+        gboolean    res;
+        gboolean    failsafe = FALSE;
+        char       *filename;
+        char       *full_path;
+
+        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 (),
+                                         &full_path,
+                                         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, "FailSafe", NULL);
+        if (!res) {
+                failsafe =  FALSE;
+                goto out;
+        } else {
+                failsafe = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "FailSafe", &error);
+                if (error) {
+                        failsafe = FALSE;
+                        g_error_free (error);
+                        goto out;
+                } else if (failsafe == TRUE) {
+                        g_debug ("GdmSessionDirect: Session %s is tagged as failsafe", filename);
+                }
+        }
+
+out:
+        g_free (filename);
+        return failsafe;
+}
+
 static void
 gdm_session_direct_select_session (GdmSession *session,
                                    const char *text)
--- gdm-2.27.90/daemon/gdm-session-direct.h	2009-08-25 05:31:18.000000000 +1000
+++ gdm-2.27.90-failsafe/daemon/gdm-session-direct.h	2009-09-09 21:04:18.660554358 +1000
@@ -56,6 +56,7 @@
                                                                 gboolean    display_is_local) G_GNUC_MALLOC;
 
 char             * gdm_session_direct_get_username             (GdmSessionDirect     *session_direct);
+gboolean           gdm_session_direct_is_failsafe              (GdmSessionDirect     *session_direct);
 
 /* Exported methods */
 gboolean           gdm_session_direct_restart                  (GdmSessionDirect     *session_direct,
--- gdm-2.27.90/daemon/gdm-simple-slave.c	2009-09-09 18:39:10.855368061 +1000
+++ gdm-2.27.90-failsafe/daemon/gdm-simple-slave.c	2009-09-09 14:30:13.156128123 +1000
@@ -112,7 +112,11 @@
         username = gdm_session_direct_get_username (slave->priv->session);
         gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/PreSession", username);
 
-        /* FIXME: should we do something here? */
+        /* FIXME: should we do something here?
+         * Note that error return status from PreSession script should
+         * be ignored in the case of a Failsafe session, which can be checked
+         * by calling: gdm_session_direct_is_failsafe(session)
+         */
 }
 
 static void
--- gdm-2.27.90/gui/simple-greeter/gdm-session-option-widget.c	2009-08-25 05:31:18.000000000 +1000
+++ gdm-2.27.90-failsafe/gui/simple-greeter/gdm-session-option-widget.c	2009-09-11 13:39:55.220573428 +1000
@@ -113,17 +113,25 @@
 
         for (i = 0; session_ids[i] != NULL; i++) {
                 char *name;
+                char *rename;
                 char *comment;
+                gboolean failsafe;
 
                 if (!gdm_get_details_for_session (session_ids[i],
-                                                  &name, &comment)) {
+                                                  &name,
+                                                  &comment,
+                                                  &failsafe)) {
                         continue;
                 }
 
+                rename = g_strdup_printf("%s%s",
+                                        name,
+                                        failsafe ? _(" (Failsafe)") : "");
                 gdm_option_widget_add_item (GDM_OPTION_WIDGET (widget),
-                                            session_ids[i], name, comment,
+                                            session_ids[i], rename, comment,
                                             GDM_OPTION_WIDGET_POSITION_MIDDLE);
                 g_free (name);
+                g_free (rename);
                 g_free (comment);
         }
 
--- gdm-2.27.90/gui/simple-greeter/gdm-sessions.c	2009-08-25 05:31:18.000000000 +1000
+++ gdm-2.27.90-failsafe/gui/simple-greeter/gdm-sessions.c	2009-09-11 13:26:16.492374847 +1000
@@ -38,10 +38,11 @@
 #include "gdm-sessions.h"
 
 typedef struct _GdmSessionFile {
-        char    *id;
-        char    *path;
-        char    *translated_name;
-        char    *translated_comment;
+        char            *id;
+        char            *path;
+        char            *translated_name;
+        char            *translated_comment;
+        gboolean         failsafe;
 } GdmSessionFile;
 
 static GHashTable *gdm_available_sessions_map;
@@ -144,6 +145,19 @@
         session->translated_name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "Name", NULL, NULL);
         session->translated_comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "Comment", NULL, NULL);
 
+        res = g_key_file_has_key (key_file, G_KEY_FILE_DESKTOP_GROUP, "FailSafe", NULL);
+        if (!res) {
+                session->failsafe =  FALSE;
+        } else {
+                session->failsafe = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "FailSafe", &error);
+                if (error) {
+                        session->failsafe = FALSE;
+                        g_error_free (error);
+                }
+        }
+
+        error = NULL;
+
         g_hash_table_insert (gdm_available_sessions_map,
                              g_strdup (id),
                              session);
@@ -236,7 +250,8 @@
 gboolean
 gdm_get_details_for_session (const char  *id,
                              char       **name,
-                             char       **comment)
+                             char       **comment,
+                             gboolean    *failsafe)
 {
         GdmSessionFile *session;
 
@@ -261,5 +276,9 @@
                 *comment = g_strdup (session->translated_comment);
         }
 
+        if (failsafe != NULL) {
+                *failsafe = session->failsafe;
+        }
+
         return TRUE;
 }
--- gdm-2.27.90/gui/simple-greeter/gdm-sessions.h	2009-08-25 05:31:18.000000000 +1000
+++ gdm-2.27.90-failsafe/gui/simple-greeter/gdm-sessions.h	2009-09-11 13:37:03.260327946 +1000
@@ -31,7 +31,8 @@
 char **                gdm_get_all_sessions (void);
 gboolean               gdm_get_details_for_session (const char  *id,
                                                     char       **name,
-                                                    char       **comment);
+                                                    char       **comment,
+						    gboolean    *failsafe);
 
 G_END_DECLS
 
--- gdm-2.27.90/gui/simple-greeter/test-sessions.c	2009-08-25 05:31:18.000000000 +1000
+++ gdm-2.27.90-failsafe/gui/simple-greeter/test-sessions.c	2009-09-11 13:44:11.011192336 +1000
@@ -42,17 +42,20 @@
 
         for (i = 0; session_names[i] != NULL; i++) {
                 gboolean res;
+                gboolean failsafe;
                 char    *name;
                 char    *comment;
 
                 res = gdm_get_details_for_session (session_names[i],
                                                    &name,
-                                                   &comment);
+                                                   &comment,
+                                                   &failsafe);
                 if (! res) {
                         continue;
                 }
-                g_print ("%s\t%s\t%s\n",
+                g_print ("%s%s\t%s\t%s\n",
                          session_names[i],
+                         failsafe ? _(" (Failsafe)") : "",
                          name,
                          comment);
 
