[gnome-online-accounts/wip/kerberos: 5/5] start to port to new realmd



commit 916c93e6655db8761121b057cd60a5efe755cdcf
Author: Ray Strode <rstrode redhat com>
Date:   Mon Aug 20 00:21:28 2012 -0400

    start to port to new realmd
    
    it's not working very well yet

 src/goabackend/goakerberosprovider.c       |    2 +-
 src/goaidentity/Makefile.am                |    5 +-
 src/goaidentity/goaidentityservice.c       |  178 ++++++---
 src/goaidentity/org.freedesktop.realmd.xml |  645 +++++++++++++++++++++++++---
 src/goaidentity/um-realm-manager.c         |  501 +++++++++-------------
 src/goaidentity/um-realm-manager.h         |   13 +-
 6 files changed, 923 insertions(+), 421 deletions(-)
---
diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c
index ad17e30..9449e90 100644
--- a/src/goabackend/goakerberosprovider.c
+++ b/src/goabackend/goakerberosprovider.c
@@ -80,7 +80,7 @@ get_provider_type (GoaProvider *provider)
 static gchar *
 get_provider_name (GoaProvider *provider, GoaObject *object)
 {
-  return g_strdup(_("Enterprise Identity"));
+  return g_strdup(_("Enterprise Login (Kerberos)"));
 }
 
 typedef struct
diff --git a/src/goaidentity/Makefile.am b/src/goaidentity/Makefile.am
index 1be71b4..9e74b26 100644
--- a/src/goaidentity/Makefile.am
+++ b/src/goaidentity/Makefile.am
@@ -82,8 +82,11 @@ realmd_dbus_built_sources =					\
 $(realmd_dbus_built_sources) : Makefile.am org.freedesktop.realmd.xml
 	gdbus-codegen						\
 		--interface-prefix org.freedesktop.realmd.	\
-		--c-namespace UmRealm				\
 		--generate-c-code um-realm-generated		\
+		--c-generate-object-manager			\
+		--c-namespace UmRealm				\
+		--annotate "org.freedesktop.realmd.Realm"	\
+		            org.gtk.GDBus.C.Name Common		\
 		org.freedesktop.realmd.xml			\
 		$(NULL)
 BUILT_SOURCES += $(realmd_dbus_built_sources)
diff --git a/src/goaidentity/goaidentityservice.c b/src/goaidentity/goaidentityservice.c
index f4b7cb3..03f0473 100644
--- a/src/goaidentity/goaidentityservice.c
+++ b/src/goaidentity/goaidentityservice.c
@@ -64,10 +64,14 @@ struct _GoaIdentityServicePrivate
 
 static void identity_service_manager_interface_init (GoaIdentityServiceManagerIface *interface);
 
-static void on_realm_joined (UmRealmKerberos    *realm,
+static void on_realm_joined (UmRealmObject      *realm,
                              GAsyncResult       *result,
                              GSimpleAsyncResult *operation_result);
 
+static void on_realm_looked_up_for_sign_in (GoaIdentityService *self,
+                                            GAsyncResult       *result,
+                                            GSimpleAsyncResult *operation_result);
+
 static void
 look_up_realm (GoaIdentityService  *self,
                const char          *identifier,
@@ -78,7 +82,7 @@ look_up_realm (GoaIdentityService  *self,
 static void
 sign_in (GoaIdentityService     *self,
          const char             *identifier,
-         UmRealmKerberos        *realm,
+         UmRealmObject          *realm,
          gconstpointer           initial_password,
          GoaIdentitySignInFlags  flags,
          GCancellable           *cancellable,
@@ -163,13 +167,13 @@ unexport_identity (GoaIdentityService *self,
 
 static char *
 get_object_path_for_realm (GoaIdentityService *self,
-                           UmRealmKerberos    *realm)
+                           UmRealmObject      *realm)
 {
   const char *domain;
   char       *escaped_domain;
   char       *object_path;
 
-  domain = um_realm_kerberos_get_domain (realm);
+  domain = um_realm_kerberos_get_domain_name (um_realm_object_peek_kerberos (realm));
   escaped_domain = goa_identity_utils_escape_object_path (domain,
                                                           strlen (domain));
   object_path = g_strdup_printf ("/org/gnome/Identity/Realms/%s", escaped_domain);
@@ -191,15 +195,18 @@ on_realm_gone (GoaIdentityService *self,
 
 static char *
 export_realm (GoaIdentityService *self,
-              UmRealmKerberos    *realm)
+              UmRealmObject      *realm)
 {
   char *object_path;
   GDBusObjectSkeleton *object;
   GDBusInterfaceSkeleton *interface;
+  UmRealmKerberos    *kerberos;
   GSimpleAsyncResult *operation_result;
 
+  kerberos = um_realm_object_peek_kerberos (realm);
+
   goa_debug ("GoaIdentityService: exporting realm %s",
-             um_realm_kerberos_get_domain (realm));
+             um_realm_kerberos_get_domain_name (kerberos));
 
   object_path = get_object_path_for_realm (self, realm);
 
@@ -207,21 +214,21 @@ export_realm (GoaIdentityService *self,
   interface = G_DBUS_INTERFACE_SKELETON (goa_identity_service_realm_skeleton_new ());
 
   g_object_bind_property (G_OBJECT (realm),
-                          "enrolled",
+                          "configured",
                           G_OBJECT (interface),
                           "is-enrolled",
                           G_BINDING_SYNC_CREATE);
 
-  g_object_bind_property (G_OBJECT (realm),
-                          "name",
+  g_object_bind_property (G_OBJECT (kerberos),
+                          "realm-name",
                           G_OBJECT (interface),
-                          "name",
+                          "realm-name",
                           G_BINDING_SYNC_CREATE);
 
-  g_object_bind_property (G_OBJECT (realm),
-                          "domain",
+  g_object_bind_property (G_OBJECT (kerberos),
+                          "domain-name",
                           G_OBJECT (interface),
-                          "domain",
+                          "domain-name",
                           G_BINDING_SYNC_CREATE);
   operation_result = g_simple_async_result_new (G_OBJECT (self),
                                                 (GAsyncReadyCallback)
@@ -355,7 +362,7 @@ on_system_enrollment_password_answered (GoaIdentityService  *self,
 {
   GCancellable       *cancellable;
   GcrPrompt          *prompt;
-  UmRealmKerberos    *realm;
+  UmRealmObject      *realm;
   GBytes             *credentials;
   const char         *username;
   const char         *password;
@@ -450,7 +457,7 @@ on_system_enrollment_username_answered (GoaIdentityService  *self,
 static void
 enroll_machine_as_administrator (GoaIdentityService  *self,
                                  GoaIdentity         *identity,
-                                 UmRealmKerberos     *realm,
+                                 UmRealmObject       *realm,
                                  GBytes              *credentials,
                                  GCancellable        *cancellable,
                                  GAsyncReadyCallback  callback,
@@ -493,12 +500,11 @@ on_machine_enrolled (GoaIdentityService *self,
                      GAsyncResult       *result,
                      GSimpleAsyncResult *operation_result)
 {
-  g_simple_async_result_complete_in_idle (operation_result);
   g_object_unref (operation_result);
 }
 
 static void
-on_realm_joined (UmRealmKerberos    *realm,
+on_realm_joined (UmRealmObject      *realm,
                  GAsyncResult       *result,
                  GSimpleAsyncResult *operation_result)
 {
@@ -547,7 +553,7 @@ on_realm_joined (UmRealmKerberos    *realm,
 static void
 enroll_machine_as_user (GoaIdentityService  *self,
                         GoaIdentity         *identity,
-                        UmRealmKerberos     *realm,
+                        UmRealmObject       *realm,
                         const char          *password,
                         GBytes              *credentials,
                         GCancellable        *cancellable,
@@ -596,16 +602,61 @@ enroll_machine_as_user (GoaIdentityService  *self,
 }
 
 static void
+on_realm_looked_up_for_enrollment (GoaIdentityService *self,
+                                   GAsyncResult       *result,
+                                   GSimpleAsyncResult *operation_result)
+{
+  UmRealmObject *realm;
+  GoaIdentity   *identity;
+  GError        *error;
+  GCancellable  *cancellable;
+  GBytes        *credentials;
+  gconstpointer  initial_password;
+
+  realm = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+  error = NULL;
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+                                             &error))
+    {
+      goa_debug ("GoaIdentityService: Could not discover realm: %s",
+                 error->message);
+      g_error_free (error);
+
+      g_object_unref (operation_result);
+      return;
+    }
+
+  cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+  initial_password = g_object_get_data (G_OBJECT (operation_result),
+                                        "initial-password");
+  identity = g_object_get_data (G_OBJECT (operation_result), "identity");
+  credentials = goa_identity_get_credentials (identity);
+
+  /* Otherwise, try to enroll the machine with the domain controller
+   */
+  enroll_machine_as_user (self,
+                          identity,
+                          realm,
+                          initial_password,
+                          credentials,
+                          cancellable,
+                          (GAsyncReadyCallback)
+                          on_machine_enrolled,
+                          operation_result);
+  g_bytes_unref (credentials);
+}
+
+static void
 on_sign_in_done (GoaIdentityService *self,
                  GAsyncResult       *result,
                  GSimpleAsyncResult *operation_result)
 {
   GoaIdentity      *identity;
   char             *object_path;
-  char             *initial_password;
+  char             *domain;
   GCancellable     *cancellable;
-  UmRealmKerberos  *realm;
-  GBytes           *credentials;
+  UmRealmObject    *realm;
   GError           *error;
 
   error = NULL;
@@ -626,33 +677,35 @@ on_sign_in_done (GoaIdentityService *self,
                                              (GDestroyNotify)
                                              g_free);
 
-  /* If realmd isn't around or the machine is already enrolled,
-   * then we're done.
+  /* User is signed in, so we're mostly done
    */
-  if (realm == NULL || um_realm_kerberos_get_enrolled (realm))
+  g_simple_async_result_complete_in_idle (operation_result);
+
+  if (realm != NULL && um_realm_is_configured (realm))
     {
-      g_simple_async_result_complete_in_idle (operation_result);
       g_object_unref (operation_result);
       return;
     }
 
-  initial_password = g_object_get_data (G_OBJECT (operation_result),
-                                        "initial-password");
+  /* Try to enroll the machine at the point, too, if necessary.
+   */
+  g_object_set_data_full (G_OBJECT (operation_result),
+                          "identity",
+                          g_object_ref (identity),
+                          (GDestroyNotify)
+                          g_object_unref);
+
+  domain = g_object_get_data (G_OBJECT (operation_result),
+                                        "domain");
   cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
-  credentials = goa_identity_get_credentials (identity);
 
-  /* Otherwise, try to enroll the machine with the domain controller
-   */
-  enroll_machine_as_user (self,
-                          identity,
-                          realm,
-                          initial_password,
-                          credentials,
-                          cancellable,
-                          (GAsyncReadyCallback)
-                          on_machine_enrolled,
-                          operation_result);
-  g_bytes_unref (credentials);
+  look_up_realm (self,
+                 goa_identity_get_identifier (identity),
+                 domain,
+                 cancellable,
+                 (GAsyncReadyCallback)
+                 on_realm_looked_up_for_enrollment,
+                 operation_result);
 }
 
 static GoaObject *
@@ -826,7 +879,7 @@ on_realm_looked_up_for_sign_in (GoaIdentityService *self,
                                 GAsyncResult       *result,
                                 GSimpleAsyncResult *operation_result)
 {
-  UmRealmKerberos        *realm;
+  UmRealmObject          *realm;
   GoaIdentitySignInFlags  flags;
   GError                 *error;
   GCancellable           *cancellable;
@@ -851,6 +904,7 @@ on_realm_looked_up_for_sign_in (GoaIdentityService *self,
   else
     {
       char *user;
+      UmRealmKerberos *kerberos;
 
       /* Rebuild the identifier using the updated realm
        */
@@ -861,10 +915,12 @@ on_realm_looked_up_for_sign_in (GoaIdentityService *self,
                                            &user,
                                            NULL);
 
+      kerberos = um_realm_object_peek_kerberos (realm);
+
       if (user != NULL)
         new_identifier = g_strdup_printf ("%s %s",
                                           user,
-                                          um_realm_kerberos_get_name (realm));
+                                          um_realm_kerberos_get_realm_name (kerberos));
 
       identifier = new_identifier;
 
@@ -922,7 +978,7 @@ on_realm_looked_up (UmRealmManager     *manager,
 
 static void
 on_manager_realm_added (UmRealmManager     *manager,
-                        UmRealmKerberos    *realm,
+                        UmRealmObject      *realm,
                         GoaIdentityService *self)
 {
   export_realm (self, realm);
@@ -1007,7 +1063,6 @@ on_realm_manager_ensured_for_look_up (GoaIdentityService *self,
 
   domain = g_object_get_data (G_OBJECT (operation_result), "domain");
   cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
-
   um_realm_manager_discover (self->priv->realm_manager,
                              domain,
                              cancellable,
@@ -1057,7 +1112,7 @@ look_up_realm (GoaIdentityService  *self,
                           g_free);
 
   ensure_realm_manager (self,
-                        NULL,
+                        cancellable,
                         (GAsyncReadyCallback)
                         on_realm_manager_ensured_for_look_up,
                         operation_result);
@@ -1120,18 +1175,33 @@ goa_identity_service_handle_sign_in (GoaIdentityServiceManager *manager,
                      "initial-password",
                      (gpointer)
                      initial_password);
+  g_object_set_data_full (G_OBJECT (operation_result),
+                          "domain",
+                          domain,
+                          (GDestroyNotify)
+                          g_free);
   g_object_set_data (G_OBJECT (operation_result),
                      "flags",
                      GINT_TO_POINTER ((int) flags));
+  if (domain == NULL)
+    sign_in (self,
+             identifier,
+             NULL,
+             initial_password,
+             flags,
+             cancellable,
+             (GAsyncReadyCallback)
+             on_sign_in_done,
+             operation_result);
+  else
+    look_up_realm (self,
+                   identifier,
+                   domain,
+                   cancellable,
+                   (GAsyncReadyCallback)
+                   on_realm_looked_up_for_sign_in,
+                   operation_result);
 
-  look_up_realm (self,
-                 identifier,
-                 domain,
-                 cancellable,
-                 (GAsyncReadyCallback)
-                 on_realm_looked_up_for_sign_in,
-                 operation_result);
-  g_free (domain);
   g_object_unref (cancellable);
 
   return TRUE;
@@ -1935,7 +2005,7 @@ cancel_sign_in (GoaIdentityManager *identity_manager,
 static void
 sign_in (GoaIdentityService     *self,
          const char             *identifier,
-         UmRealmKerberos        *realm,
+         UmRealmObject          *realm,
          gconstpointer           initial_password,
          GoaIdentitySignInFlags  flags,
          GCancellable           *cancellable,
diff --git a/src/goaidentity/org.freedesktop.realmd.xml b/src/goaidentity/org.freedesktop.realmd.xml
index e09eb50..557de5c 100644
--- a/src/goaidentity/org.freedesktop.realmd.xml
+++ b/src/goaidentity/org.freedesktop.realmd.xml
@@ -1,150 +1,435 @@
 <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
  "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
-
 <node name="/">
+
 	<!--
-	 * Global interface implemented by realmd. Allows listing of providers
-	 * and discovering which one is relevant for a given domain.
-	 *
-	 * This is implemented by individual providers, but is aggregated
-	 * globally at the system bus name 'org.freedesktop.realmd' with the
-	 * object path '/org/freedesktop/realmd'
+	  org.freedesktop.realmd.Provider:
+	  @short_description: a realm provider
+
+	  Various realm providers represent different software implementations
+	  that provide access to realms or domains.
+
+	  This interface is implemented by individual providers, but is
+	  aggregated globally at the system bus name
+	  <literal>org.freedesktop.realmd</literal>
+	  with the object path <literal>/org/freedesktop/realmd</literal>
 	-->
 	<interface name="org.freedesktop.realmd.Provider">
 
 		<!--
-		 * The name of the provider
+		  Name: the name of the provider
+
+		  The name of the provider. This is not normally displayed
+		  to the user, but may be useful for diagnostics or debugging.
 		-->
 		<property name="Name" type="s" access="read"/>
 
 		<!--
-		 * A version number for the provider
+		  Version: the version of the provider
+
+		  The version of the provider. This is not normally used in
+		  logic, but may be useful for diagnostics or debugging.
 		-->
 		<property name="Version" type="s" access="read"/>
 
 		<!--
-		 * A list of known, enrolled or discovered realms.
-		 * Each realm is a DBus object and is represeted by a:
-		 *   o: DBus object path of the realm
-		 *   s: DBus interface name, like 'ofr.Kerberos' (below)
+		  Realms: a list of realms
+
+		  A list of known, enrolled or discovered realms. All realms
+		  that this provider knows about are listed here. As realms
+		  are discovered they are added to this list.
+
+		  Each realm is represented by the DBus object path of the
+		  realm object.
 		-->
-		<property name="Realms" type="a(os)" access="read"/>
+		<property name="Realms" type="ao" access="read"/>
 
 		<!--
-		 * Discover whether a string represents a realm that a provider
-		 * can enroll or otherwise use.
+		  Discover:
+		  @string: an input string to discover realms for
+		  @options: options for the discovery operation
+		  @relevance: the relevance of the returned results
+		  @realm: a list of realms discovered
+
+		  Discover realms for the given string. The input @string is
+		  usually a domain or realm name, perhaps typed by a user. If
+		  an empty string is provided the realm provider should try to
+		  discover a default realm if possible (eg: from DHCP).
+
+		  @options can contain, but is not limited to, the following values:
+		  <itemizedlist>
+		    <listitem><para><literal>operation</literal>: a string
+		      identifier chosen by the client, which can then later be
+		      passed to org.freedesktop.realmd.Service.Cancel() in order
+		      to cancel the operation</para></listitem>
+		  </itemizedlist>
+
+		  The @relevance returned can be used to rank results from
+		  different discover calls to different providers. Implementors
+		  should return a positive number if the provider highly
+		  recommends that the realms be handled by this provider,
+		  or a zero if it can possibly handle the realms. Negative
+		  should be returned if no realms are found.
+
+		  This method does not return an error when no realms are
+		  discovered. It simply returns an @realm list.
+
+		  To see diagnostic information about the discovery process
+		  connect to the org.freedesktop.realmd.Service::Diagnostics
+		  signal.
+
+		  This method requires authorization for the PolicyKit action
+		  called <literal>org.freedesktop.realmd.discover-realm</literal>.
+
+		  In addition to common DBus error results, this method may
+		  return:
+		  <itemizedlist>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Failed</literal>:
+		      may be returned if the discovery could not be run for some reason.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Cancelled</literal>:
+		      returned if the operation was cancelled.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.NotAuthorized</literal>:
+		      returned if the calling client is not permitted to perform a discovery
+		      operation.</para></listitem>
+		  </itemizedlist>
 		-->
 		<method name="Discover">
-			<!-- The input string -->
 			<arg name="string" type="s" direction="in"/>
 			<arg name="options" type="a{sv}" direction="in"/>
-
-			<!-- Returned match relevance -->
 			<arg name="relevance" type="i" direction="out"/>
-
-			<!-- The realm objects: bus name, object path, interface -->
-			<arg name="realm" type="a(os)" direction="out"/>
+			<arg name="realm" type="ao" direction="out"/>
 		</method>
+
 	</interface>
 
+	<!--
+	  org.freedesktop.realmd.Service:
+	  @short_description: the realmd service
+
+	  Global calls for managing the realmd service. Usually you'll want
+	  to use #org.freedesktop.realmd.Provider instead.
+
+	  This interface is implemented by the realmd service, and is always
+	  available at the object path <literal>/org/freedesktop/realmd</literal>
+
+	  The service also implements the
+	  <literal>org.freedesktop.DBus.ObjectManager</literal> interface which
+	  makes it easy to retrieve all realmd objects and properties in one go.
+	-->
 	<interface name="org.freedesktop.realmd.Service">
+
+		<!--
+		  Cancel:
+		  @operation: the operation to cancel
+
+		  Cancel a realmd operation. To be able to cancel an operation
+		  pass a uniquely chosen <literal>operation</literal> string
+		  identifier as an option in the methods <literal>options</literal>
+		  argument.
+
+		  These operation string identifiers should be unique per client
+		  calling the realmd service.
+
+		  It is not guaranteed that the service can or will cancel the
+		  operation. For example the operation may have already completed
+		  by the time this method is handled. The caller of the operation
+		  method will receive a
+		  <literal>org.freedesktop.realmd.Error.Cancelled</literal>
+		  if the operation was cancelled.
+		-->
 		<method name="Cancel">
-			<arg name="operation_id" type="s" direction="in"/>
+			<arg name="operation" type="s" direction="in"/>
 		</method>
 
+		<!--
+		  SetLocale:
+		  @locale: the locale for the client
+
+		  Set the language @locale for the client. This locale is used
+		  for error messages. The locale is used until the next time
+		  this method is called, the client disconnects, or the client
+		  calls #org.freedesktop.realmd.Service.Release().
+		-->
 		<method name="SetLocale">
 			<arg name="locale" type="s" direction="in"/>
 		</method>
 
+		<!--
+		  Diagnostics:
+		  @data: diagnostic data
+		  @operation: the operation this data resulted from
+
+		  This signal is fired when diagnostics result from an operation
+		  in the provider or one of its realms.
+
+		  It is not guaranteed that this signal is emitted once per line.
+		  More than one line may be contained in @data, or a partial
+		  line. New line characters are embedded in @data.
+
+		  This signal is sent explicitly to the client which invoked
+		  operation method. In order to tell which operation this
+		  diagnostic data results from, pass a unique
+		  <literal>operation</literal> string identifier in the
+		  <literal>options</literal> argument of the operation method.
+		  That same identifier will be passed back via the @operation
+		  argument of this signal.
+		-->
 		<signal name="Diagnostics">
 			<arg name="data" type="s"/>
-			<arg name="operation_id" type="s"/>
+			<arg name="operation" type="s"/>
 		</signal>
 
 		<!--
-		 * Normally realmd waits until all clients have disconnected
-		 * before exiting. For long lived clients, they can call
-		 * Release() allow realmd to quit. This is an optimization.
-		 * The daemon will not exit immediately. It is safe to call
-		 * this multiple times.
+		  Release:
+
+		  Normally realmd waits until all clients have disconnected
+		  before exiting itself, sometime later. For long lived clients
+		  they can call this method to allow the realmd service to quit.
+		  This is an optimization. The daemon will not exit immediately.
+		  It is safe to call this multiple times.
 		-->
 		<method name="Release">
 			<!-- no arguments -->
 		</method>
+
 	</interface>
 
 	<!--
-	 * This interface is implemented by Kerberos realms.
+	  org.freedesktop.realmd.Realm:
+	  @short_description: a realm
+
+	  Represents one realm.
+
+	  Contains generic information about a realm, and useful properties for
+	  introspecting what kind of realm this is and how to work with
+	  the realm.
+
+	  Use #org.freedesktop.realmd.Provider:Realms or
+	  #org.freedesktop.realmd.Provider.Discover() to get access to some
+	  kerberos realm objects.
+
+	  Realms will always implement additional interfaces, such as
+	  #org.freedesktop.realmd.Kerberos.  Do not assume that all realms
+	  implement that kerberos interface. Use the
+	  #org.freedesktop.realmd.Realm:SupportedInterfaces property to see
+	  which interfaces are set.
+
+	  Different realms support various ways to configure them on the
+	  system. Use the #org.freedesktop.realmd.Realm:Configured property
+	  to determine if a realm is configured. If it is configured the
+	  property will be set to the interface of the mechanism that was
+	  used to configure it.
+
+	  To configure a realm, look in the
+	  #org.freedesktop.realmd.Realm:SupportedInterfaces property for a
+	  recognized purpose specific interface that can be used for
+	  configuration, such as the
+	  #org.freedesktop.realmd.KerberosMembership interface and its
+	  #org.freedesktop.realmd.KerberosMembership.Join() method.
+
+	  To deconfigure a realm from the current system, you can use the
+	  #org.freedesktop.realmd.Realm.Deconfigure() method. In additon some
+	  of the configuration specific interfaces provide methods to
+	  deconfigure a realm in a specific way, such as
+	  #org.freedesktop.realmd.KerberosMembership.Leave() method.
+
+	  The various properties are guaranteed to have been updated before
+	  the operation methods return, if they change state.
 	-->
-	<interface name="org.freedesktop.realmd.Kerberos">
+	<interface name="org.freedesktop.realmd.Realm">
 
 		<!--
-		 * The kerberos realm name. Usually capitalized.
+		  Name: the realm name
+
+		  This is the name of the realm, appropriate for display to
+		  end users where necessary.
 		-->
 		<property name="Name" type="s" access="read"/>
 
 		<!--
-		 * The DNS domain name for this realm.
-		-->
-		<property name="Domain" type="s" access="read"/>
+		  Configured: whether this domain is configured and how
 
-		<!--
-		 * The server software, for information only. eg: active-directory
+		  If this property is an empty string, then the realm is not
+		  configured. Otherwise the realm is configured, and contains
+		  a string which is the interface that represents how it was
+		  configured, for example #org.freedesktop.realmd.KerberosMembership.
 		-->
-		<property name="Details" type="a{ss}" access="read"/>
+		<property name="Configured" type="s" access="read"/>
 
 		<!--
-		 * The suggested Administrator login name for this realm
+		  Deconfigure: deconfigure this realm
+
+		  Deconfigure this realm from the local machine with standard
+		  default behavior.
+
+		  The behavior of this method depends on the which configuration
+		  interface is present in the
+		  #org.freedesktop.realmd.Realm.Configured property. It does not
+		  always delete membership accounts in the realm, but just
+		  reconfigures the local machine so it no longer is configured
+		  for the given realm. In some cases the implementation may try
+		  to update membership accounts, but this is not guaranteed.
+
+		  Various configuration interfaces may support more specific ways
+		  to deconfigure a realm in a specific way, such as the
+		  #org.freedesktop.realmd.KerberosMembership.Leave() method.
+
+		  @options can contain, but is not limited to, the following values:
+		  <itemizedlist>
+		    <listitem><para><literal>operation</literal>: a string
+		      identifier chosen by the client, which can then later be
+		      passed to org.freedesktop.realmd.Service.Cancel() in order
+		      to cancel the operation</para></listitem>
+		  </itemizedlist>
+
+		  This method requires authorization for the PolicyKit action
+		  called <literal>org.freedesktop.realmd.deconfigure-realm</literal>.
+
+		  In addition to common DBus error results, this method may return:
+		  <itemizedlist>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Failed</literal>:
+		      may be returned if the deconfigure failed for a generic reason.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Cancelled</literal>:
+		      returned if the operation was cancelled.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.NotAuthorized</literal>:
+		      returned if the calling client is not permitted to deconfigure a
+		      realm.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.NotConfigured</literal>:
+		      returned if this realm is not configured on the machine.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Busy</literal>:
+		      returned if the service is currently performing another operation like
+		      join or leave.</para></listitem>
+		  </itemizedlist>
 		-->
-		<property name="SuggestedAdministrator" type="s" access="read"/>
+		<method name="Deconfigure">
+			<arg name="options" type="a{sv}" direction="in"/>
+		</method>
 
 		<!--
-		 * Whether the machine is enrolled in this realm or not.
+		  SupportedInterfaces:
+
+		  Additional supported interfaces of this realm. This includes
+		  interfaces that contain more information about the realm,
+		  such as #org.freedesktop.realmd.Kerberos and interfaces
+		  which contain methods for configuring a realm, such as
+		  #org.freedesktop.realmd.KerberosMembership.
 		-->
-		<property name="Enrolled" type="b" access="read"/>
+		<property name="SupportedInterfaces" type="as" access="read"/>
 
 		<!--
-		 * Credentials: (ssv)
-		 *  type: 'ccache', 'password', 'automatic'
-		 *  who: 'administrator', 'user', 'computer', 'secret'
-		 *  contents: ay, ss, b
-		-->
-		<property name="SupportedEnrollCredentials" type="a(ss)" access="read"/>
+		  Details: informational details about the realm
 
-		<property name="SupportedUnenrollCredentials" type="a(ss)" access="read"/>
+		  Informational details about the realm. The following values
+		  should be present:
+		  <itemizedlist>
+		    <listitem><para><literal>server-software</literal>:
+		      identifier of the software running on the server (eg:
+		      <literal>active-directory</literal>).</para></listitem>
+		    <listitem><para><literal>client-software</literal>:
+		      identifier of the software running on the client (eg:
+		      <literal>sssd</literal>).</para></listitem>
+		  </itemizedlist>
+		-->
+		<property name="Details" type="a(ss)" access="read"/>
 
-		<method name="Enroll">
-			<arg name="credentials" type="(ssv)" direction="in"/>
-			<arg name="options" type="a{sv}" direction="in"/>
-		</method>
+		<!--
+		  LoginFormats: supported formats for login names
 
-		<method name="Unenroll">
-			<arg name="credentials" type="(ssv)" direction="in"/>
-			<arg name="options" type="a{sv}" direction="in"/>
-		</method>
+		  Supported formats for login to this realm. This is only
+		  relevant once the realm has been enrolled. The formats
+		  will contain a <literal>%U</literal> in the string, which
+		  indicate where the user name should be placed. The formats
+		  may contain a <literal>%D</literal> in the string which
+		  indicate where a domain name should be placed.
 
-		<!--
-		 * The format for user logins when this realm is enrolled.
-		 * This property may not be valid unless machine is enrolled
-		 * in this realm. The format contains a %s where the user name
-		 * goes eg: "DOMAIN\%s"
+		  The first format in the list is the preferred format for
+		  login names.
 		-->
-		<property name="LoginFormat" type="s" access="read"/>
+		<property name="LoginFormats" type="as" access="read"/>
 
 		<!--
-		 * The policy for logins using this realm.
-		 * 'allow-any-login' 'allow-permitted-logins' 'deny-any-login'
+		  LoginPolicy: the policy for logins using this realm
+
+		  The policy for logging into this computer using this realm.
+
+		  The policy can be changed using the
+		  #org.freedesktop.realmd.Realm.ChangeLoginPolicy() method.
+
+		  The following policies are predefined. Not all providers
+		  support all these policies and there may be provider specific
+		  policies or multiple policies represented in the string:
+		  <itemizedlist>
+		    <listitem><para><literal>allow-any-login</literal>: allow
+		      login by any authenticated user present in this
+		      realm.</para></listitem>
+		    <listitem><para><literal>allow-permitted-logins</literal>:
+		      only allow the logins permitted in the
+		      #org.freedesktop.realmd.Realm:PermittedLogins
+		      property.</para></listitem>
+		    <listitem><para><literal>deny-any-login</literal>:
+		      don't allow any logins via authenticated users of this
+		      realm.</para></listitem>
+		  </itemizedlist>
 		-->
 		<property name="LoginPolicy" type="s" access="read"/>
 
 		<!--
-		 * The list of permitted logins in the LoginFormat style
+		  PermittedLogins: the permitted login names
+
+		  The list of permitted authenticated users allowed to login
+		  into this computer. This is only relevant if the
+		  #org.freedesktop.realmd.Realm:LoginPolicy property
+		  contains the <literal>allow-permitted-logins</literal>
+		  string.
 		-->
 		<property name="PermittedLogins" type="as" access="read"/>
 
 		<!--
-		 * Change the PermittedLogins property. Should take effect
-		 * immediately.
+		  ChangeLoginPolicy:
+		  @login_policy: the new login policy, or an empty string
+		  @permitted_add: a list of logins to permit
+		  @permitted_remove: a list of logins to not permit
+		  @options: options for this operation
+
+		  Change the login policy and/or permitted logins for this realm.
+
+		  Not all realms support the all the various login policies. An
+		  error will be returned if the new login policy is not supported.
+		  You may specify an empty string for the @login_policy argument
+		  which will cause no change in the policy itself. If the policy
+		  is changed, it will be reflected in the
+		  #org.freedesktop.realmd.Realm:LoginPolicy property.
+
+		  The @permitted_add and @permitted_remove arguments represent
+		  lists of login names that should be added and removed from
+		  the #org.freedesktop.realmd.Kerberos:PermittedLogins property.
+
+		  @options can contain, but is not limited to, the following values:
+		  <itemizedlist>
+		    <listitem><para><literal>operation</literal>: a string
+		      identifier chosen by the client, which can then later be
+		      passed to org.freedesktop.realmd.Service.Cancel() in order
+		      to cancel the operation</para></listitem>
+		  </itemizedlist>
+
+		  This method requires authorization for the PolicyKit action
+		  called <literal>org.freedesktop.realmd.login-policy</literal>.
+
+		  In addition to common DBus error results, this method may return:
+		  <itemizedlist>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Failed</literal>:
+		      may be returned if the policy change failed for a generic reason.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Cancelled</literal>:
+		      returned if the operation was cancelled.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.NotAuthorized</literal>:
+		      returned if the calling client is not permitted to change login policy
+		      operation.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.NotConfigured</literal>:
+		      returned if the realm is not configured.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Busy</literal>:
+		      returned if the service is currently performing another operation like
+		      join or leave.</para></listitem>
+		  </itemizedlist>
 		-->
 		<method name="ChangeLoginPolicy">
 			<arg name="login_policy" type="s" direction="in"/>
@@ -154,4 +439,228 @@
 		</method>
 
 	</interface>
+
+	<!--
+	  org.freedesktop.realmd.Kerberos:
+	  @short_description: a kerberos realm
+
+	  An interface that describes a kerberos realm in more detail. This
+	  is always implemented on an DBus object path that also implements
+	  the #org.freedesktop.realmd.Realm interface.
+	-->
+	<interface name="org.freedesktop.realmd.Kerberos">
+
+		<!--
+		  RealmName: the kerberos realm name
+
+		  The kerberos name for this realm. This is usually in upper
+		  case.
+		-->
+		<property name="RealmName" type="s" access="read"/>
+
+		<!--
+		  DomainName: the DNS domain name
+
+		  The DNS domain name for this realm.
+		-->
+		<property name="DomainName" type="s" access="read"/>
+
+	</interface>
+
+	<!--
+	  org.freedesktop.realmd.KerberosMembership:
+
+	  An interface used to configure this machine by joining a realm.
+
+	  It sets up a computer/host account in the realm for this machine
+	  and a keytab to track the credentials for that account.
+
+	  The various properties are guaranteed to have been updated before
+	  the operation methods return, if they change state.
+	-->
+	<interface name="org.freedesktop.realmd.KerberosMembership">
+
+		<!--
+		  SuggestedAdministrator: common administrator name
+
+		  The common administrator name for this type of realm. This
+		  can be used by clients as a hint when prompting the user for
+		  administrative authentication.
+		-->
+		<property name="SuggestedAdministrator" type="s" access="read"/>
+
+		<!--
+		  SupportedJoinCredentials: credentials supported for joining
+
+		  Various kinds of credentials that are supported when calling the
+		  #org.freedesktop.realmd.Kerberos.Join() method.
+
+		  Each credential is represented by a type, and an owner. The type
+		  denotes which kind of credential is passed to the method. The
+		  owner indicates to the client how to prompt the user or obtain
+		  the credential, and to the service how to use the credential.
+
+		  The various types are:
+		  <itemizedlist>
+		    <listitem><para><literal>ccache</literal>:
+		      the credentials should contain an array of bytes as a
+		      <literal>ay</literal> containing the data from a kerberos
+		      credential cache file.</para></listitem>
+		    <listitem><para><literal>password</literal>:
+		      the credentials should contain a pair of strings as a
+		      <literal>(ss)</literal> representing a name and
+		      password. The name may contain a realm in the standard
+		      kerberos format. If missing, it will default to this
+		      realm. The name may be empty for a computer or one time
+		      password.</para></listitem>
+		    <listitem><para><literal>automatic</literal>:
+		      the credentials should contain an empty string as a
+		      <literal>s</literal>. Using <literal>automatic</literal>
+		      indicates that default or system credentials are to be
+		      used.</para></listitem>
+		  </itemizedlist>
+
+		  The various owners are:
+		  <itemizedlist>
+		    <listitem><para><literal>administrator</literal>:
+		      the credentials belong to a kerberos user principal.
+		      The caller may use this as a hint to prompt the user
+		      for administrative credentials.</para></listitem>
+		    <listitem><para><literal>user</literal>:
+		      the credentials belong to a kerberos user principal.
+		      The caller may use this as a hint to prompt the user
+		      for his (possibly non-administrative)
+		      credentials.</para></listitem>
+		    <listitem><para><literal>computer</literal>:
+		      the credentials belong to the computer realmd is
+		      being run on.</para></listitem>
+		    <listitem><para><literal>secret</literal>:
+		      the credentials are a one time password or other secret
+		      used to join or leave the computer.</para></listitem>
+		  </itemizedlist>
+		-->
+		<property name="SupportedJoinCredentials" type="a(ss)" access="read"/>
+
+		<!--
+		  SupportedLeaveCredentials: credentials supported for leaving
+
+		  Various kinds of credentials that are supported when calling the
+		  #org.freedesktop.realmd.Kerberos.Leave() method.
+
+		  See #org.freedesktop.realmd.Kerberos:SupportedJoinCredentials for
+		  a discussion of what the values represent.
+		-->
+		<property name="SupportedLeaveCredentials" type="a(ss)" access="read"/>
+
+		<!--
+		  Join:
+
+		  Join this machine to the realm and enroll the machine.
+
+		  If this method returns successfully then the machine will be
+		  joined to the realm. It is not necessary to restart services or the
+		  machine afterward. Relevant properties on the realm will be updated
+		  before the method returns.
+
+		  The @credentials should be set according to one of the
+		  supported credentials returned by
+		  #org.freedesktop.realmd.Kerberos:SupportedJoinCredentials.
+		  The first string in the tuple is the type, the second string
+		  is the owner, and the variant contains the credential contents
+		  See the discussion at
+		  #org.freedesktop.realmd.Kerberos:SupportedJoinCredentials
+		  for more information.
+
+		  @options can contain, but is not limited to, the following values:
+		  <itemizedlist>
+		    <listitem><para><literal>operation</literal>: a string
+		      identifier chosen by the client, which can then later be
+		      passed to org.freedesktop.realmd.Service.Cancel() in order
+		      to cancel the operation</para></listitem>
+		  </itemizedlist>
+
+		  This method requires authorization for the PolicyKit action
+		  called <literal>org.freedesktop.realmd.configure-realm</literal>.
+
+		  In addition to common DBus error results, this method may return:
+		  <itemizedlist>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Failed</literal>:
+		      may be returned if the join failed for a generic reason.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Cancelled</literal>:
+		      returned if the operation was cancelled.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.NotAuthorized</literal>:
+		      returned if the calling client is not permitted to perform an join
+		      operation.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.AuthenticationFailed</literal>:
+		      returned if the credentials passed did not authenticate against the realm
+		      correctly. It is appropriate to prompt the user again.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.AlreadyEnrolled</literal>:
+		      returned if already enrolled in this realm, or another realm and enrolling
+		      in multiple realms is not supported.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Busy</literal>:
+		      returned if the service is currently performing another operation like
+		      join or leave.</para></listitem>
+		  </itemizedlist>
+		-->
+		<method name="Join">
+			<arg name="credentials" type="(ssv)" direction="in"/>
+			<arg name="options" type="a{sv}" direction="in"/>
+		</method>
+
+		<!--
+		  Leave:
+
+		  Leave the realm and unenroll the machine.
+
+		  If this method returns successfully then the machine will have
+		  left the domain and been unenrolled. It is not necessary to restart
+		  services or the machine afterward. Relevant properties on the realm
+		  will be updated before the method returns.
+
+		  The @credentials should be set according to one of the
+		  supported credentials returned by
+		  #org.freedesktop.realmd.Kerberos:SupportedUnenrollCredentials.
+		  The first string in the tuple is the type, the second string
+		  is the owner, and the variant contains the credential contents
+		  See the discussion at
+		  #org.freedesktop.realmd.Kerberos:SupportedEnrollCredentials
+		  for more information.
+
+		  @options can contain, but is not limited to, the following values:
+		  <itemizedlist>
+		    <listitem><para><literal>operation</literal>: a string
+		      identifier chosen by the client, which can then later be
+		      passed to org.freedesktop.realmd.Service.Cancel() in order
+		      to cancel the operation</para></listitem>
+		  </itemizedlist>
+
+		  This method requires authorization for the PolicyKit action
+		  called <literal>org.freedesktop.realmd.deconfigure-realm</literal>.
+
+		  In addition to common DBus error results, this method may return:
+		  <itemizedlist>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Failed</literal>:
+		      may be returned if the unenroll failed for a generic reason.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Cancelled</literal>:
+		      returned if the operation was cancelled.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.NotAuthorized</literal>:
+		      returned if the calling client is not permitted to perform an unenroll
+		      operation.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.AuthenticationFailed</literal>:
+		      returned if the credentials passed did not authenticate against the realm
+		      correctly. It is appropriate to prompt the user again.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.NotEnrolled</literal>:
+		      returned if not enrolled in this realm.</para></listitem>
+		    <listitem><para><literal>org.freedesktop.realmd.Error.Busy</literal>:
+		      returned if the service is currently performing another operation like
+		      enroll or unenroll.</para></listitem>
+		  </itemizedlist>
+		-->
+		<method name="Leave">
+			<arg name="credentials" type="(ssv)" direction="in"/>
+			<arg name="options" type="a{sv}" direction="in"/>
+		</method>
+
+	</interface>
+
 </node>
diff --git a/src/goaidentity/um-realm-manager.c b/src/goaidentity/um-realm-manager.c
index 4ff40d8..f4fec71 100644
--- a/src/goaidentity/um-realm-manager.c
+++ b/src/goaidentity/um-realm-manager.c
@@ -37,9 +37,9 @@
 
 
 struct _UmRealmManager {
-        UmRealmProviderProxy parent;
+        UmRealmObjectManagerClient parent;
+        UmRealmProvider *provider;
         guint diagnostics_sig;
-        GHashTable *realms;
 };
 
 typedef struct {
@@ -53,7 +53,7 @@ enum {
 
 static gint signals[NUM_SIGNALS] = { 0, };
 
-G_DEFINE_TYPE (UmRealmManager, um_realm_manager, UM_REALM_TYPE_PROVIDER_PROXY);
+G_DEFINE_TYPE (UmRealmManager, um_realm_manager, UM_REALM_TYPE_OBJECT_MANAGER_CLIENT);
 
 GQuark
 um_realm_error_get_quark (void)
@@ -64,172 +64,49 @@ um_realm_error_get_quark (void)
         return quark;
 }
 
-typedef struct {
-        UmRealmManager *manager;
-        GList *realms;
-        gint outstanding;
-} LoadClosure;
-
-static void
-load_closure_free (gpointer data)
-{
-        LoadClosure *load = data;
-        g_list_free_full (load->realms, g_object_unref);
-        g_object_unref (load->manager);
-        g_slice_free (LoadClosure, load);
-}
-
-static void
-on_realm_proxy_created (GObject *source,
-                        GAsyncResult *result,
-                        gpointer user_data)
+static gboolean
+is_realm_with_kerberos_and_membership (gpointer object)
 {
-        GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
-        LoadClosure *load = g_simple_async_result_get_op_res_gpointer (async);
-        UmRealmManager *self = load->manager;
-        UmRealmKerberos *realm;
-        UmRealmKerberos *have;
-        GError *error = NULL;
-        GDBusProxy *proxy;
-        GVariant *info;
+        GDBusInterface *interface;
 
-        realm = um_realm_kerberos_proxy_new_finish (result, &error);
-        if (error == NULL) {
-                proxy = G_DBUS_PROXY (realm);
-                info = g_variant_new ("(os)",
-                                      g_dbus_proxy_get_object_path (proxy),
-                                      g_dbus_proxy_get_interface_name (proxy));
-
-                /* Add it to the manager, unless race */
-                have = g_hash_table_lookup (self->realms, info);
-                if (have == NULL) {
-                        g_dbus_proxy_set_default_timeout (proxy, G_MAXINT);
-                        g_hash_table_insert (self->realms,
-                                             g_variant_ref_sink (info), realm);
-                        g_signal_emit (self, signals[REALM_ADDED], 0, realm);
-
-                } else {
-                        g_object_unref (realm);
-                        g_variant_unref (info);
-                        realm = have;
-                }
-
-                load->realms = g_list_prepend (load->realms, g_object_ref (realm));
+        if (!G_IS_DBUS_OBJECT (object))
+                return FALSE;
 
-        } else {
-                g_simple_async_result_take_error (async, error);
-        }
+        interface = g_dbus_object_get_interface (object, "org.freedesktop.realmd.Kerberos");
+        if (interface == NULL)
+                return FALSE;
+        g_object_unref (interface);
 
-        if (load->outstanding-- == 1)
-                g_simple_async_result_complete (async);
+        interface = g_dbus_object_get_interface (object, "org.freedesktop.realmd.KerberosMembership");
+        if (interface == NULL)
+                return FALSE;
+        g_object_unref (interface);
 
-        g_object_unref (async);
+        return TRUE;
 }
 
 static void
-um_realm_manager_load (UmRealmManager *self,
-                       GVariant *realms,
-                       GCancellable *cancellable,
-                       GAsyncReadyCallback callback,
-                       gpointer user_data)
+on_interface_added (GDBusObjectManager *manager,
+                    GDBusObject *object,
+                    GDBusInterface *interface)
 {
-        GSimpleAsyncResult *async;
-        GDBusConnection *connection;
-        LoadClosure *load;
-        GVariantIter iter;
-        GVariant *info;
-        UmRealmKerberos *realm;
-        const gchar *path;
-        const gchar *iface;
-
-        g_return_if_fail (realms != NULL);
-
-        async = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
-                                           um_realm_manager_load);
-        load = g_slice_new0 (LoadClosure);
-        load->manager = g_object_ref (self);
-        g_simple_async_result_set_op_res_gpointer (async, load, load_closure_free);
-
-        connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (self));
-
-        g_variant_iter_init (&iter, realms);
-        while (1) {
-                info = g_variant_iter_next_value (&iter);
-                if (info == NULL)
-                        break;
-                realm = g_hash_table_lookup (self->realms, info);
-                if (realm == NULL) {
-                        g_variant_get (info, "(&o&s)", &path, &iface);
-                        if (g_str_equal (iface, "org.freedesktop.realmd.Kerberos")) {
-                                um_realm_kerberos_proxy_new (connection,
-                                                             G_DBUS_PROXY_FLAGS_NONE,
-                                                             "org.freedesktop.realmd",
-                                                             path, cancellable,
-                                                             on_realm_proxy_created,
-                                                             g_object_ref (async));
-                                load->outstanding++;
-                        }
-                } else {
-                        load->realms = g_list_prepend (load->realms, g_object_ref (realm));
-                }
-                g_variant_unref (info);
-        }
-
-        if (load->outstanding == 0)
-                g_simple_async_result_complete_in_idle (async);
-
-        g_object_unref (async);
-}
-
-static GList *
-um_realm_manager_load_finish (UmRealmManager *self,
-                              GAsyncResult *result,
-                              GError **error)
-{
-        GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (result);
-        LoadClosure *load;
-        GList *realms;
-
-        if (g_simple_async_result_propagate_error (async, error))
-                return NULL;
-
-        load = g_simple_async_result_get_op_res_gpointer (async);
-        realms = g_list_reverse (load->realms);
-        load->realms = NULL;
-        return realms;
-}
-
-static guint
-hash_realm_info (gconstpointer value)
-{
-        const gchar *path, *iface;
-        g_variant_get ((GVariant *)value, "(&o&s)", &path, &iface);
-        return g_str_hash (path) ^ g_str_hash (iface);
+        g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (interface), G_MAXINT);
 }
 
 static void
-um_realm_manager_init (UmRealmManager *self)
+on_object_added (GDBusObjectManager *manager,
+                 GDBusObject *object,
+                 gpointer user_data)
 {
-        self->realms = g_hash_table_new_full (hash_realm_info, g_variant_equal,
-                                              (GDestroyNotify)g_variant_unref,
-                                              g_object_unref);
+        if (is_realm_with_kerberos_and_membership (object))
+                g_signal_emit (user_data, signals[REALM_ADDED], 0, object);
 }
 
 static void
-um_realm_manager_notify (GObject *obj,
-                         GParamSpec *spec)
+um_realm_manager_init (UmRealmManager *self)
 {
-        UmRealmManager *self = UM_REALM_MANAGER (obj);
-        GVariant *realms;
-
-        if (G_OBJECT_CLASS (um_realm_manager_parent_class)->notify)
-                G_OBJECT_CLASS (um_realm_manager_parent_class)->notify (obj, spec);
-
-        if (g_str_equal (spec->name, "realms")) {
-                realms = um_realm_provider_get_realms (UM_REALM_PROVIDER (self));
-                if (realms != NULL)
-                        um_realm_manager_load (self, realms, NULL, NULL, NULL);
-        }
+        g_signal_connect (self, "object-added", G_CALLBACK (on_object_added), self);
+        g_signal_connect (self, "interface-added", G_CALLBACK (on_interface_added), self);
 }
 
 static void
@@ -238,8 +115,10 @@ um_realm_manager_dispose (GObject *obj)
         UmRealmManager *self = UM_REALM_MANAGER (obj);
         GDBusConnection *connection;
 
+        g_clear_object (&self->provider);
+
         if (self->diagnostics_sig) {
-                connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (self));
+                connection = g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (self));
                 if (connection != NULL)
                         g_dbus_connection_signal_unsubscribe (connection, self->diagnostics_sig);
                 self->diagnostics_sig = 0;
@@ -249,28 +128,16 @@ um_realm_manager_dispose (GObject *obj)
 }
 
 static void
-um_realm_manager_finalize (GObject *obj)
-{
-        UmRealmManager *self = UM_REALM_MANAGER (obj);
-
-        g_hash_table_destroy (self->realms);
-
-        G_OBJECT_CLASS (um_realm_manager_parent_class)->finalize (obj);
-}
-
-static void
 um_realm_manager_class_init (UmRealmManagerClass *klass)
 {
         GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-        object_class->notify = um_realm_manager_notify;
         object_class->dispose = um_realm_manager_dispose;
-        object_class->finalize = um_realm_manager_finalize;
 
         signals[REALM_ADDED] = g_signal_new ("realm-added", UM_TYPE_REALM_MANAGER,
                                              G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
                                              g_cclosure_marshal_generic,
-                                             G_TYPE_NONE, 1, UM_REALM_TYPE_KERBEROS);
+                                             G_TYPE_NONE, 1, UM_REALM_TYPE_OBJECT);
 }
 
 static void
@@ -324,80 +191,19 @@ version_compare (const char *version,
         return match;
 }
 
-static void
-on_realm_manager_async_init (GObject *source,
-                             GAsyncResult *result,
-                             gpointer user_data)
-{
-        GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
-        UmRealmManager *self;
-        GError *error = NULL;
-        const gchar *version;
-        GDBusProxy *proxy;
-        GObject *object;
-        guint sig;
-
-        object = g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, &error);
-
-        if (error != NULL)
-                g_simple_async_result_take_error (async, error);
-
-        /* This is temporary until the dbus interface stabilizes */
-        if (object) {
-                version = um_realm_provider_get_version (UM_REALM_PROVIDER (object));
-                if (!version_compare (version, 0, 6)) {
-                        /* No need to bother translators with this temporary message */
-                        g_simple_async_result_set_error (async, UM_REALM_ERROR,
-                                                         UM_REALM_ERROR_GENERIC,
-                                                         "Unsupported version of realmd: %s", version);
-                        g_object_unref (object);
-                        object = NULL;
-                }
-        }
-
-        if (object != NULL) {
-                proxy = G_DBUS_PROXY (object);
-                sig = g_dbus_connection_signal_subscribe (g_dbus_proxy_get_connection (proxy),
-                                                          "org.freedesktop.realmd",
-                                                          "org.freedesktop.realmd.Service",
-                                                          "Diagnostics",
-                                                          NULL,
-                                                          NULL,
-                                                          G_DBUS_SIGNAL_FLAGS_NONE,
-                                                          on_realm_diagnostics,
-                                                          NULL,
-                                                          NULL);
-
-                self = UM_REALM_MANAGER (object);
-                self->diagnostics_sig = sig;
-                g_simple_async_result_set_op_res_gpointer (async, self, g_object_unref);
-        }
-
-        g_simple_async_result_complete (async);
-        g_object_unref (async);
-}
-
 void
 um_realm_manager_new (GCancellable *cancellable,
                       GAsyncReadyCallback callback,
                       gpointer user_data)
 {
-        GSimpleAsyncResult *async;
-
-        async = g_simple_async_result_new (NULL, callback, user_data,
-                                           um_realm_manager_new);
-
-        g_async_initable_new_async (UM_TYPE_REALM_MANAGER,
-                                    G_PRIORITY_DEFAULT, cancellable,
-                                    on_realm_manager_async_init, g_object_ref (async),
-                                    "g-name", "org.freedesktop.realmd",
-                                    "g-bus-type", G_BUS_TYPE_SYSTEM,
-                                    "g-object-path", "/org/freedesktop/realmd",
-                                    "g-interface-name", "org.freedesktop.realmd.Provider",
-                                    "g-default-timeout", G_MAXINT,
+        g_async_initable_new_async (UM_TYPE_REALM_MANAGER, G_PRIORITY_DEFAULT,
+                                    cancellable, callback, user_data,
+                                    "flags", G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+                                    "name", "org.freedesktop.realmd",
+                                    "bus-type", G_BUS_TYPE_SYSTEM,
+                                    "object-path", "/org/freedesktop/realmd",
+                                    "get-proxy-type-func", um_realm_object_manager_client_get_proxy_type,
                                     NULL);
-
-        g_object_unref (async);
 }
 
 UmRealmManager *
@@ -405,23 +211,63 @@ um_realm_manager_new_finish (GAsyncResult *result,
                              GError **error)
 {
         UmRealmManager *self;
-        GSimpleAsyncResult *async;
+        GDBusConnection *connection;
+        GObject *source_object;
+        const gchar *version;
+        GObject *ret;
+        guint sig;
 
-        g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
-                              um_realm_manager_new), NULL);
-        g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+        source_object = g_async_result_get_source_object (result);
+        ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error);
+        g_object_unref (source_object);
 
-        async = G_SIMPLE_ASYNC_RESULT (result);
-        if (g_simple_async_result_propagate_error (async, error))
+        if (ret == NULL)
+                return NULL;
+
+        self = UM_REALM_MANAGER (ret);
+        connection = g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (self));
+
+        /*
+         * TODO: Remove this version checking. This is temporary code, so
+         * just use sync here. Shortly we'll be stabilizing the realmd
+         * interfaces.
+         */
+
+        self->provider = um_realm_provider_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
+                                                           "org.freedesktop.realmd",
+                                                           "/org/freedesktop/realmd",
+                                                           NULL, error);
+        if (self->provider == NULL) {
+                g_object_unref (self);
+                return NULL;
+        }
+
+        version = um_realm_provider_get_version (self->provider);
+        if (!version_compare (version, 0, 7)) {
+                /* No need to bother translators with this temporary message */
+                g_set_error (error, UM_REALM_ERROR, UM_REALM_ERROR_GENERIC,
+                             "Unsupported version of realmd: %s", version);
+                g_object_unref (self);
                 return NULL;
+        }
+
+        sig = g_dbus_connection_signal_subscribe (connection,
+                                                  "org.freedesktop.realmd",
+                                                  "org.freedesktop.realmd.Service",
+                                                  "Diagnostics",
+                                                  NULL,
+                                                  NULL,
+                                                  G_DBUS_SIGNAL_FLAGS_NONE,
+                                                  on_realm_diagnostics,
+                                                  NULL,
+                                                  NULL);
+        self->diagnostics_sig = sig;
 
-        self = g_simple_async_result_get_op_res_gpointer (async);
-        if (self != NULL)
-                g_object_ref (self);
         return self;
 }
 
 typedef struct {
+        GDBusObjectManager *manager;
         GCancellable *cancellable;
         GList *realms;
 } DiscoverClosure;
@@ -430,46 +276,35 @@ static void
 discover_closure_free (gpointer data)
 {
         DiscoverClosure *discover = data;
+        g_object_unref (discover->manager);
         g_clear_object (&discover->cancellable);
         g_list_free_full (discover->realms, g_object_unref);
         g_slice_free (DiscoverClosure, discover);
 }
 
 static void
-on_manager_load (GObject *source,
-                 GAsyncResult *result,
-                 gpointer user_data)
-{
-        GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
-        DiscoverClosure *discover = g_simple_async_result_get_op_res_gpointer (async);
-        GError *error = NULL;
-
-        discover->realms = um_realm_manager_load_finish (UM_REALM_MANAGER (source),
-                                                         result, &error);
-        if (error != NULL)
-                g_simple_async_result_take_error (async, error);
-        g_simple_async_result_complete (async);
-
-        g_object_unref (async);
-}
-
-static void
 on_provider_discover (GObject *source,
                       GAsyncResult *result,
                       gpointer user_data)
 {
         GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
         DiscoverClosure *discover = g_simple_async_result_get_op_res_gpointer (async);
-        UmRealmManager *self = UM_REALM_MANAGER (source);
+        GDBusObject *object;
         GError *error = NULL;
-        GVariant *realms;
+        gchar **realms;
         gint relevance;
+        gint i;
 
-        um_realm_provider_call_discover_finish (UM_REALM_PROVIDER (self),
-                                                &relevance, &realms, result, &error);
+        um_realm_provider_call_discover_finish (UM_REALM_PROVIDER (source), &relevance,
+                                                &realms, result, &error);
         if (error == NULL) {
-                um_realm_manager_load (self, realms, discover->cancellable,
-                                       on_manager_load, g_object_ref (async));
+                for (i = 0; realms[i]; i++) {
+                        object = g_dbus_object_manager_get_object (discover->manager, realms[i]);
+                        if (object == NULL)
+                                g_warning ("Realm is not in object manager: %s", realms[i]);
+                        else
+                                discover->realms = g_list_prepend (discover->realms, object);
+                }
 
         } else {
                 g_simple_async_result_take_error (async, error);
@@ -497,12 +332,13 @@ um_realm_manager_discover (UmRealmManager *self,
         res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
                                          um_realm_manager_discover);
         discover = g_slice_new0 (DiscoverClosure);
+        discover->manager = g_object_ref (self);
         discover->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
         g_simple_async_result_set_op_res_gpointer (res, discover, discover_closure_free);
 
 	options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
 
-        um_realm_provider_call_discover (UM_REALM_PROVIDER (self), input, options, cancellable,
+        um_realm_provider_call_discover (self->provider, input, options, cancellable,
                                          on_provider_discover, g_object_ref (res));
 
         g_object_unref (res);
@@ -533,7 +369,7 @@ um_realm_manager_discover_finish (UmRealmManager *self,
                 return NULL;
         }
 
-        realms = discover->realms;
+        realms = g_list_reverse (discover->realms);
         discover->realms = NULL;
         return realms;
 }
@@ -541,12 +377,75 @@ um_realm_manager_discover_finish (UmRealmManager *self,
 GList *
 um_realm_manager_get_realms (UmRealmManager *self)
 {
+        GList *objects;
+        GList *realms = NULL;
+        GList *l;
+
         g_return_val_if_fail (UM_IS_REALM_MANAGER (self), NULL);
-        return g_hash_table_get_values (self->realms);
+
+        objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self));
+        for (l = objects; l != NULL; l = g_list_next (l)) {
+                if (is_realm_with_kerberos_and_membership (l->data))
+                        realms = g_list_prepend (realms, g_object_ref (l->data));
+        }
+
+        g_list_free_full (objects, g_object_unref);
+        return realms;
+}
+
+static void
+string_replace (GString *string,
+                const gchar *find,
+                const gchar *replace)
+{
+        const gchar *at;
+        gssize pos;
+
+        at = strstr (string->str, find);
+        if (at != NULL) {
+                pos = at - string->str;
+                g_string_erase (string, pos, strlen (find));
+                g_string_insert (string, pos, replace);
+        }
+}
+
+gchar *
+um_realm_calculate_login (UmRealmCommon *realm,
+                          const gchar *username)
+{
+        GString *string;
+        const gchar *const *formats;
+        gchar *login = NULL;
+
+        formats = um_realm_common_get_login_formats (realm);
+        if (formats[0] != NULL) {
+                string = g_string_new (formats[0]);
+                string_replace (string, "%U", username);
+                string_replace (string, "%D", um_realm_common_get_name (realm));
+                login = g_string_free (string, FALSE);
+        }
+
+        return login;
+
+}
+
+gboolean
+um_realm_is_configured (UmRealmObject *realm)
+{
+        UmRealmCommon *common;
+        const gchar *configured;
+        gboolean is;
+
+        common = um_realm_object_get_common (realm);
+        configured = um_realm_common_get_configured (common);
+        is = configured != NULL && !g_str_equal (configured, "");
+        g_object_unref (common);
+
+        return is;
 }
 
 static const gchar *
-find_supported_credentials (UmRealmKerberos *realm,
+find_supported_credentials (UmRealmKerberosMembership *membership,
                             const gchar *owner)
 {
         const gchar *cred_owner;
@@ -554,7 +453,7 @@ find_supported_credentials (UmRealmKerberos *realm,
         GVariant *supported;
         GVariantIter iter;
 
-        supported = um_realm_kerberos_get_supported_enroll_credentials (realm);
+        supported = um_realm_kerberos_membership_get_supported_join_credentials (membership);
         g_return_val_if_fail (supported != NULL, NULL);
 
         g_variant_iter_init (&iter, supported);
@@ -582,7 +481,7 @@ on_realm_join_complete (GObject *source,
 }
 
 static gboolean
-realm_join_as_owner (UmRealmKerberos *realm,
+realm_join_as_owner (UmRealmObject *realm,
                      const gchar *owner,
                      const gchar *login,
                      const gchar *password,
@@ -591,15 +490,21 @@ realm_join_as_owner (UmRealmKerberos *realm,
                      GAsyncReadyCallback callback,
                      gpointer user_data)
 {
+        UmRealmKerberosMembership *membership;
         GSimpleAsyncResult *async;
         GVariant *contents;
         GVariant *options;
         GVariant *creds;
         const gchar *type;
 
-        type = find_supported_credentials (realm, owner);
-        if (type == NULL)
+        membership = um_realm_object_get_kerberos_membership (realm);
+        g_return_val_if_fail (membership != NULL, FALSE);
+
+        type = find_supported_credentials (membership, owner);
+        if (type == NULL) {
+                g_object_unref (membership);
                 return FALSE;
+        }
 
         async = g_simple_async_result_new (G_OBJECT (realm), callback, user_data,
                                            realm_join_as_owner);
@@ -620,16 +525,18 @@ realm_join_as_owner (UmRealmKerberos *realm,
         creds = g_variant_new ("(ssv)", type, owner, contents);
         options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
 
-        um_realm_kerberos_call_enroll (realm, creds, options,
-                                       cancellable, on_realm_join_complete, g_object_ref (async));
+        um_realm_kerberos_membership_call_join (membership, creds, options,
+                                                cancellable, on_realm_join_complete,
+                                                g_object_ref (async));
 
         g_object_unref (async);
+        g_object_unref (membership);
 
         return TRUE;
 }
 
 gboolean
-um_realm_join_as_user (UmRealmKerberos *realm,
+um_realm_join_as_user (UmRealmObject *realm,
                        const gchar *login,
                        const gchar *password,
                        GBytes *credentials,
@@ -637,19 +544,19 @@ um_realm_join_as_user (UmRealmKerberos *realm,
                        GAsyncReadyCallback callback,
                        gpointer user_data)
 {
-        g_return_val_if_fail (UM_REALM_IS_KERBEROS (realm), FALSE);
+        g_return_val_if_fail (UM_REALM_IS_OBJECT (realm), FALSE);
         g_return_val_if_fail (credentials != NULL, FALSE);
         g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
         g_return_val_if_fail (login != NULL, FALSE);
         g_return_val_if_fail (password != NULL, FALSE);
         g_return_val_if_fail (credentials != NULL, FALSE);
 
-        return realm_join_as_owner (realm, "user", login, password, credentials,
-                                    cancellable, callback, user_data);
+        return realm_join_as_owner (realm, "user", login, password,
+                                    credentials, cancellable, callback, user_data);
 }
 
 gboolean
-um_realm_join_as_admin (UmRealmKerberos *realm,
+um_realm_join_as_admin (UmRealmObject *realm,
                         const gchar *login,
                         const gchar *password,
                         GBytes *credentials,
@@ -657,7 +564,7 @@ um_realm_join_as_admin (UmRealmKerberos *realm,
                         GAsyncReadyCallback callback,
                         gpointer user_data)
 {
-        g_return_val_if_fail (UM_REALM_IS_KERBEROS (realm), FALSE);
+        g_return_val_if_fail (UM_REALM_IS_OBJECT (realm), FALSE);
         g_return_val_if_fail (credentials != NULL, FALSE);
         g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
         g_return_val_if_fail (login != NULL, FALSE);
@@ -669,19 +576,25 @@ um_realm_join_as_admin (UmRealmKerberos *realm,
 }
 
 gboolean
-um_realm_join_finish (UmRealmKerberos *self,
+um_realm_join_finish (UmRealmObject *realm,
                       GAsyncResult *result,
                       GError **error)
 {
+        UmRealmKerberosMembership *membership;
         GError *call_error = NULL;
         gchar *dbus_error;
         GAsyncResult *async;
 
-        g_return_val_if_fail (UM_REALM_IS_KERBEROS (self), FALSE);
+        g_return_val_if_fail (UM_REALM_IS_OBJECT (realm), FALSE);
         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
+        membership = um_realm_object_get_kerberos_membership (realm);
+        g_return_val_if_fail (membership != NULL, FALSE);
+
         async = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
-        um_realm_kerberos_call_enroll_finish (self, async, &call_error);
+        um_realm_kerberos_membership_call_join_finish (membership, async, &call_error);
+        g_object_unref (membership);
+
         if (call_error == NULL)
                 return TRUE;
 
@@ -693,7 +606,7 @@ um_realm_join_finish (UmRealmKerberos *self,
 
         g_dbus_error_strip_remote_error (call_error);
 
-        if (g_str_equal (dbus_error, "org.freedesktop.realmd.Error.AuthFailed")) {
+        if (g_str_equal (dbus_error, "org.freedesktop.realmd.Error.AuthenticationFailed")) {
                 g_set_error (error, UM_REALM_ERROR, UM_REALM_ERROR_BAD_LOGIN,
                              "%s", call_error->message);
                 g_error_free (call_error);
@@ -851,8 +764,7 @@ kinit_thread_func (GSimpleAsyncResult *async,
 }
 
 void
-um_realm_login (const gchar *realm,
-                const gchar *domain,
+um_realm_login (UmRealmObject *realm,
                 const gchar *user,
                 const gchar *password,
                 GCancellable *cancellable,
@@ -861,17 +773,21 @@ um_realm_login (const gchar *realm,
 {
         GSimpleAsyncResult *async;
         LoginClosure *login;
+        UmRealmKerberos *kerberos;
 
-        g_return_if_fail (realm != NULL);
+        g_return_if_fail (UM_REALM_IS_OBJECT (realm));
         g_return_if_fail (user != NULL);
         g_return_if_fail (password != NULL);
         g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
+        kerberos = um_realm_object_get_kerberos (realm);
+        g_return_if_fail (kerberos != NULL);
+
         async = g_simple_async_result_new (NULL, callback, user_data,
                                            um_realm_login);
         login = g_slice_new0 (LoginClosure);
-        login->domain = g_strdup (domain ? domain : realm);
-        login->realm = g_strdup (realm);
+        login->domain = g_strdup (um_realm_kerberos_get_domain_name (kerberos));
+        login->realm = g_strdup (um_realm_kerberos_get_realm_name (kerberos));
         login->user = g_strdup (user);
         login->password = g_strdup (password);
         g_simple_async_result_set_op_res_gpointer (async, login, login_closure_free);
@@ -881,6 +797,7 @@ um_realm_login (const gchar *realm,
                                              G_PRIORITY_DEFAULT, cancellable);
 
         g_object_unref (async);
+        g_object_unref (kerberos);
 }
 
 gboolean
diff --git a/src/goaidentity/um-realm-manager.h b/src/goaidentity/um-realm-manager.h
index c5ffea3..a604fae 100644
--- a/src/goaidentity/um-realm-manager.h
+++ b/src/goaidentity/um-realm-manager.h
@@ -63,8 +63,7 @@ GList *          um_realm_manager_discover_finish (UmRealmManager *self,
 
 GList *          um_realm_manager_get_realms      (UmRealmManager *self);
 
-void             um_realm_login                   (const gchar *realm_name,
-                                                   const gchar *domain,
+void             um_realm_login                   (UmRealmObject *realm,
                                                    const gchar *login,
                                                    const gchar *password,
                                                    GCancellable *cancellable,
@@ -75,7 +74,7 @@ gboolean         um_realm_login_finish            (GAsyncResult *result,
                                                    GBytes **credentials,
                                                    GError **error);
 
-gboolean         um_realm_join_as_user            (UmRealmKerberos *realm,
+gboolean         um_realm_join_as_user            (UmRealmObject *realm,
                                                    const gchar *login,
                                                    const gchar *password,
                                                    GBytes *credentials,
@@ -84,7 +83,7 @@ gboolean         um_realm_join_as_user            (UmRealmKerberos *realm,
                                                    gpointer user_data)
                                                    G_GNUC_WARN_UNUSED_RESULT;
 
-gboolean         um_realm_join_as_admin           (UmRealmKerberos *realm,
+gboolean         um_realm_join_as_admin           (UmRealmObject *realm,
                                                    const gchar *login,
                                                    const gchar *password,
                                                    GBytes *credentials,
@@ -93,10 +92,14 @@ gboolean         um_realm_join_as_admin           (UmRealmKerberos *realm,
                                                    gpointer user_data)
                                                    G_GNUC_WARN_UNUSED_RESULT;
 
-gboolean         um_realm_join_finish             (UmRealmKerberos *self,
+gboolean         um_realm_join_finish             (UmRealmObject *realm,
                                                    GAsyncResult *result,
                                                    GError **error);
 
+gboolean         um_realm_is_configured           (UmRealmObject *realm);
+
+gchar *          um_realm_calculate_login         (UmRealmCommon *realm,
+                                                   const gchar *username);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]