• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

KLDAP Library

ldapconnection.cpp

00001 /*
00002   This file is part of libkldap.
00003   Copyright (c) 2004-2006 Szombathelyi György <gyurco@freemail.hu>
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Library General  Public
00007   License as published by the Free Software Foundation; either
00008   version 2 of the License, or (at your option) any later version.
00009 
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Library General Public License for more details.
00014 
00015   You should have received a copy of the GNU Library General Public License
00016   along with this library; see the file COPYING.LIB.  If not, write to
00017   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018   Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "kldap_config.h" // SASL2_FOUND, LDAP_FOUND
00022 #include "ldapconnection.h"
00023 #include "ldapdefs.h"
00024 
00025 #include <stdlib.h>
00026 #include <klocale.h>
00027 #include <kdebug.h>
00028 
00029 #ifdef SASL2_FOUND
00030 #include <sasl/sasl.h>
00031 static sasl_callback_t callbacks[] = {
00032   { SASL_CB_ECHOPROMPT, NULL, NULL },
00033   { SASL_CB_NOECHOPROMPT, NULL, NULL },
00034   { SASL_CB_GETREALM, NULL, NULL },
00035   { SASL_CB_USER, NULL, NULL },
00036   { SASL_CB_AUTHNAME, NULL, NULL },
00037   { SASL_CB_PASS, NULL, NULL },
00038   { SASL_CB_CANON_USER, NULL, NULL },
00039   { SASL_CB_LIST_END, NULL, NULL }
00040 };
00041 
00042 static bool ldapoperation_sasl_initialized = false;
00043 #endif
00044                                 
00045 #ifdef LDAP_FOUND
00046 #include <lber.h>
00047 #include <ldap.h>
00048 
00049 #ifndef LDAP_OPT_SUCCESS
00050 #define LDAP_OPT_SUCCESS 0
00051 #endif
00052 
00053 #endif
00054 
00055 using namespace KLDAP;
00056 
00057 class LdapConnection::LdapConnectionPrivate
00058 {
00059   public:
00060     LdapConnectionPrivate();
00061     LdapServer mServer;
00062     QString mConnectionError;
00063 
00064 #ifdef LDAP_FOUND
00065     LDAP *mLDAP;
00066 #else
00067     void *mLDAP;
00068 #endif
00069 #ifdef SASL2_FOUND
00070   sasl_conn_t *mSASLconn;
00071 #else
00072   void *mSASLconn;
00073 #endif
00074   
00075 };
00076 
00077 LdapConnection::LdapConnectionPrivate::LdapConnectionPrivate()
00078 {
00079   mSASLconn = 0;
00080 #ifdef SASL2_FOUND
00081   if ( !ldapoperation_sasl_initialized ) {
00082     sasl_client_init(NULL);
00083     ldapoperation_sasl_initialized = true;
00084   }
00085 #endif
00086 }
00087 
00088 LdapConnection::LdapConnection()
00089   : d( new LdapConnectionPrivate )
00090 {
00091   d->mLDAP = 0;
00092 }
00093 
00094 LdapConnection::LdapConnection( const LdapUrl &url )
00095   : d( new LdapConnectionPrivate )
00096 {
00097   d->mLDAP = 0;
00098   setUrl( url );
00099 }
00100 
00101 LdapConnection::LdapConnection( const LdapServer &server )
00102   : d( new LdapConnectionPrivate )
00103 {
00104   d->mLDAP = 0;
00105   setServer( server );
00106 }
00107 
00108 LdapConnection::~LdapConnection()
00109 {
00110   close();
00111   delete d;
00112 }
00113 
00114 void LdapConnection::setUrl( const LdapUrl &url )
00115 {
00116   d->mServer.setUrl( url );
00117 }
00118 
00119 void LdapConnection::setServer( const LdapServer &server )
00120 {
00121   d->mServer = server;
00122 }
00123 
00124 const LdapServer &LdapConnection::server() const
00125 {
00126   return d->mServer;
00127 }
00128 
00129 void *LdapConnection::handle() const
00130 {
00131   return (void *)d->mLDAP;
00132 }
00133 
00134 void *LdapConnection::saslHandle() const
00135 {
00136   return (void *)d->mSASLconn;
00137 }
00138 
00139 QString LdapConnection::errorString( int code )
00140 {
00141   //No translated error messages yet
00142 #ifdef LDAP_FOUND
00143   return QString::fromUtf8( ldap_err2string( code ) );
00144   switch ( code ) {
00145     case LDAP_OPERATIONS_ERROR: return i18n("LDAP Operations error");
00146     //FIXME:
00147     /* add the LDAP error codes */
00148   }
00149 #else
00150   return i18n("No LDAP Support...");
00151 #endif
00152 }
00153 
00154 QString LdapConnection::saslErrorString() const
00155 {
00156 #ifdef SASL2_FOUND
00157   const char *str;
00158   str = sasl_errdetail( d->mSASLconn );
00159   return QString::fromLocal8Bit( str );
00160 #else
00161   return i18n("SASL support is not available...Please recompile libkldap with the "
00162     "Cyrus-SASL (or compatible) client libraries, or complain to your "
00163     "distribution packagers.");
00164 #endif
00165 }
00166 
00167 QString LdapConnection::connectionError() const
00168 {
00169   return d->mConnectionError;
00170 }
00171 
00172 #ifdef LDAP_FOUND
00173 int LdapConnection::getOption( int option, void *value ) const
00174 {
00175   Q_ASSERT( d->mLDAP );
00176   return ldap_get_option( d->mLDAP, option, value );
00177 }
00178 
00179 int LdapConnection::setOption( int option, void *value )
00180 {
00181   Q_ASSERT( d->mLDAP );
00182   return ldap_set_option( d->mLDAP, option, value );
00183 }
00184 
00185 int LdapConnection::ldapErrorCode() const
00186 {
00187   Q_ASSERT( d->mLDAP );
00188   int err;
00189   ldap_get_option( d->mLDAP, LDAP_OPT_ERROR_NUMBER, &err );
00190   return err;
00191 }
00192 
00193 QString LdapConnection::ldapErrorString() const
00194 {
00195   Q_ASSERT( d->mLDAP );
00196   char *errmsg;
00197   ldap_get_option( d->mLDAP, LDAP_OPT_ERROR_STRING, &errmsg );
00198   QString msg = QString::fromLocal8Bit( errmsg );
00199   free( errmsg );
00200   return msg;
00201 }
00202 
00203 bool LdapConnection::setSizeLimit( int sizelimit )
00204 {
00205   Q_ASSERT( d->mLDAP );
00206   kDebug(5322) << "sizelimit:" << sizelimit;
00207   if ( setOption( LDAP_OPT_SIZELIMIT, &sizelimit ) != LDAP_OPT_SUCCESS ) {
00208     return false;
00209   }
00210   return true;
00211 }
00212 
00213 int LdapConnection::sizeLimit() const
00214 {
00215   Q_ASSERT( d->mLDAP );
00216   int sizelimit;
00217   if ( getOption( LDAP_OPT_SIZELIMIT, &sizelimit ) != LDAP_OPT_SUCCESS ) {
00218     return -1;
00219   }
00220   return sizelimit;
00221 }
00222 
00223 bool LdapConnection::setTimeLimit( int timelimit )
00224 {
00225   Q_ASSERT( d->mLDAP );
00226   kDebug(5322) << "timelimit:" << timelimit;
00227   if ( setOption( LDAP_OPT_TIMELIMIT, &timelimit ) != LDAP_OPT_SUCCESS ) {
00228     return false;
00229   }
00230   return true;
00231 }
00232 
00233 int LdapConnection::timeLimit() const
00234 {
00235   Q_ASSERT( d->mLDAP );
00236   int timelimit;
00237   if ( getOption( LDAP_OPT_TIMELIMIT, &timelimit ) != LDAP_OPT_SUCCESS ) {
00238     return -1;
00239   }
00240   return timelimit;
00241 }
00242 
00243 int LdapConnection::connect()
00244 {
00245   int ret;
00246   QString url;
00247   if ( d->mLDAP ) {
00248     close();
00249   }
00250 
00251   int version = d->mServer.version();
00252   int timeout = d->mServer.timeout();
00253 
00254   url = d->mServer.security() == LdapServer::SSL ? "ldaps" : "ldap";
00255   url += "://";
00256   url += d->mServer.host();
00257   url += ':';
00258   url += QString::number( d->mServer.port() );
00259   kDebug(5322) << "ldap url:" << url;
00260 #ifdef HAVE_LDAP_INITIALIZE
00261   ret = ldap_initialize( &d->mLDAP, url.toLatin1() );
00262 #else
00263   d->mLDAP = ldap_init( d->mServer.host().toLatin1().data(), d->mServer.port() );
00264   if ( d->mLDAP == 0 ) {
00265     ret = -1;
00266   }
00267 #endif
00268   if ( ret != LDAP_SUCCESS ) {
00269     d->mConnectionError = i18n("An error occurred during the connection initialization phase.");
00270     return ret;
00271   }
00272 
00273   kDebug(5322) << "setting version to:" << version;
00274   if ( setOption( LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS ) {
00275     ret = ldapErrorCode();
00276     d->mConnectionError = i18n("Cannot set protocol version to %1.", version );
00277     close();
00278     return ret;
00279   }
00280 
00281 #if defined(LDAP_OPT_TIMEOUT)
00282   kDebug(5322) << "setting timeout to:" << timeout;
00283 
00284   if ( timeout ) {
00285     if ( setOption( LDAP_OPT_TIMEOUT, &timeout ) != LDAP_OPT_SUCCESS ) {
00286       ret = ldapErrorCode();
00287       d->mConnectionError = i18n("Cannot set timeout to %1 seconds.", timeout );
00288       close();
00289       return ret;
00290     }
00291   }
00292 #endif
00293 
00294   //FIXME: accessing to certificate handling would be good
00295   kDebug(5322) << "setting security to:" << d->mServer.security();
00296   if ( d->mServer.security() == LdapServer::TLS ) {
00297     kDebug(5322) << "start TLS";
00298 #ifdef HAVE_LDAP_START_TLS_S
00299     if ( ( ret = ldap_start_tls_s( d->mLDAP, NULL, NULL ) ) != LDAP_SUCCESS ) {
00300       d->mConnectionError = ldapErrorString();
00301       close();
00302       return ret;
00303     }
00304 #else
00305     close();
00306     d->mConnectionError = i18n("TLS support not available in the LDAP client libraries.");
00307     return -1;
00308 #endif
00309   }
00310 
00311   kDebug(5322) << "setting sizelimit to:" << d->mServer.sizeLimit();
00312   if ( d->mServer.sizeLimit() ) {
00313     if ( !setSizeLimit( d->mServer.sizeLimit() ) ) {
00314       ret = ldapErrorCode();
00315       close();
00316       d->mConnectionError = i18n("Cannot set size limit.");
00317       return ret;
00318     }
00319   }
00320 
00321   kDebug(5322) << "setting timelimit to:" << d->mServer.timeLimit();
00322   if ( d->mServer.timeLimit() ) {
00323     if ( !setTimeLimit( d->mServer.timeLimit() ) ) {
00324       ret = ldapErrorCode();
00325       close();
00326       d->mConnectionError = i18n("Cannot set time limit.");
00327       return ret;
00328     }
00329   }
00330 
00331 #ifdef SASL2_FOUND
00332   kDebug(5322) << "initializing SASL client";
00333   int saslresult = sasl_client_new( "ldap", d->mServer.host().toLatin1(),
00334         0, 0, callbacks, 0, &d->mSASLconn );
00335   if ( saslresult != SASL_OK ) {
00336     d->mConnectionError = i18n("Cannot initialize the SASL client.");
00337     return KLDAP_SASL_ERROR;
00338   }
00339 #endif
00340 
00341   return 0;
00342 }
00343 
00344 void LdapConnection::close()
00345 {
00346   if ( d->mLDAP ) {
00347 #ifdef HAVE_LDAP_UNBIND_EXT
00348     ldap_unbind_ext( d->mLDAP, 0, 0 );
00349 #else
00350     ldap_unbind( d->mLDAP );
00351 #endif
00352   }
00353   d->mLDAP = 0;
00354 #ifdef SASL2_FOUND
00355   if ( d->mSASLconn ) {
00356     sasl_dispose( &d->mSASLconn );
00357     d->mSASLconn = 0;
00358   }
00359 #endif
00360   kDebug(5322) << "connection closed!";
00361 }
00362 #else //LDAP_FOUND
00363 
00364 int LdapConnection::getOption( int option, void *value ) const
00365 {
00366   kError() << "No LDAP support...";
00367   return -1;
00368 }
00369 
00370 int LdapConnection::setOption( int option, void *value )
00371 {
00372   kError() << "No LDAP support...";
00373   return -1;
00374 }
00375 
00376 int LdapConnection::ldapErrorCode() const
00377 {
00378   kError() << "No LDAP support...";
00379   return -1;
00380 }
00381 
00382 QString LdapConnection::ldapErrorString() const
00383 {
00384   kError() << "No LDAP support...";
00385   return QString();
00386 }
00387 
00388 bool LdapConnection::setSizeLimit( int sizelimit )
00389 {
00390   kError() << "No LDAP support...";
00391   return false;
00392 }
00393 
00394 int LdapConnection::sizeLimit() const
00395 {
00396   kError() << "No LDAP support...";
00397   return -1;
00398 }
00399 
00400 bool LdapConnection::setTimeLimit( int timelimit )
00401 {
00402   kError() << "No LDAP support...";
00403   return false;
00404 }
00405 
00406 int LdapConnection::timeLimit() const
00407 {
00408   kError() << "No LDAP support...";
00409   return -1;
00410 }
00411 
00412 int LdapConnection::connect( )
00413 {
00414   d->mConnectionError =
00415     i18n("LDAP support not compiled in. Please recompile libkldap with the "
00416          "OpenLDAP (or compatible) client libraries, or complain to your "
00417          "distribution packagers.");
00418   kError() << "No LDAP support...";
00419   return -1;
00420 }
00421 
00422 void LdapConnection::close()
00423 {
00424   kError() << "No LDAP support...";
00425 }
00426 
00427 #endif

KLDAP Library

Skip menu "KLDAP Library"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • kabc
  • kblog
  • kcal
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal