• Skip to content
  • Skip to link menu
KDE 4.8 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • KDE Home
  • Contact Us
 

KLDAP Library

ldapoperation.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 "ldapoperation.h"
00022 #include "kldap_config.h"
00023 
00024 #include <kdebug.h>
00025 
00026 #include <QtCore/QTime>
00027 
00028 #include <stdlib.h>
00029 #ifdef HAVE_SYS_TIME_H
00030 #include <sys/time.h>
00031 #endif
00032 
00033 #ifdef SASL2_FOUND
00034 #include <sasl/sasl.h>
00035 #endif
00036 
00037 #ifdef LDAP_FOUND
00038 # ifndef HAVE_WINLDAP_H
00039 #  include <lber.h>
00040 #  include <ldap.h>
00041 # else
00042 #  include <w32-ldap-help.h>
00043 # endif // HAVE_WINLDAP_H
00044 #endif // LDAP_FOUND
00045 
00046 #include "ldapdefs.h"
00047 
00048 using namespace KLDAP;
00049 
00050 #ifdef LDAP_FOUND
00051 static void extractControls( LdapControls &ctrls, LDAPControl **pctrls );
00052 #endif // LDAP_FOUND
00053 
00054 /*
00055    Returns the difference between msecs and elapsed. If msecs is -1,
00056    however, -1 is returned.
00057 */
00058 static int kldap_timeout_value( int msecs, int elapsed )
00059 {
00060   if ( msecs == -1 ) {
00061     return -1;
00062   }
00063 
00064   int timeout = msecs - elapsed;
00065   return timeout < 0 ? 0 : timeout;
00066 }
00067 
00068 class LdapOperation::LdapOperationPrivate
00069 {
00070   public:
00071     LdapOperationPrivate();
00072     ~LdapOperationPrivate();
00073 #ifdef LDAP_FOUND
00074     int processResult( int rescode, LDAPMessage *msg );
00075     int bind( const QByteArray &creds, SASL_Callback_Proc *saslproc, void *data, bool async );
00076 #endif
00077     LdapControls mClientCtrls, mServerCtrls, mControls;
00078     LdapObject mObject;
00079     QByteArray mExtOid, mExtData;
00080     QByteArray mServerCred;
00081     QString mMatchedDn;
00082     QList<QByteArray> mReferrals;
00083 
00084   LdapConnection *mConnection;
00085   };
00086 
00087 LdapOperation::LdapOperation()
00088   : d( new LdapOperationPrivate )
00089 {
00090   d->mConnection = 0;
00091 }
00092 
00093 LdapOperation::LdapOperation( LdapConnection &conn )
00094   : d( new LdapOperationPrivate )
00095 {
00096   setConnection( conn );
00097 }
00098 
00099 LdapOperation::~LdapOperation()
00100 {
00101   delete d;
00102 }
00103 
00104 void LdapOperation::setConnection( LdapConnection &conn )
00105 {
00106   d->mConnection = &conn;
00107 }
00108 
00109 LdapConnection &LdapOperation::connection()
00110 {
00111   return *d->mConnection;
00112 }
00113 
00114 void LdapOperation::setClientControls( const LdapControls &ctrls )
00115 {
00116   d->mClientCtrls = ctrls;
00117 }
00118 
00119 void LdapOperation::setServerControls( const LdapControls &ctrls )
00120 {
00121   d->mServerCtrls = ctrls;
00122 }
00123 
00124 LdapControls LdapOperation::clientControls() const
00125 {
00126   return d->mClientCtrls;
00127 }
00128 
00129 LdapControls LdapOperation::serverControls() const
00130 {
00131   return d->mServerCtrls;
00132 }
00133 
00134 LdapObject LdapOperation::object() const
00135 {
00136   return d->mObject;
00137 }
00138 
00139 LdapControls LdapOperation::controls() const
00140 {
00141   return d->mControls;
00142 }
00143 
00144 QByteArray LdapOperation::extendedOid() const
00145 {
00146   return d->mExtOid;
00147 }
00148 
00149 QByteArray LdapOperation::extendedData() const
00150 {
00151   return d->mExtData;
00152 }
00153 
00154 QString LdapOperation::matchedDn() const
00155 {
00156   return d->mMatchedDn;
00157 }
00158 
00159 QList<QByteArray> LdapOperation::referrals() const
00160 {
00161   return d->mReferrals;
00162 }
00163 
00164 QByteArray LdapOperation::serverCred() const
00165 {
00166   return d->mServerCred;
00167 }
00168 
00169 LdapOperation::LdapOperationPrivate::LdapOperationPrivate()
00170 {
00171 }
00172 
00173 LdapOperation::LdapOperationPrivate::~LdapOperationPrivate()
00174 {
00175 }
00176 
00177 #ifdef LDAP_FOUND
00178 
00179 #ifdef SASL2_FOUND
00180 static int kldap_sasl_interact( sasl_interact_t *interact, LdapOperation::SASL_Data *data )
00181 {
00182   if ( data->proc ) {
00183     for ( ; interact->id != SASL_CB_LIST_END; interact++ ) {
00184       switch ( interact->id ) {
00185       case SASL_CB_GETREALM:
00186         data->creds.fields |= LdapOperation::SASL_Realm;
00187         break;
00188       case SASL_CB_AUTHNAME:
00189         data->creds.fields |= LdapOperation::SASL_Authname;
00190         break;
00191       case SASL_CB_PASS:
00192         data->creds.fields |= LdapOperation::SASL_Password;
00193         break;
00194       case SASL_CB_USER:
00195         data->creds.fields |= LdapOperation::SASL_Authzid;
00196         break;
00197       }
00198     }
00199     int retval;
00200     if ( ( retval = data->proc( data->creds, data->data ) ) ) {
00201       return retval;
00202     }
00203   }
00204 
00205   QString value;
00206 
00207   while ( interact->id != SASL_CB_LIST_END ) {
00208     value.clear();
00209     switch( interact->id ) {
00210     case SASL_CB_GETREALM:
00211       value = data->creds.realm;
00212       kDebug() << "SASL_REALM=" << value;
00213       break;
00214     case SASL_CB_AUTHNAME:
00215       value = data->creds.authname;
00216       kDebug() << "SASL_AUTHNAME=" << value;
00217       break;
00218     case SASL_CB_PASS:
00219       value = data->creds.password;
00220       kDebug() << "SASL_PASSWD=[hidden]";
00221       break;
00222     case SASL_CB_USER:
00223       value = data->creds.authzid;
00224       kDebug() << "SASL_AUTHZID=" << value;
00225       break;
00226     }
00227     if ( value.isEmpty() ) {
00228       interact->result = NULL;
00229       interact->len = 0;
00230     } else {
00231       interact->result = strdup( value.toUtf8() );
00232       interact->len = strlen( (const char *)interact->result );
00233     }
00234     interact++;
00235   }
00236   return KLDAP_SUCCESS;
00237 }
00238 #endif
00239 
00240 int LdapOperation::LdapOperationPrivate::bind( const QByteArray &creds,
00241                                                SASL_Callback_Proc *saslproc,
00242                                                void *data, bool async )
00243 {
00244   Q_ASSERT( mConnection );
00245   LDAP *ld = (LDAP*) mConnection->handle();
00246   LdapServer server;
00247   server = mConnection->server();
00248 
00249   int ret;
00250 
00251   if ( server.auth() == LdapServer::SASL ) {
00252 #if defined( SASL2_FOUND ) && !defined( HAVE_WINLDAP_H )
00253     sasl_conn_t *saslconn = (sasl_conn_t *)mConnection->saslHandle();
00254     sasl_interact_t *client_interact = NULL;
00255     const char *out = NULL;
00256     uint outlen;
00257     const char *mechusing = NULL;
00258     struct berval ccred, *scred;
00259     int saslresult;
00260     QByteArray sdata = creds;
00261 
00262     QString mech = server.mech();
00263     if ( mech.isEmpty() ) {
00264       mech = "DIGEST-MD5";
00265     }
00266 
00267     SASL_Data sasldata;
00268     sasldata.proc = saslproc;
00269     sasldata.data = data;
00270     sasldata.creds.fields = 0;
00271     sasldata.creds.realm = server.realm();
00272     sasldata.creds.authname = server.user();
00273     sasldata.creds.authzid = server.bindDn();
00274     sasldata.creds.password = server.password();
00275 
00276     do {
00277       if ( sdata.isEmpty() ) {
00278         do {
00279           saslresult = sasl_client_start( saslconn, mech.toLatin1(),
00280                                           &client_interact, &out, &outlen, &mechusing );
00281 
00282           if ( saslresult == SASL_INTERACT ) {
00283             if ( kldap_sasl_interact( client_interact, &sasldata ) != KLDAP_SUCCESS ) {
00284               return KLDAP_SASL_ERROR;
00285             }
00286           }
00287           kDebug() << "sasl_client_start mech: "
00288                    << mechusing << " outlen " << outlen
00289                    << " result: " << saslresult;
00290         } while ( saslresult == SASL_INTERACT );
00291         if ( saslresult != SASL_CONTINUE && saslresult != SASL_OK ) {
00292           return KLDAP_SASL_ERROR;
00293         }
00294 
00295       } else {
00296         kDebug() << "sasl_client_step";
00297         do {
00298           saslresult = sasl_client_step( saslconn, sdata.data(), sdata.size(),
00299                                          &client_interact, &out, &outlen );
00300           if ( saslresult == SASL_INTERACT ) {
00301             if ( kldap_sasl_interact( client_interact, &sasldata ) != KLDAP_SUCCESS ) {
00302               return KLDAP_SASL_ERROR;
00303             }
00304           }
00305         } while ( saslresult == SASL_INTERACT );
00306         kDebug() << "sasl_client_step result" << saslresult;
00307         if ( saslresult != SASL_CONTINUE && saslresult != SASL_OK ) {
00308           return KLDAP_SASL_ERROR;
00309         }
00310       }
00311 
00312       ccred.bv_val = (char*) out;
00313       ccred.bv_len = outlen;
00314 
00315       if ( async ) {
00316         kDebug() << "ldap_sasl_bind";
00317         int msgid;
00318         ret =
00319           ldap_sasl_bind( ld, server.bindDn().toUtf8().data(), mech.toLatin1(),
00320                           &ccred, 0, 0, &msgid );
00321         if ( ret == 0 ) {
00322           ret = msgid;
00323         }
00324         kDebug() << "ldap_sasl_bind msgid" << ret;
00325       } else {
00326         kDebug() << "ldap_sasl_bind_s";
00327         ret =
00328           ldap_sasl_bind_s( ld, server.bindDn().toUtf8().data(), mech.toLatin1(),
00329                             &ccred, 0, 0, &scred );
00330         kDebug() << "ldap_sasl_bind_s ret" << ret;
00331         if ( scred ) {
00332           sdata = QByteArray( scred->bv_val, scred->bv_len );
00333         } else {
00334           sdata = QByteArray();
00335         }
00336       }
00337     } while ( !async && ret == KLDAP_SASL_BIND_IN_PROGRESS );
00338 #else
00339     kError() << "SASL authentication is not available "
00340              << "(re-compile kldap with cyrus-sasl and OpenLDAP development).";
00341     return KLDAP_SASL_ERROR;
00342 #endif
00343   } else { //simple auth
00344     QByteArray bindname, pass;
00345     struct berval ccred;
00346     if ( server.auth() == LdapServer::Simple ) {
00347       bindname = server.bindDn().toUtf8();
00348       pass = server.password().toUtf8();
00349     }
00350     ccred.bv_val = pass.data();
00351     ccred.bv_len = pass.size();
00352     kDebug() << "binding to server, bindname: " << bindname << " password: *****";
00353 
00354     if ( async ) {
00355       kDebug() << "ldap_sasl_bind (simple)";
00356 #ifndef HAVE_WINLDAP_H
00357       int msgid = 0;
00358       ret = ldap_sasl_bind( ld, bindname.data(), 0, &ccred, 0, 0, &msgid );
00359       if ( ret == 0 ) {
00360         ret = msgid;
00361       }
00362 #else
00363       ret = ldap_simple_bind( ld, bindname.data(), pass.data() );
00364 #endif
00365     } else {
00366       kDebug() << "ldap_sasl_bind_s (simple)";
00367 #ifndef HAVE_WINLDAP_H
00368       ret = ldap_sasl_bind_s( ld, bindname.data(), 0, &ccred, 0, 0, 0 );
00369 #else
00370       ret = ldap_simple_bind_s( ld, bindname.data(), pass.data() );
00371 #endif
00372     }
00373   }
00374   return ret;
00375 }
00376 
00377 int LdapOperation::LdapOperationPrivate::processResult( int rescode, LDAPMessage *msg )
00378 {
00379   //kDebug();
00380   int retval;
00381   LDAP *ld = (LDAP*) mConnection->handle();
00382 
00383   kDebug() << "rescode: " << rescode;
00384   switch ( rescode ) {
00385   case RES_SEARCH_ENTRY:
00386   {
00387     //kDebug() << "Found search entry";
00388     mObject.clear();
00389     LdapAttrMap attrs;
00390     char *name;
00391     struct berval **bvals;
00392     BerElement     *entry;
00393 
00394     char *dn = ldap_get_dn( ld, msg );
00395     mObject.setDn( QString::fromUtf8( dn ) );
00396     ldap_memfree( dn );
00397 
00398     // iterate over the attributes
00399     name = ldap_first_attribute( ld, msg, &entry );
00400     while ( name != 0 ) {
00401       // print the values
00402       bvals = ldap_get_values_len( ld, msg, name );
00403       LdapAttrValue values;
00404       if ( bvals ) {
00405         for ( int i = 0; bvals[i] != 0; i++ ) {
00406           char *val = bvals[i]->bv_val;
00407           unsigned long len = bvals[i]->bv_len;
00408           values.append( QByteArray( val, len ) );
00409         }
00410         ldap_value_free_len( bvals );
00411       }
00412       attrs[ QString::fromLatin1( name ) ] = values;
00413       ldap_memfree( name );
00414 
00415       // next attribute
00416       name = ldap_next_attribute( ld, msg, entry );
00417     }
00418     ber_free( entry, 0 );
00419     mObject.setAttributes( attrs );
00420     break;
00421   }
00422   case RES_SEARCH_REFERENCE:
00423     // Will only get this if following references is disabled. ignore it
00424     rescode = 0;
00425     break;
00426   case RES_EXTENDED:
00427   {
00428     char *retoid;
00429     struct berval *retdata;
00430     retval = ldap_parse_extended_result( ld, msg, &retoid, &retdata, 0 );
00431     if ( retval != KLDAP_SUCCESS ) {
00432       ldap_msgfree( msg );
00433       return -1;
00434     }
00435     mExtOid = retoid ? QByteArray( retoid ) : QByteArray();
00436     mExtData = retdata ? QByteArray( retdata->bv_val, retdata->bv_len ) : QByteArray();
00437     ldap_memfree( retoid );
00438     ber_bvfree( retdata );
00439     break;
00440   }
00441   case RES_BIND:
00442   {
00443     struct berval *servercred = 0;
00444 #ifndef HAVE_WINLDAP_H
00445     // FIXME: Error handling Winldap does not have ldap_parse_sasl_bind_result
00446     retval = ldap_parse_sasl_bind_result( ld, msg, &servercred, 0 );
00447 #else
00448     retval = KLDAP_SUCCESS;
00449 #endif
00450     if ( retval != KLDAP_SUCCESS && retval != KLDAP_SASL_BIND_IN_PROGRESS ) {
00451       kDebug() << "RES_BIND error: " << retval;
00452       ldap_msgfree( msg );
00453       return -1;
00454     }
00455     kDebug() << "RES_BIND rescode" << rescode << "retval:" << retval;
00456     if ( servercred ) {
00457       mServerCred = QByteArray( servercred->bv_val, servercred->bv_len );
00458       ber_bvfree( servercred );
00459     } else {
00460       mServerCred = QByteArray();
00461     }
00462     break;
00463   }
00464   default:
00465   {
00466     LDAPControl **serverctrls = 0;
00467     char *matcheddn = 0, *errmsg = 0;
00468     char **referralsp;
00469     int errcodep;
00470     retval =
00471       ldap_parse_result( ld, msg, &errcodep, &matcheddn, &errmsg, &referralsp,
00472                          &serverctrls, 0 );
00473     kDebug() << "rescode" << rescode << "retval:" << retval
00474                  << "matcheddn:" << matcheddn << "errcode:"
00475                  << errcodep << "errmsg:" << errmsg;
00476     if ( retval != KLDAP_SUCCESS ) {
00477       ldap_msgfree( msg );
00478       return -1;
00479     }
00480     mControls.clear();
00481     if ( serverctrls ) {
00482       extractControls( mControls, serverctrls );
00483       ldap_controls_free( serverctrls );
00484     }
00485     mReferrals.clear();
00486     if ( referralsp ) {
00487       char **tmp = referralsp;
00488       while ( *tmp ) {
00489         mReferrals.append( QByteArray( *tmp ) );
00490         ldap_memfree( *tmp );
00491         tmp++;
00492       }
00493       ldap_memfree( (char *) referralsp );
00494     }
00495     mMatchedDn.clear();
00496     if ( matcheddn ) {
00497       mMatchedDn = QString::fromUtf8( matcheddn );
00498       ldap_memfree( matcheddn );
00499     }
00500     if ( errmsg ) {
00501       ldap_memfree( errmsg );
00502     }
00503   }
00504   }
00505 
00506   ldap_msgfree( msg );
00507 
00508   return rescode;
00509 }
00510 
00511 static void addModOp( LDAPMod ***pmods, int mod_type, const QString &attr,
00512                       const QByteArray *value = 0 )
00513 {
00514   //  kDebug() << "type:" << mod_type << "attr:" << attr <<
00515   //    "value:" << QString::fromUtf8(value,value.size()) <<
00516   //    "size:" << value.size();
00517   LDAPMod **mods;
00518 
00519   mods = *pmods;
00520 
00521   uint i = 0;
00522 
00523   if ( mods == 0 ) {
00524     mods = (LDAPMod **)malloc( 2 * sizeof( LDAPMod * ) );
00525     mods[ 0 ] = (LDAPMod *)malloc( sizeof( LDAPMod ) );
00526     mods[ 1 ] = 0;
00527     memset( mods[ 0 ], 0, sizeof( LDAPMod ) );
00528   } else {
00529     while ( mods[ i ] != 0 &&
00530             ( strcmp( attr.toUtf8(), mods[i]->mod_type ) != 0 ||
00531               ( mods[ i ]->mod_op & ~LDAP_MOD_BVALUES ) != mod_type ) ) i++;
00532 
00533     if ( mods[ i ] == 0 ) {
00534       mods = (LDAPMod **)realloc( mods, ( i + 2 ) * sizeof( LDAPMod * ) );
00535       if ( mods == 0 ) {
00536         kError() << "addModOp: realloc";
00537         return;
00538       }
00539       mods[ i + 1 ] = 0;
00540       mods[ i ] = (LDAPMod *) malloc( sizeof( LDAPMod ) );
00541       memset( mods[ i ], 0, sizeof( LDAPMod ) );
00542     }
00543   }
00544 
00545   mods[ i ]->mod_op = mod_type | LDAP_MOD_BVALUES;
00546   if ( mods[ i ]->mod_type == 0 ) {
00547     mods[ i ]->mod_type = strdup( attr.toUtf8() );
00548   }
00549 
00550   *pmods = mods;
00551 
00552   if ( value == 0 ) {
00553     return;
00554   }
00555 
00556   int vallen = value->size();
00557   BerValue *berval;
00558   berval = (BerValue *) malloc( sizeof( BerValue ) );
00559   berval -> bv_len = vallen;
00560   if ( vallen > 0 ) {
00561     berval -> bv_val = (char *) malloc( vallen );
00562     memcpy( berval -> bv_val, value->data(), vallen );
00563   } else {
00564     berval -> bv_val = 0;
00565   }
00566 
00567   if ( mods[ i ] -> mod_vals.modv_bvals == 0 ) {
00568     mods[ i ]->mod_vals.modv_bvals =
00569       (BerValue **) malloc( sizeof( BerValue * ) * 2 );
00570     mods[ i ]->mod_vals.modv_bvals[ 0 ] = berval;
00571     mods[ i ]->mod_vals.modv_bvals[ 1 ] = 0;
00572 //    kDebug() << "new bervalue struct" << attr << value;
00573   } else {
00574     uint j = 0;
00575     while ( mods[ i ]->mod_vals.modv_bvals[ j ] != 0 ) {
00576       j++;
00577     }
00578     mods[ i ]->mod_vals.modv_bvals =
00579       (BerValue **)realloc( mods[ i ]->mod_vals.modv_bvals,
00580                             ( j + 2 ) * sizeof( BerValue * ) );
00581     if ( mods[ i ]->mod_vals.modv_bvals == 0 ) {
00582       kError() << "addModOp: realloc";
00583       free( berval );
00584       return;
00585     }
00586     mods[ i ]->mod_vals.modv_bvals[ j ] = berval;
00587     mods[ i ]->mod_vals.modv_bvals[ j+1 ] = 0;
00588     kDebug() << j << ". new bervalue";
00589   }
00590 }
00591 
00592 static void addControlOp( LDAPControl ***pctrls, const QString &oid,
00593                           const QByteArray &value, bool critical )
00594 {
00595   LDAPControl **ctrls;
00596   LDAPControl *ctrl = (LDAPControl *) malloc( sizeof( LDAPControl ) );
00597 
00598   ctrls = *pctrls;
00599 
00600   kDebug() << "oid:'" << oid << "' val: '" << value << "'";
00601   int vallen = value.size();
00602   ctrl->ldctl_value.bv_len = vallen;
00603   if ( vallen ) {
00604     ctrl->ldctl_value.bv_val = (char *) malloc( vallen );
00605     memcpy( ctrl->ldctl_value.bv_val, value.data(), vallen );
00606   } else {
00607     ctrl->ldctl_value.bv_val = 0;
00608   }
00609   ctrl->ldctl_iscritical = critical;
00610   ctrl->ldctl_oid = strdup( oid.toUtf8() );
00611 
00612   uint i = 0;
00613 
00614   if ( ctrls == 0 ) {
00615     ctrls = (LDAPControl **)malloc ( 2 * sizeof( LDAPControl * ) );
00616     ctrls[ 0 ] = 0;
00617     ctrls[ 1 ] = 0;
00618   } else {
00619     while ( ctrls[ i ] != 0 ) {
00620       i++;
00621     }
00622     ctrls[ i + 1 ] = 0;
00623     ctrls =
00624       (LDAPControl **)realloc( ctrls, ( i + 2 ) * sizeof( LDAPControl * ) );
00625   }
00626   ctrls[ i ] = ctrl;
00627   *pctrls = ctrls;
00628 }
00629 
00630 static void createControls( LDAPControl ***pctrls, const LdapControls &ctrls )
00631 {
00632   for ( int i = 0; i< ctrls.count(); ++i ) {
00633     addControlOp( pctrls, ctrls[i].oid(), ctrls[i].value(), ctrls[i].critical() );
00634   }
00635 }
00636 
00637 static void extractControls( LdapControls &ctrls, LDAPControl **pctrls )
00638 {
00639   LDAPControl *ctrl;
00640   LdapControl control;
00641   int i = 0;
00642 
00643   while ( pctrls[i] ) {
00644     ctrl = pctrls[ i ];
00645     control.setOid( QString::fromUtf8( ctrl->ldctl_oid ) );
00646     control.setValue( QByteArray( ctrl->ldctl_value.bv_val,
00647                                   ctrl->ldctl_value.bv_len ) );
00648     control.setCritical( ctrl->ldctl_iscritical );
00649     ctrls.append( control );
00650     i++;
00651   }
00652 }
00653 
00654 int LdapOperation::bind( const QByteArray &creds, SASL_Callback_Proc *saslproc, void *data )
00655 {
00656   return d->bind( creds, saslproc, data, true );
00657 }
00658 
00659 int LdapOperation::bind_s( SASL_Callback_Proc *saslproc, void *data )
00660 {
00661   return d->bind( QByteArray(), saslproc, data, false );
00662 }
00663 
00664 int LdapOperation::search( const LdapDN &base, LdapUrl::Scope scope,
00665                            const QString &filter, const QStringList &attributes )
00666 {
00667   Q_ASSERT( d->mConnection );
00668   LDAP *ld = (LDAP*) d->mConnection->handle();
00669 
00670   char **attrs = 0;
00671   int msgid;
00672 
00673   LDAPControl **serverctrls = 0, **clientctrls = 0;
00674   createControls( &serverctrls, d->mServerCtrls );
00675   createControls( &serverctrls, d->mClientCtrls );
00676 
00677   int count = attributes.count();
00678   if ( count > 0 ) {
00679     attrs = static_cast<char**>( malloc( ( count + 1 ) * sizeof( char * ) ) );
00680     for ( int i=0; i<count; i++ ) {
00681       attrs[i] = strdup( attributes.at(i).toUtf8() );
00682     }
00683     attrs[count] = 0;
00684   }
00685 
00686   int lscope = LDAP_SCOPE_BASE;
00687   switch ( scope ) {
00688   case LdapUrl::Base:
00689     lscope = LDAP_SCOPE_BASE;
00690     break;
00691   case LdapUrl::One:
00692     lscope = LDAP_SCOPE_ONELEVEL;
00693     break;
00694   case LdapUrl::Sub:
00695     lscope = LDAP_SCOPE_SUBTREE;
00696     break;
00697   }
00698 
00699   kDebug() << "asyncSearch() base=\"" << base.toString()
00700            << "\" scope=" << (int)scope
00701            << "filter=\"" << filter
00702            << "\" attrs=" << attributes;
00703   int retval =
00704     ldap_search_ext( ld, base.toString().toUtf8().data(), lscope,
00705                      filter.isEmpty() ? QByteArray( "objectClass=*" ).data() :
00706                                         filter.toUtf8().data(),
00707                      attrs, 0, serverctrls, clientctrls, 0,
00708                      d->mConnection->sizeLimit(), &msgid );
00709 
00710   ldap_controls_free( serverctrls );
00711   ldap_controls_free( clientctrls );
00712 
00713   // free the attributes list again
00714   if ( count > 0 ) {
00715     for ( int i=0; i<count; i++ ) {
00716       free( attrs[i] );
00717     }
00718     free( attrs );
00719   }
00720 
00721   if ( retval == 0 ) {
00722     retval = msgid;
00723   }
00724   return retval;
00725 }
00726 
00727 int LdapOperation::add( const LdapObject &object )
00728 {
00729   Q_ASSERT( d->mConnection );
00730   LDAP *ld = (LDAP*) d->mConnection->handle();
00731 
00732   int msgid;
00733   LDAPMod **lmod = 0;
00734 
00735   LDAPControl **serverctrls = 0, **clientctrls = 0;
00736   createControls( &serverctrls, d->mServerCtrls );
00737   createControls( &serverctrls, d->mClientCtrls );
00738 
00739   for ( LdapAttrMap::ConstIterator it = object.attributes().begin();
00740         it != object.attributes().end(); ++it ) {
00741     QString attr = it.key();
00742     for ( LdapAttrValue::ConstIterator it2 = (*it).begin(); it2 != (*it).end(); ++it2 ) {
00743       addModOp( &lmod, 0, attr, &(*it2) );
00744     }
00745   }
00746 
00747   int retval =
00748     ldap_add_ext( ld, object.dn().toString().toUtf8().data(), lmod, serverctrls,
00749                   clientctrls, &msgid );
00750 
00751   ldap_controls_free( serverctrls );
00752   ldap_controls_free( clientctrls );
00753   ldap_mods_free( lmod, 1 );
00754   if ( retval == 0 ) {
00755     retval = msgid;
00756   }
00757   return retval;
00758 }
00759 
00760 int LdapOperation::add_s( const LdapObject &object )
00761 {
00762   Q_ASSERT( d->mConnection );
00763   LDAP *ld = (LDAP*) d->mConnection->handle();
00764 
00765   LDAPMod **lmod = 0;
00766 
00767   LDAPControl **serverctrls = 0, **clientctrls = 0;
00768   createControls( &serverctrls, d->mServerCtrls );
00769   createControls( &serverctrls, d->mClientCtrls );
00770 
00771   for ( LdapAttrMap::ConstIterator it = object.attributes().begin();
00772         it != object.attributes().end(); ++it ) {
00773     QString attr = it.key();
00774     for ( LdapAttrValue::ConstIterator it2 = (*it).begin(); it2 != (*it).end(); ++it2 ) {
00775       addModOp( &lmod, 0, attr, &(*it2) );
00776     }
00777   }
00778 
00779   int retval =
00780     ldap_add_ext_s( ld, object.dn().toString().toUtf8().data(), lmod, serverctrls,
00781                     clientctrls );
00782 
00783   ldap_controls_free( serverctrls );
00784   ldap_controls_free( clientctrls );
00785   ldap_mods_free( lmod, 1 );
00786   return retval;
00787 }
00788 
00789 int LdapOperation::add( const LdapDN &dn, const ModOps &ops )
00790 {
00791   Q_ASSERT( d->mConnection );
00792   LDAP *ld = (LDAP*) d->mConnection->handle();
00793 
00794   int msgid;
00795   LDAPMod **lmod = 0;
00796 
00797   LDAPControl **serverctrls = 0, **clientctrls = 0;
00798   createControls( &serverctrls, d->mServerCtrls );
00799   createControls( &serverctrls, d->mClientCtrls );
00800 
00801   for ( int i = 0; i < ops.count(); ++i ) {
00802     for ( int j = 0; j < ops[i].values.count(); ++j ) {
00803       addModOp( &lmod, 0, ops[i].attr, &ops[i].values[j] );
00804     }
00805   }
00806 
00807   int retval =
00808     ldap_add_ext( ld, dn.toString().toUtf8().data(), lmod, serverctrls,
00809                   clientctrls, &msgid );
00810 
00811   ldap_controls_free( serverctrls );
00812   ldap_controls_free( clientctrls );
00813   ldap_mods_free( lmod, 1 );
00814   if ( retval == 0 ) {
00815     retval = msgid;
00816   }
00817   return retval;
00818 }
00819 
00820 int LdapOperation::add_s( const LdapDN &dn, const ModOps &ops )
00821 {
00822   Q_ASSERT( d->mConnection );
00823   LDAP *ld = (LDAP*) d->mConnection->handle();
00824 
00825   LDAPMod **lmod = 0;
00826 
00827   LDAPControl **serverctrls = 0, **clientctrls = 0;
00828   createControls( &serverctrls, d->mServerCtrls );
00829   createControls( &serverctrls, d->mClientCtrls );
00830 
00831   for ( int i = 0; i < ops.count(); ++i ) {
00832     for ( int j = 0; j < ops[i].values.count(); ++j ) {
00833       addModOp( &lmod, 0, ops[i].attr, &ops[i].values[j] );
00834     }
00835   }
00836   kDebug() << dn.toString();
00837   int retval =
00838     ldap_add_ext_s( ld, dn.toString().toUtf8().data(), lmod, serverctrls,
00839                     clientctrls );
00840 
00841   ldap_controls_free( serverctrls );
00842   ldap_controls_free( clientctrls );
00843   ldap_mods_free( lmod, 1 );
00844   return retval;
00845 }
00846 
00847 int LdapOperation::rename( const LdapDN &dn, const QString &newRdn,
00848                            const QString &newSuperior, bool deleteold )
00849 {
00850   Q_ASSERT( d->mConnection );
00851   LDAP *ld = (LDAP*) d->mConnection->handle();
00852 
00853   int msgid;
00854 
00855   LDAPControl **serverctrls = 0, **clientctrls = 0;
00856   createControls( &serverctrls, d->mServerCtrls );
00857   createControls( &serverctrls, d->mClientCtrls );
00858 
00859   int retval = ldap_rename( ld, dn.toString().toUtf8().data(), newRdn.toUtf8().data(),
00860                             newSuperior.isEmpty() ? (char *) 0 : newSuperior.toUtf8().data(),
00861                             deleteold, serverctrls, clientctrls, &msgid );
00862 
00863   ldap_controls_free( serverctrls );
00864   ldap_controls_free( clientctrls );
00865 
00866   if ( retval == 0 ) {
00867     retval = msgid;
00868   }
00869   return retval;
00870 }
00871 
00872 int LdapOperation::rename_s( const LdapDN &dn, const QString &newRdn,
00873                              const QString &newSuperior, bool deleteold )
00874 {
00875   Q_ASSERT( d->mConnection );
00876   LDAP *ld = (LDAP*) d->mConnection->handle();
00877 
00878   LDAPControl **serverctrls = 0, **clientctrls = 0;
00879   createControls( &serverctrls, d->mServerCtrls );
00880   createControls( &serverctrls, d->mClientCtrls );
00881 
00882   int retval = ldap_rename_s( ld, dn.toString().toUtf8().data(), newRdn.toUtf8().data(),
00883                               newSuperior.isEmpty() ? (char *) 0 : newSuperior.toUtf8().data(),
00884                               deleteold, serverctrls, clientctrls );
00885 
00886   ldap_controls_free( serverctrls );
00887   ldap_controls_free( clientctrls );
00888 
00889   return retval;
00890 }
00891 
00892 int LdapOperation::del( const LdapDN &dn )
00893 {
00894   Q_ASSERT( d->mConnection );
00895   LDAP *ld = (LDAP*) d->mConnection->handle();
00896 
00897   int msgid;
00898 
00899   LDAPControl **serverctrls = 0, **clientctrls = 0;
00900   createControls( &serverctrls, d->mServerCtrls );
00901   createControls( &serverctrls, d->mClientCtrls );
00902 
00903   int retval =
00904     ldap_delete_ext( ld, dn.toString().toUtf8().data(), serverctrls, clientctrls, &msgid );
00905 
00906   ldap_controls_free( serverctrls );
00907   ldap_controls_free( clientctrls );
00908 
00909   if ( retval == 0 ) {
00910     retval = msgid;
00911   }
00912   return retval;
00913 }
00914 
00915 int LdapOperation::del_s( const LdapDN &dn )
00916 {
00917   Q_ASSERT( d->mConnection );
00918   LDAP *ld = (LDAP*) d->mConnection->handle();
00919 
00920   LDAPControl **serverctrls = 0, **clientctrls = 0;
00921   createControls( &serverctrls, d->mServerCtrls );
00922   createControls( &serverctrls, d->mClientCtrls );
00923 
00924   int retval = ldap_delete_ext_s( ld, dn.toString().toUtf8().data(), serverctrls, clientctrls );
00925 
00926   ldap_controls_free( serverctrls );
00927   ldap_controls_free( clientctrls );
00928 
00929   return retval;
00930 }
00931 
00932 int LdapOperation::modify( const LdapDN &dn, const ModOps &ops )
00933 {
00934   Q_ASSERT( d->mConnection );
00935   LDAP *ld = (LDAP *)d->mConnection->handle();
00936 
00937   int msgid;
00938   LDAPMod **lmod = 0;
00939 
00940   LDAPControl **serverctrls = 0, **clientctrls = 0;
00941   createControls( &serverctrls, d->mServerCtrls );
00942   createControls( &serverctrls, d->mClientCtrls );
00943 
00944   for ( int i = 0; i < ops.count(); ++i ) {
00945     int mtype = 0;
00946     switch ( ops[i].type ) {
00947     case Mod_None:
00948       mtype = 0;
00949       break;
00950     case Mod_Add:
00951       mtype = LDAP_MOD_ADD;
00952       break;
00953     case Mod_Replace:
00954       mtype = LDAP_MOD_REPLACE;
00955       break;
00956     case Mod_Del:
00957       mtype = LDAP_MOD_DELETE;
00958       break;
00959     }
00960     addModOp( &lmod, mtype, ops[i].attr, 0 );
00961     for ( int j = 0; j < ops[i].values.count(); ++j ) {
00962       addModOp( &lmod, mtype, ops[i].attr, &ops[i].values[j] );
00963     }
00964   }
00965 
00966   int retval =
00967     ldap_modify_ext( ld, dn.toString().toUtf8().data(), lmod, serverctrls, clientctrls, &msgid );
00968 
00969   ldap_controls_free( serverctrls );
00970   ldap_controls_free( clientctrls );
00971   ldap_mods_free( lmod, 1 );
00972   if ( retval == 0 ) {
00973     retval = msgid;
00974   }
00975   return retval;
00976 }
00977 
00978 int LdapOperation::modify_s( const LdapDN &dn, const ModOps &ops )
00979 {
00980   Q_ASSERT( d->mConnection );
00981   LDAP *ld = (LDAP*) d->mConnection->handle();
00982 
00983   LDAPMod **lmod = 0;
00984 
00985   LDAPControl **serverctrls = 0, **clientctrls = 0;
00986   createControls( &serverctrls, d->mServerCtrls );
00987   createControls( &serverctrls, d->mClientCtrls );
00988 
00989   for ( int i = 0; i < ops.count(); ++i ) {
00990     int mtype = 0;
00991     switch ( ops[i].type ) {
00992     case Mod_None:
00993       mtype = 0;
00994       break;
00995     case Mod_Add:
00996       mtype = LDAP_MOD_ADD;
00997       break;
00998     case Mod_Replace:
00999       mtype = LDAP_MOD_REPLACE;
01000       break;
01001     case Mod_Del:
01002       mtype = LDAP_MOD_DELETE;
01003       break;
01004     }
01005     addModOp( &lmod, mtype, ops[i].attr, 0 );
01006     for ( int j = 0; j < ops[i].values.count(); ++j ) {
01007       addModOp( &lmod, mtype, ops[i].attr, &ops[i].values[j] );
01008     }
01009   }
01010 
01011   int retval =
01012     ldap_modify_ext_s( ld, dn.toString().toUtf8().data(), lmod, serverctrls, clientctrls );
01013 
01014   ldap_controls_free( serverctrls );
01015   ldap_controls_free( clientctrls );
01016   ldap_mods_free( lmod, 1 );
01017   return retval;
01018 }
01019 
01020 int LdapOperation::compare( const LdapDN &dn, const QString &attr, const QByteArray &value )
01021 {
01022   Q_ASSERT( d->mConnection );
01023   LDAP *ld = (LDAP*) d->mConnection->handle();
01024   int msgid;
01025 
01026   LDAPControl **serverctrls = 0, **clientctrls = 0;
01027   createControls( &serverctrls, d->mServerCtrls );
01028   createControls( &serverctrls, d->mClientCtrls );
01029 
01030   int vallen = value.size();
01031   BerValue *berval;
01032   berval = (BerValue *) malloc( sizeof( BerValue ) );
01033   berval -> bv_val = (char *) malloc( vallen );
01034   berval -> bv_len = vallen;
01035   memcpy( berval -> bv_val, value.data(), vallen );
01036 
01037   int retval = ldap_compare_ext( ld, dn.toString().toUtf8().data(), attr.toUtf8().data(), berval,
01038                                  serverctrls, clientctrls, &msgid );
01039 
01040   ber_bvfree( berval );
01041   ldap_controls_free( serverctrls );
01042   ldap_controls_free( clientctrls );
01043 
01044   if ( retval == 0 ) {
01045     retval = msgid;
01046   }
01047   return retval;
01048 }
01049 
01050 int LdapOperation::compare_s( const LdapDN &dn, const QString &attr, const QByteArray &value )
01051 {
01052   Q_ASSERT( d->mConnection );
01053   LDAP *ld = (LDAP*) d->mConnection->handle();
01054 
01055   LDAPControl **serverctrls = 0, **clientctrls = 0;
01056   createControls( &serverctrls, d->mServerCtrls );
01057   createControls( &serverctrls, d->mClientCtrls );
01058 
01059   int vallen = value.size();
01060   BerValue *berval;
01061   berval = (BerValue *) malloc( sizeof( BerValue ) );
01062   berval -> bv_val = (char *) malloc( vallen );
01063   berval -> bv_len = vallen;
01064   memcpy( berval -> bv_val, value.data(), vallen );
01065 
01066   int retval = ldap_compare_ext_s( ld, dn.toString().toUtf8().data(), attr.toUtf8().data(), berval,
01067                                    serverctrls, clientctrls );
01068 
01069   ber_bvfree( berval );
01070   ldap_controls_free( serverctrls );
01071   ldap_controls_free( clientctrls );
01072 
01073   return retval;
01074 }
01075 
01076 int LdapOperation::exop( const QString &oid, const QByteArray &data )
01077 {
01078   Q_ASSERT( d->mConnection );
01079 #if defined(HAVE_LDAP_EXTENDED_OPERATION) && defined(HAVE_LDAP_EXTENDED_OPERATION_PROTOTYPE)
01080   LDAP *ld = (LDAP*) d->mConnection->handle();
01081   int msgid;
01082 
01083   LDAPControl **serverctrls = 0, **clientctrls = 0;
01084   createControls( &serverctrls, d->mServerCtrls );
01085   createControls( &serverctrls, d->mClientCtrls );
01086 
01087   int vallen = data.size();
01088   BerValue *berval;
01089   berval = (BerValue *) malloc( sizeof( BerValue ) );
01090   berval -> bv_val = (char *) malloc( vallen );
01091   berval -> bv_len = vallen;
01092   memcpy( berval -> bv_val, data.data(), vallen );
01093 
01094   int retval = ldap_extended_operation( ld, oid.toUtf8().data(), berval,
01095                                         serverctrls, clientctrls, &msgid );
01096 
01097   ber_bvfree( berval );
01098   ldap_controls_free( serverctrls );
01099   ldap_controls_free( clientctrls );
01100 
01101   if ( retval == 0 ) {
01102     retval = msgid;
01103   }
01104   return retval;
01105 #else
01106   kError() << "Your LDAP client libraries don't support extended operations.";
01107   return -1;
01108 #endif
01109 }
01110 
01111 int LdapOperation::exop_s( const QString &oid, const QByteArray &data )
01112 {
01113 #if defined(HAVE_LDAP_EXTENDED_OPERATION) && defined(HAVE_LDAP_EXTENDED_OPERATION_PROTOTYPE)
01114   Q_ASSERT( d->mConnection );
01115   LDAP *ld = (LDAP*) d->mConnection->handle();
01116   BerValue *retdata;
01117   char *retoid;
01118 
01119   LDAPControl **serverctrls = 0, **clientctrls = 0;
01120   createControls( &serverctrls, d->mServerCtrls );
01121   createControls( &serverctrls, d->mClientCtrls );
01122 
01123   int vallen = data.size();
01124   BerValue *berval;
01125   berval = (BerValue *) malloc( sizeof( BerValue ) );
01126   berval -> bv_val = (char *) malloc( vallen );
01127   berval -> bv_len = vallen;
01128   memcpy( berval -> bv_val, data.data(), vallen );
01129 
01130   int retval = ldap_extended_operation_s( ld, oid.toUtf8().data(), berval,
01131                                           serverctrls, clientctrls, &retoid, &retdata );
01132 
01133   ber_bvfree( berval );
01134   ber_bvfree( retdata );
01135   free( retoid );
01136   ldap_controls_free( serverctrls );
01137   ldap_controls_free( clientctrls );
01138 
01139   return retval;
01140 #else
01141   kError() << "Your LDAP client libraries don't support extended operations.";
01142   return -1;
01143 #endif
01144 }
01145 
01146 int LdapOperation::abandon( int id )
01147 {
01148   Q_ASSERT( d->mConnection );
01149   LDAP *ld = (LDAP*) d->mConnection->handle();
01150 
01151   LDAPControl **serverctrls = 0, **clientctrls = 0;
01152   createControls( &serverctrls, d->mServerCtrls );
01153   createControls( &serverctrls, d->mClientCtrls );
01154 
01155   int retval = ldap_abandon_ext( ld, id, serverctrls, clientctrls );
01156 
01157   ldap_controls_free( serverctrls );
01158   ldap_controls_free( clientctrls );
01159 
01160   return retval;
01161 }
01162 
01163 int LdapOperation::waitForResult( int id, int msecs )
01164 {
01165   Q_ASSERT( d->mConnection );
01166   LDAP *ld = (LDAP*) d->mConnection->handle();
01167 
01168   LDAPMessage *msg;
01169   int rescode;
01170 
01171   QTime stopWatch;
01172   stopWatch.start();
01173   int attempt( 1 );
01174   int timeout( 0 );
01175 
01176   do {
01177     // Calculate the timeout value to use and assign it to a timeval structure
01178     // see man select (2) for details
01179     timeout = kldap_timeout_value( msecs, stopWatch.elapsed() );
01180     kDebug() << "(" << id << "," << msecs
01181              << "): Waiting" << timeout
01182              << "msecs for result. Attempt #" << attempt++;
01183     struct timeval tv;
01184     tv.tv_sec = timeout / 1000;
01185     tv.tv_usec = ( timeout % 1000 ) * 1000;
01186 
01187     // Wait for a result
01188     rescode = ldap_result( ld, id, 0, timeout < 0 ? 0 : &tv, &msg );
01189     if ( rescode == -1 ) {
01190       return -1;
01191     }
01192     // Act on the return code
01193     if ( rescode != 0 ) {
01194       // Some kind of result is available for processing
01195       return d->processResult( rescode, msg );
01196     }
01197   } while ( msecs == -1 || stopWatch.elapsed() < msecs );
01198 
01199   return 0; //timeout
01200 }
01201 
01202 #else
01203 
01204 int LdapOperation::bind( const QByteArray &creds, SASL_Callback_Proc *saslproc, void *data )
01205 {
01206   kError() << "LDAP support not compiled";
01207   return -1;
01208 }
01209 
01210 int LdapOperation::bind_s( SASL_Callback_Proc *saslproc, void *data )
01211 {
01212   kError() << "LDAP support not compiled";
01213   return -1;
01214 }
01215 
01216 int LdapOperation::search( const LdapDN &base, LdapUrl::Scope scope,
01217                            const QString &filter, const QStringList &attributes )
01218 {
01219   kError() << "LDAP support not compiled";
01220   return -1;
01221 }
01222 
01223 int LdapOperation::add( const LdapObject &object )
01224 {
01225   kError() << "LDAP support not compiled";
01226   return -1;
01227 }
01228 
01229 int LdapOperation::add_s( const LdapObject &object )
01230 {
01231   kError() << "LDAP support not compiled";
01232   return -1;
01233 }
01234 
01235 int LdapOperation::add( const LdapDN &dn, const ModOps &ops )
01236 {
01237   kError() << "LDAP support not compiled";
01238   return -1;
01239 }
01240 
01241 int LdapOperation::add_s( const LdapDN &dn, const ModOps &ops )
01242 {
01243   kError() << "LDAP support not compiled";
01244   return -1;
01245 }
01246 
01247 int LdapOperation::rename( const LdapDN &dn, const QString &newRdn,
01248                            const QString &newSuperior, bool deleteold )
01249 {
01250   kError() << "LDAP support not compiled";
01251   return -1;
01252 }
01253 
01254 int LdapOperation::rename_s( const LdapDN &dn, const QString &newRdn,
01255                              const QString &newSuperior, bool deleteold )
01256 {
01257   kError() << "LDAP support not compiled";
01258   return -1;
01259 }
01260 
01261 int LdapOperation::del( const LdapDN &dn )
01262 {
01263   kError() << "LDAP support not compiled";
01264   return -1;
01265 }
01266 
01267 int LdapOperation::del_s( const LdapDN &dn )
01268 {
01269   kError() << "LDAP support not compiled";
01270   return -1;
01271 }
01272 
01273 int LdapOperation::modify( const LdapDN &dn, const ModOps &ops )
01274 {
01275   kError() << "LDAP support not compiled";
01276   return -1;
01277 }
01278 
01279 int LdapOperation::modify_s( const LdapDN &dn, const ModOps &ops )
01280 {
01281   kError() << "LDAP support not compiled";
01282   return -1;
01283 }
01284 
01285 int LdapOperation::compare( const LdapDN &dn, const QString &attr, const QByteArray &value )
01286 {
01287   kError() << "LDAP support not compiled";
01288   return -1;
01289 }
01290 
01291 int LdapOperation::exop( const QString &oid, const QByteArray &data )
01292 {
01293   kError() << "LDAP support not compiled";
01294   return -1;
01295 }
01296 
01297 int LdapOperation::compare_s( const LdapDN &dn, const QString &attr, const QByteArray &value )
01298 {
01299   kError() << "LDAP support not compiled";
01300   return -1;
01301 }
01302 
01303 int LdapOperation::exop_s( const QString &oid, const QByteArray &data )
01304 {
01305   kError() << "LDAP support not compiled";
01306   return -1;
01307 }
01308 
01309 int LdapOperation::waitForResult( int id, int msecs )
01310 {
01311   kError() << "LDAP support not compiled";
01312   return -1;
01313 }
01314 
01315 int LdapOperation::abandon( int id )
01316 {
01317   kError() << "LDAP support not compiled";
01318   return -1;
01319 }
01320 
01321 #endif

KLDAP Library

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • 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.6.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