• Skip to content
  • Skip to link menu
KDE 4.4 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 = i18np( "Cannot set timeout to %1 second.",
00289                                    "Cannot set timeout to %1 seconds.",
00290                                    timeout );
00291       close();
00292       return ret;
00293     }
00294   }
00295 #endif
00296 
00297   //FIXME: accessing to certificate handling would be good
00298   kDebug() << "setting security to:" << d->mServer.security();
00299   if ( d->mServer.security() == LdapServer::TLS ) {
00300     kDebug() << "start TLS";
00301 #ifdef HAVE_LDAP_START_TLS_S
00302     if ( ( ret = ldap_start_tls_s( d->mLDAP, NULL, NULL ) ) != LDAP_SUCCESS ) {
00303       d->mConnectionError = ldapErrorString();
00304       close();
00305       return ret;
00306     }
00307 #else
00308     close();
00309     d->mConnectionError = i18n( "TLS support not available in the LDAP client libraries." );
00310     return -1;
00311 #endif
00312   }
00313 
00314   kDebug() << "setting sizelimit to:" << d->mServer.sizeLimit();
00315   if ( d->mServer.sizeLimit() ) {
00316     if ( !setSizeLimit( d->mServer.sizeLimit() ) ) {
00317       ret = ldapErrorCode();
00318       close();
00319       d->mConnectionError = i18n( "Cannot set size limit." );
00320       return ret;
00321     }
00322   }
00323 
00324   kDebug() << "setting timelimit to:" << d->mServer.timeLimit();
00325   if ( d->mServer.timeLimit() ) {
00326     if ( !setTimeLimit( d->mServer.timeLimit() ) ) {
00327       ret = ldapErrorCode();
00328       close();
00329       d->mConnectionError = i18n( "Cannot set time limit." );
00330       return ret;
00331     }
00332   }
00333 
00334 #ifdef SASL2_FOUND
00335   kDebug() << "initializing SASL client";
00336   int saslresult = sasl_client_new( "ldap", d->mServer.host().toLatin1(),
00337         0, 0, callbacks, 0, &d->mSASLconn );
00338   if ( saslresult != SASL_OK ) {
00339     d->mConnectionError = i18n( "Cannot initialize the SASL client." );
00340     return KLDAP_SASL_ERROR;
00341   }
00342 #endif
00343 
00344   return 0;
00345 }
00346 
00347 void LdapConnection::close()
00348 {
00349   if ( d->mLDAP ) {
00350 #ifdef HAVE_LDAP_UNBIND_EXT
00351     ldap_unbind_ext( d->mLDAP, 0, 0 );
00352 #else
00353     ldap_unbind( d->mLDAP );
00354 #endif
00355   }
00356   d->mLDAP = 0;
00357 #ifdef SASL2_FOUND
00358   if ( d->mSASLconn ) {
00359     sasl_dispose( &d->mSASLconn );
00360     d->mSASLconn = 0;
00361   }
00362 #endif
00363   kDebug() << "connection closed!";
00364 }
00365 #else //LDAP_FOUND
00366 
00367 int LdapConnection::getOption( int option, void *value ) const
00368 {
00369   kError() << "No LDAP support...";
00370   return -1;
00371 }
00372 
00373 int LdapConnection::setOption( int option, void *value )
00374 {
00375   kError() << "No LDAP support...";
00376   return -1;
00377 }
00378 
00379 int LdapConnection::ldapErrorCode() const
00380 {
00381   kError() << "No LDAP support...";
00382   return -1;
00383 }
00384 
00385 QString LdapConnection::ldapErrorString() const
00386 {
00387   kError() << "No LDAP support...";
00388   return QString();
00389 }
00390 
00391 bool LdapConnection::setSizeLimit( int sizelimit )
00392 {
00393   kError() << "No LDAP support...";
00394   return false;
00395 }
00396 
00397 int LdapConnection::sizeLimit() const
00398 {
00399   kError() << "No LDAP support...";
00400   return -1;
00401 }
00402 
00403 bool LdapConnection::setTimeLimit( int timelimit )
00404 {
00405   kError() << "No LDAP support...";
00406   return false;
00407 }
00408 
00409 int LdapConnection::timeLimit() const
00410 {
00411   kError() << "No LDAP support...";
00412   return -1;
00413 }
00414 
00415 int LdapConnection::connect( )
00416 {
00417   d->mConnectionError =
00418     i18n( "LDAP support not compiled in. Please recompile libkldap with the "
00419           "OpenLDAP (or compatible) client libraries, or complain to your "
00420           "distribution packagers." );
00421   kError() << "No LDAP support...";
00422   return -1;
00423 }
00424 
00425 void LdapConnection::close()
00426 {
00427   kError() << "No LDAP support...";
00428 }
00429 
00430 #endif

KLDAP Library

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.6.2-20100208
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