2007-01-21 [colin] 2.7.1cvs48
[claws.git] / src / ldapquery.c
index 9baaa73687833ec39c9d8dd8fec153f98be80cec..54053e857f35653842813eb8b054371b7e03d1c3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2003-2004 Match Grun
+ * Copyright (C) 2003-2007 Match Grun and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 /*
@@ -32,6 +32,7 @@
 #include <string.h>
 #include <lber.h>
 
+#include "ldaputil.h"
 #include "ldapquery.h"
 #include "ldapctrl.h"
 #include "mgutils.h"
 #include "addritem.h"
 #include "addrcache.h"
 
-#include "ldapquery.h"
-
 /*
  * Key for thread specific data.
  */
 static pthread_key_t _queryThreadKey_;
 static gboolean _queryThreadInit_ = FALSE;
 
-gboolean callbackend (gpointer data)
+static gboolean callbackend (gpointer data)
 {
        LdapQuery *qry = (LdapQuery *)data;
        qry->callBackEnd( qry, ADDRQUERY_ID(qry), ADDRQUERY_RETVAL(qry), qry->data );
@@ -128,15 +127,6 @@ void ldapqry_set_search_value( LdapQuery *qry, const gchar *value ) {
        g_strstrip( ADDRQUERY_SEARCHVALUE(qry) );
 }
 
-/**
- * Specify error/status.
- * \param qry   Query object.
- * \param value Status.
- */
-void ldapqry_set_error_status( LdapQuery* qry, const gint value ) {
-       ADDRQUERY_RETVAL(qry) = value;
-}
-
 /**
  * Specify query type.
  * \param qry Query object.
@@ -172,20 +162,6 @@ void ldapqry_set_query_id( LdapQuery* qry, const gint value ) {
        ADDRQUERY_ID(qry) = value;
 }
 
-/**
- * Specify maximum number of LDAP entries to retrieve.
- * \param qry Query object.
- * \param value Entries to read.
- */
-void ldapqry_set_entries_read( LdapQuery* qry, const gint value ) {
-       if( value > 0 ) {
-               qry->entriesRead = value;
-       }
-       else {
-               qry->entriesRead = 0;
-       }
-}
-
 /**
  * Register a callback function that will be executed when each entry
  * has been read and processed. When called, the function will be passed
@@ -238,7 +214,7 @@ void ldapqry_set_callback_end( LdapQuery *qry, void *func ) {
  * \param qry Query object.
  * \param value Value of stop flag.
  */
-void ldapqry_set_stop_flag( LdapQuery *qry, const gboolean value ) {
+static void ldapqry_set_stop_flag( LdapQuery *qry, const gboolean value ) {
        g_return_if_fail( qry != NULL );
 
        pthread_mutex_lock( qry->mutexStop );
@@ -252,9 +228,9 @@ void ldapqry_set_stop_flag( LdapQuery *qry, const gboolean value ) {
  * \param qry Query object.
  * \return Value of stop flag.
  */
-gboolean ldapqry_get_stop_flag( LdapQuery *qry ) {
+static gboolean ldapqry_get_stop_flag( LdapQuery *qry ) {
        gboolean value;
-       g_return_if_fail( qry != NULL );
+       g_return_val_if_fail( qry != NULL, TRUE );
 
        pthread_mutex_lock( qry->mutexStop );
        value = qry->stopFlag;
@@ -267,7 +243,7 @@ gboolean ldapqry_get_stop_flag( LdapQuery *qry ) {
  * \param qry Query object.
  * \param value Value of busy flag.
  */
-void ldapqry_set_busy_flag( LdapQuery *qry, const gboolean value ) {
+static void ldapqry_set_busy_flag( LdapQuery *qry, const gboolean value ) {
        g_return_if_fail( qry != NULL );
 
        pthread_mutex_lock( qry->mutexBusy );
@@ -281,9 +257,9 @@ void ldapqry_set_busy_flag( LdapQuery *qry, const gboolean value ) {
  * \param qry Query object.
  * \return Value of busy flag.
  */
-gboolean ldapqry_get_busy_flag( LdapQuery *qry ) {
+static gboolean ldapqry_get_busy_flag( LdapQuery *qry ) {
        gboolean value;
-       g_return_if_fail( qry != NULL );
+       g_return_val_if_fail( qry != NULL, FALSE );
 
        pthread_mutex_lock( qry->mutexBusy );
        value = qry->busyFlag;
@@ -296,58 +272,16 @@ gboolean ldapqry_get_busy_flag( LdapQuery *qry ) {
  * \param qry Query object.
  * \param value Value of aged flag.
  */
-void ldapqry_set_aged_flag( LdapQuery *qry, const gboolean value ) {
+static void ldapqry_set_aged_flag( LdapQuery *qry, const gboolean value ) {
        g_return_if_fail( qry != NULL );
        qry->agedFlag = value;
 }
 
-/**
- * Test value of aged flag.
- * \param qry Query object.
- * \return <i>TRUE</i> if query has been marked as aged (and can be retired).
- */
-gboolean ldapqry_get_aged_flag( LdapQuery *qry ) {
-       g_return_if_fail( qry != NULL );
-       return qry->agedFlag;
-}
-
-/**
- * Specify user data for query.
- * \param qry Query object.
- * \param value Data to set.
- */
-void ldapqry_set_data( LdapQuery *qry, const gpointer value ) {
-       g_return_if_fail( qry != NULL );
-       qry->data = value;
-}
-
-/**
- * Retrieve user data associated with query.
- * \param qry Query object.
- * \return Data.
- */
-gpointer ldapqry_get_data( LdapQuery *qry ) {
-       g_return_if_fail( qry != NULL );
-       return qry->data;
-}
-
-/**
- * Release the LDAP control data associated with the query.
- * \param qry Query object to process.
- */
-void ldapqry_release_control( LdapQuery *qry ) {
-       g_return_if_fail( qry != NULL );
-       if( qry->control != NULL ) {
-               ldapctl_free( qry->control );
-       }
-       qry->control = NULL;
-}
-
 /**
  * Clear LDAP query member variables.
  * \param qry Query object.
  */
-void ldapqry_clear( LdapQuery *qry ) {
+static void ldapqry_clear( LdapQuery *qry ) {
        g_return_if_fail( qry != NULL );
 
        /* Free internal stuff */
@@ -408,30 +342,6 @@ void ldapqry_free( LdapQuery *qry ) {
        g_free( qry );
 }
 
-/**
- * Display object to specified stream.
- * \param qry    Query object to process.
- * \param stream Output stream.
- */
-void ldapqry_print( const LdapQuery *qry, FILE *stream ) {
-       g_return_if_fail( qry != NULL );
-
-       fprintf( stream, "LdapQuery:\n" );
-       fprintf( stream, "  control?: %s\n",   qry->control ? "yes" : "no" );
-       fprintf( stream, "err/status: %d\n",   ADDRQUERY_RETVAL(qry) );
-       fprintf( stream, "query type: %d\n",   ADDRQUERY_TYPE(qry) );
-       fprintf( stream, "searchType: %d\n",   ADDRQUERY_SEARCHTYPE(qry) );
-       fprintf( stream, "query name: '%s'\n", ADDRQUERY_NAME(qry) );
-       fprintf( stream, "search val: '%s'\n", ADDRQUERY_SEARCHVALUE(qry) );
-       fprintf( stream, "   queryID: %d\n",   ADDRQUERY_ID(qry) );
-       fprintf( stream, "   entries: %d\n",   qry->entriesRead );
-       fprintf( stream, "   elapsed: %d\n",   qry->elapsedTime );
-       fprintf( stream, " stop flag: %s\n",   qry->stopFlag  ? "yes" : "no" );
-       fprintf( stream, " busy flag: %s\n",   qry->busyFlag  ? "yes" : "no" );
-       fprintf( stream, " aged flag: %s\n",   qry->agedFlag  ? "yes" : "no" );
-       fprintf( stream, " completed: %s\n",   qry->completed ? "yes" : "no" );
-}
-
 /**
  * Free linked lists of character strings.
  * \param listName  List of common names.
@@ -461,15 +371,15 @@ static GSList *ldapqry_add_list_values(
 {
        GSList *list = NULL;
        gint i;
-       gchar **vals;
+       struct berval **vals;
 
-       if( ( vals = ldap_get_values( ld, entry, attr ) ) != NULL ) {
+       if( ( vals = ldap_get_values_len( ld, entry, attr ) ) != NULL ) {
                for( i = 0; vals[i] != NULL; i++ ) {
                        /* printf( "lv\t%s: %s\n", attr, vals[i] ); */
-                       list = g_slist_append( list, g_strdup( vals[i] ) );
+                       list = g_slist_append( list, g_strndup( vals[i]->bv_val, vals[i]->bv_len) );
                }
        }
-       ldap_value_free( vals );
+       ldap_value_free_len( vals );
        return list;
 }
 
@@ -482,15 +392,15 @@ static GSList *ldapqry_add_list_values(
  */
 static GSList *ldapqry_add_single_value( LDAP *ld, LDAPMessage *entry, char *attr ) {
        GSList *list = NULL;
-       gchar **vals;
+       struct berval **vals;
 
-       if( ( vals = ldap_get_values( ld, entry, attr ) ) != NULL ) {
+       if( ( vals = ldap_get_values_len( ld, entry, attr ) ) != NULL ) {
                if( vals[0] != NULL ) {
                        /* printf( "sv\t%s: %s\n", attr, vals[0] ); */
-                       list = g_slist_append( list, g_strdup( vals[0] ) );
+                       list = g_slist_append( list, g_strndup( vals[0]->bv_val, vals[0]->bv_len ));
                }
        }
-       ldap_value_free( vals );
+       ldap_value_free_len( vals );
        return list;
 }
 
@@ -700,9 +610,10 @@ void ldapqry_touch( LdapQuery *qry ) {
  */
 static gint ldapqry_connect( LdapQuery *qry ) {
        LdapControl *ctl;
-       LDAP *ld;
+       LDAP *ld = NULL;
        gint rc;
        gint version;
+       gchar *uri = NULL;
 
        /* Initialize connection */
        /* printf( "===ldapqry_connect===\n" ); */
@@ -714,9 +625,16 @@ static gint ldapqry_connect( LdapQuery *qry ) {
        qry->startTime = qry->touchTime;
        qry->elapsedTime = -1;
        ADDRQUERY_RETVAL(qry) = LDAPRC_INIT;
-       if( ( ld = ldap_init( ctl->hostName, ctl->port ) ) == NULL ) {
+
+       uri = g_strdup_printf("ldap%s://%s:%d",
+                               ctl->enableSSL?"s":"",
+                               ctl->hostName, ctl->port);
+       ldap_initialize(&ld, uri);
+       g_free(uri);
+
+       if (ld == NULL)
                return ADDRQUERY_RETVAL(qry);
-       }
+
        qry->ldap = ld;
        ADDRQUERY_RETVAL(qry) = LDAPRC_STOP_FLAG;
        if( ldapqry_get_stop_flag( qry ) ) {
@@ -737,13 +655,13 @@ static gint ldapqry_connect( LdapQuery *qry ) {
        }
 
        if( ctl->version == LDAP_VERSION3 ) {
-               if( ctl->enableTLS ) {
+               if( ctl->enableTLS && !ctl->enableSSL ) {
                        ADDRQUERY_RETVAL(qry) = LDAPRC_TLS;
                        rc = ldap_start_tls_s( ld, NULL, NULL );
-                       /*
-                       printf( "rc=%d\n", rc );
-                       printf( "LDAP Status: set_option: %s\n", ldap_err2string( rc ) );
-                       */
+                       
+                       /* printf( "rc=%d\n", rc );
+                       printf( "LDAP Status: set_option: %s\n", ldap_err2string( rc ) ); */
+                       
                        if( rc != LDAP_SUCCESS ) {
                                return ADDRQUERY_RETVAL(qry);
                        }
@@ -756,7 +674,7 @@ static gint ldapqry_connect( LdapQuery *qry ) {
        if( ctl->bindDN ) {
                if( * ctl->bindDN != '\0' ) {
                        /* printf( "binding...\n" ); */
-                       rc = ldap_simple_bind_s( ld, ctl->bindDN, ctl->bindPass );
+                       rc = claws_ldap_simple_bind_s( ld, ctl->bindDN, ctl->bindPass );
                        /* printf( "rc=%d\n", rc ); */
                        if( rc != LDAP_SUCCESS ) {
                                /*
@@ -785,7 +703,7 @@ static gint ldapqry_connect( LdapQuery *qry ) {
  */
 static gint ldapqry_disconnect( LdapQuery *qry ) {
        /* Disconnect */
-       if( qry->ldap ) ldap_unbind( qry->ldap );
+       if( qry->ldap ) ldap_unbind_ext( qry->ldap, NULL, NULL );
        qry->ldap = NULL;
 
        ldapqry_touch( qry );
@@ -807,7 +725,7 @@ static gint ldapqry_disconnect( LdapQuery *qry ) {
 static gint ldapqry_search_retrieve( LdapQuery *qry ) {
        LdapControl *ctl;
        LDAP *ld;
-       LDAPMessage *result, *e;
+       LDAPMessage *result, *e = NULL;
        char **attribs;
        gchar *criteria;
        gboolean searchFlag;
@@ -951,12 +869,14 @@ static gint ldapqry_perform_search( LdapQuery *qry ) {
        return ADDRQUERY_RETVAL(qry);
 }
 
+static gint ldapqry_perform_locate( LdapQuery *qry );
+
 /**
  * Wrapper around search.
  * \param  qry Query object to process.
  * \return Error/status code.
  */
-gint ldapqry_search( LdapQuery *qry ) {
+static gint ldapqry_search( LdapQuery *qry ) {
        gint retVal;
 
        g_return_val_if_fail( qry != NULL, -1 );
@@ -1160,17 +1080,6 @@ void ldapqry_free_name_value( NameValuePair *nvp ) {
        }
 }
 
-/**
- * Print name/value pair object for debug.
- * \param nvp    Name/value object.
- * \param stream Output stream.
- */
-void ldapqry_print_name_value( NameValuePair *nvp, FILE *stream ) {
-       if( nvp ) {
-               fprintf( stream, "n/v ::%s::%s::\n", nvp->name, nvp->value );
-       }
-}
-
 /**
  * Free up a list name/value pair objects.
  * \param list List of name/value objects.
@@ -1202,17 +1111,19 @@ static GList *ldapqry_load_attrib_values(
 {
        GList *list = NULL;
        gint i;
-       gchar **vals;
+       struct berval **vals;
        NameValuePair *nvp;
 
        list = listValues;
-       if( ( vals = ldap_get_values( ld, entry, attr ) ) != NULL ) {
+       if( ( vals = ldap_get_values_len( ld, entry, attr ) ) != NULL ) {
                for( i = 0; vals[i] != NULL; i++ ) {
-                       nvp = ldapqry_create_name_value( attr, vals[i] );
+                       gchar *tmp = g_strndup( vals[i]->bv_val, vals[i]->bv_len);
+                       nvp = ldapqry_create_name_value( attr, tmp );
+                       g_free(tmp);
                        list = g_list_append( list, nvp );
                }
        }
-       ldap_value_free( vals );
+       ldap_value_free_len( vals );
        return list;
 }
 
@@ -1253,7 +1164,7 @@ static GList *ldapqry_fetch_attribs( LDAP *ld, LDAPMessage *e )
 static gint ldapqry_locate_retrieve( LdapQuery *qry ) {
        LdapControl *ctl;
        LDAP *ld;
-       LDAPMessage *result, *e;
+       LDAPMessage *result, *e = NULL;
        gboolean entriesFound;
        gboolean first;
        struct timeval timeout;
@@ -1351,7 +1262,7 @@ static gint ldapqry_locate_retrieve( LdapQuery *qry ) {
  * \param  qry Query object to process.
  * \return Error/status code.
  */
-gint ldapqry_perform_locate( LdapQuery *qry ) {
+static gint ldapqry_perform_locate( LdapQuery *qry ) {
        /* Connect */
        qry->ldap = NULL;
        ldapqry_connect( qry );