• Skip to content
  • Skip to link menu
KDE 4.1 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 "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 #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:
00146     return i18n( "LDAP Operations error" );
00147     //FIXME:
00148     /* add the LDAP error codes */
00149   }
00150 #else
00151   return i18n( "No LDAP Support..." );
00152 #endif
00153 }
00154 
00155 QString LdapConnection::saslErrorString() const
00156 {
00157 #ifdef SASL2_FOUND
00158   const char *str;
00159   str = sasl_errdetail( d->mSASLconn );
00160   return QString::fromLocal8Bit( str );
00161 #else
00162   return i18n( "SASL support is not available...Please recompile libkldap with the "
00163                "Cyrus-SASL (or compatible) client libraries, or complain to your "
00164                "distribution packagers." );
00165 #endif
00166 }
00167 
00168 QString LdapConnection::connectionError() const
00169 {
00170   return d->mConnectionError;
00171 }
00172 
00173 #ifdef LDAP_FOUND
00174 int LdapConnection::getOption( int option, void *value ) const
00175 {
00176   Q_ASSERT( d->mLDAP );
00177   return ldap_get_option( d->mLDAP, option, value );
00178 }
00179 
00180 int LdapConnection::setOption( int option, void *value )
00181 {
00182   Q_ASSERT( d->mLDAP );
00183   return ldap_set_option( d->mLDAP, option, value );
00184 }
00185 
00186 int LdapConnection::ldapErrorCode() const
00187 {
00188   Q_ASSERT( d->mLDAP );
00189   int err;
00190   ldap_get_option( d->mLDAP, LDAP_OPT_ERROR_NUMBER, &err );
00191   return err;
00192 }
00193 
00194 QString LdapConnection::ldapErrorString() const
00195 {
00196   Q_ASSERT( d->mLDAP );
00197   char *errmsg;
00198   ldap_get_option( d->mLDAP, LDAP_OPT_ERROR_STRING, &errmsg );
00199   QString msg = QString::fromLocal8Bit( errmsg );
00200   free( errmsg );
00201   return msg;
00202 }
00203 
00204 bool LdapConnection::setSizeLimit( int sizelimit )
00205 {
00206   Q_ASSERT( d->mLDAP );
00207   kDebug() << "sizelimit:" << sizelimit;
00208   if ( setOption( LDAP_OPT_SIZELIMIT, &sizelimit ) != LDAP_OPT_SUCCESS ) {
00209     return false;
00210   }
00211   return true;
00212 }
00213 
00214 int LdapConnection::sizeLimit() const
00215 {
00216   Q_ASSERT( d->mLDAP );
00217   int sizelimit;
00218   if ( getOption( LDAP_OPT_SIZELIMIT, &sizelimit ) != LDAP_OPT_SUCCESS ) {
00219     return -1;
00220   }
00221   return sizelimit;
00222 }
00223 
00224 bool LdapConnection::setTimeLimit( int timelimit )
00225 {
00226   Q_ASSERT( d->mLDAP );
00227   kDebug() << "timelimit:" << timelimit;
00228   if ( setOption( LDAP_OPT_TIMELIMIT, &timelimit ) != LDAP_OPT_SUCCESS ) {
00229     return false;
00230   }
00231   return true;
00232 }
00233 
00234 int LdapConnection::timeLimit() const
00235 {
00236   Q_ASSERT( d->mLDAP );
00237   int timelimit;
00238   if ( getOption( LDAP_OPT_TIMELIMIT, &timelimit ) != LDAP_OPT_SUCCESS ) {
00239     return -1;
00240   }
00241   return timelimit;
00242 }
00243 
00244 int LdapConnection::connect()
00245 {
00246   int ret;
00247   QString url;
00248   if ( d->mLDAP ) {
00249     close();
00250   }
00251 
00252   int version = d->mServer.version();
00253   int timeout = d->mServer.timeout();
00254 
00255   url = d->mServer.security() == LdapServer::SSL ? "ldaps" : "ldap";
00256   url += "://";
00257   url += d->mServer.host();
00258   url += ':';
00259   url += QString::number( d->mServer.port() );
00260   kDebug() << "ldap url:" << url;
00261 #ifdef HAVE_LDAP_INITIALIZE
00262   ret = ldap_initialize( &d->mLDAP, url.toLatin1() );
00263 #else
00264   d->mLDAP = ldap_init( d->mServer.host().toLatin1().data(), d->mServer.port() );
00265   if ( d->mLDAP == 0 ) {
00266     ret = -1;
00267   }
00268 #endif
00269   if ( ret != LDAP_SUCCESS ) {
00270     d->mConnectionError = i18n( "An error occurred during the connection initialization phase." );
00271     return ret;
00272   }
00273 
00274   kDebug() << "setting version to:" << version;
00275   if ( setOption( LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS ) {
00276     ret = ldapErrorCode();
00277     d->mConnectionError = i18n( "Cannot set protocol version to %1.", version );
00278     close();
00279     return ret;
00280   }
00281 
00282 #if defined(LDAP_OPT_TIMEOUT)
00283   kDebug() << "setting timeout to:" << timeout;
00284 
00285   if ( timeout ) {
00286     if ( setOption( LDAP_OPT_TIMEOUT, &timeout ) != LDAP_OPT_SUCCESS ) {
00287       ret = ldapErrorCode();
00288       d->mConnectionError = i18n( "Cannot set timeout to %1 seconds.", timeout );
00289       close();
00290       return ret;
00291     }
00292   }
00293 #endif
00294 
00295   //FIXME: accessing to certificate handling would be good
00296   kDebug() << "setting security to:" << d->mServer.security();
00297   if ( d->mServer.security() == LdapServer::TLS ) {
00298     kDebug() << "start TLS";
00299 #ifdef HAVE_LDAP_START_TLS_S
00300     if ( ( ret = ldap_start_tls_s( d->mLDAP, NULL, NULL ) ) != LDAP_SUCCESS ) {
00301       d->mConnectionError = ldapErrorString();
00302       close();
00303       return ret;
00304     }
00305 #else
00306     close();
00307     d->mConnectionError = i18n( "TLS support not available in the LDAP client libraries." );
00308     return -1;
00309 #endif
00310   }
00311 
00312   kDebug() << "setting sizelimit to:" << d->mServer.sizeLimit();
00313   if ( d->mServer.sizeLimit() ) {
00314     if ( !setSizeLimit( d->mServer.sizeLimit() ) ) {
00315       ret = ldapErrorCode();
00316       close();
00317       d->mConnectionError = i18n( "Cannot set size limit." );
00318       return ret;
00319     }
00320   }
00321 
00322   kDebug() << "setting timelimit to:" << d->mServer.timeLimit();
00323   if ( d->mServer.timeLimit() ) {
00324     if ( !setTimeLimit( d->mServer.timeLimit() ) ) {
00325       ret = ldapErrorCode();
00326       close();
00327       d->mConnectionError = i18n( "Cannot set time limit." );
00328       return ret;
00329     }
00330   }
00331 
00332 #ifdef SASL2_FOUND
00333   kDebug() << "initializing SASL client";
00334   int saslresult = sasl_client_new( "ldap", d->mServer.host().toLatin1(),
00335         0, 0, callbacks, 0, &d->mSASLconn );
00336   if ( saslresult != SASL_OK ) {
00337     d->mConnectionError = i18n( "Cannot initialize the SASL client." );
00338     return KLDAP_SASL_ERROR;
00339   }
00340 #endif
00341 
00342   return 0;
00343 }
00344 
00345 void LdapConnection::close()
00346 {
00347   if ( d->mLDAP ) {
00348 #ifdef HAVE_LDAP_UNBIND_EXT
00349     ldap_unbind_ext( d->mLDAP, 0, 0 );
00350 #else
00351     ldap_unbind( d->mLDAP );
00352 #endif
00353   }
00354   d->mLDAP = 0;
00355 #ifdef SASL2_FOUND
00356   if ( d->mSASLconn ) {
00357     sasl_dispose( &d->mSASLconn );
00358     d->mSASLconn = 0;
00359   }
00360 #endif
00361   kDebug() << "connection closed!";
00362 }
00363 #else //LDAP_FOUND
00364 
00365 int LdapConnection::getOption( int option, void *value ) const
00366 {
00367   kError() << "No LDAP support...";
00368   return -1;
00369 }
00370 
00371 int LdapConnection::setOption( int option, void *value )
00372 {
00373   kError() << "No LDAP support...";
00374   return -1;
00375 }
00376 
00377 int LdapConnection::ldapErrorCode() const
00378 {
00379   kError() << "No LDAP support...";
00380   return -1;
00381 }
00382 
00383 QString LdapConnection::ldapErrorString() const
00384 {
00385   kError() << "No LDAP support...";
00386   return QString();
00387 }
00388 
00389 bool LdapConnection::setSizeLimit( int sizelimit )
00390 {
00391   kError() << "No LDAP support...";
00392   return false;
00393 }
00394 
00395 int LdapConnection::sizeLimit() const
00396 {
00397   kError() << "No LDAP support...";
00398   return -1;
00399 }
00400 
00401 bool LdapConnection::setTimeLimit( int timelimit )
00402 {
00403   kError() << "No LDAP support...";
00404   return false;
00405 }
00406 
00407 int LdapConnection::timeLimit() const
00408 {
00409   kError() << "No LDAP support...";
00410   return -1;
00411 }
00412 
00413 int LdapConnection::connect( )
00414 {
00415   d->mConnectionError =
00416     i18n( "LDAP support not compiled in. Please recompile libkldap with the "
00417           "OpenLDAP (or compatible) client libraries, or complain to your "
00418           "distribution packagers." );
00419   kError() << "No LDAP support...";
00420   return -1;
00421 }
00422 
00423 void LdapConnection::close()
00424 {
00425   kError() << "No LDAP support...";
00426 }
00427 
00428 #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
  • 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.7.1
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