]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Return errors from all liblightdm methods
authorRobert Ancell <robert.ancell@canonical.com>
Mon, 27 Jun 2016 04:04:49 +0000 (16:04 +1200)
committerRobert Ancell <robert.ancell@canonical.com>
Mon, 27 Jun 2016 04:04:49 +0000 (16:04 +1200)
doc/tmpl/greeter.sgml
liblightdm-gobject/greeter.c
liblightdm-gobject/lightdm/greeter.h
liblightdm-qt/greeter.cpp
tests/scripts/login-invalid-session.conf
tests/scripts/shared-data-invalid-user.conf
tests/src/test-gobject-greeter.c
tests/src/test-python-greeter
tests/src/test-qt-greeter.cpp

index 682433edfe46ed7d18e284af595cb641f6823205..cb1a4a0e8b54f8ae99fbd1f1ab42a087d62a489c 100644 (file)
@@ -206,6 +206,7 @@ static void authentication_complete_cb (LightDMGreeter *greeter)
 
 @greeter: 
 @result: 
+@error: 
 @Returns: 
 
 
@@ -216,6 +217,7 @@ static void authentication_complete_cb (LightDMGreeter *greeter)
 
 @greeter: 
 @username: 
+@error: 
 @Returns: 
 
 
@@ -335,6 +337,8 @@ static void authentication_complete_cb (LightDMGreeter *greeter)
 
 @greeter: 
 @language: 
+@error: 
+@Returns: 
 
 
 <!-- ##### FUNCTION lightdm_greeter_cancel_autologin ##### -->
@@ -352,6 +356,8 @@ static void authentication_complete_cb (LightDMGreeter *greeter)
 
 @greeter: 
 @username: 
+@error: 
+@Returns: 
 
 
 <!-- ##### FUNCTION lightdm_greeter_authenticate_as_guest ##### -->
@@ -360,6 +366,8 @@ static void authentication_complete_cb (LightDMGreeter *greeter)
 </para>
 
 @greeter: 
+@error: 
+@Returns: 
 
 
 <!-- ##### FUNCTION lightdm_greeter_authenticate_autologin ##### -->
@@ -368,6 +376,8 @@ static void authentication_complete_cb (LightDMGreeter *greeter)
 </para>
 
 @greeter: 
+@error: 
+@Returns: 
 
 
 <!-- ##### FUNCTION lightdm_greeter_authenticate_remote ##### -->
@@ -378,6 +388,8 @@ static void authentication_complete_cb (LightDMGreeter *greeter)
 @greeter: 
 @session: 
 @username: 
+@error: 
+@Returns: 
 
 
 <!-- ##### FUNCTION lightdm_greeter_respond ##### -->
@@ -387,6 +399,8 @@ static void authentication_complete_cb (LightDMGreeter *greeter)
 
 @greeter: 
 @response: 
+@error: 
+@Returns: 
 
 
 <!-- ##### FUNCTION lightdm_greeter_cancel_authentication ##### -->
@@ -395,6 +409,8 @@ static void authentication_complete_cb (LightDMGreeter *greeter)
 </para>
 
 @greeter: 
+@error: 
+@Returns: 
 
 
 <!-- ##### FUNCTION lightdm_greeter_get_in_authentication ##### -->
index 7db92c021c6226a73f6f2299c8bb44d5b677d774..57ac2774469fd188c3a2edb0ca1d5bae44084e9b 100644 (file)
@@ -127,12 +127,13 @@ typedef enum
 typedef struct
 {
     GObject parent_instance;
+    LightDMGreeter *greeter;
     GCancellable *cancellable;
     GAsyncReadyCallback callback;
     gpointer user_data;
     gboolean complete;
-    gboolean connected;
-    guint32 return_code;
+    gboolean result;
+    GError *error;
     gchar *dir;
 } Request;
 typedef struct
@@ -144,6 +145,8 @@ static void request_iface_init (GAsyncResultIface *iface);
 #define REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), request_get_type (), Request))
 G_DEFINE_TYPE_WITH_CODE (Request, request, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, request_iface_init));
 
+static gboolean from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data);
+
 GType
 lightdm_greeter_error_get_type (void)
 {
@@ -151,8 +154,11 @@ lightdm_greeter_error_get_type (void)
 
     if (G_UNLIKELY(enum_type == 0)) {
         static const GEnumValue values[] = {
+            { LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR, "LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR", "communication-error" },
             { LIGHTDM_GREETER_ERROR_CONNECTION_FAILED, "LIGHTDM_GREETER_ERROR_CONNECTION_FAILED", "connection-failed" },
             { LIGHTDM_GREETER_ERROR_SESSION_FAILED, "LIGHTDM_GREETER_ERROR_SESSION_FAILED", "session-failed" },
+            { LIGHTDM_GREETER_ERROR_NO_AUTOLOGIN, "LIGHTDM_GREETER_ERROR_NO_AUTOLOGIN", "no-autologin" },
+            { LIGHTDM_GREETER_ERROR_INVALID_USER, "LIGHTDM_GREETER_ERROR_INVALID_USER", "invalid-user" },          
             { 0, NULL, NULL }
         };
         enum_type = g_enum_register_static (g_intern_static_string ("LightDMGreeterError"), values);
@@ -231,11 +237,12 @@ lightdm_greeter_set_resettable (LightDMGreeter *greeter, gboolean resettable)
 }
 
 static Request *
-request_new (GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
+request_new (LightDMGreeter *greeter, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
 {
     Request *request;
 
     request = g_object_new (request_get_type (), NULL);
+    request->greeter = g_object_ref (greeter);
     if (cancellable)
         request->cancellable = g_object_ref (cancellable);
     request->callback = callback;
@@ -244,8 +251,18 @@ request_new (GCancellable *cancellable, GAsyncReadyCallback callback, gpointer u
     return request;
 }
 
+static gboolean
+request_callback_cb (gpointer data)
+{
+    Request *request = data;
+    if (request->callback)
+        request->callback (G_OBJECT (request->greeter), G_ASYNC_RESULT (request), request->user_data);
+    g_object_unref (request);
+    return G_SOURCE_REMOVE;
+}
+
 static void
-request_complete (Request *request, GObject *object)
+request_complete (Request *request)
 {
     request->complete = TRUE;
 
@@ -255,7 +272,7 @@ request_complete (Request *request, GObject *object)
     if (request->cancellable && g_cancellable_is_cancelled (request->cancellable))
         return;
 
-    request->callback (object, G_ASYNC_RESULT (request), request->user_data);
+    g_idle_add (request_callback_cb, g_object_ref (request));
 }
 
 static gboolean
@@ -276,31 +293,44 @@ int_length (void)
     return 4;
 }
 
-static void
-write_int (guint8 *buffer, gint buffer_length, guint32 value, gsize *offset)
+static gboolean
+write_int (guint8 *buffer, gint buffer_length, guint32 value, gsize *offset, GError **error)
 {
     if (*offset + 4 >= buffer_length)
-        return;
+    {
+        g_set_error_literal (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
+                             "Not enough buffer space to write integer");
+        return FALSE;
+    }
     buffer[*offset] = value >> 24;
     buffer[*offset+1] = (value >> 16) & 0xFF;
     buffer[*offset+2] = (value >> 8) & 0xFF;
     buffer[*offset+3] = value & 0xFF;
     *offset += 4;
+
+    return TRUE;
 }
 
-static void
-write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset)
+static gboolean
+write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *offset, GError **error)
 {
     gint length = 0;
 
     if (value)
         length = strlen (value);
-    write_int (buffer, buffer_length, length, offset);
+    if (!write_int (buffer, buffer_length, length, offset, error))
+        return FALSE;
     if (*offset + length >= buffer_length)
-        return;
+    {
+        g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
+                     "Not enough buffer space to write string of length %d octets", length);
+        return FALSE;
+    }
     if (value)
         memcpy (buffer + *offset, value, length);
     *offset += length;
+
+    return TRUE;
 }
 
 static guint32
