2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2001-2006 Match Grun and the Claws Mail team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * Functions necessary to access LDAP servers.
39 #include "addrcache.h"
42 #include "adbookbase.h"
45 * Create new LDAP server interface object.
47 SyldapServer
*syldap_create() {
48 SyldapServer
*ldapServer
;
50 debug_print("Creating LDAP server interface object\n");
52 ldapServer
= g_new0( SyldapServer
, 1 );
53 ldapServer
->type
= ADBOOKTYPE_LDAP
;
54 ldapServer
->addressCache
= addrcache_create();
55 ldapServer
->retVal
= MGU_SUCCESS
;
56 ldapServer
->hostName
= NULL
;
57 ldapServer
->port
= SYLDAP_DFL_PORT
;
58 ldapServer
->baseDN
= NULL
;
59 ldapServer
->bindDN
= NULL
;
60 ldapServer
->bindPass
= NULL
;
61 ldapServer
->searchCriteria
= NULL
;
62 ldapServer
->searchValue
= NULL
;
63 ldapServer
->entriesRead
= 0;
64 ldapServer
->maxEntries
= SYLDAP_MAX_ENTRIES
;
65 ldapServer
->timeOut
= SYLDAP_DFL_TIMEOUT
;
66 ldapServer
->newSearch
= TRUE
;
67 ldapServer
->thread
= NULL
;
68 ldapServer
->busyFlag
= FALSE
;
69 ldapServer
->callBack
= NULL
;
70 ldapServer
->idleId
= 0;
75 * Specify name to be used.
77 void syldap_set_name( SyldapServer
* ldapServer
, const gchar
*value
) {
78 g_return_if_fail( ldapServer
!= NULL
);
79 addrcache_set_name( ldapServer
->addressCache
, value
);
83 * Specify hostname to be used.
85 void syldap_set_host( SyldapServer
* ldapServer
, const gchar
*value
) {
86 addrcache_refresh( ldapServer
->addressCache
);
87 ldapServer
->hostName
= mgu_replace_string( ldapServer
->hostName
, value
);
88 g_strstrip( ldapServer
->hostName
);
92 * Specify port to be used.
94 void syldap_set_port( SyldapServer
* ldapServer
, const gint value
) {
95 addrcache_refresh( ldapServer
->addressCache
);
97 ldapServer
->port
= value
;
100 ldapServer
->port
= SYLDAP_DFL_PORT
;
105 * Specify base DN to be used.
107 void syldap_set_base_dn( SyldapServer
* ldapServer
, const gchar
*value
) {
108 addrcache_refresh( ldapServer
->addressCache
);
109 ldapServer
->baseDN
= mgu_replace_string( ldapServer
->baseDN
, value
);
110 g_strstrip( ldapServer
->baseDN
);
114 * Specify bind DN to be used.
116 void syldap_set_bind_dn( SyldapServer
* ldapServer
, const gchar
*value
) {
117 addrcache_refresh( ldapServer
->addressCache
);
118 ldapServer
->bindDN
= mgu_replace_string( ldapServer
->bindDN
, value
);
119 g_strstrip( ldapServer
->bindDN
);
123 * Specify bind password to be used.
125 void syldap_set_bind_password( SyldapServer
* ldapServer
, const gchar
*value
) {
126 addrcache_refresh( ldapServer
->addressCache
);
127 ldapServer
->bindPass
= mgu_replace_string( ldapServer
->bindPass
, value
);
128 g_strstrip( ldapServer
->bindPass
);
132 * Specify search criteria to be used.
134 void syldap_set_search_criteria( SyldapServer
* ldapServer
, const gchar
*value
) {
135 addrcache_refresh( ldapServer
->addressCache
);
136 ldapServer
->searchCriteria
= mgu_replace_string( ldapServer
->searchCriteria
, value
);
137 g_strstrip( ldapServer
->searchCriteria
);
138 ldapServer
->newSearch
= TRUE
;
142 * Specify search value to be searched for.
144 void syldap_set_search_value( SyldapServer
* ldapServer
, const gchar
*value
) {
145 addrcache_refresh( ldapServer
->addressCache
);
146 ldapServer
->searchValue
= mgu_replace_string( ldapServer
->searchValue
, value
);
147 g_strstrip( ldapServer
->searchValue
);
148 ldapServer
->newSearch
= TRUE
;
152 * Specify maximum number of entries to retrieve.
154 void syldap_set_max_entries( SyldapServer
* ldapServer
, const gint value
) {
155 addrcache_refresh( ldapServer
->addressCache
);
157 ldapServer
->maxEntries
= value
;
160 ldapServer
->maxEntries
= SYLDAP_MAX_ENTRIES
;
165 * Specify timeout value for LDAP operation (in seconds).
167 void syldap_set_timeout( SyldapServer
* ldapServer
, const gint value
) {
168 addrcache_refresh( ldapServer
->addressCache
);
170 ldapServer
->timeOut
= value
;
173 ldapServer
->timeOut
= SYLDAP_DFL_TIMEOUT
;
178 * Register a callback function. When called, the function will be passed
179 * this object as an argument.
181 void syldap_set_callback( SyldapServer
*ldapServer
, void *func
) {
182 ldapServer
->callBack
= func
;
186 * Refresh internal variables to force a file read.
188 void syldap_force_refresh( SyldapServer
*ldapServer
) {
189 addrcache_refresh( ldapServer
->addressCache
);
190 ldapServer
->newSearch
= TRUE
;
193 gint
syldap_get_status( SyldapServer
*ldapServer
) {
194 g_return_val_if_fail( ldapServer
!= NULL
, -1 );
195 return ldapServer
->retVal
;
198 ItemFolder
*syldap_get_root_folder( SyldapServer
*ldapServer
) {
199 g_return_val_if_fail( ldapServer
!= NULL
, NULL
);
200 return addrcache_get_root_folder( ldapServer
->addressCache
);
203 gchar
*syldap_get_name( SyldapServer
*ldapServer
) {
204 g_return_val_if_fail( ldapServer
!= NULL
, NULL
);
205 return addrcache_get_name( ldapServer
->addressCache
);
208 gboolean
syldap_get_accessed( SyldapServer
*ldapServer
) {
209 g_return_val_if_fail( ldapServer
!= NULL
, FALSE
);
210 return ldapServer
->addressCache
->accessFlag
;
213 void syldap_set_accessed( SyldapServer
*ldapServer
, const gboolean value
) {
214 g_return_if_fail( ldapServer
!= NULL
);
215 ldapServer
->addressCache
->accessFlag
= value
;
218 gboolean
syldap_get_modified( SyldapServer
*ldapServer
) {
219 g_return_val_if_fail( ldapServer
!= NULL
, FALSE
);
220 return ldapServer
->addressCache
->modified
;
223 void syldap_set_modified( SyldapServer
*ldapServer
, const gboolean value
) {
224 g_return_if_fail( ldapServer
!= NULL
);
225 ldapServer
->addressCache
->modified
= value
;
229 * Free up LDAP server interface object by releasing internal memory.
231 void syldap_free( SyldapServer
*ldapServer
) {
232 g_return_if_fail( ldapServer
!= NULL
);
234 debug_print("Freeing LDAP server interface object\n");
236 ldapServer
->callBack
= NULL
;
239 addrcache_clear( ldapServer
->addressCache
);
240 addrcache_free( ldapServer
->addressCache
);
242 /* Free internal stuff */
243 g_free( ldapServer
->hostName
);
244 g_free( ldapServer
->baseDN
);
245 g_free( ldapServer
->bindDN
);
246 g_free( ldapServer
->bindPass
);
247 g_free( ldapServer
->searchCriteria
);
248 g_free( ldapServer
->searchValue
);
249 g_free( ldapServer
->thread
);
253 ldapServer
->hostName
= NULL
;
254 ldapServer
->port
= 0;
255 ldapServer
->baseDN
= NULL
;
256 ldapServer
->bindDN
= NULL
;
257 ldapServer
->bindPass
= NULL
;
258 ldapServer
->searchCriteria
= NULL
;
259 ldapServer
->searchValue
= NULL
;
260 ldapServer
->entriesRead
= 0;
261 ldapServer
->maxEntries
= 0;
262 ldapServer
->timeOut
= 0;
263 ldapServer
->newSearch
= FALSE
;
264 ldapServer
->thread
= NULL
;
265 ldapServer
->busyFlag
= FALSE
;
266 ldapServer
->callBack
= NULL
;
267 ldapServer
->idleId
= 0;
269 ldapServer
->type
= ADBOOKTYPE_NONE
;
270 ldapServer
->addressCache
= NULL
;
271 ldapServer
->retVal
= MGU_SUCCESS
;
273 /* Now release LDAP object */
274 g_free( ldapServer
);
278 * Display object to specified stream.
280 void syldap_print_data( SyldapServer
*ldapServer
, FILE *stream
) {
281 g_return_if_fail( ldapServer
!= NULL
);
283 fprintf( stream
, "SyldapServer:\n" );
284 fprintf( stream
, "host name: '%s'\n", ldapServer
->hostName
);
285 fprintf( stream
, " port: %d\n", ldapServer
->port
);
286 fprintf( stream
, " base dn: '%s'\n", ldapServer
->baseDN
);
287 fprintf( stream
, " bind dn: '%s'\n", ldapServer
->bindDN
);
288 fprintf( stream
, "bind pass: '%s'\n", ldapServer
->bindPass
);
289 fprintf( stream
, " criteria: '%s'\n", ldapServer
->searchCriteria
);
290 fprintf( stream
, "searchval: '%s'\n", ldapServer
->searchValue
);
291 fprintf( stream
, "max entry: %d\n", ldapServer
->maxEntries
);
292 fprintf( stream
, " num read: %d\n", ldapServer
->entriesRead
);
293 fprintf( stream
, " ret val: %d\n", ldapServer
->retVal
);
294 addrcache_print( ldapServer
->addressCache
, stream
);
295 addritem_print_item_folder( ldapServer
->addressCache
->rootFolder
, stream
);
299 * Display object to specified stream.
301 void syldap_print_short( SyldapServer
*ldapServer
, FILE *stream
) {
302 g_return_if_fail( ldapServer
!= NULL
);
304 fprintf( stream
, "SyldapServer:\n" );
305 fprintf( stream
, "host name: '%s'\n", ldapServer
->hostName
);
306 fprintf( stream
, " port: %d\n", ldapServer
->port
);
307 fprintf( stream
, " base dn: '%s'\n", ldapServer
->baseDN
);
308 fprintf( stream
, " bind dn: '%s'\n", ldapServer
->bindDN
);
309 fprintf( stream
, "bind pass: '%s'\n", ldapServer
->bindPass
);
310 fprintf( stream
, " criteria: '%s'\n", ldapServer
->searchCriteria
);
311 fprintf( stream
, "searchval: '%s'\n", ldapServer
->searchValue
);
312 fprintf( stream
, "max entry: %d\n", ldapServer
->maxEntries
);
313 fprintf( stream
, " num read: %d\n", ldapServer
->entriesRead
);
314 fprintf( stream
, " ret val: %d\n", ldapServer
->retVal
);
318 * Build an address list entry and append to list of address items. Name is formatted
319 * as "<first-name> <last-name>".
321 static void syldap_build_items_fl( SyldapServer
*ldapServer
, GSList
*listAddr
, GSList
*listFirst
, GSList
*listLast
) {
322 GSList
*nodeFirst
= listFirst
;
323 GSList
*nodeAddress
= listAddr
;
324 gchar
*firstName
= NULL
, *lastName
= NULL
, *fullName
= NULL
;
325 gint iLen
= 0, iLenT
= 0;
329 /* Find longest first name in list */
331 if( firstName
== NULL
) {
332 firstName
= nodeFirst
->data
;
333 iLen
= strlen( firstName
);
336 if( ( iLenT
= strlen( nodeFirst
->data
) ) > iLen
) {
337 firstName
= nodeFirst
->data
;
341 nodeFirst
= g_slist_next( nodeFirst
);
346 lastName
= listLast
->data
;
351 fullName
= g_strdup_printf( "%s %s", firstName
, lastName
);
354 fullName
= g_strdup_printf( "%s", firstName
);
359 fullName
= g_strdup_printf( "%s", lastName
);
363 g_strchug( fullName
); g_strchomp( fullName
);
367 person
= addritem_create_item_person();
368 addritem_person_set_common_name( person
, fullName
);
369 addritem_person_set_first_name( person
, firstName
);
370 addritem_person_set_last_name( person
, lastName
);
371 addrcache_id_person( ldapServer
->addressCache
, person
);
372 addrcache_add_person( ldapServer
->addressCache
, person
);
375 /* Add address item */
376 while( nodeAddress
) {
377 email
= addritem_create_item_email();
378 addritem_email_set_address( email
, nodeAddress
->data
);
379 addrcache_id_email( ldapServer
->addressCache
, email
);
380 addrcache_person_add_email( ldapServer
->addressCache
, person
, email
);
381 nodeAddress
= g_slist_next( nodeAddress
);
382 ldapServer
->entriesRead
++;
385 fullName
= firstName
= lastName
= NULL
;
390 * Add all attribute values to a list.
392 static GSList
*syldap_add_list_values( LDAP
*ld
, LDAPMessage
*entry
, char *attr
) {
397 if( ( vals
= ldap_get_values( ld
, entry
, attr
) ) != NULL
) {
398 for( i
= 0; vals
[i
] != NULL
; i
++ ) {
399 /* printf( "lv\t%s: %s\n", attr, vals[i] ); */
400 list
= g_slist_append( list
, g_strdup( vals
[i
] ) );
403 ldap_value_free( vals
);
408 * Add a single attribute value to a list.
410 static GSList
*syldap_add_single_value( LDAP
*ld
, LDAPMessage
*entry
, char *attr
) {
414 if( ( vals
= ldap_get_values( ld
, entry
, attr
) ) != NULL
) {
415 if( vals
[0] != NULL
) {
416 /* printf( "sv\t%s: %s\n", attr, vals[0] ); */
417 list
= g_slist_append( list
, g_strdup( vals
[0] ) );
420 ldap_value_free( vals
);
425 * Free linked lists of character strings.
427 static void syldap_free_lists( GSList
*listName
, GSList
*listAddr
, GSList
*listID
, GSList
*listDN
, GSList
*listFirst
, GSList
*listLast
) {
428 mgu_free_list( listName
);
429 mgu_free_list( listAddr
);
430 mgu_free_list( listID
);
431 mgu_free_list( listDN
);
432 mgu_free_list( listFirst
);
433 mgu_free_list( listLast
);
437 * Check parameters that are required for a search. This should
438 * be called before performing a search.
439 * Return: TRUE if search criteria appear OK.
441 gboolean
syldap_check_search( SyldapServer
*ldapServer
) {
442 g_return_val_if_fail( ldapServer
!= NULL
, FALSE
);
444 ldapServer
->retVal
= MGU_LDAP_CRITERIA
;
446 /* Test search criteria */
447 if( ldapServer
->searchCriteria
== NULL
) {
450 if( strlen( ldapServer
->searchCriteria
) < 1 ) {
454 if( ldapServer
->searchValue
== NULL
) {
457 if( strlen( ldapServer
->searchValue
) < 1 ) {
461 ldapServer
->retVal
= MGU_SUCCESS
;
466 * Perform the LDAP search, reading LDAP entries into cache.
467 * Note that one LDAP entry can have multiple values for many of its
468 * attributes. If these attributes are E-Mail addresses; these are
469 * broken out into separate address items. For any other attribute,
470 * only the first occurrence is read.
472 gint
syldap_search( SyldapServer
*ldapServer
) {
474 LDAPMessage
*result
, *e
;
480 GSList
*listName
= NULL
, *listAddress
= NULL
, *listID
= NULL
;
481 GSList
*listFirst
= NULL
, *listLast
= NULL
, *listDN
= NULL
;
482 struct timeval timeout
;
483 gboolean entriesFound
= FALSE
;
485 g_return_val_if_fail( ldapServer
!= NULL
, -1 );
487 ldapServer
->retVal
= MGU_SUCCESS
;
488 if( ! syldap_check_search( ldapServer
) ) {
489 return ldapServer
->retVal
;
493 timeout
.tv_sec
= ldapServer
->timeOut
;
494 timeout
.tv_usec
= 0L;
496 ldapServer
->entriesRead
= 0;
497 if( ( ld
= ldap_init( ldapServer
->hostName
, ldapServer
->port
) ) == NULL
) {
498 ldapServer
->retVal
= MGU_LDAP_INIT
;
499 return ldapServer
->retVal
;
502 /* printf( "connected to LDAP host %s on port %d\n", ldapServer->hostName, ldapServer->port ); */
504 /* Bind to the server, if required */
505 if( ldapServer
->bindDN
) {
506 if( * ldapServer
->bindDN
!= '\0' ) {
507 /* printf( "binding...\n" ); */
508 rc
= ldap_simple_bind_s( ld
, ldapServer
->bindDN
, ldapServer
->bindPass
);
509 /* printf( "rc=%d\n", rc ); */
510 if( rc
!= LDAP_SUCCESS
) {
511 /* printf( "LDAP Error: ldap_simple_bind_s: %s\n", ldap_err2string( rc ) ); */
513 ldapServer
->retVal
= MGU_LDAP_BIND
;
514 return ldapServer
->retVal
;
519 /* Define all attributes we are interested in. */
520 attribs
[0] = SYLDAP_ATTR_DN
;
521 attribs
[1] = SYLDAP_ATTR_COMMONNAME
;
522 attribs
[2] = SYLDAP_ATTR_GIVENNAME
;
523 attribs
[3] = SYLDAP_ATTR_SURNAME
;
524 attribs
[4] = SYLDAP_ATTR_EMAIL
;
525 attribs
[5] = SYLDAP_ATTR_UID
;
528 /* Create LDAP search string and apply search criteria */
529 criteria
= g_strdup_printf( ldapServer
->searchCriteria
, ldapServer
->searchValue
);
530 rc
= ldap_search_ext_s( ld
, ldapServer
->baseDN
, LDAP_SCOPE_SUBTREE
, criteria
, attribs
, 0, NULL
, NULL
,
531 &timeout
, 0, &result
);
534 if( rc
== LDAP_TIMEOUT
) {
536 ldapServer
->retVal
= MGU_LDAP_TIMEOUT
;
537 return ldapServer
->retVal
;
539 if( rc
!= LDAP_SUCCESS
) {
540 /* printf( "LDAP Error: ldap_search_st: %s\n", ldap_err2string( rc ) ); */
542 ldapServer
->retVal
= MGU_LDAP_SEARCH
;
543 return ldapServer
->retVal
;
546 /* printf( "Total results are: %d\n", ldap_count_entries( ld, result ) ); */
548 /* Clear the cache if we have new entries, otherwise leave untouched. */
549 if( ldap_count_entries( ld
, result
) > 0 ) {
550 addrcache_clear( ldapServer
->addressCache
);
553 /* Process results */
554 ldapServer
->entriesRead
= 0;
555 for( e
= ldap_first_entry( ld
, result
); e
!= NULL
; e
= ldap_next_entry( ld
, e
) ) {
557 if( ldapServer
->entriesRead
>= ldapServer
->maxEntries
) break;
558 /* printf( "DN: %s\n", ldap_get_dn( ld, e ) ); */
560 /* Process all attributes */
561 for( attribute
= ldap_first_attribute( ld
, e
, &ber
); attribute
!= NULL
;
562 attribute
= ldap_next_attribute( ld
, e
, ber
) ) {
563 if( strcasecmp( attribute
, SYLDAP_ATTR_COMMONNAME
) == 0 ) {
564 listName
= syldap_add_list_values( ld
, e
, attribute
);
566 if( strcasecmp( attribute
, SYLDAP_ATTR_EMAIL
) == 0 ) {
567 listAddress
= syldap_add_list_values( ld
, e
, attribute
);
569 if( strcasecmp( attribute
, SYLDAP_ATTR_UID
) == 0 ) {
570 listID
= syldap_add_single_value( ld
, e
, attribute
);
572 if( strcasecmp( attribute
, SYLDAP_ATTR_GIVENNAME
) == 0 ) {
573 listFirst
= syldap_add_list_values( ld
, e
, attribute
);
575 if( strcasecmp( attribute
, SYLDAP_ATTR_SURNAME
) == 0 ) {
576 listLast
= syldap_add_single_value( ld
, e
, attribute
);
578 if( strcasecmp( attribute
, SYLDAP_ATTR_DN
) == 0 ) {
579 listDN
= syldap_add_single_value( ld
, e
, attribute
);
582 /* Free memory used to store attribute */
583 ldap_memfree( attribute
);
586 /* Format and add items to cache */
587 syldap_build_items_fl( ldapServer
, listAddress
, listFirst
, listLast
);
590 syldap_free_lists( listName
, listAddress
, listID
, listDN
, listFirst
, listLast
);
591 listName
= listAddress
= listID
= listFirst
= listLast
= listDN
= NULL
;
598 syldap_free_lists( listName
, listAddress
, listID
, listDN
, listFirst
, listLast
);
599 listName
= listAddress
= listID
= listFirst
= listLast
= listDN
= NULL
;
601 /* Free up and disconnect */
602 ldap_msgfree( result
);
604 ldapServer
->newSearch
= FALSE
;
606 ldapServer
->retVal
= MGU_SUCCESS
;
609 ldapServer
->retVal
= MGU_LDAP_NOENTRIES
;
611 return ldapServer
->retVal
;
614 /* ============================================================================================ */
616 * Read data into list. Main entry point
617 * Return: TRUE if file read successfully.
619 /* ============================================================================================ */
620 gint
syldap_read_data( SyldapServer
*ldapServer
) {
621 g_return_val_if_fail( ldapServer
!= NULL
, -1 );
623 ldapServer
->addressCache
->accessFlag
= FALSE
;
624 pthread_detach( pthread_self() );
625 if( ldapServer
->newSearch
) {
626 /* Read data into the list */
627 syldap_search( ldapServer
);
630 ldapServer
->addressCache
->modified
= FALSE
;
631 ldapServer
->addressCache
->dataRead
= TRUE
;
632 ldapServer
->addressCache
->accessFlag
= FALSE
;
634 ldapServer
->busyFlag
= FALSE
;
636 return ldapServer
->retVal
;
639 /* ============================================================================================ */
641 * Cancel read with thread.
643 /* ============================================================================================ */
644 void syldap_cancel_read( SyldapServer
*ldapServer
) {
645 g_return_if_fail( ldapServer
!= NULL
);
647 if( ldapServer
->thread
) {
648 /* printf( "thread cancelled\n" ); */
649 pthread_cancel( *ldapServer
->thread
);
650 g_free(ldapServer
->thread
);
652 ldapServer
->thread
= NULL
;
653 ldapServer
->busyFlag
= FALSE
;
656 /* ============================================================================================ */
658 * Read data into list using a background thread.
659 * Return: TRUE if file read successfully. Callback function will be
660 * notified when search is complete.
662 /* ============================================================================================ */
663 gint
syldap_read_data_th( SyldapServer
*ldapServer
) {
664 g_return_val_if_fail( ldapServer
!= NULL
, -1 );
666 ldapServer
->busyFlag
= FALSE
;
667 syldap_check_search( ldapServer
);
668 if( ldapServer
->retVal
== MGU_SUCCESS
) {
669 /* debug_print("Starting LDAP read thread\n"); */
671 ldapServer
->busyFlag
= TRUE
;
672 ldapServer
->thread
= g_new0(pthread_t
, 1);
674 ldapServer
->thread
, NULL
, (void *) syldap_read_data
,
675 (void *) ldapServer
);
677 return ldapServer
->retVal
;
681 * Return link list of persons.
683 GList
*syldap_get_list_person( SyldapServer
*ldapServer
) {
684 g_return_val_if_fail( ldapServer
!= NULL
, NULL
);
685 return addrcache_get_list_person( ldapServer
->addressCache
);
689 * Return link list of folders. This is always NULL since there are
690 * no folders in GnomeCard.
693 GList
*syldap_get_list_folder( SyldapServer
*ldapServer
) {
694 g_return_val_if_fail( ldapServer
!= NULL
, NULL
);
698 #define SYLDAP_TEST_FILTER "(objectclass=*)"
699 #define SYLDAP_SEARCHBASE_V2 "cn=config"
700 #define SYLDAP_SEARCHBASE_V3 ""
701 #define SYLDAP_V2_TEST_ATTR "database"
702 #define SYLDAP_V3_TEST_ATTR "namingcontexts"
705 * Attempt to discover the base DN for the server.
709 * bindDN Bind DN (optional).
710 * bindPW Bind PW (optional).
711 * tov Timeout value (seconds), or 0 for none, default 30 secs.
712 * Return: List of Base DN's, or NULL if could not read. Base DN should
713 * be g_free() when done.
715 GList
*syldap_read_basedn_s( const gchar
*host
, const gint port
, const gchar
*bindDN
, const gchar
*bindPW
, const gint tov
) {
716 GList
*baseDN
= NULL
;
719 LDAPMessage
*result
, *e
;
724 struct timeval timeout
;
726 if( host
== NULL
) return baseDN
;
727 if( port
< 1 ) return baseDN
;
730 timeout
.tv_usec
= 0L;
732 timeout
.tv_sec
= tov
;
735 timeout
.tv_sec
= 30L;
738 /* Connect to server. */
739 if( ( ld
= ldap_init( host
, port
) ) == NULL
) {
743 /* Bind to the server, if required */
745 if( *bindDN
!= '\0' ) {
746 rc
= ldap_simple_bind_s( ld
, bindDN
, bindPW
);
747 if( rc
!= LDAP_SUCCESS
) {
748 /* printf( "LDAP Error: ldap_simple_bind_s: %s\n", ldap_err2string( rc ) ); */
755 /* Test for LDAP version 3 */
756 attribs
[0] = SYLDAP_V3_TEST_ATTR
;
758 rc
= ldap_search_ext_s( ld
, SYLDAP_SEARCHBASE_V3
, LDAP_SCOPE_BASE
, SYLDAP_TEST_FILTER
, attribs
,
759 0, NULL
, NULL
, &timeout
, 0, &result
);
760 if( rc
== LDAP_SUCCESS
) {
761 /* Process entries */
762 for( e
= ldap_first_entry( ld
, result
); e
!= NULL
; e
= ldap_next_entry( ld
, e
) ) {
763 /* printf( "DN: %s\n", ldap_get_dn( ld, e ) ); */
765 /* Process attributes */
766 for( attribute
= ldap_first_attribute( ld
, e
, &ber
); attribute
!= NULL
;
767 attribute
= ldap_next_attribute( ld
, e
, ber
) ) {
768 if( strcasecmp( attribute
, SYLDAP_V3_TEST_ATTR
) == 0 ) {
769 if( ( vals
= ldap_get_values( ld
, e
, attribute
) ) != NULL
) {
770 for( i
= 0; vals
[i
] != NULL
; i
++ ) {
771 /* printf( "\t%s: %s\n", attribute, vals[i] ); */
772 baseDN
= g_list_append( baseDN
, g_strdup( vals
[i
] ) );
775 ldap_value_free( vals
);
777 ldap_memfree( attribute
);
783 ldap_msgfree( result
);
788 if( baseDN
== NULL
) {
789 /* Test for LDAP version 2 */
791 rc
= ldap_search_ext_s( ld
, SYLDAP_SEARCHBASE_V2
, LDAP_SCOPE_BASE
, SYLDAP_TEST_FILTER
, attribs
,
792 0, NULL
, NULL
, &timeout
, 0, &result
);
793 if( rc
== LDAP_SUCCESS
) {
794 /* Process entries */
795 for( e
= ldap_first_entry( ld
, result
); e
!= NULL
; e
= ldap_next_entry( ld
, e
) ) {
796 /* if( baseDN ) break; */
797 /* printf( "DN: %s\n", ldap_get_dn( ld, e ) ); */
799 /* Process attributes */
800 for( attribute
= ldap_first_attribute( ld
, e
, &ber
); attribute
!= NULL
;
801 attribute
= ldap_next_attribute( ld
, e
, ber
) ) {
802 /* if( baseDN ) break; */
803 if( strcasecmp( attribute
, SYLDAP_V2_TEST_ATTR
) == 0 ) {
804 if( ( vals
= ldap_get_values( ld
, e
, attribute
) ) != NULL
) {
805 for( i
= 0; vals
[i
] != NULL
; i
++ ) {
807 /* Strip the 'ldb:' from the front of the value */
808 ch
= ( char * ) strchr( vals
[i
], ':' );
810 gchar
*bn
= g_strdup( ++ch
);
813 baseDN
= g_list_append( baseDN
, g_strdup( bn
) );
817 ldap_value_free( vals
);
819 ldap_memfree( attribute
);
825 ldap_msgfree( result
);
833 * Attempt to discover the base DN for the server.
834 * Enter: ldapServer Server to test.
835 * Return: List of Base DN's, or NULL if could not read. Base DN should
836 * be g_free() when done. Return code set in ldapServer.
838 GList
*syldap_read_basedn( SyldapServer
*ldapServer
) {
839 GList
*baseDN
= NULL
;
842 LDAPMessage
*result
, *e
;
847 struct timeval timeout
;
849 ldapServer
->retVal
= MGU_BAD_ARGS
;
850 if( ldapServer
== NULL
) return baseDN
;
851 if( ldapServer
->hostName
== NULL
) return baseDN
;
852 if( ldapServer
->port
< 1 ) return baseDN
;
855 timeout
.tv_usec
= 0L;
856 if( ldapServer
->timeOut
> 0 ) {
857 timeout
.tv_sec
= ldapServer
->timeOut
;
860 timeout
.tv_sec
= 30L;
863 /* Connect to server. */
864 if( ( ld
= ldap_init( ldapServer
->hostName
, ldapServer
->port
) ) == NULL
) {
865 ldapServer
->retVal
= MGU_LDAP_INIT
;
869 /* Bind to the server, if required */
870 if( ldapServer
->bindDN
) {
871 if( *ldapServer
->bindDN
!= '\0' ) {
872 rc
= ldap_simple_bind_s( ld
, ldapServer
->bindDN
, ldapServer
->bindPass
);
873 if( rc
!= LDAP_SUCCESS
) {
874 /* printf( "LDAP Error: ldap_simple_bind_s: %s\n", ldap_err2string( rc ) ); */
876 ldapServer
->retVal
= MGU_LDAP_BIND
;
882 ldapServer
->retVal
= MGU_LDAP_SEARCH
;
884 /* Test for LDAP version 3 */
885 attribs
[0] = SYLDAP_V3_TEST_ATTR
;
887 rc
= ldap_search_ext_s( ld
, SYLDAP_SEARCHBASE_V3
, LDAP_SCOPE_BASE
, SYLDAP_TEST_FILTER
, attribs
,
888 0, NULL
, NULL
, &timeout
, 0, &result
);
889 if( rc
== LDAP_SUCCESS
) {
890 /* Process entries */
891 for( e
= ldap_first_entry( ld
, result
); e
!= NULL
; e
= ldap_next_entry( ld
, e
) ) {
892 /* printf( "DN: %s\n", ldap_get_dn( ld, e ) ); */
894 /* Process attributes */
895 for( attribute
= ldap_first_attribute( ld
, e
, &ber
); attribute
!= NULL
;
896 attribute
= ldap_next_attribute( ld
, e
, ber
) ) {
897 if( strcasecmp( attribute
, SYLDAP_V3_TEST_ATTR
) == 0 ) {
898 if( ( vals
= ldap_get_values( ld
, e
, attribute
) ) != NULL
) {
899 for( i
= 0; vals
[i
] != NULL
; i
++ ) {
900 /* printf( "\t%s: %s\n", attribute, vals[i] ); */
901 baseDN
= g_list_append( baseDN
, g_strdup( vals
[i
] ) );
904 ldap_value_free( vals
);
906 ldap_memfree( attribute
);
912 ldap_msgfree( result
);
913 ldapServer
->retVal
= MGU_SUCCESS
;
915 else if( rc
== LDAP_TIMEOUT
) {
916 ldapServer
->retVal
= MGU_LDAP_TIMEOUT
;
919 if( baseDN
== NULL
) {
920 /* Test for LDAP version 2 */
922 rc
= ldap_search_ext_s( ld
, SYLDAP_SEARCHBASE_V2
, LDAP_SCOPE_BASE
, SYLDAP_TEST_FILTER
, attribs
,
923 0, NULL
, NULL
, &timeout
, 0, &result
);
924 if( rc
== LDAP_SUCCESS
) {
925 /* Process entries */
926 for( e
= ldap_first_entry( ld
, result
); e
!= NULL
; e
= ldap_next_entry( ld
, e
) ) {
927 /* if( baseDN ) break; */
928 /* printf( "DN: %s\n", ldap_get_dn( ld, e ) ); */
930 /* Process attributes */
931 for( attribute
= ldap_first_attribute( ld
, e
, &ber
); attribute
!= NULL
;
932 attribute
= ldap_next_attribute( ld
, e
, ber
) ) {
933 /* if( baseDN ) break; */
934 if( strcasecmp( attribute
, SYLDAP_V2_TEST_ATTR
) == 0 ) {
935 if( ( vals
= ldap_get_values( ld
, e
, attribute
) ) != NULL
) {
936 for( i
= 0; vals
[i
] != NULL
; i
++ ) {
938 /* Strip the 'ldb:' from the front of the value */
939 ch
= ( char * ) strchr( vals
[i
], ':' );
941 gchar
*bn
= g_strdup( ++ch
);
944 baseDN
= g_list_append( baseDN
, g_strdup( bn
) );
948 ldap_value_free( vals
);
950 ldap_memfree( attribute
);
956 ldap_msgfree( result
);
957 ldapServer
->retVal
= MGU_SUCCESS
;
959 else if( rc
== LDAP_TIMEOUT
) {
960 ldapServer
->retVal
= MGU_LDAP_TIMEOUT
;
969 * Attempt to connect to the server.
973 * Return: TRUE if connected successfully.
975 gboolean
syldap_test_connect_s( const gchar
*host
, const gint port
) {
976 gboolean retVal
= FALSE
;
979 if( host
== NULL
) return retVal
;
980 if( port
< 1 ) return retVal
;
981 if( ( ld
= ldap_open( host
, port
) ) != NULL
) {
991 * Attempt to connect to the server.
992 * Enter: ldapServer Server to test.
993 * Return: TRUE if connected successfully. Return code set in ldapServer.
995 gboolean
syldap_test_connect( SyldapServer
*ldapServer
) {
996 gboolean retVal
= FALSE
;
999 ldapServer
->retVal
= MGU_BAD_ARGS
;
1000 if( ldapServer
== NULL
) return retVal
;
1001 if( ldapServer
->hostName
== NULL
) return retVal
;
1002 if( ldapServer
->port
< 1 ) return retVal
;
1003 ldapServer
->retVal
= MGU_LDAP_INIT
;
1004 if( ( ld
= ldap_open( ldapServer
->hostName
, ldapServer
->port
) ) != NULL
) {
1005 ldapServer
->retVal
= MGU_SUCCESS
;
1015 * Test whether LDAP libraries installed.
1016 * Return: TRUE if library available.
1018 gboolean
syldap_test_ldap_lib() {
1022 #endif /* USE_LDAP */