[gnome-control-center] user-panel: Update to new DBus interface for realmd 0.6



commit 1f4aeb1d05c24af428294b5955d36456d0a3544e
Author: Stef Walter <stefw gnome org>
Date:   Tue Jul 31 09:17:34 2012 +0200

    user-panel: Update to new DBus interface for realmd 0.6
    
     * In particular support of different credential methods and better
       hints for different owners of those credentials, so we can prompt
       more cleanly.
     * Less abstraction in the realmd interfaces
    
    https://bugzilla.gnome.org/show_bug.cgi?id=680892

 .../user-accounts/data/org.freedesktop.realmd.xml  |  101 +++++-------
 panels/user-accounts/um-account-dialog.c           |   47 ++++--
 panels/user-accounts/um-realm-manager.c            |  169 ++++++++++++++++----
 panels/user-accounts/um-realm-manager.h            |   16 ++-
 4 files changed, 224 insertions(+), 109 deletions(-)
---
diff --git a/panels/user-accounts/data/org.freedesktop.realmd.xml b/panels/user-accounts/data/org.freedesktop.realmd.xml
index 92b8861..18f1324 100644
--- a/panels/user-accounts/data/org.freedesktop.realmd.xml
+++ b/panels/user-accounts/data/org.freedesktop.realmd.xml
@@ -25,11 +25,10 @@
 		<!--
 		 * A list of known, enrolled or discovered realms.
 		 * Each realm is a DBus object and is represeted by a:
-		 *   s: DBus bus name of the realm
 		 *   o: DBus object path of the realm
 		 *   s: DBus interface name, like 'ofr.Kerberos' (below)
 		-->
-		<property name="Realms" type="a(sos)" access="read"/>
+		<property name="Realms" type="a(os)" access="read"/>
 
 		<!--
 		 * Discover whether a string represents a realm that a provider
@@ -38,29 +37,40 @@
 		<method name="Discover">
 			<!-- The input string -->
 			<arg name="string" type="s" direction="in"/>
-
-			<arg name="operation_id" 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(sos)" direction="out"/>
+			<arg name="realm" type="a(os)" direction="out"/>
 		</method>
 	</interface>
 
-	<!--
-	 * This interface is implemented by Providers and Realms to provide
-	 * additional information when an long running operation is happening
-	 *
-	 * In particular you can connect to the "Diagnostics" signal when
-	 * during an enroll or unenroll to get details.
-	-->
-	<interface name="org.freedesktop.realmd.Diagnostics">
+	<interface name="org.freedesktop.realmd.Service">
+		<method name="Cancel">
+			<arg name="operation_id" type="s" direction="in"/>
+		</method>
+
+		<method name="SetLocale">
+			<arg name="locale" type="s" direction="in"/>
+		</method>
+
 		<signal name="Diagnostics">
 			<arg name="data" type="s"/>
 			<arg name="operation_id" 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.
+		-->
+		<method name="Release">
+			<!-- no arguments -->
+		</method>
 	</interface>
 
 	<!--
@@ -94,51 +104,23 @@
 		<property name="Enrolled" type="b" access="read"/>
 
 		<!--
-		 * Enroll the machine in this realm using an administrative
-		 * account and a password.
+		 * Credentials: (ssv)
+		 *  type: 'ccache', 'password', 'automatic'
+		 *  owner: 'administrator', 'user', 'computer', 'secret'
+		 *  contents: ay, ss, b
 		-->
-		<method name="EnrollWithPassword">
-			<arg name="principal" type="s" direction="in"/>
-			<arg name="password" type="s" direction="in"/>
-			<arg name="options" type="a{sv}" direction="in"/>
-			<arg name="operation_id" type="s" direction="in"/>
-		</method>
+		<property name="SupportedEnrollCredentials" type="a(ss)" access="read"/>
 
-		<!--
-		 * Enroll the machine in this realm using kerberos cached
-		 * administrative credentials.
-		-->
-		<method name="EnrollWithCredentialCache">
-			<!-- The contents of a kerberos cache file containing administrative credentials -->
-			<arg name="kerberos_cache" type="ay" direction="in">
-				<annotation name="org.gtk.GDBus.C.ForceGVariant" value="yup"/>
-			</arg>
-			<arg name="options" type="a{sv}" direction="in"/>
-			<arg name="operation_id" type="s" direction="in"/>
-		</method>
+		<property name="SupportedUnenrollCredentials" type="a(ss)" access="read"/>
 