@@ -352,11 +382,11 @@ string_length (const gchar *value)
         return int_length ();
 }
 
-static void
-write_header (guint8 *buffer, gint buffer_length, guint32 id, guint32 length, gsize *offset)
+static gboolean
+write_header (guint8 *buffer, gint buffer_length, guint32 id, guint32 length, gsize *offset, GError **error)
 {
-    write_int (buffer, buffer_length, id, offset);
-    write_int (buffer, buffer_length, length, offset);
+    return write_int (buffer, buffer_length, id, offset, error) &&
+           write_int (buffer, buffer_length, length, offset, error);
 }
 
 static guint32
@@ -367,15 +397,44 @@ get_message_length (guint8 *message, gsize message_length)
 }
 
 static gboolean
-send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
+connect_to_daemon (LightDMGreeter *greeter, GError **error)
+{
+    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+    const gchar *to_server_fd, *from_server_fd;
+
+    if (priv->to_server_channel || priv->from_server_channel)
+        return TRUE;
+
+    to_server_fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
+    from_server_fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
+    if (!to_server_fd || !from_server_fd)
+    {
+        g_set_error_literal (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_CONNECTION_FAILED,
+                             "Unable to determine socket to daemon");
+        return FALSE;
+    }
+
+    priv->to_server_channel = g_io_channel_unix_new (atoi (to_server_fd));
+    priv->from_server_channel = g_io_channel_unix_new (atoi (from_server_fd));
+    g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
+
+    if (!g_io_channel_set_encoding (priv->to_server_channel, NULL, error) ||
+        !g_io_channel_set_encoding (priv->from_server_channel, NULL, error))
+        return FALSE;
+
+    return TRUE;
+}
+
+static gboolean
+send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length, GError **error)
 {
     LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
     gchar *data;
     gsize data_length;
-    GError *error = NULL;
     guint32 stated_length;
+    GError *flush_error = NULL;
 
-    if (!priv->to_server_channel)
+    if (!connect_to_daemon (greeter, error))
         return FALSE;
 
     /* Double check that we're sending well-formed messages.  If we say we're
@@ -386,7 +445,9 @@ send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
     stated_length = HEADER_SIZE + get_message_length (message, message_length);
     if (stated_length != message_length)
     {
-        g_warning ("Refusing to write malformed packet to daemon: declared size is %u, but actual size is %zu", stated_length, message_length);
+        g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
+                     "Refusing to write malformed packet to daemon: declared size is %u, but actual size is %zu",
+                     stated_length, message_length);
         return FALSE;
     }
 
@@ -396,22 +457,29 @@ send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
     {
         GIOStatus status;
         gsize n_written;
-
-        status = g_io_channel_write_chars (priv->to_server_channel, data, data_length, &n_written, &error);
-        if (error)
-            g_warning ("Error writing to daemon: %s", error->message);
-        g_clear_error (&error);
-        if (status != G_IO_STATUS_NORMAL)
+        GError *write_error = NULL;
+
+        status = g_io_channel_write_chars (priv->to_server_channel, data, data_length, &n_written, &write_error);
+        if (write_error)
+            g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
+                         "Failed to write to daemon: %s",
+                         write_error->message);
+        g_clear_error (&write_error);
+        if (status != G_IO_STATUS_NORMAL) 
             return FALSE;
         data_length -= n_written;
         data += n_written;
     }
 
     g_debug ("Wrote %zi bytes to daemon", message_length);
-    g_io_channel_flush (priv->to_server_channel, &error);
-    if (error)
-        g_warning ("Failed to flush data to daemon: %s", error->message);
-    g_clear_error (&error);
+    if (!g_io_channel_flush (priv->to_server_channel, &flush_error))
+    {
+        g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
+                     "Failed to write to daemon: %s",
+                     flush_error->message);
+        g_clear_error (&flush_error);
+        return FALSE;
+    }
 
     return TRUE;
 }
@@ -454,8 +522,8 @@ handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length
     request = g_list_nth_data (priv->connect_requests, 0);
     if (request)
     {
-        request->connected = TRUE;
-        request_complete (request, G_OBJECT (greeter));
+        request->result = TRUE;
+        request_complete (request);
         priv->connect_requests = g_list_remove (priv->connect_requests, request);
         g_object_unref (request);
     }
@@ -606,8 +674,15 @@ handle_session_result (LightDMGreeter *greeter, guint8 *message, gsize message_l
     request = g_list_nth_data (priv->start_session_requests, 0);
     if (request)
     {
-        request->return_code = read_int (message, message_length, offset);
-        request_complete (request, G_OBJECT (greeter));
+        guint32 return_code;
+
+        return_code = read_int (message, message_length, offset);
+        if (return_code == 0)
+            request->result = TRUE;
+        else
+            request->error = g_error_new (LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_SESSION_FAILED,
+                                          "Session returned error code %d", return_code);
+        request_complete (request);
         priv->start_session_requests = g_list_remove (priv->start_session_requests, request);
         g_object_unref (request);
     }
@@ -629,8 +704,10 @@ handle_shared_dir_result (LightDMGreeter *greeter, guint8 *message, gsize messag
         {
             g_free (request->dir);
             request->dir = NULL;
+            request->error = g_error_new (LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_INVALID_USER,
+                                          "No such user");
         }
-        request_complete (request, G_OBJECT (greeter));
+        request_complete (request);
         priv->ensure_shared_data_dir_requests = g_list_remove (priv->ensure_shared_data_dir_requests, request);
         g_object_unref (request);
     }
@@ -673,16 +750,14 @@ handle_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
     }
 }
 
-static guint8 *
-recv_message (LightDMGreeter *greeter, gsize *length, gboolean block)
+static gboolean
+recv_message (LightDMGreeter *greeter, gboolean block, guint8 **message, gsize *length, GError **error)
 {
     LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
     gsize n_to_read, n_read;
-    guint8 *buffer;
-    GError *error = NULL;
 
-    if (!priv->from_server_channel)
-        return NULL;
+    if (!connect_to_daemon (greeter, error))
+        return FALSE;
 
     /* Read the header, or the whole message if we already have that */
     n_to_read = HEADER_SIZE;
@@ -692,16 +767,21 @@ recv_message (LightDMGreeter *greeter, gsize *length, gboolean block)
     do
     {
         GIOStatus status;
+        GError *read_error = NULL;
+
         status = g_io_channel_read_chars (priv->from_server_channel,
                                           (gchar *) priv->read_buffer + priv->n_read,
                                           n_to_read - priv->n_read,
                                           &n_read,
-                                          &error);
-        if (error)
-            g_warning ("Error reading from server: %s", error->message);
-        g_clear_error (&error);
+                                          &read_error);
         if (status != G_IO_STATUS_NORMAL)
-            break;
+        {
+            g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
+                         "Failed to read from daemon: %s",
+                         read_error->message);
+            g_clear_error (&read_error);
+            return FALSE;
+        }
 
         g_debug ("Read %zi bytes from daemon", n_read);
 
