From 8bf99fad977d29a7144300bfa884dcff30dc0e2d Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Thu, 25 Apr 2013 12:58:20 +0200 Subject: [PATCH] Fallback to configured realms when discovering * If no discovered realms for a string, check locally configured realms to see if they're available locally, but just not online right now. * Reorganize how realms are enumerated on a provider, so that we can accomplish the above generically https://bugs.freedesktop.org/show_bug.cgi?id=62863 --- service/realm-all-provider.c | 47 +++++++++++++++++++++++------------ service/realm-kerberos.c | 21 ++++++++++++++++ service/realm-kerberos.h | 3 +++ service/realm-provider.c | 58 +++++++++++++++++++++++++++++++++++++++----- service/realm-provider.h | 6 +++-- 5 files changed, 111 insertions(+), 24 deletions(-) diff --git a/service/realm-all-provider.c b/service/realm-all-provider.c index d94fc47..e8e65c7 100644 --- a/service/realm-all-provider.c +++ b/service/realm-all-provider.c @@ -54,27 +54,27 @@ realm_all_provider_constructed (GObject *obj) } static void -update_realms_property (RealmAllProvider *self) +update_realms_property (RealmProvider *self) { - const gchar *const * paths; - GPtrArray *realms; + GPtrArray *paths; + GList *realms; GList *l; - gint i; - realms = g_ptr_array_new (); - for (l = self->providers; l != NULL; l = g_list_next (l)) { - paths = realm_provider_get_realms (l->data); - for (i = 0; paths != NULL && paths[i] != NULL; i++) - g_ptr_array_add (realms, (gchar *)paths[i]); - } + realms = realm_provider_get_realms (self); + + paths = g_ptr_array_new (); + for (l = realms; l != NULL; l = g_list_next (l)) + g_ptr_array_add (paths, (gchar *)g_dbus_object_get_object_path (l->data)); + g_ptr_array_add (paths, NULL); + + g_list_free (realms); - g_ptr_array_add (realms, NULL); - realm_provider_set_realms (REALM_PROVIDER (self), (const gchar **)realms->pdata); - g_ptr_array_free (realms, TRUE); + realm_provider_set_realm_paths (REALM_PROVIDER (self), (const gchar **)paths->pdata); + g_ptr_array_free (paths, TRUE); } static void -update_all_properties (RealmAllProvider *self) +update_all_properties (RealmProvider *self) { update_realms_property (self); } @@ -84,7 +84,7 @@ on_provider_notify (GObject *obj, GParamSpec *spec, gpointer user_data) { - RealmAllProvider *self = REALM_ALL_PROVIDER (user_data); + RealmProvider *self = REALM_PROVIDER (user_data); update_all_properties (self); } @@ -262,6 +262,20 @@ realm_all_provider_discover_finish (RealmProvider *provider, return realms; } +static GList * +realm_all_provider_get_realms (RealmProvider *provider) +{ + RealmAllProvider *self = REALM_ALL_PROVIDER (provider); + GList *realms = NULL; + GList *l; + + for (l = self->providers; l != NULL; l = g_list_next (l)) + realms = g_list_concat (realms, realm_provider_get_realms (l->data)); + + return realms; +} + + static void realm_all_provider_finalize (GObject *obj) { @@ -286,6 +300,7 @@ realm_all_provider_class_init (RealmAllProviderClass *klass) provider_class->discover_async = realm_all_provider_discover_async; provider_class->discover_finish = realm_all_provider_discover_finish; + provider_class->get_realms = realm_all_provider_get_realms; } RealmProvider * @@ -327,6 +342,6 @@ realm_all_provider_register (RealmProvider *all_provider, self = REALM_ALL_PROVIDER (all_provider); self->providers = g_list_prepend (self->providers, g_object_ref (provider)); - update_all_properties (self); + update_all_properties (all_provider); g_signal_connect (provider, "notify", G_CALLBACK (on_provider_notify), self); } diff --git a/service/realm-kerberos.c b/service/realm-kerberos.c index 55320dc..a594fb7 100644 --- a/service/realm-kerberos.c +++ b/service/realm-kerberos.c @@ -772,6 +772,27 @@ realm_kerberos_set_domain_name (RealmKerberos *self, realm_dbus_kerberos_set_domain_name (self->pv->kerberos_iface, value); } +gboolean +realm_kerberos_matches (RealmKerberos *self, + const gchar *string) +{ + const gchar *value; + + g_return_val_if_fail (REALM_IS_KERBEROS (self), FALSE); + + value = realm_dbus_realm_get_name (self->pv->realm_iface); + if (value != NULL && g_utf8_collate (value, string) == 0) + return TRUE; + value = realm_dbus_kerberos_get_domain_name (self->pv->kerberos_iface); + if (value != NULL && g_utf8_collate (value, string) == 0) + return TRUE; + value = realm_dbus_kerberos_get_realm_name (self->pv->kerberos_iface); + if (value != NULL && g_utf8_collate (value, string) == 0) + return TRUE; + + return FALSE; +} + void realm_kerberos_set_suggested_admin (RealmKerberos *self, const gchar *value) diff --git a/service/realm-kerberos.h b/service/realm-kerberos.h index 30bb75b..0274779 100644 --- a/service/realm-kerberos.h +++ b/service/realm-kerberos.h @@ -120,6 +120,9 @@ void realm_kerberos_set_configured (RealmKerberos *s void realm_kerberos_set_required_package_sets (RealmKerberos *self, const gchar **package_sets); +gboolean realm_kerberos_matches (RealmKerberos *self, + const gchar *string); + G_END_DECLS #endif /* __REALM_KERBEROS_H__ */ diff --git a/service/realm-provider.c b/service/realm-provider.c index 7aa0dd8..680baa0 100644 --- a/service/realm-provider.c +++ b/service/realm-provider.c @@ -77,6 +77,25 @@ sort_configured_first (gconstpointer a, return a_val - b_val; } +static GList * +discover_configured (RealmProvider *self, + const gchar *string) +{ + GList *matched = NULL; + GList *realms; + GList *l; + + realms = realm_provider_get_realms (self); + for (l = realms; l != NULL; l = g_list_next (l)) { + if (realm_kerberos_is_configured (l->data) && + realm_kerberos_matches (l->data, string)) + matched = g_list_prepend (matched, g_object_ref (l->data)); + } + g_list_free (realms); + + return matched; +} + static void return_discover_result (MethodClosure *closure, GList *realms, @@ -104,6 +123,12 @@ return_discover_result (MethodClosure *closure, } } + /* If no realms were discovered, try matching configured realms */ + if (error == NULL && realms == NULL && closure->string) { + realms = discover_configured (closure->self, closure->string); + relevance = 20; + } + if (error == NULL) { realms = g_list_sort (realms, sort_configured_first); results = g_ptr_array_new (); @@ -111,7 +136,6 @@ return_discover_result (MethodClosure *closure, path = g_dbus_object_get_object_path (l->data); g_ptr_array_add (results, g_variant_new_object_path (path)); } - g_list_free_full (realms, g_object_unref); retval = g_variant_new ("(i@ao)", relevance, g_variant_new_array (G_VARIANT_TYPE ("o"), @@ -139,6 +163,7 @@ return_discover_result (MethodClosure *closure, g_error_free (error); } + g_list_free_full (realms, g_object_unref); method_closure_free (closure); } @@ -240,6 +265,20 @@ realm_provider_authorize_method (GDBusObjectSkeleton *skeleton, return realm_invocation_authorize (invocation); } +static GList * +realm_provider_real_get_realms (RealmProvider *self) +{ + GHashTableIter iter; + GList *realms = NULL; + RealmKerberos *realm; + + g_hash_table_iter_init (&iter, self->pv->realms); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&realm)) + realms = g_list_prepend (realms, realm); + + return realms; +} + static void realm_provider_init (RealmProvider *self) { @@ -283,7 +322,7 @@ update_realms_property (RealmProvider *self) g_ptr_array_add (realms, NULL); - realm_provider_set_realms (self, (const gchar **)realms->pdata); + realm_provider_set_realm_paths (self, (const gchar **)realms->pdata); g_ptr_array_free (realms, TRUE); } @@ -307,6 +346,8 @@ realm_provider_class_init (RealmProviderClass *klass) object_class->finalize = realm_provider_finalize; skeleton_class->authorize_method = realm_provider_authorize_method; + klass->get_realms = realm_provider_real_get_realms; + g_type_class_add_private (klass, sizeof (RealmProviderPrivate)); } @@ -376,16 +417,21 @@ realm_provider_set_name (RealmProvider *self, realm_dbus_provider_set_name (self->pv->provider_iface, value); } -const gchar ** +GList * realm_provider_get_realms (RealmProvider *self) { + RealmProviderClass *klass; + g_return_val_if_fail (REALM_IS_PROVIDER (self), NULL); - return (const gchar **)realm_dbus_provider_get_realms (self->pv->provider_iface); + klass = REALM_PROVIDER_GET_CLASS (self); + g_return_val_if_fail (klass->get_realms != NULL, NULL); + + return (klass->get_realms) (self); } void -realm_provider_set_realms (RealmProvider *self, - const gchar **value) +realm_provider_set_realm_paths (RealmProvider *self, + const gchar **value) { g_return_if_fail (REALM_IS_PROVIDER (self)); g_return_if_fail (value != NULL); diff --git a/service/realm-provider.h b/service/realm-provider.h index e3be0bc..f2470e1 100644 --- a/service/realm-provider.h +++ b/service/realm-provider.h @@ -55,6 +55,8 @@ struct _RealmProviderClass { GAsyncResult *result, gint *relevance, GError **error); + + GList * (* get_realms) (RealmProvider *provider); }; GType realm_provider_get_type (void) G_GNUC_CONST; @@ -87,9 +89,9 @@ GList * realm_provider_discover_finish (RealmProvider void realm_provider_set_name (RealmProvider *self, const gchar *value); -const gchar ** realm_provider_get_realms (RealmProvider *self); +GList * realm_provider_get_realms (RealmProvider *self); -void realm_provider_set_realms (RealmProvider *self, +void realm_provider_set_realm_paths (RealmProvider *self, const gchar **value); gboolean realm_provider_match_software (GVariant *options, -- 1.8.1.4