evolution-3.6.4/modules/book-config-ldap/e-source-ldap.c

No issues found

  1 /*
  2  * e-source-ldap.c
  3  *
  4  * This program is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU Lesser General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2 of the License, or (at your option) version 3.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * Lesser General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU Lesser General Public
 15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 16  *
 17  */
 18 
 19 #include "e-source-ldap.h"
 20 
 21 #include <ldap.h>
 22 
 23 #include <libedataserver/libedataserver.h>
 24 
 25 #define E_SOURCE_LDAP_GET_PRIVATE(obj) \
 26 	(G_TYPE_INSTANCE_GET_PRIVATE \
 27 	((obj), E_TYPE_SOURCE_LDAP, ESourceLDAPPrivate))
 28 
 29 struct _ESourceLDAPPrivate {
 30 	GMutex *property_lock;
 31 	gboolean can_browse;
 32 	gchar *filter;
 33 	guint limit;
 34 	gchar *root_dn;
 35 	ESourceLDAPScope scope;
 36 
 37 	/* These are bound to other extensions. */
 38 	ESourceLDAPAuthentication authentication;
 39 	ESourceLDAPSecurity security;
 40 };
 41 
 42 enum {
 43 	PROP_0,
 44 	PROP_AUTHENTICATION,
 45 	PROP_CAN_BROWSE,
 46 	PROP_FILTER,
 47 	PROP_LIMIT,
 48 	PROP_ROOT_DN,
 49 	PROP_SCOPE,
 50 	PROP_SECURITY
 51 };
 52 
 53 static GType e_source_ldap_authentication_type = G_TYPE_INVALID;
 54 static GType e_source_ldap_scope_type = G_TYPE_INVALID;
 55 static GType e_source_ldap_security_type = G_TYPE_INVALID;
 56 
 57 G_DEFINE_DYNAMIC_TYPE (
 58 	ESourceLDAP,
 59 	e_source_ldap,
 60 	E_TYPE_SOURCE_EXTENSION)
 61 
 62 static gboolean
 63 source_ldap_transform_enum_nick_to_value (GBinding *binding,
 64                                           const GValue *source_value,
 65                                           GValue *target_value,
 66                                           gpointer not_used)
 67 {
 68 	GEnumClass *enum_class;
 69 	GEnumValue *enum_value;
 70 	const gchar *string;
 71 	gboolean success = FALSE;
 72 
 73 	enum_class = g_type_class_peek (G_VALUE_TYPE (target_value));
 74 	g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), FALSE);
 75 
 76 	string = g_value_get_string (source_value);
 77 	enum_value = g_enum_get_value_by_nick (enum_class, string);
 78 	if (enum_value != NULL) {
 79 		g_value_set_enum (target_value, enum_value->value);
 80 		success = TRUE;
 81 	}
 82 
 83 	return success;
 84 }
 85 
 86 static gboolean
 87 source_ldap_transform_enum_value_to_nick (GBinding *binding,
 88                                           const GValue *source_value,
 89                                           GValue *target_value,
 90                                           gpointer not_used)
 91 {
 92 	GEnumClass *enum_class;
 93 	GEnumValue *enum_value;
 94 	gint value;
 95 	gboolean success = FALSE;
 96 
 97 	enum_class = g_type_class_peek (G_VALUE_TYPE (source_value));
 98 	g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), FALSE);
 99 