@@ -710,7 +790,13 @@ recv_message (LightDMGreeter *greeter, gsize *length, gboolean block)
 
     /* Stop if haven't got all the data we want */
     if (priv->n_read != n_to_read)
-        return NULL;
+    {
+        if (message)
+            *message = NULL;
+        if (length)
+            *length = 0;
+        return TRUE;
+    }
 
     /* If have header, rerun for content */
     if (priv->n_read == HEADER_SIZE)
@@ -719,17 +805,21 @@ recv_message (LightDMGreeter *greeter, gsize *length, gboolean block)
         if (n_to_read > 0)
         {
             priv->read_buffer = g_realloc (priv->read_buffer, HEADER_SIZE + n_to_read);
-            return recv_message (greeter, length, block);
+            return recv_message (greeter, block, message, length, error);
         }
     }
 
-    buffer = priv->read_buffer;
-    *length = priv->n_read;
+    if (message)
+        *message = priv->read_buffer;
+    else
+        g_free (priv->read_buffer);
+    if (length)
+        *length = priv->n_read;
 
     priv->read_buffer = g_malloc (priv->n_read);
     priv->n_read = 0;
 
-    return buffer;
+    return TRUE;
 }
 
 static gboolean
@@ -738,34 +828,41 @@ from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
     LightDMGreeter *greeter = data;
     guint8 *message;
     gsize message_length;
+    GError *error = NULL;
 
     /* Read one message and process it */
-    message = recv_message (greeter, &message_length, FALSE);
+    if (!recv_message (greeter, FALSE, &message, &message_length, &error))
+    {
+        // FIXME: Should push this up to the client somehow
+        g_warning ("Failed to read from daemon: %s\n", error->message);
+        g_clear_error (&error);
+        return G_SOURCE_REMOVE;
+    }
+
     if (message)
     {
         handle_message (greeter, message, message_length);
         g_free (message);
     }
 
-    return TRUE;
+    return G_SOURCE_CONTINUE;
 }
 
 static gboolean
-send_connect (LightDMGreeter *greeter, gboolean resettable)
+send_connect (LightDMGreeter *greeter, gboolean resettable, GError **error)
 {
     guint8 message[MAX_MESSAGE_LENGTH];
     gsize offset = 0;
 
     g_debug ("Connecting to display manager...");
-    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION) + int_length (), &offset);
-    write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
-    write_int (message, MAX_MESSAGE_LENGTH, resettable ? 1 : 0, &offset);
-
-    return send_message (greeter, message, offset);
+    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION) + int_length (), &offset, error) &&
+           write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset, error) &&
+           write_int (message, MAX_MESSAGE_LENGTH, resettable ? 1 : 0, &offset, error) &&
+           send_message (greeter, message, offset, error);
 }
 
 static gboolean
-send_start_session (LightDMGreeter *greeter, const gchar *session)
+send_start_session (LightDMGreeter *greeter, const gchar *session, GError **error)
 {
     guint8 message[MAX_MESSAGE_LENGTH];
     gsize offset = 0;
@@ -775,22 +872,22 @@ send_start_session (LightDMGreeter *greeter, const gchar *session)
     else
         g_debug ("Starting default session");
 
-    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
-    write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
-    return send_message (greeter, message, offset);
+    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset, error) &&
+           write_string (message, MAX_MESSAGE_LENGTH, session, &offset, error) &&
+           send_message (greeter, message, offset, error);
 }
 
 static gboolean
-send_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username)
+send_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username, GError **error)
 {
     guint8 message[MAX_MESSAGE_LENGTH];
     gsize offset = 0;
 
     g_debug ("Ensuring data directory for user %s", username);
 
-    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_ENSURE_SHARED_DIR, string_length (username), &offset);
-    write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
-    return send_message (greeter, message, offset);
+    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_ENSURE_SHARED_DIR, string_length (username), &offset, error) &&
+           write_string (message, MAX_MESSAGE_LENGTH, username, &offset, error) &&
+           send_message (greeter, message, offset, error);
 }
 
 /**
@@ -811,14 +908,21 @@ lightdm_greeter_connect_to_daemon (LightDMGreeter *greeter, GCancellable *cancel
 {
     LightDMGreeterPrivate *priv;
     Request *request;
+    GError *error = NULL;
 
     g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
     priv = GET_PRIVATE (greeter);
 
-    request = request_new (cancellable, callback, user_data);
-    priv->connect_requests = g_list_append (priv->connect_requests, request);
-    send_connect (greeter, priv->resettable);
+    request = request_new (greeter, cancellable, callback, user_data);
+    if (send_connect (greeter, priv->resettable, &error))
+        priv->connect_requests = g_list_append (priv->connect_requests, request);
+    else
+    {
+        request->error = error;
+        request_complete (request);
+        g_object_unref (request);
+    }
 }
 
 /**
@@ -837,14 +941,9 @@ lightdm_greeter_connect_to_daemon_finish (LightDMGreeter *greeter, GAsyncResult
     Request *request = REQUEST (result);
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
-
-    if (request->connected)
-        return TRUE;
-    else
-    {
-        g_set_error_literal (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_CONNECTION_FAILED, "Failed to connect to daemon");
-        return FALSE;
-    }
+  
+    g_propagate_error (error, request->error);
+    return request->result;
 }
 
 /**
@@ -867,17 +966,17 @@ lightdm_greeter_connect_to_daemon_sync (LightDMGreeter *greeter, GError **error)
     priv = GET_PRIVATE (greeter);
 
     /* Read until we are connected */
-    send_connect (greeter, priv->resettable);
-    request = request_new (NULL, NULL, NULL);
+    if (!send_connect (greeter, priv->resettable, error))
+        return FALSE;
+    request = request_new (greeter, NULL, NULL, NULL);
     priv->connect_requests = g_list_append (priv->connect_requests, g_object_ref (request));
     do
     {
         guint8 *message;
         gsize message_length;
 
-        message = recv_message (greeter, &message_length, TRUE);
-        if (!message)
-            break;
+        if (!recv_message (greeter, TRUE, &message, &message_length, error))
+            return FALSE;
         handle_message (greeter, message, message_length);
         g_free (message);
     } while (!request->complete);
@@ -1154,21 +1253,24 @@ lightdm_greeter_cancel_autologin (LightDMGreeter *greeter)
  * lightdm_greeter_authenticate:
  * @greeter: A #LightDMGreeter
  * @username: (allow-none): A username or #NULL to prompt for a username.
+ * @error: return location for a #GError, or %NULL
  *
  * Starts the authentication procedure for a user.
+ *
+ * Return value: #TRUE if authentication request sent.
  **/
-void
-lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username)
+gboolean
+lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username, GError **error)
 {
     LightDMGreeterPrivate *priv;
     guint8 message[MAX_MESSAGE_LENGTH];
     gsize offset = 0;
 
-    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
+    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
     priv = GET_PRIVATE (greeter);
 
-    g_return_if_fail (priv->connected);
+    g_return_val_if_fail (priv->connected, FALSE);
 
     priv->cancelling_authentication = FALSE;
     priv->authenticate_sequence_number++;
@@ -1181,30 +1283,33 @@ lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username)
     }
 
     g_debug ("Starting authentication for user %s...", username);
-    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset);
-    write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
-    write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
-    send_message (greeter, message, offset);
+    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset, error) &&
+           write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset, error) &&
+           write_string (message, MAX_MESSAGE_LENGTH, username, &offset, error) &&
+           send_message (greeter, message, offset, error);
 }
 
 /**
  * lightdm_greeter_authenticate_as_guest:
  * @greeter: A #LightDMGreeter
+ * @error: return location for a #GError, or %NULL
  *
  * Starts the authentication procedure for the guest user.
+ *
+ * Return value: #TRUE if authentication request sent.
  **/
-void
-lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter)
+gboolean
+lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter, GError **error)
 {
     LightDMGreeterPrivate *priv;
     guint8 message[MAX_MESSAGE_LENGTH];
     gsize offset = 0;
 
-    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
+    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
     priv = GET_PRIVATE (greeter);
 
-    g_return_if_fail (priv->connected);
+    g_return_val_if_fail (priv->connected, FALSE);
 
     priv->cancelling_authentication = FALSE;
     priv->authenticate_sequence_number++;
@@ -1214,27 +1319,36 @@ lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter)
     priv->authentication_user = NULL;
 
     g_debug ("Starting authentication for guest account...");
-    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset);
-    write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
-    send_message (greeter, message, offset);
+    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset, error) &&
+           write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset, error) &&
+           send_message (greeter, message, offset, error);
 }
 
 /**
  * lightdm_greeter_authenticate_autologin:
  * @greeter: A #LightDMGreeter
+ * @error: return location for a #GError, or %NULL
  *
  * Starts the authentication procedure for the automatic login user.
+ *
+ * Return value: #TRUE if authentication request sent.
  **/
-void
-lightdm_greeter_authenticate_autologin (LightDMGreeter *greeter)
+gboolean
+lightdm_greeter_authenticate_autologin (LightDMGreeter *greeter, GError **error)
 {
     const gchar *user;
 
     user = lightdm_greeter_get_autologin_user_hint (greeter);
     if (lightdm_greeter_get_autologin_guest_hint (greeter))
-        lightdm_greeter_authenticate_as_guest (greeter);
+        return lightdm_greeter_authenticate_as_guest (greeter, error);
     else if (user)
-        lightdm_greeter_authenticate (greeter, user);
+        return lightdm_greeter_authenticate (greeter, user, error);
+    else
+    {
+        g_set_error_literal (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_NO_AUTOLOGIN,
+                             "Can't authenticate autologin; autologin not configured");
+        return FALSE;
+    }
 }
 
 /**
@@ -1242,21 +1356,24 @@ lightdm_greeter_authenticate_autologin (LightDMGreeter *greeter)
  * @greeter: A #LightDMGreeter
  * @session: The name of a remote session
  * @username: (allow-none): A username of #NULL to prompt for a username.
+ * @error: return location for a #GError, or %NULL
  *
  * Start authentication for a remote session type.
+ *
+ * Return value: #TRUE if authentication request sent.
  **/
-void
-lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username)
+gboolean
+lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username, GError **error)
 {
     LightDMGreeterPrivate *priv;
     guint8 message[MAX_MESSAGE_LENGTH];
     gsize offset = 0;
 
-    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
+    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
     priv = GET_PRIVATE (greeter);
 
-    g_return_if_fail (priv->connected);
+    g_return_val_if_fail (priv->connected, FALSE);
 
     priv->cancelling_authentication = FALSE;
     priv->authenticate_sequence_number++;
@@ -1269,34 +1386,38 @@ lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *sessi
         g_debug ("Starting authentication for remote session %s as user %s...", session, username);
     else
         g_debug ("Starting authentication for remote session %s...", session);
-    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_REMOTE, int_length () + string_length (session) + string_length (username), &offset);
-    write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset);
-    write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
-    write_string (message, MAX_MESSAGE_LENGTH, username, &offset);
-    send_message (greeter, message, offset);
+
+    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_REMOTE, int_length () + string_length (session) + string_length (username), &offset, error) &&
+           write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset, error) &&
+           write_string (message, MAX_MESSAGE_LENGTH, session, &offset, error) &&
+           write_string (message, MAX_MESSAGE_LENGTH, username, &offset, error) &&
+           send_message (greeter, message, offset, error);
 }
 
 /**
  * lightdm_greeter_respond:
  * @greeter: A #LightDMGreeter
  * @response: Response to a prompt
+ * @error: return location for a #GError, or %NULL
  *
  * Provide response to a prompt.  May be one in a series.
+ *
+ * Return value: #TRUE if response sent.
  **/
