Blame SOURCES/kerberos-separate-process.patch

4bc980
From 2c351af58d1ba5581a95ed02d38fdc8dd904ad7b Mon Sep 17 00:00:00 2001
1e691d
From: Ray Strode <rstrode@redhat.com>
1e691d
Date: Tue, 28 Oct 2014 17:16:18 -0400
1e691d
Subject: [PATCH 1/2] kerberos: maintain one long-lasting object manager client
1e691d
 to kerberos service
1e691d
1e691d
At the moment, the kerberos backend creates one object manager to the
1e691d
kerberos identity service per provider object.  Provider objects are actually
1e691d
fairly transient and get created and destroyed, in some cases, per operation
1e691d
on an account. The upshot is, object manager clients end up getting created
1e691d
more frequently than they really should be. To make matters worse, the kerberos
1e691d
provider has no finalize function, so these object manager clients are getting
1e691d
leaked.
1e691d
1e691d
This commit makes the object manager client get created once at start up,
1e691d
and get reused by all providers.  Since there's only one object manager,
1e691d
rooted in the main thread, using the main thread's main loop context
1e691d
now, the per-thread synchronous codepaths can't call object manager async
1e691d
functions using a local main loop context. They do this, at the moment, because
1e691d
there are async, main thread code paths that also need to talk to the
1e691d
kerberos service. The local main loop context provides a way to call the
1e691d
async code synchronously, and prevent duplication of logic.
1e691d
1e691d
This commit gets rid of all the local main loop contexts, and instead uses
1e691d
sync functions.  To prevent duplication of logic, the async code now
1e691d
leverages the sync code, in a thread.
1e691d
---
1e691d
 src/goabackend/goakerberosprovider.c | 963 +++++++++++++----------------------
1e691d
 1 file changed, 345 insertions(+), 618 deletions(-)
1e691d
1e691d
diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c
4bc980
index f9c54cd4f79c..2eb6b677ab22 100644
1e691d
--- a/src/goabackend/goakerberosprovider.c
1e691d
+++ b/src/goabackend/goakerberosprovider.c
1e691d
@@ -41,8 +41,6 @@ struct _GoaKerberosProvider
1e691d
 {
1e691d
   /*< private >*/
1e691d
   GoaProvider parent_instance;
1e691d
-  GoaIdentityServiceManager *identity_manager;
1e691d
-  GDBusObjectManager *object_manager;
1e691d
 };
1e691d
 
1e691d
 typedef struct _GoaKerberosProviderClass GoaKerberosProviderClass;
1e691d
@@ -52,6 +50,35 @@ struct _GoaKerberosProviderClass
1e691d
   GoaProviderClass parent_class;
1e691d
 };
1e691d
 
1e691d
+static GoaIdentityServiceManager *identity_manager;
1e691d
+static GMutex identity_manager_mutex;
1e691d
+static GCond identity_manager_condition;
1e691d
+
1e691d
+static GDBusObjectManager *object_manager;
1e691d
+static GMutex object_manager_mutex;
1e691d
+static GCond object_manager_condition;
1e691d
+
1e691d
+static void ensure_identity_manager (void);
1e691d
+static void ensure_object_manager (void);
1e691d
+
1e691d
+static char *sign_in_identity_sync (GoaKerberosProvider  *self,
1e691d
+                                    const char           *identifier,
1e691d
+                                    const char           *password,
1e691d
+                                    const char           *preauth_source,
1e691d
+                                    GCancellable         *cancellable,
1e691d
+                                    GError              **error);
1e691d
+static void sign_in_thread (GSimpleAsyncResult  *result,
1e691d
+                            GoaKerberosProvider *self,
1e691d
+                            GCancellable        *cancellable);
1e691d
+static GoaIdentityServiceIdentity *get_identity_from_object_manager (GoaKerberosProvider *self,
1e691d
+                                                                     const char          *identifier);
1e691d
+static gboolean dbus_proxy_reload_properties_sync (GDBusProxy    *proxy,
1e691d
+                                                   GCancellable  *cancellable);
1e691d
+
1e691d
+static void goa_kerberos_provider_module_init (void);
1e691d
+static void create_object_manager (void);
1e691d
+static void create_identity_manager (void);
1e691d
+
1e691d
 /**
1e691d
  * SECTION:goakerberosprovider
1e691d
  * @title: GoaKerberosProvider
1e691d
@@ -61,12 +88,20 @@ struct _GoaKerberosProviderClass
1e691d
  */
1e691d
 
1e691d
 G_DEFINE_TYPE_WITH_CODE (GoaKerberosProvider, goa_kerberos_provider, GOA_TYPE_PROVIDER,
1e691d
+                         goa_kerberos_provider_module_init ();
1e691d
                          goa_provider_ensure_extension_points_registered ();
1e691d
                          g_io_extension_point_implement (GOA_PROVIDER_EXTENSION_POINT_NAME,
1e691d
                                                          g_define_type_id,
1e691d
                                                          GOA_KERBEROS_NAME,
1e691d
                                                          0));
1e691d
 
1e691d
+static void
1e691d
+goa_kerberos_provider_module_init (void)
1e691d
+{
1e691d
+  create_object_manager ();
1e691d
+  create_identity_manager ();
1e691d
+}
1e691d
+
1e691d
 static const gchar *
1e691d
 get_provider_type (GoaProvider *provider)
1e691d
 {
1e691d
@@ -189,359 +224,6 @@ clear_entry_validation_error (GtkEntry *entry)
1e691d
 }
1e691d
 
1e691d
 static void