100 	value = g_value_get_enum (source_value);
101 	enum_value = g_enum_get_value (enum_class, value);
102 	if (enum_value != NULL) {
103 		g_value_set_string (target_value, enum_value->value_nick);
104 		success = TRUE;
105 	}
106 
107 	return success;
108 }
109 
110 static void
111 source_ldap_set_property (GObject *object,
112                           guint property_id,
113                           const GValue *value,
114                           GParamSpec *pspec)
115 {
116 	switch (property_id) {
117 		case PROP_AUTHENTICATION:
118 			e_source_ldap_set_authentication (
119 				E_SOURCE_LDAP (object),
120 				g_value_get_enum (value));
121 			return;
122 
123 		case PROP_CAN_BROWSE:
124 			e_source_ldap_set_can_browse (
125 				E_SOURCE_LDAP (object),
126 				g_value_get_boolean (value));
127 			return;
128 
129 		case PROP_FILTER:
130 			e_source_ldap_set_filter (
131 				E_SOURCE_LDAP (object),
132 				g_value_get_string (value));
133 			return;
134 
135 		case PROP_LIMIT:
136 			e_source_ldap_set_limit (
137 				E_SOURCE_LDAP (object),
138 				g_value_get_uint (value));
139 			return;
140 
141 		case PROP_ROOT_DN:
142 			e_source_ldap_set_root_dn (
143 				E_SOURCE_LDAP (object),
144 				g_value_get_string (value));
145 			return;
146 
147 		case PROP_SCOPE:
148 			e_source_ldap_set_scope (
149 				E_SOURCE_LDAP (object),
150 				g_value_get_enum (value));
151 			return;
152 
153 		case PROP_SECURITY:
154 			e_source_ldap_set_security (
155 				E_SOURCE_LDAP (object),
156 				g_value_get_enum (value));
157 			return;
158 	}
159 
160 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
161 }
162 
163 static void
164 source_ldap_get_property (GObject *object,
165                           guint property_id,
166                           GValue *value,
167                           GParamSpec *pspec)
168 {
169 	switch (property_id) {
170 		case PROP_AUTHENTICATION:
171 			g_value_set_enum (
172 				value,
173 				e_source_ldap_get_authentication (
174 				E_SOURCE_LDAP (object)));
175 			return;
176 
177 		case PROP_CAN_BROWSE:
178 			g_value_set_boolean (
179 				value,
180 				e_source_ldap_get_can_browse (
181 				E_SOURCE_LDAP (object)));
182 			return;
183 
184 		case PROP_FILTER:
185 			g_value_take_string (
186 				value,
187 				e_source_ldap_dup_filter (
188 				E_SOURCE_LDAP (object)));
189 			return;
190 
191 		case PROP_LIMIT:
192 			g_value_set_uint (
193 				value,
194 				e_source_ldap_get_limit (
195 				E_SOURCE_LDAP (object)));
196 			return;
197 
198 		case PROP_ROOT_DN:
199 			g_value_take_string (
200 				value,
201 				e_source_ldap_dup_root_dn (
202 				E_SOURCE_LDAP (object)));
203 			return;
204 
205 		case PROP_SCOPE:
206 			g_value_set_enum (
207 				value,
208 				e_source_ldap_get_scope (
209 				E_SOURCE_LDAP (object)));
210 			return;
211 
212 		case PROP_SECURITY:
213 			g_value_set_enum (
214 				value,
215 				e_source_ldap_get_security (
216 				E_SOURCE_LDAP (object)));
217 			return;
218 	}
219 
220 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
221 }
222 
223 static void
224 source_ldap_finalize (GObject *object)
225 {
226 	ESourceLDAPPrivate *priv;
227 
228 	priv = E_SOURCE_LDAP_GET_PRIVATE (object);
229 
230 	g_mutex_free (priv->property_lock);
231 
232 	g_free (priv->filter);
233 	g_free (priv->root_dn);
234 
235 	/* Chain up to parent's finalize() method. */
236 	G_OBJECT_CLASS (e_source_ldap_parent_class)->finalize (object);
237 }
238 
239 static void
240 source_ldap_constructed (GObject *object)
241 {
242 	ESource *source;
243 	ESourceExtension *this_extension;
244 	ESourceExtension *other_extension;
245 	const gchar *extension_name;
246 
247 	this_extension = E_SOURCE_EXTENSION (object);
248 	source = e_source_extension_get_source (this_extension);
249 
250 	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
251 	other_extension = e_source_get_extension (source, extension_name);
252 
253 	g_object_bind_property_full (
254 		other_extension, "method",
255 		this_extension, "authentication",
256 		G_BINDING_BIDIRECTIONAL |
257 		G_BINDING_SYNC_CREATE,
258 		source_ldap_transform_enum_nick_to_value,
259 		source_ldap_transform_enum_value_to_nick,
260 		NULL, (GDestroyNotify) NULL);
261 
262 	extension_name = E_SOURCE_EXTENSION_SECURITY;
263 	other_extension = e_source_get_extension (source, extension_name);
264 
265 	g_object_bind_property_full (
266 		other_extension, "method",
267 		this_extension, "security",
268 		G_BINDING_BIDIRECTIONAL |
269 		G_BINDING_SYNC_CREATE,
270 		source_ldap_transform_enum_nick_to_value,
271 		source_ldap_transform_enum_value_to_nick,
272 		NULL, (GDestroyNotify) NULL);
273 }
274 
275 static void
276 e_source_ldap_class_init (ESourceLDAPClass *class)
277 {
278 	GObjectClass *object_class;
279 	ESourceExtensionClass *extension_class;
280 
281 	g_type_class_add_private (class, sizeof (ESourceLDAPPrivate));
282 
283 	object_class = G_OBJECT_CLASS (class);
284 	object_class->set_property = source_ldap_set_property;
285 	object_class->get_property = source_ldap_get_property;
286 	object_class->finalize = source_ldap_finalize;
287 	object_class->constructed = source_ldap_constructed;
288 
289 	extension_class = E_SOURCE_EXTENSION_CLASS (class);
290 	extension_class->name = E_SOURCE_EXTENSION_LDAP_BACKEND;
291 
292 	/* This is bound to the authentication extension.
293 	 * Do not use E_SOURCE_PARAM_SETTING here. */
294 	g_object_class_install_property (
295 		object_class,
296 		PROP_AUTHENTICATION,
297 		g_param_spec_enum (
298 			"authentication",
299 			"Authentication",
300 			"LDAP authentication method",
301 			E_TYPE_SOURCE_LDAP_AUTHENTICATION,
302 			E_SOURCE_LDAP_AUTHENTICATION_NONE,
303 			G_PARAM_READWRITE));
304 
305 	g_object_class_install_property (
306 		object_class,
307 		PROP_CAN_BROWSE,
308 		g_param_spec_boolean (
309 			"can-browse",
310 			"Can Browse",
311 			"Allow browsing contacts",
312 			FALSE,
313 			G_PARAM_READWRITE |
314 			G_PARAM_CONSTRUCT |
315 			E_SOURCE_PARAM_SETTING));
316 
317 	g_object_class_install_property (
318 		object_class,
319 		PROP_FILTER,
320 		g_param_spec_string (
321 			"filter",
322 			"Filter",
323 			"LDAP search filter",
324 			"",
325 			G_PARAM_READWRITE |
326 			G_PARAM_CONSTRUCT |
327 			E_SOURCE_PARAM_SETTING));
328 
329 	g_object_class_install_property (
330 		object_class,
331 		PROP_LIMIT,
332 		g_param_spec_uint (
333 			"limit",
334 			"Limit",
335 			"Download limit",
336 			0, G_MAXUINT, 100,
337 			G_PARAM_READWRITE |
338 			G_PARAM_CONSTRUCT |
339 			E_SOURCE_PARAM_SETTING));
340 
341 	g_object_class_install_property (
342 		object_class,
343 		PROP_ROOT_DN,
344 		g_param_spec_string (
345 			"root-dn",
346 			"Root DN",
347 			"LDAP search base",
348 			"",
349 			G_PARAM_READWRITE |
350 			G_PARAM_CONSTRUCT |
351 			E_SOURCE_PARAM_SETTING));
352 
353 	g_object_class_install_property (
354 		object_class,
355 		PROP_SCOPE,
356 		g_param_spec_enum (
357 			"scope",
358 			"Scope",
359 			"LDAP search scope",
360 			E_TYPE_SOURCE_LDAP_SCOPE,
361 			E_SOURCE_LDAP_SCOPE_ONELEVEL,
362 			G_PARAM_READWRITE |
363 			G_PARAM_CONSTRUCT |
364 			E_SOURCE_PARAM_SETTING));
365 
366 	/* This is bound to the security extension.
367 	 * Do not use E_SOURCE_PARAM_SETTING here. */
368 	g_object_class_install_property (
369 		object_class,
370 		PROP_SECURITY,
371 		g_param_spec_enum (
372 			"security",
373 			"Security",
374 			"LDAP security method",
375 			E_TYPE_SOURCE_LDAP_SECURITY,
376 			E_SOURCE_LDAP_SECURITY_NONE,
377 			G_PARAM_READWRITE));
378 }
379 
380 static void
381 e_source_ldap_class_finalize (ESourceLDAPClass *class)
382 {
383 }
384 
385 static void
386 e_source_ldap_init (ESourceLDAP *extension)
387 {
388 	extension->priv = E_SOURCE_LDAP_GET_PRIVATE (extension);
389 	extension->priv->property_lock = g_mutex_new ();
390 }
391 
392 void
393 e_source_ldap_type_register (GTypeModule *type_module)
394 {
395 	static const GEnumValue e_source_ldap_authentication_values[] = {
396 		{ E_SOURCE_LDAP_AUTHENTICATION_NONE,
397 		  "E_SOURCE_LDAP_AUTHENTICATION_NONE",
398 		  "none" },
399 		{ E_SOURCE_LDAP_AUTHENTICATION_EMAIL,
400 		  "E_SOURCE_LDAP_AUTHENTICATION_EMAIL",
401 		  "ldap/simple-email" },
402 		{ E_SOURCE_LDAP_AUTHENTICATION_BINDDN,
403 		  "E_SOURCE_LDAP_AUTHENTICATION_BINDDN",
404 		  "ldap/simple-binddn" },
405 		{ 0, NULL, NULL }
406 	};
407 
408 	static const GEnumValue e_source_ldap_scope_values[] = {
409 		{ E_SOURCE_LDAP_SCOPE_ONELEVEL,
410 		  "E_SOURCE_LDAP_SCOPE_ONELEVEL",
411 		  "onelevel" },
412 		{ E_SOURCE_LDAP_SCOPE_SUBTREE,
413 		  "E_SOURCE_LDAP_SCOPE_SUBTREE",
414 		  "subtree" },
415 		{ 0, NULL, NULL }
416 	};
417 
418 	static const GEnumValue e_source_ldap_security_values[] = {
419 		{ E_SOURCE_LDAP_SECURITY_NONE,
420 		  "E_SOURCE_LDAP_SECURITY_NONE",
421 		  "none" },
422 		{ E_SOURCE_LDAP_SECURITY_LDAPS,
423 		  "E_SOURCE_LDAP_SECURITY_LDAPS",
424 		  "ldaps" },
425 		{ E_SOURCE_LDAP_SECURITY_STARTTLS,
426 		  "E_SOURCE_LDAP_SECURITY_STARTTLS",
427 		  "starttls" },
428 		{ 0, NULL, NULL }
429 	};
430 
431 	e_source_ldap_authentication_type =
432 		g_type_module_register_enum (
433 		type_module, "ESourceLDAPAuthentication",
434 		e_source_ldap_authentication_values);
435 
436 	e_source_ldap_scope_type =
437 		g_type_module_register_enum (
438 		type_module, "ESourceLDAPScope",
439 		e_source_ldap_scope_values);
440 
441 	e_source_ldap_security_type =
442 		g_type_module_register_enum (
443 		type_module, "ESourceLDAPSecurity",
444 		e_source_ldap_security_values);
445 
446 	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
447 	 *     function, so we have to wrap it with a public function in
448 	 *     order to register types from a separate compilation unit. */
449 	e_source_ldap_register_type (type_module);
450 }
451 
452 ESourceLDAPAuthentication
453 e_source_ldap_get_authentication (ESourceLDAP *extension)
454 {
455 	g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), 0);
456 
457 	return extension->priv->authentication;
458 }
459 
460 void
461 e_source_ldap_set_authentication (ESourceLDAP *extension,
462                                   ESourceLDAPAuthentication authentication)
463 {
464 	g_return_if_fail (E_IS_SOURCE_LDAP (extension));
465 
466 	if (extension->priv->authentication == authentication)
467 		return;
468 
469 	extension->priv->authentication = authentication;
470 
471 	g_object_notify (G_OBJECT (extension), "authentication");
472 }
473 
474 gboolean
475 e_source_ldap_get_can_browse (ESourceLDAP *extension)
476 {
477 	g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), FALSE);
478 
479 	return extension->priv->can_browse;
480 }
481 
482 void
483 e_source_ldap_set_can_browse (ESourceLDAP *extension,
484                               gboolean can_browse)
485 {
486 	g_return_if_fail (E_IS_SOURCE_LDAP (extension));
487 
488 	if (extension->priv->can_browse == can_browse)
489 		return;
490 
491 	extension->priv->can_browse = can_browse;
492 
493 	g_object_notify (G_OBJECT (extension), "can-browse");
494 }
495 
496 const gchar *
497 e_source_ldap_get_filter (ESourceLDAP *extension)
498 {
499 	g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), NULL);
500 
501 	return extension->priv->filter;
502 }
503 
504 gchar *
505 e_source_ldap_dup_filter (ESourceLDAP *extension)
506 {
507 	const gchar *protected;
508 	gchar *duplicate;
509 
510 	g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), NULL);
511 
512 	g_mutex_lock (extension->priv->property_lock);
513 
514 	protected = e_source_ldap_get_filter (extension);
515 	duplicate = g_strdup (protected);
516 
517 	g_mutex_unlock (extension->priv->property_lock);
518 
519 	return duplicate;
520 }
521 
522 void
523 e_source_ldap_set_filter (ESourceLDAP *extension,
524                           const gchar *filter)
525 {
526 	gboolean needs_parens;
527 	gchar *new_filter;
528 
529 	g_return_if_fail (E_IS_SOURCE_LDAP (extension));
530 
531 	needs_parens =
532 		(filter != NULL) && (*filter != '\0') &&
533 		!g_str_has_prefix (filter, "(") &&
534 		!g_str_has_suffix (filter, ")");
535 
536 	g_mutex_lock (extension->priv->property_lock);
537 
538 	if (needs_parens)
539 		new_filter = g_strdup_printf ("(%s)", filter);
540 	else
541 		new_filter = g_strdup (filter);
542 
543 	if (g_strcmp0 (extension->priv->filter, new_filter) == 0) {
544 		g_mutex_unlock (extension->priv->property_lock);
545 		g_free (new_filter);
546 		return;
547 	}
548 
549 	g_free (extension->priv->filter);
550 	extension->priv->filter = new_filter;
551 
552 	g_mutex_unlock (extension->priv->property_lock);
553 
554 	g_object_notify (G_OBJECT (extension), "filter");
555 }
556 
557 guint
558 e_source_ldap_get_limit (ESourceLDAP *extension)
559 {
560 	g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), 0);
561 
562 	return extension->priv->limit;
563 }
564 
565 void
566 e_source_ldap_set_limit (ESourceLDAP *extension,
567                          guint limit)
568 {
569 	g_return_if_fail (E_IS_SOURCE_LDAP (extension));
570 
571 	if (extension->priv->limit == limit)
572 		return;
573 
574 	extension->priv->limit = limit;
575 
576 	g_object_notify (G_OBJECT (extension), "limit");
577 }
578 
579 const gchar *
580 e_source_ldap_get_root_dn (ESourceLDAP *extension)
581 {
582 	g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), NULL);
583 
584 	return extension->priv->root_dn;
585 }
586 
587 gchar *
588 e_source_ldap_dup_root_dn (ESourceLDAP *extension)
589 {
590 	const gchar *protected;
591 	gchar *duplicate;
592 
593 	g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), NULL);
594 
595 	g_mutex_lock (extension->priv->property_lock);
596 
597 	protected = e_source_ldap_get_root_dn (extension);
598 	duplicate = g_strdup (protected);
599 
600 	g_mutex_unlock (extension->priv->property_lock);
601 
602 	return duplicate;
603 }
604 
605 void
606 e_source_ldap_set_root_dn (ESourceLDAP *extension,
607                            const gchar *root_dn)
608 {
609 	g_return_if_fail (E_IS_SOURCE_LDAP (extension));
610 
611 	g_mutex_lock (extension->priv->property_lock);
612 
613 	if (g_strcmp0 (extension->priv->root_dn, root_dn) == 0) {
614 		g_mutex_unlock (extension->priv->property_lock);
615 		return;
616 	}
617 
618 	g_free (extension->priv->root_dn);
619 	extension->priv->root_dn = e_util_strdup_strip (root_dn);
620 
621 	g_mutex_unlock (extension->priv->property_lock);
622 
623 	g_object_notify (G_OBJECT (extension), "root-dn");
624 }
625 
626 ESourceLDAPScope
627 e_source_ldap_get_scope (ESourceLDAP *extension)
628 {
629 	g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), 0);
630 
631 	return extension->priv->scope;
632 }
633 
634 void
635 e_source_ldap_set_scope (ESourceLDAP *extension,
636                          ESourceLDAPScope scope)
637 {
638 	g_return_if_fail (E_IS_SOURCE_LDAP (extension));
639 
640 	if (extension->priv->scope == scope)
641 		return;
642 
643 	extension->priv->scope = scope;
644 
645 	g_object_notify (G_OBJECT (extension), "scope");
646 }
647 
648 ESourceLDAPSecurity
649 e_source_ldap_get_security (ESourceLDAP *extension)
650 {
651 	g_return_val_if_fail (E_IS_SOURCE_LDAP (extension), 0);
652 
653 	return extension->priv->security;
654 }
655 
656 void
657 e_source_ldap_set_security (ESourceLDAP *extension,
658                             ESourceLDAPSecurity security)
659 {
660 	g_return_if_fail (E_IS_SOURCE_LDAP (extension));
661 
662 	if (extension->priv->security == security)
663 		return;
664 
665 	extension->priv->security = security;
666 
667 	g_object_notify (G_OBJECT (extension), "security");
668 }
669 
670 GType
671 e_source_ldap_authentication_get_type (void)
672 {
673 	return e_source_ldap_authentication_type;
674 }
675 
676 GType
677 e_source_ldap_scope_get_type (void)
678 {
679 	return e_source_ldap_scope_type;
680 }
681 
682 GType
683 e_source_ldap_security_get_type (void)
684 {
685 	return e_source_ldap_security_type;
686 }