-void
-lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response)
+gboolean
+lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response, GError **error)
 {
     LightDMGreeterPrivate *priv;
     guint8 message[MAX_MESSAGE_LENGTH];
     gsize offset = 0;
 
-    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
-    g_return_if_fail (response != NULL);
+    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
+    g_return_val_if_fail (response != NULL, FALSE);
 
     priv = GET_PRIVATE (greeter);
 
-    g_return_if_fail (priv->connected);
-    g_return_if_fail (priv->n_responses_waiting > 0);
+    g_return_val_if_fail (priv->connected, FALSE);
+    g_return_val_if_fail (priv->n_responses_waiting > 0, FALSE);
 
     priv->n_responses_waiting--;
     priv->responses_received = g_list_append (priv->responses_received, g_strdup (response));
@@ -1312,39 +1433,49 @@ lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response)
         for (iter = priv->responses_received; iter; iter = iter->next)
             msg_length += string_length ((gchar *)iter->data);
 
-        write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, msg_length, &offset);
-        write_int (message, MAX_MESSAGE_LENGTH, g_list_length (priv->responses_received), &offset);
+        if (!write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, msg_length, &offset, error) ||
+            !write_int (message, MAX_MESSAGE_LENGTH, g_list_length (priv->responses_received), &offset, error))
+            return FALSE;
         for (iter = priv->responses_received; iter; iter = iter->next)
-            write_string (message, MAX_MESSAGE_LENGTH, (gchar *)iter->data, &offset);
-        send_message (greeter, message, offset);
+        {
+            if (!write_string (message, MAX_MESSAGE_LENGTH, (gchar *)iter->data, &offset, error))
+                return FALSE;
+        }
+        if (!send_message (greeter, message, offset, error))
+            return FALSE;
 
         g_list_free_full (priv->responses_received, g_free);
         priv->responses_received = NULL;
     }
+
+    return TRUE;
 }
 
 /**
  * lightdm_greeter_cancel_authentication:
  * @greeter: A #LightDMGreeter
+ * @error: return location for a #GError, or %NULL
  *
  * Cancel the current user authentication.
+ *
+ * Return value: #TRUE if cancel request sent.
  **/
-void
-lightdm_greeter_cancel_authentication (LightDMGreeter *greeter)
+gboolean
+lightdm_greeter_cancel_authentication (LightDMGreeter *greeter, GError **error)
 {
     LightDMGreeterPrivate *priv;
     guint8 message[MAX_MESSAGE_LENGTH];
     gsize offset = 0;
 
-    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
+    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
     priv = GET_PRIVATE (greeter);
 
-    g_return_if_fail (priv->connected);
+    g_return_val_if_fail (priv->connected, FALSE);
 
     priv->cancelling_authentication = TRUE;
-    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0, &offset);
-    send_message (greeter, message, offset);
+    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0, &offset, error) &&
+           send_message (greeter, message, offset, error);
 }
 
 /**
@@ -1396,25 +1527,28 @@ lightdm_greeter_get_authentication_user (LightDMGreeter *greeter)
  * lightdm_greeter_set_language:
  * @greeter: A #LightDMGreeter
  * @language: The language to use for this user in the form of a locale specification (e.g. "de_DE.UTF-8").
+ * @error: return location for a #GError, or %NULL
  *
  * Set the language for the currently authenticated user.
+ *
+ * Return value: #TRUE if set language request sent.
  **/
-void
-lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language)
+gboolean
+lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language, GError **error)
 {
     LightDMGreeterPrivate *priv;
     guint8 message[MAX_MESSAGE_LENGTH];
     gsize offset = 0;
 
-    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
+    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
     priv = GET_PRIVATE (greeter);
 
-    g_return_if_fail (priv->connected);
+    g_return_val_if_fail (priv->connected, FALSE);
 
-    write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset);
-    write_string (message, MAX_MESSAGE_LENGTH, language, &offset);
-    send_message (greeter, message, offset);
+    return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset, error) &&
+           write_string (message, MAX_MESSAGE_LENGTH, language, &offset, error) &&
+           send_message (greeter, message, offset, error);
 }
 
 /**
@@ -1436,14 +1570,19 @@ lightdm_greeter_start_session (LightDMGreeter *greeter, const gchar *session, GC
 {
     LightDMGreeterPrivate *priv;
     Request *request;
+    GError *error = NULL;
 
     g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
     priv = GET_PRIVATE (greeter);
 
-    send_start_session (greeter, session);
-    request = request_new (cancellable, callback, user_data);
+    request = request_new (greeter, cancellable, callback, user_data);
     priv->start_session_requests = g_list_append (priv->start_session_requests, request);
+    if (!send_start_session (greeter, session, &error))
+    {
+        request->error = error;
+        request_complete (request);
+    }
 }
 
 /**
@@ -1463,13 +1602,8 @@ lightdm_greeter_start_session_finish (LightDMGreeter *greeter, GAsyncResult *res
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
-    if (request->return_code == 0)
-        return TRUE;
-    else
-    {
-        g_set_error (error, LIGHTDM_GREETER_ERROR, LIGHTDM_GREETER_ERROR_SESSION_FAILED, "Session returned error code %d", request->return_code);
-        return FALSE;
-    }
+    g_propagate_error (error, request->error);
+    return request->result;
 }
 
 /**
@@ -1496,17 +1630,17 @@ lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *sessio
     g_return_val_if_fail (priv->is_authenticated, FALSE);
 
     /* Read until the session is started */
-    send_start_session (greeter, session);
-    request = request_new (NULL, NULL, NULL);
+    if (!send_start_session (greeter, session, error))
+        return FALSE;
+    request = request_new (greeter, NULL, NULL, NULL);
     priv->start_session_requests = g_list_append (priv->start_session_requests, g_object_ref (request));
     do
     {
         guint8 *message;
         gsize message_length;
 
-        message = recv_message (greeter, &message_length, TRUE);
-        if (!message)
-            break;
+        if (!recv_message (greeter, TRUE, &message, &message_length, error))
+            return FALSE;
         handle_message (greeter, message, message_length);
         g_free (message);
     } while (!request->complete);
@@ -1538,36 +1672,47 @@ lightdm_greeter_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *us
 {
     LightDMGreeterPrivate *priv;
     Request *request;
+    GError *error = NULL;
 
     g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
 
     priv = GET_PRIVATE (greeter);
 
-    send_ensure_shared_data_dir (greeter, username);
-    request = request_new (cancellable, callback, user_data);
+    request = request_new (greeter, cancellable, callback, user_data);
     priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, request);
+    if (!send_ensure_shared_data_dir (greeter, username, &error))
+    {
+        request->error = error;
+        request_complete (request);
+    }
 }
 
 /**
  * lightdm_greeter_ensure_shared_data_dir_finish:
  * @result: A #GAsyncResult.
  * @greeter: A #LightDMGreeter
+ * @error: return location for a #GError, or %NULL
  *
  * Function to call from lightdm_greeter_ensure_shared_data_dir callback.
  *
  * Return value: The path to the shared directory, free with g_free.
  **/
 gchar *
-lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncResult *result)
+lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error)
 {
+    Request *request = REQUEST (result);
+
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
-    return g_strdup (REQUEST (result)->dir);
+
+    g_propagate_error (error, request->error);
+    return g_strdup (request->dir);
 }
 
 /**
  * lightdm_greeter_ensure_shared_data_dir_sync:
  * @greeter: A #LightDMGreeter
  * @username: A username
+ * @error: return location for a #GError, or %NULL
  *
  * Ensure that a shared data dir for the given user is available.  Both the
  * greeter user and @username will have write access to that folder.  The
@@ -1583,11 +1728,10 @@ lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncRe
  * Return value: The path to the shared directory, free with g_free.
  **/
 gchar *
-lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username)
+lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username, GError **error)
 {
     LightDMGreeterPrivate *priv;
     Request *request;
-    gchar *data_dir;
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
 
@@ -1596,80 +1740,47 @@ lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gcha
     g_return_val_if_fail (priv->connected, NULL);
 
     /* Read until a response */
-    send_ensure_shared_data_dir (greeter, username);
-    request = request_new (NULL, NULL, NULL);
+    if (!send_ensure_shared_data_dir (greeter, username, error))
+        return NULL;
+    request = request_new (greeter, NULL, NULL, NULL);
     priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, g_object_ref (request));
     do
     {
         guint8 *message;
         gsize message_length;
 
-        message = recv_message (greeter, &message_length, TRUE);
-        if (!message)
-            break;
+        if (!recv_message (greeter, TRUE, &message, &message_length, error))
+            return FALSE;
         handle_message (greeter, message, message_length);
         g_free (message);
     } while (!request->complete);
 
-    data_dir = g_strdup (request->dir);
-    g_object_unref (request);
-
-    return data_dir;
+    return lightdm_greeter_ensure_shared_data_dir_finish (greeter, G_ASYNC_RESULT (request), error);
 }
 
 static void
 lightdm_greeter_init (LightDMGreeter *greeter)
 {
     LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
-    const gchar *fd;
 
     priv->read_buffer = g_malloc (HEADER_SIZE);
     priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
-    fd = g_getenv ("LIGHTDM_TO_SERVER_FD");
-    if (fd)
-    {
-        GError *error = NULL;
-
-        priv->to_server_channel = g_io_channel_unix_new (atoi (fd));
-        g_io_channel_set_encoding (priv->to_server_channel, NULL, &error);
-        if (error)
-            g_warning ("Failed to set encoding on to server channel to binary: %s\n", error->message);
-        g_clear_error (&error);
-    }
-    else
-        g_warning ("No LIGHTDM_TO_SERVER_FD environment variable");
-
-    fd = g_getenv ("LIGHTDM_FROM_SERVER_FD");
-    if (fd)
-    {
-        GError *error = NULL;
-
-        priv->from_server_channel = g_io_channel_unix_new (atoi (fd));
-        g_io_channel_set_encoding (priv->from_server_channel, NULL, &error);
-        if (error)
-            g_warning ("Failed to set encoding on from server channel to binary: %s\n", error->message);
-        g_clear_error (&error);
-        g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
-    }
-    else
-        g_warning ("No LIGHTDM_FROM_SERVER_FD environment variable");
 }
 
 static void
 lightdm_greeter_set_property (GObject      *object,
-                          guint         prop_id,
-                          const GValue *value,
-                          GParamSpec   *pspec)
+                              guint         prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
 {
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 }
 
 static void
 lightdm_greeter_get_property (GObject    *object,
-                          guint       prop_id,
-                          GValue     *value,
-                          GParamSpec *pspec)
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
 {
     LightDMGreeter *self;
 
@@ -1985,8 +2096,9 @@ request_finalize (GObject *object)
 {
     Request *request = REQUEST (object);
 
-    g_free (request->dir);
+    g_clear_object (&request->greeter);
     g_clear_object (&request->cancellable);
+    g_free (request->dir);
 
     G_OBJECT_CLASS (request_parent_class)->finalize (object);
 }
@@ -2005,9 +2117,9 @@ request_get_user_data (GAsyncResult *result)
 }
 
 static GObject *
-request_get_source_object (GAsyncResult *res)
+request_get_source_object (GAsyncResult *result)
 {
-    return NULL;
+    return g_object_ref (REQUEST (result)->greeter);
 }
 
 static void
index aac67e969ec172d477848dadaf84a61c9a923057..922068b5dd22cdc814bb56e9437c703303f75383 100644 (file)
@@ -91,13 +91,19 @@ static inline void glib_autoptr_cleanup_LightDMGreeter (LightDMGreeter **_ptr)
 
 /**
  * LightDMGreeterError:
+ * @LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR: Error communicating with daemon
  * @LIGHTDM_GREETER_ERROR_CONNECTION_FAILED: Failed to connect to the daemon
  * @LIGHTDM_GREETER_ERROR_SESSION_FAILED: Requested session failed to start
+ * @LIGHTDM_GREETER_ERROR_NO_AUTOLOGIN: Autologin not configured
+ * @LIGHTDM_GREETER_ERROR_INVALID_USER: Autologin not configured
  */
 typedef enum
 {
+  LIGHTDM_GREETER_ERROR_COMMUNICATION_ERROR,
   LIGHTDM_GREETER_ERROR_CONNECTION_FAILED,
-  LIGHTDM_GREETER_ERROR_SESSION_FAILED
+  LIGHTDM_GREETER_ERROR_SESSION_FAILED,
+  LIGHTDM_GREETER_ERROR_NO_AUTOLOGIN,
+  LIGHTDM_GREETER_ERROR_INVALID_USER
 } LightDMGreeterError;
 
 GQuark lightdm_greeter_error_quark (void);