-		<!--
-		 * Unenroll the machine from this realm using an administrative
-		 * account and a password.
-		-->
-		<method name="UnenrollWithPassword">
-			<arg name="principal" type="s" direction="in"/>
-			<arg name="password" type="s" direction="in"/>
+		<method name="Enroll">
+			<arg name="credentials" type="(ssv)" direction="in"/>
 			<arg name="options" type="a{sv}" direction="in"/>
-			<arg name="operation_id" type="s" direction="in"/>
 		</method>
 
-		<!--
-		 * Unenroll the machine from this realm using a kerberos cached
-		 * administrative credentials.
-		-->
-		<method name="UnenrollWithCredentialCache">
-			<!-- The contents of a kerberos cache file containing administrative credentials -->
-			<arg name="kerberos_cache" type="ay" direction="in">
-				<annotation name="org.gtk.GDBus.C.ForceGVariant" value="yup"/>
-			</arg>
+		<method name="Unenroll">
+			<arg name="credentials" type="(ssv)" direction="in"/>
 			<arg name="options" type="a{sv}" direction="in"/>
-			<arg name="operation_id" type="s" direction="in"/>
 		</method>
 
 		<!--
@@ -150,18 +132,25 @@
 		<property name="LoginFormat" type="s" access="read"/>
 
 		<!--
+		 * The policy for logins using this realm.
+		 * 'allow-any-login' 'allow-permitted-logins' 'deny-any-login'
+		-->
+		<property name="LoginPolicy" type="s" access="read"/>
+
+		<!--
 		 * The list of permitted logins in the LoginFormat style
 		-->
 		<property name="PermittedLogins" type="as" access="read"/>
 
 		<!--
 		 * Change the PermittedLogins property. Should take effect
-		 * immediately. Some providers may not enforce this :S
+		 * immediately.
 		-->
-		<method name="ChangePermittedLogins">
-			<arg name="add" type="as" direction="in"/>
-			<arg name="remove" type="as" direction="in"/>
-			<arg name="operation_id" type="s" direction="in"/>
+		<method name="ChangeLoginPolicy">
+			<arg name="login_policy" type="s" direction="in"/>
+			<arg name="permitted_add" type="as" direction="in"/>
+			<arg name="permitted_remove" type="as" direction="in"/>
+			<arg name="options" type="a{sv}" direction="in"/>
 		</method>
 
 	</interface>