1e691d
-on_identity_signed_in (GoaIdentityServiceManager *manager,
1e691d
-                       GAsyncResult              *result,
1e691d
-                       GSimpleAsyncResult        *operation_result)
1e691d
-{
1e691d
-  gboolean  signed_in;
1e691d
-  GError   *error;
1e691d
-  char     *identity_object_path;
1e691d
-
1e691d
-  error = NULL;
1e691d
-  signed_in = goa_identity_service_manager_call_sign_in_finish (manager,
1e691d
-                                                                &identity_object_path,
1e691d
-                                                                result,
1e691d
-                                                                &error);
1e691d
-
1e691d
-  if (!signed_in)
1e691d
-    {
1e691d
-      translate_error (&error);
1e691d
-
1e691d
-      if (g_error_matches (error,
1e691d
-                           G_IO_ERROR,
1e691d
-                           G_IO_ERROR_CANCELLED))
1e691d
-        {
1e691d
-          g_clear_error (&error);
1e691d
-          g_set_error_literal (&error,
1e691d
-                               GOA_ERROR,
1e691d
-                               GOA_ERROR_DIALOG_DISMISSED,
1e691d
-                               "");
1e691d
-        }
1e691d
-
1e691d
-      g_simple_async_result_take_error (operation_result, error);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  g_simple_async_result_set_op_res_gpointer (operation_result,
1e691d
-                                             g_strdup (identity_object_path),
1e691d
-                                             (GDestroyNotify)
1e691d
-                                             g_free);
1e691d
-  g_simple_async_result_complete_in_idle (operation_result);
1e691d
-  g_object_unref (operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-on_identity_manager_ensured (GoaKerberosProvider *self,
1e691d
-                             GAsyncResult        *result,
1e691d
-                             GSimpleAsyncResult  *operation_result)
1e691d
-{
1e691d
-  GoaIdentityServiceManager *manager;
1e691d
-  GError             *error;
1e691d
-
1e691d
-  error = NULL;
1e691d
-  manager = goa_identity_service_manager_proxy_new_for_bus_finish (result, &error);
1e691d
-  if (manager == NULL)
1e691d
-    {
1e691d
-      translate_error (&error);
1e691d
-      g_simple_async_result_take_error (operation_result, error);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  g_simple_async_result_set_op_res_gpointer (operation_result,
1e691d
-                                             g_object_ref (manager),
1e691d
-                                             (GDestroyNotify)
1e691d
-                                             g_object_unref);
1e691d
-  g_simple_async_result_complete_in_idle (operation_result);
1e691d
-  g_object_unref (operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-ensure_identity_manager (GoaKerberosProvider *self,
1e691d
-                         GCancellable        *cancellable,
1e691d
-                         GAsyncReadyCallback  callback,
1e691d
-                         gpointer             user_data)
1e691d
-{
1e691d
-  GSimpleAsyncResult *operation_result;
1e691d
-
1e691d
-  operation_result = g_simple_async_result_new (G_OBJECT (self),
1e691d
-                                                callback,
1e691d
-                                                user_data,
1e691d
-                                                ensure_identity_manager);
1e691d
-  g_simple_async_result_set_check_cancellable (operation_result, cancellable);
1e691d
-
1e691d
-  g_object_set_data (G_OBJECT (operation_result),
1e691d
-                     "cancellable",
1e691d
-                     cancellable);
1e691d
-
1e691d
-  if (self->identity_manager != NULL)
1e691d
-    {
1e691d
-      g_simple_async_result_set_op_res_gpointer (operation_result,
1e691d
-                                                 g_object_ref (self->identity_manager),
1e691d
-                                                 (GDestroyNotify)
1e691d
-                                                 g_object_unref);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  goa_identity_service_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION,
1e691d
-                                                  G_DBUS_PROXY_FLAGS_NONE,
1e691d
-                                                  "org.gnome.Identity",
1e691d
-                                                  "/org/gnome/Identity/Manager",
1e691d
-                                                  cancellable,
1e691d
-                                                  (GAsyncReadyCallback)
1e691d
-                                                  on_identity_manager_ensured,
1e691d
-                                                  operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-on_object_manager_ensured (GoaKerberosProvider *self,
1e691d
-                           GAsyncResult        *result,
1e691d
-                           GSimpleAsyncResult  *operation_result)
1e691d
-{
1e691d
-  GDBusObjectManager *manager;
1e691d
-  GError *error;
1e691d
-
1e691d
-  error = NULL;
1e691d
-  manager = goa_identity_service_object_manager_client_new_for_bus_finish (result, &error);
1e691d
-  if (manager == NULL)
1e691d
-    {
1e691d
-      translate_error (&error);
1e691d
-      g_simple_async_result_take_error (operation_result, error);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  g_simple_async_result_set_op_res_gpointer (operation_result,
1e691d
-                                             g_object_ref (manager),
1e691d
-                                             (GDestroyNotify)
1e691d
-                                             g_object_unref);
1e691d
-  g_simple_async_result_complete_in_idle (operation_result);
1e691d
-  g_object_unref (operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-ensure_object_manager (GoaKerberosProvider *self,
1e691d
-                       GCancellable        *cancellable,
1e691d
-                       GAsyncReadyCallback  callback,
1e691d
-                       gpointer             user_data)
1e691d
-{
1e691d
-  GSimpleAsyncResult *operation_result;
1e691d
-
1e691d
-  operation_result = g_simple_async_result_new (G_OBJECT (self),
1e691d
-                                                callback,
1e691d
-                                                user_data,
1e691d
-                                                ensure_object_manager);
1e691d
-  g_simple_async_result_set_check_cancellable (operation_result, cancellable);
1e691d
-
1e691d
-  g_object_set_data (G_OBJECT (operation_result),
1e691d
-                     "cancellable",
1e691d
-                     cancellable);
1e691d
-
1e691d
-  if (self->object_manager != NULL)
1e691d
-    {
1e691d
-      g_simple_async_result_set_op_res_gpointer (operation_result,
1e691d
-                                                 g_object_ref (self->object_manager),
1e691d
-                                                 (GDestroyNotify)
1e691d
-                                                 g_object_unref);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-  goa_identity_service_object_manager_client_new_for_bus (G_BUS_TYPE_SESSION,
1e691d
-                                                          G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
1e691d
-                                                          "org.gnome.Identity",
1e691d
-                                                          "/org/gnome/Identity",
1e691d
-                                                          cancellable,
1e691d
-                                                          (GAsyncReadyCallback)
1e691d
-                                                          on_object_manager_ensured,
1e691d
-                                                          operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-on_secret_keys_exchanged_for_sign_in (GoaKerberosProvider *self,
1e691d
-                                      GAsyncResult        *result,
1e691d
-                                      GSimpleAsyncResult  *operation_result)
1e691d
-{
1e691d
-  const char       *identifier;
1e691d
-  const char       *password;
1e691d
-  const char       *preauth_source;
1e691d
-  GCancellable     *cancellable;
1e691d
-  GError           *error;
1e691d
-  GVariantBuilder   details;
1e691d
-
1e691d
-  error = NULL;
1e691d
-
1e691d
-  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
1e691d
-                                             &error))
1e691d
-    {
1e691d
-      g_simple_async_result_take_error (operation_result, error);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
1e691d
-  password = g_object_get_data (G_OBJECT (operation_result), "password");
1e691d
-  preauth_source = g_object_get_data (G_OBJECT (operation_result), "preauthentication-source");
1e691d
-  identifier = g_simple_async_result_get_source_tag (operation_result);
1e691d
-
1e691d
-  g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
1e691d
-
1e691d
-  if (password != NULL)
1e691d
-    {
1e691d
-      GcrSecretExchange *secret_exchange;
1e691d
-      char *secret;
1e691d
-
1e691d
-      secret_exchange = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
1e691d
-
1e691d
-      secret = gcr_secret_exchange_send (secret_exchange, password, -1);
1e691d
-      g_variant_builder_add (&details, "{ss}", "initial-password", secret);
1e691d
-      g_free (secret);
1e691d
-    }
1e691d
-
1e691d
-  if (preauth_source != NULL)
1e691d
-    {
1e691d
-      g_variant_builder_add (&details, "{ss}", "preauthentication-source", preauth_source);
1e691d
-    }
1e691d
-
1e691d
-  goa_identity_service_manager_call_sign_in (self->identity_manager,
1e691d
-                                             identifier,
1e691d
-                                             g_variant_builder_end (&details),
1e691d
-                                             cancellable,
1e691d
-                                             (GAsyncReadyCallback)
1e691d
-                                             on_identity_signed_in,
1e691d
-                                             operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-on_secret_keys_exchanged (GoaIdentityServiceManager *manager,
1e691d
-                          GAsyncResult              *result,
1e691d
-                          GSimpleAsyncResult        *operation_result)
1e691d
-{
1e691d
-  GcrSecretExchange *secret_exchange;
1e691d
-  char              *return_key;
1e691d
-  GError            *error;
1e691d
-
1e691d
-  secret_exchange = g_simple_async_result_get_source_tag (operation_result);
1e691d
-
1e691d
-  error = NULL;
1e691d
-  if (!goa_identity_service_manager_call_exchange_secret_keys_finish (manager,
1e691d
-                                                                      &return_key,
1e691d
-                                                                      result,
1e691d
-                                                                      &error))
1e691d
-    {
1e691d
-      g_object_unref (secret_exchange);
1e691d
-
1e691d
-      g_simple_async_result_take_error (operation_result, error);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  if (!gcr_secret_exchange_receive (secret_exchange, return_key))
1e691d
-    {
1e691d
-      g_object_unref (secret_exchange);
1e691d
-
1e691d
-      g_simple_async_result_set_error (operation_result,
1e691d
-                                       GCR_ERROR,
1e691d
-                                       GCR_ERROR_UNRECOGNIZED,
1e691d
-                                       _("Identity service returned invalid key"));
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  g_simple_async_result_set_op_res_gpointer (operation_result,
1e691d
-                                             secret_exchange,
1e691d
-                                             (GDestroyNotify)
1e691d
-                                             g_object_unref);
1e691d
-  g_simple_async_result_complete_in_idle (operation_result);
1e691d
-  g_object_unref (operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-exchange_secret_keys (GoaKerberosProvider  *self,
1e691d
-                      const char           *password,
1e691d
-                      GCancellable         *cancellable,
1e691d
-                      GAsyncReadyCallback   callback,
1e691d
-                      gpointer              user_data)
1e691d
-{
1e691d
-
1e691d
-  GSimpleAsyncResult *operation_result;
1e691d
-  GcrSecretExchange  *secret_exchange;
1e691d
-  char               *secret_key;
1e691d
-
1e691d
-  secret_exchange = gcr_secret_exchange_new (NULL);
1e691d
-
1e691d
-  operation_result = g_simple_async_result_new (G_OBJECT (self),
1e691d
-                                                callback,
1e691d
-                                                user_data,
1e691d
-                                                secret_exchange);
1e691d
-
1e691d
-  if (password == NULL)
1e691d
-    {
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
1e691d
-                                                 NULL,
1e691d
-                                                 NULL);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  secret_key = gcr_secret_exchange_begin (secret_exchange);
1e691d
-
1e691d
-  goa_identity_service_manager_call_exchange_secret_keys (self->identity_manager,
1e691d
-                                                          secret_key,
1e691d
-                                                          cancellable,
1e691d
-                                                          (GAsyncReadyCallback)
1e691d
-                                                          on_secret_keys_exchanged,
1e691d
-                                                          operation_result);
1e691d
-  g_free (secret_key);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-on_identity_manager_ensured_for_sign_in (GoaKerberosProvider *self,
1e691d
-                                         GAsyncResult        *result,
1e691d
-                                         GSimpleAsyncResult  *operation_result)
1e691d
-{
1e691d
-  GoaIdentityServiceManager *manager;
1e691d
-  const char                *password;
1e691d
-  GCancellable              *cancellable;
1e691d
-  GError                    *error;
1e691d
-
1e691d
-  error = NULL;
1e691d
-
1e691d
-  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
1e691d
-                                             &error))
1e691d
-    {
1e691d
-      g_simple_async_result_take_error (operation_result, error);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  manager = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
1e691d
-
1e691d
-  if (self->identity_manager == NULL)
1e691d
-    self->identity_manager = g_object_ref (manager);
1e691d
-
1e691d
-  cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
1e691d
-  password = g_object_get_data (G_OBJECT (operation_result), "password");
1e691d
-
1e691d
-  exchange_secret_keys (self,
1e691d
-                        password,
1e691d
-                        cancellable,
1e691d
-                        (GAsyncReadyCallback)
1e691d
-                        on_secret_keys_exchanged_for_sign_in,
1e691d
-                        operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
 sign_in_identity (GoaKerberosProvider  *self,
1e691d
                   const char           *identifier,
1e691d
                   const char           *password,
1e691d
@@ -567,116 +249,15 @@ sign_in_identity (GoaKerberosProvider  *self,
1e691d
                      "password",
1e691d
                      (gpointer)
1e691d
                      password);
1e691d
-
1e691d
   g_object_set_data_full (G_OBJECT (operation_result),
1e691d
                           "preauthentication-source",
1e691d
                           g_strdup (preauth_source),
1e691d
                           g_free);
1e691d
-
1e691d
-  ensure_identity_manager (self,
1e691d
-                           cancellable,
1e691d
-                           (GAsyncReadyCallback)
1e691d
-                           on_identity_manager_ensured_for_sign_in,
1e691d
-                           operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-on_object_manager_ensured_for_look_up (GoaKerberosProvider *self,
1e691d
-                                       GAsyncResult        *result,
1e691d
-                                       GSimpleAsyncResult  *operation_result)
1e691d
-{
1e691d
-  GDBusObjectManager *manager;
1e691d
-  const char         *identifier;
1e691d
-  GList              *objects, *node;
1e691d
-  GError             *error;
1e691d
-  gboolean            found;
1e691d
-
1e691d
-  error = NULL;
1e691d
-  found = FALSE;
1e691d
-
1e691d
-  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
1e691d
-                                             &error))
1e691d
-    {
1e691d
-
1e691d
-      g_simple_async_result_take_error (operation_result, error);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  manager = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
1e691d
-
1e691d
-  if (self->object_manager == NULL)
1e691d
-    self->object_manager = g_object_ref (manager);
1e691d
-
1e691d
-  identifier = g_simple_async_result_get_source_tag (operation_result);
1e691d
-
1e691d
-  g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
1e691d
-                                             NULL,
1e691d
-                                             NULL);
1e691d
-  objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self->object_manager));
1e691d
-
1e691d
-  for (node = objects; node != NULL; node = node->next)
1e691d
-    {
1e691d
-      GoaIdentityServiceIdentity *candidate_identity;
1e691d
-      const char                 *candidate_identifier;
1e691d
-      GDBusObject                *object;
1e691d
-
1e691d
-      object = node->data;
1e691d
-
1e691d
-      candidate_identity = GOA_IDENTITY_SERVICE_IDENTITY (g_dbus_object_get_interface (object, "org.gnome.Identity"));
1e691d
-
1e691d
-      if (candidate_identity == NULL)
1e691d
-        continue;
1e691d
-
1e691d
-      candidate_identifier = goa_identity_service_identity_get_identifier (candidate_identity);
1e691d
-
1e691d
-      if (g_strcmp0 (candidate_identifier, identifier) == 0)
1e691d
-        {
1e691d
-          g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
1e691d
-                                                     candidate_identity,
1e691d
-                                                     (GDestroyNotify)
1e691d
-                                                     g_object_unref);
1e691d
-          found = TRUE;
1e691d
-          break;
1e691d
-        }
1e691d
-
1e691d
-      g_object_unref (candidate_identity);
1e691d
-    }
1e691d
-
1e691d
-  if (!found)
1e691d
-    g_simple_async_result_set_error (operation_result, GOA_ERROR, GOA_ERROR_FAILED, "Failed to find an identity");
1e691d
-
1e691d
-  g_list_free_full (objects, (GDestroyNotify) g_object_unref);
1e691d
-  g_simple_async_result_complete_in_idle (G_SIMPLE_ASYNC_RESULT (operation_result));
1e691d
-  g_object_unref (operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-look_up_identity (GoaKerberosProvider  *self,
1e691d
-                  const char           *identifier,
1e691d
-                  GCancellable         *cancellable,
1e691d
-                  GAsyncReadyCallback   callback,
1e691d
-                  gpointer              user_data)
1e691d
-{
1e691d
-  GSimpleAsyncResult *operation_result;
1e691d
-
1e691d
-  operation_result = g_simple_async_result_new (G_OBJECT (self),
1e691d
-                                                callback,
1e691d
-                                                user_data,
1e691d
-                                                (gpointer)
1e691d
-                                                identifier);
1e691d
-
1e691d
-  g_simple_async_result_set_check_cancellable (operation_result, cancellable);
1e691d
-
1e691d
-  g_object_set_data (G_OBJECT (operation_result),
1e691d
-                     "cancellable",
1e691d
-                     cancellable);
1e691d
-  ensure_object_manager (self,
1e691d
-                         cancellable,
1e691d
-                         (GAsyncReadyCallback)
1e691d
-                         on_object_manager_ensured_for_look_up,
1e691d
-                         operation_result);
1e691d
+  g_simple_async_result_run_in_thread (operation_result,
1e691d
+                                       (GSimpleAsyncThreadFunc)
1e691d
+                                       sign_in_thread,
1e691d
+                                       G_PRIORITY_DEFAULT,
1e691d
+                                       cancellable);
1e691d
 }
1e691d
 
1e691d
 static void
1e691d
@@ -703,13 +284,14 @@ get_ticket_sync (GoaKerberosProvider *self,
1e691d
 {
1e691d
   GVariant            *credentials;
1e691d
   GError              *lookup_error;
1e691d
+  GError              *sign_in_error;
1e691d
   GoaAccount          *account;
1e691d
   GoaTicketing        *ticketing;
1e691d
   GVariant            *details;
1e691d
   const char          *identifier;
1e691d
   const char          *password;
1e691d
   const char          *preauth_source;
1e691d
-  SignInRequest        request;
1e691d
+  char                *object_path = NULL;
1e691d
   gboolean             ret;
1e691d
 
1e691d
   ret = FALSE;
1e691d
@@ -758,31 +340,24 @@ get_ticket_sync (GoaKerberosProvider *self,
1e691d
         }
1e691d
     }
1e691d
 
1e691d
-  memset (&request, 0, sizeof (SignInRequest));
1e691d
-  request.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
1e691d
-  request.error = NULL;
1e691d
-
1e691d
-  sign_in_identity (self,
1e691d
-                    identifier,
1e691d
-                    password,
1e691d
-                    preauth_source,
1e691d
-                    cancellable,
1e691d
-                    (GAsyncReadyCallback)
1e691d
-                    on_account_signed_in,
1e691d
-                    &request);
1e691d
-
1e691d
-  g_main_loop_run (request.loop);
1e691d
-  g_main_loop_unref (request.loop);
1e691d
+  sign_in_error = NULL;
1e691d
+  object_path = sign_in_identity_sync (self,
1e691d
+                                       identifier,
1e691d
+                                       password,
1e691d
+                                       preauth_source,
1e691d
+                                       cancellable,
1e691d
+                                       &sign_in_error);
1e691d
 
1e691d
-  if (request.error != NULL)
1e691d
+  if (sign_in_error != NULL)
1e691d
     {
1e691d
-      g_propagate_error (error, request.error);
1e691d
+      g_propagate_error (error, sign_in_error);
1e691d
       goto out;
1e691d
     }
1e691d
 
1e691d
   ret = TRUE;
1e691d
 out:
1e691d
   g_clear_object (&ticketing);
1e691d
+  g_free (object_path);
1e691d
 
1e691d
   if (credentials != NULL)
1e691d
     g_variant_unref (credentials);
1e691d
@@ -1764,106 +1339,39 @@ show_account (GoaProvider *provider,
1e691d
                                                    _("Network _Resources"));
1e691d
 }
1e691d
 
1e691d
-static void
1e691d
-on_identity_looked_up (GoaKerberosProvider *provider,
1e691d
-                       GAsyncResult        *result,
1e691d
-                       GSimpleAsyncResult  *operation_result)
1e691d
-{
1e691d
-
1e691d
-  GoaIdentityServiceIdentity *identity;
1e691d
-  GError                     *error;
1e691d
-
1e691d
-  error = NULL;
1e691d
-  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
1e691d
-    {
1e691d
-      g_simple_async_result_take_error (operation_result, error);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  identity = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
1e691d
-  if (identity != NULL)
1e691d
-    g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
1e691d
-                                               g_object_ref (identity),
1e691d
-                                               (GDestroyNotify)
1e691d
-                                               g_object_unref);
1e691d
-  else
1e691d
-    g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
1e691d
-                                               NULL,
1e691d
-                                               NULL);
1e691d
-
1e691d
-  g_simple_async_result_complete_in_idle (operation_result);
1e691d
-  g_object_unref (operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-on_identity_looked_up_to_ensure_credentials (GoaKerberosProvider *self,
1e691d
-                                             GAsyncResult        *result,
1e691d
-                                             GSimpleAsyncResult  *operation_result)
1e691d
+static gboolean
1e691d
+dbus_proxy_reload_properties_sync (GDBusProxy    *proxy,
1e691d
+                                   GCancellable  *cancellable)
1e691d
 {
1e691d
-
1e691d
-  GoaIdentityServiceIdentity *identity;
1e691d
-  GError                     *error;
1e691d
-  GoaObject                  *object;
1e691d
-  GoaAccount                 *account;
1e691d
-  const char                 *identifier;
1e691d
-  GCancellable               *cancellable;
1e691d
-
1e691d
-  error = NULL;
1e691d
-  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
1e691d
-    {
1e691d
-      g_simple_async_result_take_error (operation_result, error);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  identity = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
1e691d
-
1e691d
-  if (identity != NULL && goa_identity_service_identity_get_is_signed_in (identity))
1e691d
+  GVariant *result;
1e691d
+  char *name;
1e691d
+  GVariant *value;
1e691d
+  GVariantIter *iter;
1e691d
+
1e691d
+  result = g_dbus_connection_call_sync (g_dbus_proxy_get_connection (proxy),
1e691d
+                                        g_dbus_proxy_get_name_owner (proxy),
1e691d
+                                        g_dbus_proxy_get_object_path (proxy),
1e691d
+                                        "org.freedesktop.DBus.Properties",
1e691d
+                                        "GetAll",
1e691d
+                                        g_variant_new ("(s)", g_dbus_proxy_get_interface_name (proxy)),
1e691d
+                                        G_VARIANT_TYPE ("(a{sv})"),
1e691d
+                                        G_DBUS_CALL_FLAGS_NONE,
1e691d
+                                        -1,
1e691d
+                                        cancellable,
1e691d
+                                        NULL);
1e691d
+  if (result == NULL)
1e691d
+    return FALSE;
1e691d
+
1e691d
+  g_variant_get (result, "(a{sv})", &iter);
1e691d
+  while (g_variant_iter_next (iter, "{sv}", &name, &value))
1e691d
     {
1e691d
-      g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
1e691d
-                                                 g_object_ref (identity),
1e691d
-                                                 (GDestroyNotify)
1e691d
-                                                 g_object_unref);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
-    }
1e691d
-
1e691d
-  object = GOA_OBJECT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
1e691d
-  cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
1e691d
+      g_dbus_proxy_set_cached_property (proxy, name, value);
1e691d
 
1e691d
-  if (!get_ticket_sync (self,
1e691d
-                        object,
1e691d
-                        FALSE /* Don't allow interaction */,
1e691d
-                        cancellable,
1e691d
-                        &error))
1e691d
-    {
1e691d
-      g_simple_async_result_take_error (operation_result, error);
1e691d
-      g_simple_async_result_complete_in_idle (operation_result);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return;
1e691d
+      g_free (name);
1e691d
+      g_variant_unref (value);
1e691d
     }
1e691d
-
1e691d
-  account = goa_object_peek_account (object);
1e691d
-  identifier = goa_account_get_identity (account);
1e691d
-
1e691d
-  look_up_identity (self,
1e691d
-                    identifier,
1e691d
-                    cancellable,
1e691d
-                    (GAsyncReadyCallback)
1e691d
-                    on_identity_looked_up,
1e691d
-                    operation_result);
1e691d
-}
1e691d
-
1e691d
-static void
1e691d
-on_credentials_ensured (GoaObject    *object,
1e691d
-                        GAsyncResult *result,
1e691d
-                        GMainLoop    *loop)
1e691d
-{
1e691d
-  g_main_loop_quit (loop);
1e691d
+  g_variant_iter_free (iter);
1e691d
+  return TRUE;
1e691d
 }
1e691d
 
1e691d
 static gboolean
1e691d
@@ -1873,65 +1381,57 @@ ensure_credentials_sync (GoaProvider    *provider,
1e691d
                          GCancellable   *cancellable,
1e691d
                          GError        **error)
1e691d
 {
1e691d
-  GoaIdentityServiceIdentity *identity;
1e691d
+  GoaIdentityServiceIdentity *identity = NULL;
1e691d
   GoaAccount                 *account;
1e691d
   const char                 *identifier;
1e691d
-  GSimpleAsyncResult         *operation_result;
1e691d
-  GMainLoop                  *loop;
1e691d
-  GMainContext               *context;
1e691d
   gint64                      timestamp;
1e691d
   GDateTime                  *now, *expiration_time;
1e691d
   GTimeSpan                   time_span;
1e691d
-  GError                     *lookup_error;
1e691d
+  gboolean                    credentials_ensured = FALSE;
1e691d
 
1e691d
   account = goa_object_peek_account (object);
1e691d
   identifier = goa_account_get_identity (account);
1e691d
 
1e691d
-  context = g_main_context_new ();
1e691d
-  g_main_context_push_thread_default (context);
1e691d
-  loop = g_main_loop_new (context, FALSE);
1e691d
-  operation_result = g_simple_async_result_new (G_OBJECT (object),
1e691d
-                                                (GAsyncReadyCallback)
1e691d
-                                                on_credentials_ensured,
1e691d
-                                                loop,
1e691d
-                                                ensure_credentials_sync);
1e691d
-  g_simple_async_result_set_check_cancellable (operation_result, cancellable);
1e691d
-
1e691d
-  g_object_set_data (G_OBJECT (operation_result),
1e691d
-                     "cancellable",
1e691d
-                     cancellable);
1e691d
+  ensure_identity_manager ();
1e691d
 
1e691d
-  g_object_ref (operation_result);
1e691d
-  look_up_identity (GOA_KERBEROS_PROVIDER (provider),
1e691d
-                    identifier,
1e691d
-                    cancellable,
1e691d
-                    (GAsyncReadyCallback)
1e691d
-                    on_identity_looked_up_to_ensure_credentials,
1e691d
-                    operation_result);
1e691d
+  g_mutex_lock (&identity_manager_mutex);
1e691d
+  identity = get_identity_from_object_manager (GOA_KERBEROS_PROVIDER (provider),
1e691d
+                                               identifier);
1e691d
 
1e691d
-  g_main_loop_run (loop);
1e691d
-  g_main_loop_unref (loop);
1e691d
-
1e691d
-  g_main_context_pop_thread_default (context);
1e691d
-  g_main_context_unref (context);
1e691d
+  if (identity != NULL)
1e691d
+    {
1e691d
+      if (!dbus_proxy_reload_properties_sync (G_DBUS_PROXY (identity), cancellable))
1e691d
+        g_clear_object (&identity);
1e691d
+    }
1e691d
 
1e691d
-  lookup_error = NULL;
1e691d
-  if (g_simple_async_result_propagate_error (operation_result, &lookup_error))
1e691d
+  if (identity == NULL || !goa_identity_service_identity_get_is_signed_in (identity))
1e691d
     {
1e691d
-      translate_error (&lookup_error);
1e691d
-      g_set_error_literal (error,
1e691d
-                           GOA_ERROR,
1e691d
-                           GOA_ERROR_NOT_AUTHORIZED,
1e691d
-                           lookup_error->message);
1e691d
-      g_error_free (lookup_error);
1e691d
-      g_object_unref (operation_result);
1e691d
-      return FALSE;
1e691d
+      gboolean ticket_synced;
1e691d
+
1e691d
+      g_mutex_unlock (&identity_manager_mutex);
1e691d
+      ticket_synced = get_ticket_sync (GOA_KERBEROS_PROVIDER (provider),
1e691d
+                                       object,
1e691d
+                                       FALSE /* Don't allow interaction */,
1e691d
+                                       cancellable,
1e691d
+                                       error);
1e691d
+      g_mutex_lock (&identity_manager_mutex);
1e691d
+
1e691d
+      if (!ticket_synced)
1e691d
+        goto out;
1e691d
+
1e691d
+      if (identity == NULL)
1e691d
+        identity = get_identity_from_object_manager (GOA_KERBEROS_PROVIDER (provider),
1e691d
+                                                     identifier);
1e691d
     }
1e691d
 
1e691d
-  identity = g_simple_async_result_get_op_res_gpointer (operation_result);
1e691d
+  if (identity == NULL)
1e691d
+    goto out;
1e691d
+
1e691d
+  dbus_proxy_reload_properties_sync (G_DBUS_PROXY (identity), cancellable);
1e691d
 
1e691d
   now = g_date_time_new_now_local ();
1e691d
   timestamp = goa_identity_service_identity_get_expiration_timestamp (identity);
1e691d
+
1e691d
   expiration_time = g_date_time_new_from_unix_local (timestamp);
1e691d
   time_span = g_date_time_difference (expiration_time, now);
1e691d
 
1e691d
@@ -1941,12 +1441,239 @@ ensure_credentials_sync (GoaProvider    *provider,
1e691d
     time_span = 0;
1e691d
 
1e691d
   *out_expires_in = (int) time_span;
1e691d
+  credentials_ensured = TRUE;
1e691d
 
1e691d
   g_date_time_unref (now);
1e691d
   g_date_time_unref (expiration_time);
1e691d
-  g_object_unref (operation_result);
1e691d
 
1e691d
-  return TRUE;
1e691d
+out:
1e691d
+  g_clear_object (&identity);
1e691d
+  g_mutex_unlock (&identity_manager_mutex);
1e691d
+  return credentials_ensured;
1e691d
+}
1e691d
+
1e691d
+static GoaIdentityServiceIdentity *
1e691d
+get_identity_from_object_manager (GoaKerberosProvider *self,
1e691d
+                                  const char          *identifier)
1e691d
+{
1e691d
+  GoaIdentityServiceIdentity *identity = NULL;
1e691d
+  GList                      *objects, *node;
1e691d
+
1e691d
+  ensure_object_manager ();
1e691d
+
1e691d
+  g_mutex_lock (&object_manager_mutex);
1e691d
+  objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager));
1e691d
+
1e691d
+  for (node = objects; node != NULL; node = node->next)
1e691d
+    {
1e691d
+      GoaIdentityServiceIdentity *candidate_identity;
1e691d
+      const char                 *candidate_identifier;
1e691d
+      GDBusObject                *object;
1e691d
+
1e691d
+      object = node->data;
1e691d
+
1e691d
+      candidate_identity = GOA_IDENTITY_SERVICE_IDENTITY (g_dbus_object_get_interface (object, "org.gnome.Identity"));
1e691d
+
1e691d
+      if (candidate_identity == NULL)
1e691d
+        continue;
1e691d
+
1e691d
+      candidate_identifier = goa_identity_service_identity_get_identifier (candidate_identity);
1e691d
+
1e691d
+      if (g_strcmp0 (candidate_identifier, identifier) == 0)
1e691d
+        {
1e691d
+          identity = candidate_identity;
1e691d
+          break;
1e691d
+        }
1e691d
+
1e691d
+      g_object_unref (candidate_identity);
1e691d
+    }
1e691d
+
1e691d
+  g_list_free_full (objects, (GDestroyNotify) g_object_unref);
1e691d
+  g_mutex_unlock (&object_manager_mutex);
1e691d
+
1e691d
+  return identity;
1e691d
+}
1e691d
+
1e691d
+static char *
1e691d
+sign_in_identity_sync (GoaKerberosProvider  *self,
1e691d
+                       const char           *identifier,
1e691d
+                       const char           *password,
1e691d
+                       const char           *preauth_source,
1e691d
+                       GCancellable         *cancellable,
1e691d
+                       GError              **error)
1e691d
+{
1e691d
+  GcrSecretExchange  *secret_exchange;
1e691d
+  char               *secret_key;
1e691d
+  char               *return_key;
1e691d
+  char               *concealed_secret;
1e691d
+  char               *identity_object_path = NULL;
1e691d
+  gboolean            keys_exchanged;
1e691d
+  GVariantBuilder     details;
1e691d
+
1e691d
+  secret_exchange = gcr_secret_exchange_new (NULL);
1e691d
+
1e691d
+  secret_key = gcr_secret_exchange_begin (secret_exchange);
1e691d
+  ensure_identity_manager ();
1e691d
+
1e691d
+  g_mutex_lock (&identity_manager_mutex);
1e691d
+  keys_exchanged = goa_identity_service_manager_call_exchange_secret_keys_sync (identity_manager,
1e691d
+                                                                                secret_key,
1e691d
+                                                                                &return_key,
1e691d
+                                                                                cancellable,
1e691d
+                                                                                error);
1e691d
+  g_mutex_unlock (&identity_manager_mutex);
1e691d
+  g_free (secret_key);
1e691d
+
1e691d
+  if (!keys_exchanged)
1e691d
+    goto out;
1e691d
+
1e691d
+  if (!gcr_secret_exchange_receive (secret_exchange, return_key))
1e691d
+    {
1e691d
+      g_set_error (error,
1e691d
+                   GCR_ERROR,
1e691d
+                   GCR_ERROR_UNRECOGNIZED,
1e691d
+                   _("Identity service returned invalid key"));
1e691d
+      goto out;
1e691d
+    }
1e691d
+
1e691d
+  g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
1e691d
+
1e691d
+  concealed_secret = gcr_secret_exchange_send (secret_exchange, password, -1);
1e691d
+  g_variant_builder_add (&details, "{ss}", "initial-password", concealed_secret);
1e691d
+  g_free (concealed_secret);
1e691d
+
1e691d
+  if (preauth_source != NULL)
1e691d
+    {
1e691d
+      g_variant_builder_add (&details, "{ss}", "preauthentication-source", preauth_source);
1e691d
+    }
1e691d
+
1e691d
+  g_mutex_lock (&identity_manager_mutex);
1e691d
+  goa_identity_service_manager_call_sign_in_sync (identity_manager,
1e691d
+                                                  identifier,
1e691d
+                                                  g_variant_builder_end (&details),
1e691d
+                                                  &identity_object_path,
1e691d
+                                                  cancellable,
1e691d
+                                                  error);
1e691d
+  g_mutex_unlock (&identity_manager_mutex);
1e691d
+
1e691d
+out:
1e691d
+  g_object_unref (secret_exchange);
1e691d
+  return identity_object_path;
1e691d
+}
1e691d
+
1e691d
+static void
1e691d
+sign_in_thread (GSimpleAsyncResult  *result,
1e691d
+                GoaKerberosProvider *self,
1e691d
+                GCancellable        *cancellable)
1e691d
+{
1e691d
+  const char *identifier;
1e691d
+  const char *password;
1e691d
+  const char *preauth_source;
1e691d
+  char *object_path;
1e691d
+  GError *error;
1e691d
+
1e691d
+  identifier = g_simple_async_result_get_source_tag (result);
1e691d
+  password = g_object_get_data (G_OBJECT (result), "password");
1e691d
+  preauth_source = g_object_get_data (G_OBJECT (result), "preauth-source");
1e691d
+
1e691d
+  error = NULL;
1e691d
+  object_path = sign_in_identity_sync (self, identifier, password, preauth_source, cancellable, &error);
1e691d
+
1e691d
+  if (object_path == NULL)
1e691d
+    g_simple_async_result_take_error (result, error);
1e691d
+  else
1e691d
+    g_simple_async_result_set_op_res_gpointer (result, object_path, NULL);
1e691d
+}
1e691d
+
1e691d
+
1e691d
+static void
1e691d
+on_object_manager_created (gpointer             object,
1e691d
+                           GAsyncResult        *result,
1e691d
+                           GSimpleAsyncResult  *operation_result)
1e691d
+{
1e691d
+  GDBusObjectManager *manager;
1e691d
+  GError *error;
1e691d
+
1e691d
+  error = NULL;
1e691d
+  manager = goa_identity_service_object_manager_client_new_for_bus_finish (result, &error);
1e691d
+  if (manager == NULL)
1e691d
+    {
1e691d
+      g_warning ("GoaKerberosProvider: Could not connect to identity service: %s", error->message);
1e691d
+      g_clear_error (&error);
1e691d
+      return;
1e691d
+    }
1e691d
+
1e691d
+  g_mutex_lock (&object_manager_mutex);
1e691d
+  object_manager = manager;
1e691d
+  g_cond_signal (&object_manager_condition);
1e691d
+  g_mutex_unlock (&object_manager_mutex);
1e691d
+}
1e691d
+
1e691d
+static void
1e691d
+create_object_manager (void)
1e691d
+{
1e691d
+  goa_identity_service_object_manager_client_new_for_bus (G_BUS_TYPE_SESSION,
1e691d
+                                                          G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
1e691d
+                                                          "org.gnome.Identity",
1e691d
+                                                          "/org/gnome/Identity",
1e691d
+                                                          NULL,
1e691d
+                                                          (GAsyncReadyCallback)
1e691d
+                                                          on_object_manager_created,
1e691d
+                                                          NULL);
1e691d
+}
1e691d
+
1e691d
+static void
1e691d
+ensure_object_manager (void)
1e691d
+{
1e691d
+  g_mutex_lock (&object_manager_mutex);
1e691d
+  while (object_manager == NULL)
1e691d
+      g_cond_wait (&object_manager_condition, &object_manager_mutex);
1e691d
+  g_mutex_unlock (&object_manager_mutex);
1e691d
+}
1e691d
+
1e691d
+static void
1e691d
+on_identity_manager_created (gpointer             identity,
1e691d
+                             GAsyncResult        *result,
1e691d
+                             GSimpleAsyncResult  *operation_result)
1e691d
+{
1e691d
+  GoaIdentityServiceManager *manager;
1e691d
+  GError *error;
1e691d
+
1e691d
+  error = NULL;
1e691d
+  manager = goa_identity_service_manager_proxy_new_for_bus_finish (result, &error);
1e691d
+  if (manager == NULL)
1e691d
+    {
1e691d
+      g_warning ("GoaKerberosProvider: Could not connect to identity service manager: %s", error->message);
1e691d
+      g_clear_error (&error);
1e691d
+      return;
1e691d
+    }
1e691d
+
1e691d
+  g_mutex_lock (&identity_manager_mutex);
1e691d
+  identity_manager = manager;
1e691d
+  g_cond_signal (&identity_manager_condition);
1e691d
+  g_mutex_unlock (&identity_manager_mutex);
1e691d
+}
1e691d
+
1e691d
+static void
1e691d
+create_identity_manager (void)
1e691d
+{
1e691d
+  goa_identity_service_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION,
1e691d
+                                                  G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
1e691d
+                                                  "org.gnome.Identity",
1e691d
+                                                  "/org/gnome/Identity/Manager",
1e691d
+                                                  NULL,
1e691d
+                                                  (GAsyncReadyCallback)
1e691d
+                                                  on_identity_manager_created,
1e691d
+                                                  NULL);
1e691d
+}
1e691d
+
1e691d
+static void
1e691d
+ensure_identity_manager (void)
1e691d
+{
1e691d
+  g_mutex_lock (&identity_manager_mutex);
1e691d
+  while (identity_manager == NULL)
1e691d
+      g_cond_wait (&identity_manager_condition, &identity_manager_mutex);
1e691d
+  g_mutex_unlock (&identity_manager_mutex);
1e691d
 }
1e691d
 
1e691d
 static void
1e691d
-- 
4bc980
2.5.0
1e691d
1e691d
4bc980
From 2dbd414c16d8654f0cfccb54fede644b8f3216db Mon Sep 17 00:00:00 2001
1e691d
From: Ray Strode <rstrode@redhat.com>
1e691d
Date: Tue, 28 Oct 2014 17:10:49 -0400
1e691d
Subject: [PATCH 2/2] identity: separate identity service off into its own
1e691d
 process
1e691d
1e691d
This commit segregates the kerberos specific functionality off
1e691d
into its own helper process.
1e691d
1e691d
This has a couple of benefits:
1e691d
1e691d
1) It is actually a better fit for how the code was initially designed,
1e691d
which was first staged in gnome-settings-daemon with g-o-a talking to
1e691d
it. Right now we have gnome-online-accounts talking to itself,
1e691d
in-process, through d-bus, which is suboptimal.
1e691d
1e691d
2) It keeps any leaks or crashes in the kerberos code from bringing down
1e691d
the whole online accounts daemon.
1e691d
---
1e691d
 data/Makefile.am                     |  8 ++++-
1e691d
 data/org.gnome.Identity.service.in   |  3 ++
1e691d
 src/daemon/Makefile.am               |  8 -----
1e691d
 src/daemon/goadaemon.c               | 43 +++++++++++++-------------
1e691d
 src/goaidentity/Makefile.am          | 10 +++---
1e691d
 src/goaidentity/goaidentityservice.c |  2 +-
1e691d
 src/goaidentity/main.c               | 59 ++++++++++++++++++++++++++++++++++++
1e691d
 7 files changed, 97 insertions(+), 36 deletions(-)
1e691d
 create mode 100644 data/org.gnome.Identity.service.in
1e691d
 create mode 100644 src/goaidentity/main.c
1e691d
1e691d
diff --git a/data/Makefile.am b/data/Makefile.am
4bc980
index cb30eb8d1391..fb68063c8234 100644
1e691d
--- a/data/Makefile.am
1e691d
+++ b/data/Makefile.am
1e691d
@@ -14,9 +14,14 @@ gsettings_SCHEMAS = $(gsettings_in_files:.xml.in=.xml)
1e691d
 
1e691d
 servicedir       = $(datadir)/dbus-1/services
1e691d
 service_in_files = org.gnome.OnlineAccounts.service.in
1e691d
+
1e691d
+if BUILD_KERBEROS
1e691d
+service_in_files += org.gnome.Identity.service.in
1e691d
+endif
1e691d
+
1e691d
 service_DATA     = $(service_in_files:.service.in=.service)
1e691d
 
1e691d
-$(service_DATA): $(service_in_files) Makefile
1e691d
+%.service: %.service.in Makefile
1e691d
 	@sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
1e691d
 
1e691d
 EXTRA_DIST =						\
1e691d
@@ -29,6 +34,7 @@ EXTRA_DIST =						\
1e691d
 DISTCLEANFILES =					\
1e691d
 	$(gsettings_SCHEMAS)				\
1e691d
 	org.gnome.OnlineAccounts.service		\
1e691d
+	org.gnome.Identity.service			\
1e691d
 	$(NULL)
1e691d
 
1e691d
 clean-local :
1e691d
diff --git a/data/org.gnome.Identity.service.in b/data/org.gnome.Identity.service.in
1e691d
new file mode 100644
4bc980
index 000000000000..bd3b03225ab6
1e691d
--- /dev/null
1e691d
+++ b/data/org.gnome.Identity.service.in
1e691d
@@ -0,0 +1,3 @@
1e691d
+[D-BUS Service]
1e691d
+Name=org.gnome.Identity
1e691d
+Exec=@libexecdir@/goa-identity-service
1e691d
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
4bc980
index 9fdb11538a4e..8f5352fad39e 100644
1e691d
--- a/src/daemon/Makefile.am
1e691d
+++ b/src/daemon/Makefile.am
1e691d
@@ -48,14 +48,6 @@ goa_daemon_LDADD = 						\
1e691d
 	$(TP_LIBS)						\
1e691d
 	$(NULL)
1e691d
 
1e691d
-if BUILD_KERBEROS
1e691d
-goa_daemon_LDADD += 						\
1e691d
-	$(top_builddir)/src/goaidentity/libgoaidentity.la	\
1e691d
-	$(KRB5_LIBS)						\
1e691d
-	$(GCR_LIBS)						\
1e691d
-	$(NULL)
1e691d
-endif
1e691d
-
1e691d
 clean-local :
1e691d
 	rm -f *~
1e691d
 
1e691d
diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c
4bc980
index 8074f201ef46..1aa0f18aee45 100644
1e691d
--- a/src/daemon/goadaemon.c
1e691d
+++ b/src/daemon/goadaemon.c
1e691d
@@ -25,9 +25,6 @@
1e691d
 #include "goadaemon.h"
1e691d
 #include "goabackend/goabackend.h"
1e691d
 #include "goabackend/goautils.h"
1e691d
-#ifdef GOA_KERBEROS_ENABLED
1e691d
-#include "goaidentity/goaidentityservice.h"
1e691d
-#endif
1e691d
 
1e691d
 struct _GoaDaemon
1e691d
 {
1e691d
@@ -43,10 +40,6 @@ struct _GoaDaemon
1e691d
 
1e691d
   GoaManager *manager;
1e691d
 
1e691d
-#ifdef GOA_KERBEROS_ENABLED
1e691d
-  GoaIdentityService *identity_service;
1e691d
-#endif
1e691d
-
1e691d
   guint config_timeout_id;
1e691d
 };
1e691d
 
1e691d
@@ -112,10 +105,6 @@ goa_daemon_finalize (GObject *object)
1e691d
   g_object_unref (daemon->object_manager);
1e691d
   g_object_unref (daemon->connection);
1e691d
 
1e691d
-#ifdef GOA_KERBEROS_ENABLED
1e691d
-  g_clear_object (&daemon->identity_service);
1e691d
-#endif
1e691d
-
1e691d
   G_OBJECT_CLASS (goa_daemon_parent_class)->finalize (object);
1e691d
 }
1e691d
 
1e691d
@@ -173,15 +162,32 @@ on_file_monitor_changed (GFileMonitor      *monitor,
1e691d
     }
1e691d
 }
1e691d
 
1e691d
+#ifdef GOA_KERBEROS_ENABLED
1e691d
+static void
1e691d
+activate_identity_service (GoaDaemon *daemon)
1e691d
+{
1e691d
+  GoaProvider *provider;
1e691d
+
1e691d
+  /* We activate the identity service implicitly by using the kerberos
1e691d
+   * backend.  This way if the kerberos backend isn't enabled, we don't
1e691d
+   * end up starting the identity service needlessly
1e691d
+   */
1e691d
+  provider = goa_provider_get_for_provider_type (GOA_KERBEROS_NAME);
1e691d
+
1e691d
+  if (provider != NULL)
1e691d
+    {
1e691d
+      g_debug ("activated kerberos provider");
1e691d
+      g_object_unref (provider);
1e691d
+    }
1e691d
+}
1e691d
+#endif
1e691d
+
1e691d
 static void
1e691d
 goa_daemon_init (GoaDaemon *daemon)
1e691d
 {
1e691d
   static volatile GQuark goa_error_domain = 0;
1e691d
   GoaObjectSkeleton *object;
1e691d
   gchar *path;
1e691d
-#ifdef GOA_KERBEROS_ENABLED
1e691d
-  GError *error = NULL;
1e691d
-#endif
1e691d
 
1e691d
   /* this will force associating errors in the GOA_ERROR error domain
1e691d
    * with org.freedesktop.Goa.Error.* errors via g_dbus_error_register_error_domain().
1e691d
@@ -228,14 +234,7 @@ goa_daemon_init (GoaDaemon *daemon)
1e691d
   g_dbus_object_manager_server_set_connection (daemon->object_manager, daemon->connection);
1e691d
 
1e691d
 #ifdef GOA_KERBEROS_ENABLED
1e691d
-  daemon->identity_service = goa_identity_service_new ();
1e691d
-  if (!goa_identity_service_activate (daemon->identity_service,
1e691d
-                                      &error))
1e691d
-    {
1e691d
-      g_warning ("Error activating identity service: %s", error->message);
1e691d
-      g_error_free (error);
1e691d
-      g_clear_object (&daemon->identity_service);
1e691d
-    }
1e691d
+  activate_identity_service (daemon);
1e691d
 #endif
1e691d
 }
1e691d
 
1e691d
diff --git a/src/goaidentity/Makefile.am b/src/goaidentity/Makefile.am
4bc980
index 8e11f6d596da..537287a2cca3 100644
1e691d
--- a/src/goaidentity/Makefile.am
1e691d
+++ b/src/goaidentity/Makefile.am
1e691d
@@ -47,6 +47,7 @@ identity_sources =						\
1e691d
 	goakerberosidentity.c					\
1e691d
 	goakerberosidentityinquiry.c				\
1e691d
 	goakerberosidentitymanager.c				\
1e691d
+	main.c							\
1e691d
 	$(NULL)
1e691d
 
1e691d
 identity_dbus_built_sources =					\
1e691d
@@ -95,23 +96,24 @@ BUILT_SOURCES += $(realmd_dbus_built_sources)
1e691d
 EXTRA_DIST += org.freedesktop.realmd.xml
1e691d
 
1e691d
 if BUILD_KERBEROS
1e691d
-noinst_LTLIBRARIES = libgoaidentity.la
1e691d
+libexec_PROGRAMS = goa-identity-service
1e691d
 
1e691d
-libgoaidentity_la_SOURCES = 					\
1e691d
+goa_identity_service_SOURCES = 					\
1e691d
 	goaidentityenumtypes.h		goaidentityenumtypes.c	\
1e691d
 	$(identity_dbus_built_sources)				\
1e691d
 	$(realmd_dbus_built_sources)				\
1e691d
 	$(identity_sources)					\
1e691d
 	$(NULL)
1e691d
 
1e691d
-libgoaidentity_la_CFLAGS =					\
1e691d
+goa_identity_service_CFLAGS =					\
1e691d
 	$(GLIB_CFLAGS) 						\
1e691d
 	$(GTK_CFLAGS)						\
1e691d
 	$(KRB5_CFLAGS)						\
1e691d
 	$(GCR_CFLAGS)						\
1e691d
 	$(NULL)
1e691d
 
1e691d
-libgoaidentity_la_LIBADD = 					\
1e691d
+goa_identity_service_LDADD = 					\
1e691d
+	$(top_builddir)/src/goa/libgoa-1.0.la			\
1e691d
 	$(GLIB_LIBS) 						\
1e691d
 	$(GTK_LIBS)						\
1e691d
 	$(KRB5_LIBS)						\
1e691d
diff --git a/src/goaidentity/goaidentityservice.c b/src/goaidentity/goaidentityservice.c
4bc980
index 38bbde6a7d93..6b6225adbc61 100644
1e691d
--- a/src/goaidentity/goaidentityservice.c
1e691d
+++ b/src/goaidentity/goaidentityservice.c
1e691d
@@ -1757,7 +1757,7 @@ on_name_lost (GDBusConnection    *connection,
1e691d
               GoaIdentityService *self)
1e691d
 {
1e691d
   if (g_strcmp0 (name, "org.gnome.Identity") == 0)
1e691d
-    g_debug ("GoaIdentityService: Lost name org.gnome.Identity");
1e691d
+    raise (SIGTERM);
1e691d
 }
1e691d
 
1e691d
 gboolean
1e691d
diff --git a/src/goaidentity/main.c b/src/goaidentity/main.c
1e691d
new file mode 100644
4bc980
index 000000000000..2de35acfc561
1e691d
--- /dev/null
1e691d
+++ b/src/goaidentity/main.c
1e691d
@@ -0,0 +1,59 @@
1e691d
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
1e691d
+/*
1e691d
+ * Copyright (C) 2014 Red Hat, Inc.
1e691d
+ *
1e691d
+ * This library is free software; you can redistribute it and/or
1e691d
+ * modify it under the terms of the GNU Lesser General Public
1e691d
+ * License as published by the Free Software Foundation; either
1e691d
+ * version 2 of the License, or (at your option) any later version.
1e691d
+ *
1e691d
+ * This library is distributed in the hope that it will be useful,
1e691d
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1e691d
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1e691d
+ * Lesser General Public License for more details.
1e691d
+ *
1e691d
+ * You should have received a copy of the GNU Lesser General
1e691d
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
1e691d
+ */
1e691d
+
1e691d
+#include "config.h"
1e691d
+
1e691d
+#include <glib/gi18n.h>
1e691d
+#include <glib-unix.h>
1e691d
+
1e691d
+#include <gio/gio.h>
1e691d
+
1e691d
+#include "goaidentityservice.h"
1e691d
+
1e691d
+int
1e691d
+main (int    argc,
1e691d
+      char **argv)
1e691d
+{
1e691d
+  GMainLoop *loop;
1e691d
+  GoaIdentityService *service;
1e691d
+  GError *error;
1e691d
+  int ret = 1;
1e691d
+
1e691d
+  loop = g_main_loop_new (NULL, FALSE);
1e691d
+  service = goa_identity_service_new ();
1e691d
+
1e691d
+  error = NULL;
1e691d
+  goa_identity_service_activate (service, &error);
1e691d
+
1e691d
+  if (error != NULL) {
1e691d
+      g_warning ("couldn't activate identity service: %s", error->message);
1e691d
+      g_error_free (error);
1e691d
+      goto out;
1e691d
+  }
1e691d
+
1e691d
+  g_main_loop_run (loop);
1e691d
+
1e691d
+  goa_identity_service_deactivate (service);
1e691d
+
1e691d
+  ret = 0;
1e691d
+out:
1e691d
+  g_object_unref (service);
1e691d
+  g_main_loop_unref (loop);
1e691d
+
1e691d
+  return ret;
1e691d
+}
1e691d
-- 
4bc980
2.5.0
1e691d