@@ -142,17 +148,17 @@ gint lightdm_greeter_get_autologin_timeout_hint (LightDMGreeter *greeter);
 
 void lightdm_greeter_cancel_autologin (LightDMGreeter *greeter);
 
-void lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username);
+gboolean lightdm_greeter_authenticate (LightDMGreeter *greeter, const gchar *username, GError **error);
 
-void lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter);
+gboolean lightdm_greeter_authenticate_as_guest (LightDMGreeter *greeter, GError **error);
 
-void lightdm_greeter_authenticate_autologin (LightDMGreeter *greeter);
+gboolean lightdm_greeter_authenticate_autologin (LightDMGreeter *greeter, GError **error);
 
-void lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username);
+gboolean lightdm_greeter_authenticate_remote (LightDMGreeter *greeter, const gchar *session, const gchar *username, GError **error);
 
-void lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response);
+gboolean lightdm_greeter_respond (LightDMGreeter *greeter, const gchar *response, GError **error);
 
-void lightdm_greeter_cancel_authentication (LightDMGreeter *greeter);
+gboolean lightdm_greeter_cancel_authentication (LightDMGreeter *greeter, GError **error);
 
 gboolean lightdm_greeter_get_in_authentication (LightDMGreeter *greeter);
 
@@ -160,7 +166,7 @@ gboolean lightdm_greeter_get_is_authenticated (LightDMGreeter *greeter);
 
 const gchar *lightdm_greeter_get_authentication_user (LightDMGreeter *greeter);
 
-void lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language);
+gboolean lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language, GError **error);
 
 void lightdm_greeter_start_session (LightDMGreeter *greeter, const gchar *session, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
 
@@ -170,9 +176,9 @@ gboolean lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gcha
 
 void lightdm_greeter_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
 
-gchar *lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncResult *result);
+gchar *lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error);
 
-gchar *lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username);
+gchar *lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username, GError **error);
 
 #ifndef LIGHTDM_DISABLE_DEPRECATED
 gboolean lightdm_greeter_connect_sync (LightDMGreeter *greeter, GError **error);
index da1d779aa06e9463d8ce13a61af6c1668786e95c..d535a02222153752947a740243ac454a6a04dde9 100644 (file)
@@ -133,37 +133,37 @@ bool Greeter::connectSync()
 void Greeter::authenticate(const QString &username)
 {
     Q_D(Greeter);
-    lightdm_greeter_authenticate(d->ldmGreeter, username.toLocal8Bit().data());
+    lightdm_greeter_authenticate(d->ldmGreeter, username.toLocal8Bit().data(), NULL);
 }
 
 void Greeter::authenticateAsGuest()
 {
     Q_D(Greeter);
-    lightdm_greeter_authenticate_as_guest(d->ldmGreeter);
+    lightdm_greeter_authenticate_as_guest(d->ldmGreeter, NULL);
 }
 
 void Greeter::authenticateAutologin()
 {
     Q_D(Greeter);
-    lightdm_greeter_authenticate_autologin(d->ldmGreeter);
+    lightdm_greeter_authenticate_autologin(d->ldmGreeter, NULL);
 }
 
 void Greeter::authenticateRemote(const QString &session, const QString &username)
 {
     Q_D(Greeter);
-    lightdm_greeter_authenticate_remote(d->ldmGreeter, session.toLocal8Bit().data(), username.toLocal8Bit().data());
+    lightdm_greeter_authenticate_remote(d->ldmGreeter, session.toLocal8Bit().data(), username.toLocal8Bit().data(), NULL);
 }
 
 void Greeter::respond(const QString &response)
 {
     Q_D(Greeter);
-    lightdm_greeter_respond(d->ldmGreeter, response.toLocal8Bit().data());
+    lightdm_greeter_respond(d->ldmGreeter, response.toLocal8Bit().data(), NULL);
 }
 
 void Greeter::cancelAuthentication()
 {
     Q_D(Greeter);
-    lightdm_greeter_cancel_authentication(d->ldmGreeter);
+    lightdm_greeter_cancel_authentication(d->ldmGreeter, NULL);
 }
 
 void Greeter::cancelAutologin()
@@ -193,7 +193,7 @@ QString Greeter::authenticationUser() const
 void Greeter::setLanguage (const QString &language)
 {
     Q_D(Greeter);
-    lightdm_greeter_set_language(d->ldmGreeter, language.toLocal8Bit().constData());
+    lightdm_greeter_set_language(d->ldmGreeter, language.toLocal8Bit().constData(), NULL);
 }
 
 void Greeter::setResettable (bool resettable)
@@ -211,7 +211,7 @@ bool Greeter::startSessionSync(const QString &session)
 QString Greeter::ensureSharedDataDirSync(const QString &username)
 {
     Q_D(Greeter);
-    return QString::fromUtf8(lightdm_greeter_ensure_shared_data_dir_sync(d->ldmGreeter, username.toLocal8Bit().constData()));
+    return QString::fromUtf8(lightdm_greeter_ensure_shared_data_dir_sync(d->ldmGreeter, username.toLocal8Bit().constData(), NULL));
 }
 
 
index 0bab7fe1d92110f176aeb7b87555df632c4e72a3..92f594aa91cd8f572a84db3ce29d31f1846950bf 100644 (file)
@@ -29,7 +29,7 @@
 
 # Attempt to start the session, it will fail
 #?*GREETER-X-0 START-SESSION SESSION=invalid
-#?GREETER-X-0 SESSION-FAILED
+#?GREETER-X-0 SESSION-FAILED ERROR=.*
 
 # Cleanup
 #?*STOP-DAEMON
index 09fc277f9010ca386c3a9c01d5ec150dd87a6b8c..139a14f8b19d3bf8c7b9bd93a4f524af823d9cac 100644 (file)
@@ -23,7 +23,7 @@
 
 # Try and write data to an invalid user
 #?*GREETER-X-0 WRITE-SHARED-DATA USERNAME=invalid DATA=HELLO
-#?GREETER-X-0 WRITE-SHARED-DATA ERROR=NO_SHARED_DIR
+#?GREETER-X-0 WRITE-SHARED-DATA ERROR=.*
 
 # Cleanup
 #?*STOP-DAEMON
