diff options
Diffstat (limited to 'modules/book-config-ldap/e-source-ldap.c')
-rw-r--r-- | modules/book-config-ldap/e-source-ldap.c | 659 |
1 files changed, 659 insertions, 0 deletions
diff --git a/modules/book-config-ldap/e-source-ldap.c b/modules/book-config-ldap/e-source-ldap.c new file mode 100644 index 0000000000..4e182dc625 --- /dev/null +++ b/modules/book-config-ldap/e-source-ldap.c @@ -0,0 +1,659 @@ +/* + * e-source-ldap.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + */ + +#include "e-source-ldap.h" + +#include <ldap.h> + +#include <libedataserver/e-data-server-util.h> +#include <libedataserver/e-source-authentication.h> +#include <libedataserver/e-source-security.h> + +#define E_SOURCE_LDAP_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SOURCE_LDAP, ESourceLDAPPrivate)) + +struct _ESourceLDAPPrivate { + GMutex *property_lock; + gboolean can_browse; + gchar *filter; + guint limit; + gchar *root_dn; + ESourceLDAPScope scope; + + /* These are bound to other extensions. */ + ESourceLDAPAuthentication authentication; + ESourceLDAPSecurity security; +}; + +enum { + PROP_0, + PROP_AUTHENTICATION, + PROP_CAN_BROWSE, + PROP_FILTER, + PROP_LIMIT, + PROP_ROOT_DN, + PROP_SCOPE, + PROP_SECURITY +}; + +static GType e_source_ldap_authentication_type = G_TYPE_INVALID; +static GType e_source_ldap_scope_type = G_TYPE_INVALID; +static GType e_source_ldap_security_type = G_TYPE_INVALID; + +G_DEFINE_DYNAMIC_TYPE ( + ESourceLDAP, + e_source_ldap, + E_TYPE_SOURCE_EXTENSION) + +static gboolean +source_ldap_transform_enum_nick_to_value (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer not_used) +{ + GEnumClass *enum_class; + GEnumValue *enum_value; + const gchar *string; + gboolean success = FALSE; + + enum_class = g_type_class_peek (G_VALUE_TYPE (target_value)); + g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), FALSE); + + string = g_value_get_string (source_value); + enum_value = g_enum_get_value_by_nick (enum_class, string); + if (enum_value != NULL) { + g_value_set_enum (target_value, enum_value->value); + success = TRUE; + } + + return success; +} + +static gboolean +source_ldap_transform_enum_value_to_nick (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer not_used) +{ + GEnumClass *enum_class; + GEnumValue *enum_value; + gint value; + gboolean success = FALSE; + + enum_class = g_type_class_peek (G_VALUE_TYPE (source_value)); + g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), FALSE); + + value = g_value_get_enum (source_value); + enum_value = g_enum_get_value (enum_class, value); + if (enum_value != NULL) { + g_value_set_string (target_value, enum_value->value_nick); + success = TRUE; + } + + return success; +} + +static void +source_ldap_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_AUTHENTICATION: + e_source_ldap_set_authentication ( + E_SOURCE_LDAP (object), + g_value_get_enum (value)); + return; + + case PROP_CAN_BROWSE: + e_source_ldap_set_can_browse ( + E_SOURCE_LDAP (object), + g_value_get_boolean (value)); + return; + + case PROP_FILTER: + e_source_ldap_set_filter ( + E_SOURCE_LDAP (object), + g_value_get_string (value)); + return; + + case PROP_LIMIT: + e_source_ldap_set_limit ( + E_SOURCE_LDAP (object), + g_value_get_uint (value)); + return; + + case PROP_ROOT_DN: + e_source_ldap_set_root_dn ( + E_SOURCE_LDAP (object), + g_value_get_string (value)); + return; + + case PROP_SCOPE: + e_source_ldap_set_scope ( + E_SOURCE_LDAP (object), + g_value_get_enum (value)); + return; + + case PROP_SECURITY: + e_source_ldap_set_security ( + E_SOURCE_LDAP (object), + g_value_get_enum (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +source_ldap_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_AUTHENTICATION: + g_value_set_enum ( + value, + e_source_ldap_get_authentication ( + E_SOURCE_LDAP (object))); + return; + + case PROP_CAN_BROWSE: + g_value_set_boolean ( + value, + e_source_ldap_get_can_browse ( + E_SOURCE_LDAP (object))); + return; + + case PROP_FILTER: + g_value_take_string ( + value, + e_source_ldap_dup_filter ( + E_SOURCE_LDAP (object))); + return; + + case PROP_LIMIT: + g_value_set_uint ( + value, + e_source_ldap_get_limit ( + E_SOURCE_LDAP (object))); + return; + + case PROP_ROOT_DN: + g_value_take_string ( + value, + e_source_ldap_dup_root_dn ( + E_SOURCE_LDAP (object))); + return; + + case PROP_SCOPE: + g_value_set_enum ( + value, + e_source_ldap_get_scope ( + E_SOURCE_LDAP (object))); + return; + + case PROP_SECURITY: + g_value_set_enum ( + value, + e_source_ldap_get_security ( + E_SOURCE_LDAP (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +source_ldap_finalize (GObject *object) +{ + ESourceLDAPPrivate *priv; + + priv = E_SOURCE_LDAP_GET_PRIVATE (object); + + g_mutex_free (priv->property_lock); + + g_free (priv->filter); + g_free (priv->root_dn); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (e_source_ldap_parent_class)->finalize (object); +} + +static void +source_ldap_constructed (GObject *object) +{ + ESource *source; + ESourceExtension *this_extension; + ESourceExtension *other_extension; + const gchar *extension_name; + + this_extension = E_SOURCE_EXTENSION (object); + source = e_source_extension_get_source (this_extension); + + extension_name = E_SOURCE_EXTENSION_AUTHENTICATION; + other_extension = e_source_get_extension (source, extension_name); + + g_object_bind_property_full ( + other_extension, "method", + this_extension, "authentication", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE, + source_ldap_transform_enum_nick_to_value, + source_ldap_transform_enum_value_to_nick, + NULL, (GDestroyNotify) NULL); + + extension_name = E_SOURCE_EXTENSION_SECURITY; + other_extension = e_source_get_extension (source, extension_name); + + g_object_bind_property_full ( + other_extension, "method", + this_extension, "security", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE, + source_ldap_transform_enum_nick_to_value, + source_ldap_transform_enum_value_to_nick, + NULL, (GDestroyNotify) NULL); +} + +static void +e_source_ldap_class_init (ESourceLDAPClass *class) +{ + GObjectClass *object_class; + ESourceExtensionClass *extension_class; + + g_type_class_add_private (class, sizeof (ESourceLDAPPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = source_ldap_set_property; + object_class->get_property = source_ldap_get_property; + object_class->finalize = source_ldap_finalize; + object_class->constructed = source_ldap_constructed; + + extension_class = E_SOURCE_EXTENSION_CLASS (class); + extension_class->name = E_SOURCE_EXTENSION_LDAP_BACKEND; + + /* This is bound to the authentication extension. + * Do not use E_SOURCE_PARAM_SETTING here. */ + g_object_class_install_property ( + object_class, + PROP_AUTHENTICATION, + g_param_spec_enum ( + "authentication", + "Authentication", + "LDAP authentication method", + E_TYPE_SOURCE_LDAP_AUTHENTICATION, + E_SOURCE_LDAP_AUTHENTICATION_NONE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_CAN_BROWSE, + g_param_spec_boolean ( + "can-browse", + "Can Browse", + "Allow browsing contacts", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + E_SOURCE_PARAM_SETTING)); + + g_object_class_install_property ( + object_class, + PROP_FILTER, + g_param_spec_string ( + "filter", + "Filter", + "LDAP search filter", + "", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + E_SOURCE_PARAM_SETTING)); + + g_object_class_install_property ( + object_class, + PROP_LIMIT, + g_param_spec_uint ( + "limit", + "Limit", + "Download limit", + 0, G_MAXUINT, 100, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + E_SOURCE_PARAM_SETTING)); + + g_object_class_install_property ( + object_class, + PROP_ROOT_DN, + g_param_spec_string ( + "root-dn", + "Root DN", + "LDAP search base", + "", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + E_SOURCE_PARAM_SETTING)); + + g_object_class_install_property ( + object_class, + PROP_SCOPE, + g_param_spec_enum ( + "scope", + "Scope", + "LDAP search scope", + E_TYPE_SOURCE_LDAP_SCOPE, + E_SOURCE_LDAP_SCOPE_ONELEVEL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + E_SOURCE_PARAM_SETTING)); + + /* This is bound to the security extension. + * Do not use E_SOURCE_PARAM_SETTING here. */ + g_object_class_install_property ( + object_class, + PROP_SECURITY, + g_param_spec_enum ( + "security", + "Security", + "LDAP security method", + E_TYPE_SOURCE_LDAP_SECURITY, + E_SOURCE_LDAP_SECURITY_NONE, + G_PARAM_READWRITE)); +} + +static void +e_source_ldap_class_finalize (ESourceLDAPClass *class) +{ +} + +static void +e_source_ldap_init (ESourceLDAP *extension) +{ + extension->priv = E_SOURCE_LDAP_GET_PRIVATE (extension); + extension->priv->property_lock = g_mutex_new (); +} + +void +e_source_ldap_type_register (GTypeModule *type_module) +{ + static const GEnumValue e_source_ldap_authentication_values[] = { + { E_SOURCE_LDAP_AUTHENTICATION_NONE, + "E_SOURCE_LDAP_AUTHENTICATION_NONE", + "none" }, + { E_SOURCE_LDAP_AUTHENTICATION_EMAIL, + "E_SOURCE_LDAP_AUTHENTICATION_EMAIL", + "ldap/simple-email" }, + { E_SOURCE_LDAP_AUTHENTICATION_BINDDN, + "E_SOURCE_LDAP_AUTHENTICATION_BINDDN", + "ldap/simple-binddn" }, + { 0, NULL, NULL } + }; + + static const GEnumValue e_source_ldap_scope_values[] = { + { E_SOURCE_LDAP_SCOPE_ONELEVEL, + "E_SOURCE_LDAP_SCOPE_ONELEVEL", + "onelevel" }, + { E_SOURCE_LDAP_SCOPE_SUBTREE, + "E_SOURCE_LDAP_SCOPE_SUBTREE", + "subtree" }, + { 0, NULL, NULL } + }; + + static const GEnumValue e_source_ldap_security_values[] = { + { E_SOURCE_LDAP_SECURITY_NONE, + "E_SOURCE_LDAP_SECURITY_NONE", + "none" }, + { E_SOURCE_LDAP_SECURITY_LDAPS, + "E_SOURCE_LDAP_SECURITY_LDAPS", + "ldaps" }, + { E_SOURCE_LDAP_SECURITY_STARTTLS, + "E_SOURCE_LDAP_SECURITY_STARTTLS", + "starttls" }, + { 0, NULL, NULL } + }; + + e_source_ldap_authentication_type = + g_type_module_register_enum ( + type_module, "ESourceLDAPAuthentication", + e_source_ldap_authentication_values); + + e_source_ldap_scope_type = + g_type_module_register_enum ( + type_module, "ESourceLDAPScope", + e_source_ldap_scope_values); + + e_source_ldap_security_type = + g_type_module_register_enum ( + type_module, "ESourceLDAPSecurity", + e_source_ldap_security_values); + + /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration + * function, so we have to wrap it with a public function in + * order to register types from a separate compilation unit. */ + e_source_ldap_register_type (type_module); +} + +ESourceLDAPAuthentication +e_source_ldap_get_authentication (ESourceLDAP *extension) +{ + g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), 0); + + return extension->priv->authentication; +} + +void +e_source_ldap_set_authentication (ESourceLDAP *extension, + ESourceLDAPAuthentication authentication) +{ + g_return_if_fail (E_IS_SOURCE_LDAP (extension)); + + extension->priv->authentication = authentication; + + g_object_notify (G_OBJECT (extension), "authentication"); +} + +gboolean +e_source_ldap_get_can_browse (ESourceLDAP *extension) +{ + g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), FALSE); + + return extension->priv->can_browse; +} + +void +e_source_ldap_set_can_browse (ESourceLDAP *extension, + gboolean can_browse) +{ + g_return_if_fail (E_IS_SOURCE_LDAP (extension)); + + extension->priv->can_browse = can_browse; + + g_object_notify (G_OBJECT (extension), "can-browse"); +} + +const gchar * +e_source_ldap_get_filter (ESourceLDAP *extension) +{ + g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), NULL); + + return extension->priv->filter; +} + +gchar * +e_source_ldap_dup_filter (ESourceLDAP *extension) +{ + const gchar *protected; + gchar *duplicate; + + g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), NULL); + + g_mutex_lock (extension->priv->property_lock); + + protected = e_source_ldap_get_filter (extension); + duplicate = g_strdup (protected); + + g_mutex_unlock (extension->priv->property_lock); + + return duplicate; +} + +void +e_source_ldap_set_filter (ESourceLDAP *extension, + const gchar *filter) +{ + gboolean needs_parens; + + g_return_if_fail (E_IS_SOURCE_LDAP (extension)); + + needs_parens = + (filter != NULL) && (*filter != '\0') && + !g_str_has_prefix (filter, "(") && + !g_str_has_suffix (filter, ")"); + + g_mutex_lock (extension->priv->property_lock); + + g_free (extension->priv->filter); + if (needs_parens) + extension->priv->filter = g_strdup_printf ("(%s)", filter); + else + extension->priv->filter = g_strdup (filter); + + g_mutex_unlock (extension->priv->property_lock); + + g_object_notify (G_OBJECT (extension), "filter"); +} + +guint +e_source_ldap_get_limit (ESourceLDAP *extension) +{ + g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), 0); + + return extension->priv->limit; +} + +void +e_source_ldap_set_limit (ESourceLDAP *extension, + guint limit) +{ + g_return_if_fail (E_IS_SOURCE_LDAP (extension)); + + extension->priv->limit = limit; + + g_object_notify (G_OBJECT (extension), "limit"); +} + +const gchar * +e_source_ldap_get_root_dn (ESourceLDAP *extension) +{ + g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), NULL); + + return extension->priv->root_dn; +} + +gchar * +e_source_ldap_dup_root_dn (ESourceLDAP *extension) +{ + const gchar *protected; + gchar *duplicate; + + g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), NULL); + + g_mutex_lock (extension->priv->property_lock); + + protected = e_source_ldap_get_root_dn (extension); + duplicate = g_strdup (protected); + + g_mutex_unlock (extension->priv->property_lock); + + return duplicate; +} + +void +e_source_ldap_set_root_dn (ESourceLDAP *extension, + const gchar *root_dn) +{ + g_return_if_fail (E_IS_SOURCE_LDAP (extension)); + + g_mutex_lock (extension->priv->property_lock); + + g_free (extension->priv->root_dn); + extension->priv->root_dn = e_util_strdup_strip (root_dn); + + g_mutex_unlock (extension->priv->property_lock); + + g_object_notify (G_OBJECT (extension), "root-dn"); +} + +ESourceLDAPScope +e_source_ldap_get_scope (ESourceLDAP *extension) +{ + g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), 0); + + return extension->priv->scope; +} + +void +e_source_ldap_set_scope (ESourceLDAP *extension, + ESourceLDAPScope scope) +{ + g_return_if_fail (E_IS_SOURCE_LDAP (extension)); + + extension->priv->scope = scope; + + g_object_notify (G_OBJECT (extension), "scope"); +} + +ESourceLDAPSecurity +e_source_ldap_get_security (ESourceLDAP *extension) +{ + g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), 0); + + return extension->priv->security; +} + +void +e_source_ldap_set_security (ESourceLDAP *extension, + ESourceLDAPSecurity security) +{ + g_return_if_fail (E_IS_SOURCE_LDAP (extension)); + + extension->priv->security = security; + + g_object_notify (G_OBJECT (extension), "security"); +} + +GType +e_source_ldap_authentication_get_type (void) +{ + return e_source_ldap_authentication_type; +} + +GType +e_source_ldap_scope_get_type (void) +{ + return e_source_ldap_scope_type; +} + +GType +e_source_ldap_security_get_type (void) +{ + return e_source_ldap_security_type; +} |