• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • KDE Home
  • 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 "ldapconnection.h"
00022 #include "ldapdefs.h"
00023 #include "kldap_config.h" // SASL2_FOUND, LDAP_FOUND
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 # ifndef HAVE_WINLDAP_H
00047 #  include <lber.h>
00048 #  include <ldap.h>
00049 #else
00050 # include <w32-ldap-help.h>
00051 #endif // HAVE_WINLDAP_H
00052 
00053 #ifndef LDAP_OPT_SUCCESS
00054 #define LDAP_OPT_SUCCESS 0
00055 #endif
00056 
00057 #endif
00058 
00059 using namespace KLDAP;
00060 
00061 class LdapConnection::LdapConnectionPrivate
00062 {
00063   public:
00064     LdapConnectionPrivate();
00065     LdapServer mServer;
00066     QString mConnectionError;
00067 
00068 #ifdef LDAP_FOUND
00069     LDAP *mLDAP;
00070 #else
00071     void *mLDAP;
00072 #endif
00073 #ifdef SASL2_FOUND
00074   sasl_conn_t *mSASLconn;
00075 #else
00076   void *mSASLconn;
00077 #endif
00078 
00079 };
00080 
00081 LdapConnection::LdapConnectionPrivate::LdapConnectionPrivate()
00082 {
00083   mSASLconn = 0;
00084 #ifdef SASL2_FOUND
00085   if ( !ldapoperation_sasl_initialized ) {
00086     sasl_client_init(NULL);
00087     ldapoperation_sasl_initialized = true;
00088   }
00089 #endif
00090 }
00091 
00092 LdapConnection::LdapConnection()
00093   : d( new LdapConnectionPrivate )
00094 {
00095   d->mLDAP = 0;
00096 }
00097 
00098 LdapConnection::LdapConnection( const LdapUrl &url )
00099   : d( new LdapConnectionPrivate )
00100 {
00101   d->mLDAP = 0;
00102   setUrl( url );
00103 }
00104 
00105 LdapConnection::LdapConnection( const LdapServer &server )
00106   : d( new LdapConnectionPrivate )
00107 {
00108   d->mLDAP = 0;
00109   setServer( server );
00110 }
00111 
00112 LdapConnection::~LdapConnection()
00113 {
00114   close();
00115   delete d;
00116 }
00117 
00118 void LdapConnection::setUrl( const LdapUrl &url )
00119 {
00120   d->mServer.setUrl( url );
00121 }
00122 
00123 void LdapConnection::setServer( const LdapServer &server )
00124 {
00125   d->mServer = server;
00126 }
00127 
00128 const LdapServer &LdapConnection::server() const
00129 {
00130   return d->mServer;
00131 }
00132 
00133 void *LdapConnection::handle() const
00134 {
00135   return (void *)d->mLDAP;
00136 }
00137 
00138 void *LdapConnection::saslHandle() const
00139 {
00140   return (void *)d->mSASLconn;
00141 }
00142 
00143 QString LdapConnection::errorString( int code )
00144 {
00145   //No translated error messages yet
00146 #ifdef LDAP_FOUND
00147   return QString::fromUtf8( ldap_err2string( code ) );
00148   switch ( code ) {
00149   case LDAP_OPERATIONS_ERROR:
00150     return i18n( "LDAP Operations error" );
00151     //FIXME:
00152     /* add the LDAP error codes */
00153   }
00154 #else
00155   return i18n( "No LDAP Support..." );
00156 #endif
00157 }
00158 
00159 QString LdapConnection::saslErrorString() const
00160 {
00161 #ifdef SASL2_FOUND
00162   const char *str;
00163   str = sasl_errdetail( d->mSASLconn );
00164   return QString::fromLocal8Bit( str );
00165 #else
00166   return i18n( "SASL support is not available. Please recompile libkldap with the "
00167                "Cyrus-SASL (or compatible) client libraries, or complain to your "
00168                "distribution packagers." );
00169 #endif
00170 }
00171 
00172 QString LdapConnection::connectionError() const
00173 {
00174   return d->mConnectionError;
00175 }
00176 
00177 #ifdef LDAP_FOUND
00178 int LdapConnection::getOption( int option, void *value ) const
00179 {
00180   Q_ASSERT( d->mLDAP );
00181   return ldap_get_option( d->mLDAP, option, value );
00182 }
00183 
00184 int LdapConnection::setOption( int option, void *value )
00185 {
00186   Q_ASSERT( d->mLDAP );
00187   return ldap_set_option( d->mLDAP, option, value );
00188 }
00189 
00190 int LdapConnection::ldapErrorCode() const
00191 {
00192   Q_ASSERT( d->mLDAP );
00193   int err;
00194   ldap_get_option( d->mLDAP, LDAP_OPT_ERROR_NUMBER, &err );
00195   return err;
00196 }
00197 
00198 QString LdapConnection::ldapErrorString() const
00199 {
00200   Q_ASSERT( d->mLDAP );
00201   char *errmsg;
00202   ldap_get_option( d->mLDAP, LDAP_OPT_ERROR_STRING, &errmsg );
00203   QString msg = QString::fromLocal8Bit( errmsg );
00204   free( errmsg );
00205   return msg;
00206 }
00207 
00208 bool LdapConnection::setSizeLimit( int sizelimit )
00209 {
00210   Q_ASSERT( d->mLDAP );
00211   kDebug() << "sizelimit:" << sizelimit;
00212   if ( setOption( LDAP_OPT_SIZELIMIT, &sizelimit ) != LDAP_OPT_SUCCESS ) {
00213     return false;
00214   }
00215   return true;
00216 }
00217 
00218 int LdapConnection::sizeLimit() const
00219 {
00220   Q_ASSERT( d->mLDAP );
00221   int sizelimit;
00222   if ( getOption( LDAP_OPT_SIZELIMIT, &sizelimit ) != LDAP_OPT_SUCCESS ) {
00223     return -1;
00224   }
00225   return sizelimit;
00226 }
00227 
00228 bool LdapConnection::setTimeLimit( int timelimit )
00229 {
00230   Q_ASSERT( d->mLDAP );
00231   kDebug() << "timelimit:" << timelimit;
00232   if ( setOption( LDAP_OPT_TIMELIMIT, &timelimit ) != LDAP_OPT_SUCCESS ) {
00233     return false;
00234   }
00235   return true;
00236 }
00237 
00238 int LdapConnection::timeLimit() const
00239 {
00240   Q_ASSERT( d->mLDAP );
00241   int timelimit;
00242   if ( getOption( LDAP_OPT_TIMELIMIT, &timelimit ) != LDAP_OPT_SUCCESS ) {
00243     return -1;
00244   }
00245   return timelimit;
00246 }
00247 
00248 int LdapConnection::connect()
00249 {
00250   int ret;
00251   QString url;
00252   if ( d->mLDAP ) {
00253     close();
00254   }
00255 
00256   int version = d->mServer.version();
00257   int timeout = d->mServer.timeout();
00258 
00259   url = d->mServer.security() == LdapServer::SSL ? "ldaps" : "ldap";
00260   url += "://";
00261   url += d->mServer.host();
00262   url += ':';
00263   url += QString::number( d->mServer.port() );
00264   kDebug() << "ldap url:" << url;
00265 #ifdef HAVE_LDAP_INITIALIZE
00266   ret = ldap_initialize( &d->mLDAP, url.toLatin1() );
00267 #else
00268   d->mLDAP = ldap_init( d->mServer.host().toLatin1().data(), d->mServer.port() );
00269   if ( d->mLDAP == 0 ) {
00270     ret = -1;
00271   } else {
00272     ret = LDAP_SUCCESS;
00273   }
00274 #endif
00275   if ( ret != LDAP_SUCCESS ) {
00276     d->mConnectionError = i18n( "An error occurred during the connection initialization phase." );
00277     return ret;
00278   }
00279 
00280   kDebug() << "setting version to:" << version;
00281   if ( setOption( LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS ) {
00282     ret = ldapErrorCode();
00283     d->mConnectionError = i18n( "Cannot set protocol version to %1.", version );
00284     close();
00285     return ret;
00286   }
00287 
00288 #if defined(LDAP_OPT_TIMEOUT)
00289   kDebug() << "setting timeout to:" << timeout;
00290 
00291   if ( timeout ) {
00292     if ( setOption( LDAP_OPT_TIMEOUT, &timeout ) != LDAP_OPT_SUCCESS ) {
00293       ret = ldapErrorCode();
00294       d->mConnectionError = i18np( "Cannot set timeout to %1 second.",
00295                                    "Cannot set timeout to %1 seconds.",
00296                                    timeout );
00297       close();
00298       return ret;
00299     }
00300   }
00301 #endif
00302 
00303   //FIXME: accessing to certificate handling would be good
00304   kDebug() << "setting security to:" << d->mServer.security();
00305   if ( d->mServer.security() == LdapServer::TLS ) {
00306     kDebug() << "start TLS";
00307 #ifdef HAVE_LDAP_START_TLS_S
00308     if ( ( ret = ldap_start_tls_s( d->mLDAP, NULL, NULL ) ) != LDAP_SUCCESS ) {
00309       d->mConnectionError = ldapErrorString();
00310       close();
00311       return ret;
00312     }
00313 #else
00314     close();
00315     d->mConnectionError = i18n( "TLS support not available in the LDAP client libraries." );
00316     return -1;
00317 #endif
00318   }
00319 
00320   kDebug() << "setting sizelimit to:" << d->mServer.sizeLimit();
00321   if ( d->mServer.sizeLimit() ) {
00322     if ( !setSizeLimit( d->mServer.sizeLimit() ) ) {
00323       ret = ldapErrorCode();
00324       close();
00325       d->mConnectionError = i18n( "Cannot set size limit." );
00326       return ret;
00327     }
00328   }
00329 
00330   kDebug() << "setting timelimit to:" << d->mServer.timeLimit();
00331   if ( d->mServer.timeLimit() ) {
00332     if ( !setTimeLimit( d->mServer.timeLimit() ) ) {
00333       ret = ldapErrorCode();
00334       close();
00335       d->mConnectionError = i18n( "Cannot set time limit." );
00336       return ret;
00337     }
00338   }
00339 
00340 #ifdef SASL2_FOUND
00341   kDebug() << "initializing SASL client";
00342   int saslresult = sasl_client_new( "ldap", d->mServer.host().toLatin1(),
00343         0, 0, callbacks, 0, &d->mSASLconn );
00344   if ( saslresult != SASL_OK ) {
00345     d->mConnectionError = i18n( "Cannot initialize the SASL client." );
00346     return KLDAP_SASL_ERROR;
00347   }
00348 #endif
00349 
00350   return 0;
00351 }
00352 
00353 void LdapConnection::close()
00354 {
00355   if ( d->mLDAP ) {
00356 #ifdef HAVE_LDAP_UNBIND_EXT
00357     ldap_unbind_ext( d->mLDAP, 0, 0 );
00358 #else
00359     ldap_unbind( d->mLDAP );
00360 #endif
00361   }
00362   d->mLDAP = 0;
00363 #ifdef SASL2_FOUND
00364   if ( d->mSASLconn ) {
00365     sasl_dispose( &d->mSASLconn );
00366     d->mSASLconn = 0;
00367   }
00368 #endif
00369   kDebug() << "connection closed!";
00370 }
00371 #else //LDAP_FOUND
00372 
00373 int LdapConnection::getOption( int option, void *value ) const
00374 {
00375   kError() << "No LDAP support...";
00376   return -1;
00377 }
00378 
00379 int LdapConnection::setOption( int option, void *value )
00380 {
00381   kError() << "No LDAP support...";
00382   return -1;
00383 }
00384 
00385 int LdapConnection::ldapErrorCode() const
00386 {
00387   kError() << "No LDAP support...";
00388   return -1;
00389 }
00390 
00391 QString LdapConnection::ldapErrorString() const
00392 {
00393   kError() << "No LDAP support...";
00394   return QString();
00395 }
00396 
00397 bool LdapConnection::setSizeLimit( int sizelimit )
00398 {
00399   kError() << "No LDAP support...";
00400   return false;
00401 }
00402 
00403 int LdapConnection::sizeLimit() const
00404 {
00405   kError() << "No LDAP support...";
00406   return -1;
00407 }
00408 
00409 bool LdapConnection::setTimeLimit( int timelimit )
00410 {
00411   kError() << "No LDAP support...";
00412   return false;
00413 }
00414 
00415 int LdapConnection::timeLimit() const
00416 {
00417   kError() << "No LDAP support...";
00418   return -1;
00419 }
00420 
00421 int LdapConnection::connect( )
00422 {
00423   d->mConnectionError =
00424     i18n( "LDAP support not compiled in. Please recompile libkldap with the "
00425           "OpenLDAP (or compatible) client libraries, or complain to your "
00426           "distribution packagers." );
00427   kError() << "No LDAP support...";
00428   return -1;
00429 }
00430 
00431 void LdapConnection::close()
00432 {
00433   kError() << "No LDAP support...";
00434 }
00435 
00436 #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"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.3
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