index 92c9acaa8709c7e618aa8af73f2ae304aa5f29e4..6479f4c058058b592b5f6aa20eaa3bd34a6c295e 100644 (file)
@@ -135,11 +135,13 @@ write_shared_data_finished (GObject *object, GAsyncResult *result, gpointer data
     LightDMGreeter *greeter = LIGHTDM_GREETER (object);
     gchar *dir, *path, *test_data;
     FILE *f;
+    GError *error = NULL;
 
-    dir = lightdm_greeter_ensure_shared_data_dir_finish (greeter, result);
+    dir = lightdm_greeter_ensure_shared_data_dir_finish (greeter, result, &error);
     if (!dir)
     {
-        status_notify ("%s WRITE-SHARED-DATA ERROR=NO_SHARED_DIR", greeter_id);
+        status_notify ("%s WRITE-SHARED-DATA ERROR=%s", greeter_id, error->message);
+        g_clear_error (&error);
         return;
     }
 
@@ -165,10 +167,11 @@ read_shared_data_finished (GObject *object, GAsyncResult *result, gpointer data)
     gchar *contents = NULL;
     GError *error = NULL;
 
-    dir = lightdm_greeter_ensure_shared_data_dir_finish (greeter, result);
+    dir = lightdm_greeter_ensure_shared_data_dir_finish (greeter, result, &error);
     if (!dir)
     {
-        status_notify ("%s READ-SHARED-DATA ERROR=NO_SHARED_DIR", greeter_id);
+        status_notify ("%s READ-SHARED-DATA ERROR=%s", greeter_id, error->message);
+        g_clear_error (&error);
         return;
     }
 
@@ -185,6 +188,8 @@ read_shared_data_finished (GObject *object, GAsyncResult *result, gpointer data)
 static void
 request_cb (const gchar *name, GHashTable *params)
 {
+    GError *error = NULL;
+
     if (!name)
     {
         g_main_loop_quit (loop);
@@ -195,22 +200,58 @@ request_cb (const gchar *name, GHashTable *params)
         kill (getpid (), SIGSEGV);
 
     else if (strcmp (name, "AUTHENTICATE") == 0)
-        lightdm_greeter_authenticate (greeter, g_hash_table_lookup (params, "USERNAME"));
+    {
+        if (!lightdm_greeter_authenticate (greeter, g_hash_table_lookup (params, "USERNAME"), &error))
+        {
+            status_notify ("%s FAIL-AUTHENTICATE ERROR=%s", greeter_id, error->message);
+            g_clear_error (&error);
+        }
+    }
 
     else if (strcmp (name, "AUTHENTICATE-GUEST") == 0)
-        lightdm_greeter_authenticate_as_guest (greeter);
+    {
+        if (!lightdm_greeter_authenticate_as_guest (greeter, &error))
+        {
+            status_notify ("%s FAIL-AUTHENTICATE-GUEST ERROR=%s", greeter_id, error->message);
+            g_clear_error (&error);
+        }
+    }
 
     else if (strcmp (name, "AUTHENTICATE-AUTOLOGIN") == 0)
-        lightdm_greeter_authenticate_autologin (greeter);
+    {
+        if (!lightdm_greeter_authenticate_autologin (greeter, &error))
+        {
+            status_notify ("%s FAIL-AUTHENTICATE-AUTOLOGIN ERROR=%s", greeter_id, error->message);
+            g_clear_error (&error);
+        }
+    }
 
     else if (strcmp (name, "AUTHENTICATE-REMOTE") == 0)
-        lightdm_greeter_authenticate_remote (greeter, g_hash_table_lookup (params, "SESSION"), NULL);
+    {
+        if (!lightdm_greeter_authenticate_remote (greeter, g_hash_table_lookup (params, "SESSION"), NULL, &error))
+        {
+            status_notify ("%s FAIL-AUTHENTICATE-REMOTE ERROR=%s", greeter_id, error->message);
+            g_clear_error (&error);
+        }
+    }
 
     else if (strcmp (name, "RESPOND") == 0)
-        lightdm_greeter_respond (greeter, g_hash_table_lookup (params, "TEXT"));
+    {
+        if (!lightdm_greeter_respond (greeter, g_hash_table_lookup (params, "TEXT"), &error))
+        {
+            status_notify ("%s FAIL-RESPOND ERROR=%s", greeter_id, error->message);
+            g_clear_error (&error);
+        }
+    }
 
     else if (strcmp (name, "CANCEL-AUTHENTICATION") == 0)
-        lightdm_greeter_cancel_authentication (greeter);
+    {
+        if (!lightdm_greeter_cancel_authentication (greeter, &error))
+        {
+            status_notify ("%s FAIL-CANCEL-AUTHENTICATION ERROR=%s", greeter_id, error->message);
+            g_clear_error (&error);
+        }
+    }
 
     else if (strcmp (name, "START-SESSION") == 0)
         lightdm_greeter_start_session (greeter, g_hash_table_lookup (params, "SESSION"), NULL, start_session_finished, NULL);
index e2b1180dea57d56df17adbd01d9c42d72179a336..6c8fa79b40a775a5bada780c4b0aeb2e0827f357 100755 (executable)
@@ -78,15 +78,15 @@ def request_cb (channel, condition):
     if request == r:
         try:
             greeter.start_session_sync (None)
-        except:
-            status_notify ('%s SESSION-FAILED' % greeter_id)
+        except GLib.Error as e:
+            status_notify ('%s SESSION-FAILED ERROR=%s' % (greeter_id, e.message))
 
     r = '%s START-SESSION SESSION=' % greeter_id
     if request.startswith (r):
         try:
             greeter.start_session_sync (request[len(r):])
-        except:
-            status_notify ('%s SESSION-FAILED' % greeter_id)
+        except GLib.Error as e:
+            status_notify ('%s SESSION-FAILED ERROR=%s' % (greeter_id, e.message))
 
     r = '%s LOG-USER-LIST-LENGTH' % greeter_id
     if request == r:
index 6c6e4cab6aedb5dd139adbc14bd6b0941aaaf7ca..5df66b495158ce3370f99c65ecff5e63cd81dd7e 100644 (file)
@@ -161,12 +161,12 @@ request_cb (const gchar *name, GHashTable *params)
         if (g_hash_table_lookup (params, "SESSION"))
         {
             if (!greeter->startSessionSync ((const gchar *) g_hash_table_lookup (params, "SESSION")))
-                status_notify ("%s SESSION-FAILED", greeter_id);
+                status_notify ("%s SESSION-FAILED ERROR=%s", greeter_id, "FIXME: Exceptions in Qt");
         }
         else
         {
             if (!greeter->startSessionSync ())
-                status_notify ("%s SESSION-FAILED", greeter_id);
+                status_notify ("%s SESSION-FAILED ERROR=%s", greeter_id, "FIXME: Exceptions in Qt");
         }
     }