diff --git a/panels/user-accounts/um-account-dialog.c b/panels/user-accounts/um-account-dialog.c
index cb02336..ac6880f 100644
--- a/panels/user-accounts/um-account-dialog.c
+++ b/panels/user-accounts/um-account-dialog.c
@@ -383,8 +383,8 @@ on_permit_user_login (GObject *source,
         GError *error = NULL;
         gchar *login;
 
-        um_realm_kerberos_call_change_permitted_logins_finish (UM_REALM_KERBEROS (source),
-                                                               result, &error);
+        um_realm_kerberos_call_change_login_policy_finish (UM_REALM_KERBEROS (source),
+                                                           result, &error);
         if (error == NULL) {
 
                 /*
@@ -416,6 +416,7 @@ enterprise_permit_user_login (UmAccountDialog *self)
         gchar *login;
         const gchar *add[2];
         const gchar *remove[1];
+        GVariant *options;
 
         login = enterprise_calculate_login (self);
 
@@ -423,12 +424,16 @@ enterprise_permit_user_login (UmAccountDialog *self)
         add[1] = NULL;
         remove[0] = NULL;
 
-        um_realm_kerberos_call_change_permitted_logins (self->selected_realm,
-                                                        add, remove, "",
-                                                        self->cancellable,
-                                                        on_permit_user_login,
-                                                        g_object_ref (self));
+        options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
 
+        um_realm_kerberos_call_change_login_policy (self->selected_realm, "",
+                                                    add, remove,
+                                                    g_variant_ref_sink (options),
+                                                    self->cancellable,
+                                                    on_permit_user_login,
+                                                    g_object_ref (self));
+
+        g_variant_unref (options);
         g_free (login);
 }
 
@@ -508,9 +513,16 @@ on_join_login (GObject *source,
 
         /* Logged in as admin successfully, use creds to join domain */
         if (error == NULL) {
-                um_realm_join (self->selected_realm,
-                               creds, self->cancellable, on_realm_joined,
-                               g_object_ref (self));
+                if (!um_realm_join_as_admin (self->selected_realm,
+                                             gtk_entry_get_text (self->join_name),
+                                             gtk_entry_get_text (self->join_password),
+                                             creds, self->cancellable, on_realm_joined,
+                                             g_object_ref (self))) {
+                        show_error_dialog (self, _("No supported way to authenticate with this domain"), NULL);
+                        g_message ("Authenticating as admin is not supported by the realm");
+                        finish_action (self);
+                }
+
                 g_bytes_unref (creds);
 
         /* Couldn't login as admin, show prompt again */
@@ -584,12 +596,15 @@ on_realm_login (GObject *source,
                         enterprise_permit_user_login (self);
 
                 /* Join the domain, try using the user's creds */
-                } else {
-                        um_realm_join (self->selected_realm,
-                                       creds,
-                                       self->cancellable,
-                                       on_realm_joined,
-                                       g_object_ref (self));
+                } else if (!um_realm_join_as_user (self->selected_realm,
+                                                   gtk_entry_get_text (self->enterprise_login),
+                                                   gtk_entry_get_text (self->enterprise_password),
+                                                   creds, self->cancellable,
+                                                   on_realm_joined,
+                                                   g_object_ref (self))) {
+
+                        /* If we can't do user aauth, try to authenticate as admin */
+                        join_show_prompt (self, NULL);
                 }
 
                 g_bytes_unref (creds);
diff --git a/panels/user-accounts/um-realm-manager.c b/panels/user-accounts/um-realm-manager.c
index 00c079f..bf3388b 100644
--- a/panels/user-accounts/um-realm-manager.c
+++ b/panels/user-accounts/um-realm-manager.c
@@ -96,8 +96,7 @@ on_realm_proxy_created (GObject *source,
         realm = um_realm_kerberos_proxy_new_finish (result, &error);
         if (error == NULL) {
                 proxy = G_DBUS_PROXY (realm);
-                info = g_variant_new ("(sos)",
-                                      g_dbus_proxy_get_name (proxy),
+                info = g_variant_new ("(os)",
                                       g_dbus_proxy_get_object_path (proxy),
                                       g_dbus_proxy_get_interface_name (proxy));
 
@@ -142,7 +141,6 @@ um_realm_manager_load (UmRealmManager *self,
         UmRealmKerberos *realm;
         const gchar *path;
         const gchar *iface;
-        const gchar *name;
 
         g_return_if_fail (realms != NULL);
 
@@ -161,11 +159,12 @@ um_realm_manager_load (UmRealmManager *self,
                         break;
                 realm = g_hash_table_lookup (self->realms, info);
                 if (realm == NULL) {
-                        g_variant_get (info, "(&s&o&s)", &name, &path, &iface);
+                        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,
-                                                             name, path, cancellable,
+                                                             "org.freedesktop.realmd",
+                                                             path, cancellable,
                                                              on_realm_proxy_created,
                                                              g_object_ref (async));
                                 load->outstanding++;
@@ -203,9 +202,9 @@ um_realm_manager_load_finish (UmRealmManager *self,
 static guint
 hash_realm_info (gconstpointer value)
 {
-        const gchar *name, *path, *iface;
-        g_variant_get ((GVariant *)value, "(&s&o&s)", &name, &path, &iface);
-        return g_str_hash (name) ^ g_str_hash (path) ^ g_str_hash (iface);
+        const gchar *path, *iface;
+        g_variant_get ((GVariant *)value, "(&o&s)", &path, &iface);
+        return g_str_hash (path) ^ g_str_hash (iface);
 }
 
 static void
@@ -346,7 +345,7 @@ on_realm_manager_async_init (GObject *source,
         /* 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, 2)) {
+                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,
@@ -359,8 +358,8 @@ on_realm_manager_async_init (GObject *source,
         if (object != NULL) {
                 proxy = G_DBUS_PROXY (object);
                 sig = g_dbus_connection_signal_subscribe (g_dbus_proxy_get_connection (proxy),
-                                                          g_dbus_proxy_get_name_owner (proxy),
-                                                          "org.freedesktop.realmd.Diagnostics",
+                                                          "org.freedesktop.realmd",
+                                                          "org.freedesktop.realmd.Service",
                                                           "Diagnostics",
                                                           NULL,
                                                           NULL,
@@ -489,6 +488,7 @@ um_realm_manager_discover (UmRealmManager *self,
 {
         GSimpleAsyncResult *res;
         DiscoverClosure *discover;
+        GVariant *options;
 
         g_return_if_fail (UM_IS_REALM_MANAGER (self));
         g_return_if_fail (input != NULL);
@@ -500,9 +500,13 @@ um_realm_manager_discover (UmRealmManager *self,
         discover->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
         g_simple_async_result_set_op_res_gpointer (res, discover, discover_closure_free);
 
-        um_realm_provider_call_discover (UM_REALM_PROVIDER (self), input, "", cancellable,
+	options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
+	g_variant_ref_sink (options);
+
+        um_realm_provider_call_discover (UM_REALM_PROVIDER (self), input, options, cancellable,
                                          on_provider_discover, g_object_ref (res));
 
+        g_variant_unref (options);
         g_object_unref (res);
 }
 
@@ -543,36 +547,131 @@ um_realm_manager_get_realms (UmRealmManager *self)
         return g_hash_table_get_values (self->realms);
 }
 
-void
-um_realm_join (UmRealmKerberos *realm,
-               GBytes *credentials,
-               GCancellable *cancellable,
-               GAsyncReadyCallback callback,
-               gpointer user_data)
+static const gchar *
+find_supported_credentials (UmRealmKerberos *realm,
+                            const gchar *owner)
+{
+        const gchar *cred_owner;
+        const gchar *cred_type;
+        GVariant *supported;
+        GVariantIter iter;
+
+        supported = um_realm_kerberos_get_supported_enroll_credentials (realm);
+        g_return_val_if_fail (supported != NULL, NULL);
+
+        g_variant_iter_init (&iter, supported);
+        while (g_variant_iter_loop (&iter, "(&s&s)", &cred_type, &cred_owner)) {
+        	g_printerr ("%s %s %s\n", cred_type, cred_owner, owner);
+                if (g_str_equal (owner, cred_owner)) {
+                        if (g_str_equal (cred_type, "ccache") ||
+                            g_str_equal (cred_type, "password")) {
+                                return g_intern_string (cred_type);
+                        }
+                }
+        }
+
+        return NULL;
+}
+
+static void
+on_realm_join_complete (GObject *source,
+                        GAsyncResult *result,
+                        gpointer user_data)
+{
+	GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
+	g_simple_async_result_set_op_res_gpointer (async, g_object_ref (result), g_object_unref);
+	g_simple_async_result_complete_in_idle (async);
+	g_object_unref (async);
+}
+
+static gboolean
+realm_join_as_owner (UmRealmKerberos *realm,
+                     const gchar *owner,
+                     const gchar *login,
+                     const gchar *password,
+                     GBytes *credentials,
+                     GCancellable *cancellable,
+                     GAsyncReadyCallback callback,
+                     gpointer user_data)
 {
+        GSimpleAsyncResult *async;
+        GVariant *contents;
         GVariant *options;
         GVariant *creds;
+        const gchar *type;
 
-        g_return_if_fail (UM_REALM_IS_KERBEROS (realm));
-        g_return_if_fail (credentials != NULL);
-        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+        type = find_supported_credentials (realm, owner);
+        if (type == NULL)
+                return FALSE;
+
+        async = g_simple_async_result_new (G_OBJECT (realm), callback, user_data,
+                                           realm_join_as_owner);
+
+        if (g_str_equal (type, "ccache")) {
+                contents = g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
+                                                    g_bytes_get_data (credentials, NULL),
+                                                    g_bytes_get_size (credentials),
+                                                    TRUE, (GDestroyNotify)g_bytes_unref, credentials);
+
+        } else if (g_str_equal (type, "password")) {
+                contents = g_variant_new ("(ss)", login, password);
+
+        } else {
+                g_assert_not_reached ();
+        }
 
-        creds = g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
-                                         g_bytes_get_data (credentials, NULL),
-                                         g_bytes_get_size (credentials),
-                                         TRUE, (GDestroyNotify)g_bytes_unref, credentials);
+        creds = g_variant_new ("(ss v)", type, owner, g_variant_new_variant (contents));
         options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
 
-        um_realm_kerberos_call_enroll_with_credential_cache (realm,
-                                                             g_variant_ref_sink (creds),
-                                                             g_variant_ref_sink (options),
-                                                             "",
-                                                             cancellable,
-                                                             callback,
-                                                             user_data);
+        um_realm_kerberos_call_enroll (realm, g_variant_ref_sink (creds),
+                                       g_variant_ref_sink (options),
+                                       cancellable, on_realm_join_complete, g_object_ref (async));
 
         g_variant_unref (options);
         g_variant_unref (creds);
+        g_object_unref (async);
+
+        return TRUE;
+}
+
+gboolean
+um_realm_join_as_user (UmRealmKerberos *realm,
+                       const gchar *login,
+                       const gchar *password,
+                       GBytes *credentials,
+                       GCancellable *cancellable,
+                       GAsyncReadyCallback callback,
+                       gpointer user_data)
+{
+        g_return_val_if_fail (UM_REALM_IS_KERBEROS (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);
+}
+
+gboolean
+um_realm_join_as_admin (UmRealmKerberos *realm,
+                        const gchar *login,
+                        const gchar *password,
+                        GBytes *credentials,
+                        GCancellable *cancellable,
+                        GAsyncReadyCallback callback,
+                        gpointer user_data)
+{
+        g_return_val_if_fail (UM_REALM_IS_KERBEROS (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, "administrator", login, password, credentials,
+                                    cancellable, callback, user_data);
 }
 
 gboolean
@@ -582,13 +681,13 @@ um_realm_join_finish (UmRealmKerberos *self,
 {
         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 (error == NULL || *error == NULL, FALSE);
 
-        um_realm_kerberos_call_enroll_with_credential_cache_finish (self,
-                                                                    result,
-                                                                    &call_error);
+        async = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+        um_realm_kerberos_call_enroll_finish (self, async, &call_error);
         if (call_error == NULL)
                 return TRUE;
 
diff --git a/panels/user-accounts/um-realm-manager.h b/panels/user-accounts/um-realm-manager.h
index 02e6e2d..c5ffea3 100644
--- a/panels/user-accounts/um-realm-manager.h
+++ b/panels/user-accounts/um-realm-manager.h
@@ -75,11 +75,23 @@ gboolean         um_realm_login_finish            (GAsyncResult *result,
                                                    GBytes **credentials,
                                                    GError **error);
 
-void             um_realm_join                    (UmRealmKerberos *realm,
+gboolean         um_realm_join_as_user            (UmRealmKerberos *realm,
+                                                   const gchar *login,
+                                                   const gchar *password,
                                                    GBytes *credentials,
                                                    GCancellable *cancellable,
                                                    GAsyncReadyCallback callback,
-                                                   gpointer user_data);
+                                                   gpointer user_data)
+                                                   G_GNUC_WARN_UNUSED_RESULT;
+
+gboolean         um_realm_join_as_admin           (UmRealmKerberos *realm,
+                                                   const gchar *login,
+                                                   const gchar *password,
+                                                   GBytes *credentials,
+                                                   GCancellable *cancellable,
+                                                   GAsyncReadyCallback callback,
+                                                   gpointer user_data)
+                                                   G_GNUC_WARN_UNUSED_RESULT;
 
 gboolean         um_realm_join_finish             (UmRealmKerberos *self,
                                                    GAsyncResult *result,



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