# kabc Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# resourceldap.cpp

    00001 /*
    00002     This file is part of libkabc.
    00003     Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
    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., 59 Temple Place - Suite 330,
    00018     Boston, MA 02111-1307, USA.
    00019 */
    00020
    00021 #include <kdebug.h>
    00022 #include <kglobal.h>
    00023 #include <klineedit.h>
    00024 #include <klocale.h>
    00025
    00026 #include <stdlib.h>
    00027
    00028 #include "resourceconfigwidget.h"
    00029 #include "resourceldap.h"
    00030 #include "resourceldapconfig.h"
    00031
    00032 using namespace KABC;
    00033
    00034 extern "C"
    00035 {
    00036   ResourceConfigWidget *config_widget( QWidget *parent ) {
    00037     KGlobal::locale()->insertCatalogue("kabc_ldap");
    00038     return new ResourceLDAPConfig( parent, "ResourceLDAPConfig" );
    00039   }
    00040
    00041   Resource *resource( AddressBook *ab, const KConfig *config ) {
    00042     KGlobal::locale()->insertCatalogue("kabc_ldap");
    00043     return new ResourceLDAP( ab, config );
    00044   }
    00045 }
    00046
    00047 void addModOp( LDAPMod ***pmods, const QString &attr, const QString &value );
    00048
    00049 ResourceLDAP::ResourceLDAP( AddressBook *ab, const KConfig *config )
    00050   : Resource( ab )
    00051 {
    00052   mLdap = 0;
    00053
    00054   mUser = config->readEntry( "LdapUser" );
    00055   mPassword = cryptStr( config->readEntry( "LdapPassword" ) );
    00056   mDn = config->readEntry( "LdapDn" );
    00057   mHost = config->readEntry( "LdapHost" );
    00058   mPort = config->readEntry( "LdapPort" );
    00059   mFilter = config->readEntry( "LdapFilter" );
    00060   mAnonymous = config->readBoolEntry( "LdapAnonymous" );
    00061 }
    00062
    00063 ResourceLDAP::ResourceLDAP( AddressBook *ab, const QString &user,
    00064         const QString &password, const QString &dn,
    00065         const QString &host, const QString &port, const QString &filter,
    00066   const bool anonymous )
    00067     : Resource( ab )
    00068 {
    00069   mLdap = 0;
    00070
    00071   mUser = user;
    00072   mPassword = password;
    00073   mDn = dn;
    00074   mHost = host;
    00075   mPort = port;
    00076   mFilter = filter;
    00077   mAnonymous = anonymous;
    00078 }
    00079
    00080 Ticket *ResourceLDAP::requestSaveTicket()
    00081 {
    00082   if ( !addressBook() ) {
    00083           kdDebug(5700) << "no addressbook" << endl;
    00084     return 0;
    00085   }
    00086
    00087   return createTicket( this );
    00088 }
    00089
    00090 bool ResourceLDAP::open()
    00091 {
    00092   if ( mLdap )
    00093           return false;
    00094
    00095   if ( mPort.isEmpty() )
    00096           mPort = "389";
    00097
    00098   mLdap = ldap_init( mHost.local8Bit(), mPort.toInt() );
    00099   if ( !mLdap ) {
    00100           addressBook()->error( i18n( "Unable to connect to server '%1' on port '%2'" ).arg( mHost ).arg( mPort ) );
    00101           return false;
    00102   }
    00103
    00104   if ( !mUser.isEmpty() && !mAnonymous ) {
    00105           if ( ldap_simple_bind_s( mLdap, mUser.local8Bit(), mPassword.local8Bit() ) != LDAP_SUCCESS ) {
    00106             addressBook()->error( i18n( "Unable to bind to server '%1'" ).arg( mHost ) );
    00107       return false;
    00108     }
    00109
    00110     kdDebug(5700) << "ResourceLDAP: bind to server successfully" << endl;
    00111   }
    00112
    00113   int deref = LDAP_DEREF_ALWAYS;
    00114   if ( ldap_set_option( mLdap, LDAP_OPT_DEREF, (void *) &deref ) != LDAP_OPT_SUCCESS ) {
    00115     kdDebug(5700) << "ResourceLDAP: can't set 'deref' option" << endl;
    00116     return false;
    00117   }
    00118
    00119   if ( ldap_set_option( mLdap, LDAP_OPT_REFERRALS, LDAP_OPT_ON ) != LDAP_OPT_SUCCESS ) {
    00120     kdDebug(5700) << "ResourceLDAP: can't set 'referrals' option" << endl;
    00121     return false;
    00122   }
    00123
    00124   return true;
    00125 }
    00126
    00127 void ResourceLDAP::close()
    00128 {
    00129   if ( ldap_unbind_s( mLdap ) != LDAP_SUCCESS ) {
    00130     kdDebug(5700) << "ResourceLDAP: can't unbind from server" << endl;
    00131     return;
    00132   }
    00133
    00134   mLdap = 0;
    00135 }
    00136
    00137 bool ResourceLDAP::load()
    00138 {
    00139   LDAPMessage *res;
    00140   LDAPMessage *msg;
    00141   BerElement *track;
    00142   char *names;
    00143   char **values;
    00144
    00145   const char *LdapSearchAttr[ 9 ] = {
    00146     "cn",
    00147     "display-name",
    00148     "givenname",
    00149     "mail",
    00150     "mailalias",
    00151     "phoneNumber",
    00152     "sn",
    00153     "uid",
    00154     0 };
    00155
    00156   if ( ldap_search_s( mLdap, mDn.local8Bit(), LDAP_SCOPE_SUBTREE, QString( "(%1)" ).arg( mFilter ).local8Bit(),
    00157       (char **)LdapSearchAttr, 0, &res ) != LDAP_SUCCESS ) {
    00158     addressBook()->error( i18n( "Unable to search on server '%1'" ).arg( mHost ) );
    00159     return false;
    00160   }
    00161
    00162   for ( msg = ldap_first_entry( mLdap, res ); msg; msg = ldap_next_entry( mLdap, msg ) ) {
    00163     Addressee addr;
    00164     addr.setResource( this );
    00165     for ( names = ldap_first_attribute( mLdap, msg, &track ); names; names = ldap_next_attribute( mLdap, msg, track ) ) {
    00166       values = ldap_get_values( mLdap, msg, names );
    00167       for ( int i = 0; i < ldap_count_values( values ); ++i ) {
    00168         QString name = QString::fromUtf8( names );
    00169         QString value = QString::fromUtf8( values[ i ] );
    00170
    00171         if ( name == "cn" ) {
    00172           if ( !addr.formattedName().isEmpty() ) {
    00173             QString fn = addr.formattedName();
    00174             addr.setNameFromString( value );
    00175             addr.setFormattedName( fn );
    00176           } else
    00177             addr.setNameFromString( value );
    00178           continue;
    00179         }
    00180         if ( name == "display-name" ) {
    00181           addr.setFormattedName( value );
    00182           continue;
    00183         }
    00184         if ( name == "givenname" ) {
    00185           addr.setGivenName( value );
    00186           continue;
    00187         }
    00188         if ( name == "mail" ) {
    00189           addr.insertEmail( value, true );
    00190           continue;
    00191         }
    00192         if ( name == "mailalias" ) {
    00193           addr.insertEmail( value, false );
    00194           continue;
    00195         }
    00196         if ( name == "phoneNumber" ) {
    00197           PhoneNumber phone;
    00198           phone.setNumber( value );
    00199           addr.insertPhoneNumber( phone );
    00200           break; // read only the home number
    00201         }
    00202         if ( name == "sn" ) {
    00203           addr.setFamilyName( value );
    00204           continue;
    00205         }
    00206         if ( name == "uid" ) {
    00207           addr.setUid( value );
    00208           continue;
    00209         }
    00210       }
    00211       ldap_value_free( values );
    00212     }
    00213     ber_free( track, 0 );
    00214
    00215     addressBook()->insertAddressee( addr );
    00216   }
    00217
    00218   ldap_msgfree( res );
    00219
    00220   return true;
    00221 }
    00222
    00223 bool ResourceLDAP::save( Ticket * )
    00224 {
    00225   AddressBook::Iterator it;
    00226   for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) {
    00227     if ( (*it).resource() == this && (*it).changed() ) {
    00228       LDAPMod **mods = NULL;
    00229
    00230       addModOp( &mods, "objectClass", "organizationalPerson" );
    00231       addModOp( &mods, "objectClass", "person" );
    00232       addModOp( &mods, "objectClass", "Top" );
    00233       addModOp( &mods, "cn", (*it).assembledName() );
    00234       addModOp( &mods, "display-name", (*it).formattedName() );
    00235       addModOp( &mods, "givenname", (*it).givenName() );
    00236       addModOp( &mods, "sn", (*it).familyName() );
    00237       addModOp( &mods, "uid", (*it).uid() );
    00238
    00239       QStringList emails = (*it).emails();
    00240       QStringList::ConstIterator mailIt;
    00241       bool first = true;
    00242       for ( mailIt = emails.begin(); mailIt != emails.end(); ++mailIt ) {
    00243         if ( first ) {
    00244           addModOp( &mods, "mail", (*mailIt) );
    00245           first = false;
    00246         } else
    00247           addModOp( &mods, "mailalias", (*mailIt) );
    00248       }
    00249
    00250       PhoneNumber number = (*it).phoneNumber( PhoneNumber::Home );
    00251       addModOp( &mods, "phoneNumber", number.number() );
    00252
    00253       QString dn = "cn=" + (*it).assembledName() + "," + mDn;
    00254
    00255       int retval;
    00256       if ( (retval = ldap_add_s( mLdap, dn.local8Bit(), mods )) != LDAP_SUCCESS )
    00257          addressBook()->error( i18n( "Unable to modify '%1' on server '%2'" ).arg( (*it).uid() ).arg( mHost ) );
    00258
    00259       ldap_mods_free( mods, 1 );
    00260
    00261       // mark as unchanged
    00262       (*it).setChanged( false );
    00263     }
    00264   }
    00265
    00266   return true;
    00267 }
    00268
    00269 void ResourceLDAP::removeAddressee( const Addressee &addr )
    00270 {
    00271   LDAPMessage *res;
    00272   LDAPMessage *msg;
    00273
    00274   QString filter = QString( "(&(uid=%1)(%2))" ).arg( addr.uid() ).arg( mFilter );
    00275
    00276   kdDebug(5700) << "ldap:removeAddressee" << filter << endl;
    00277
    00278   ldap_search_s( mLdap, mDn.local8Bit(), LDAP_SCOPE_SUBTREE, filter.local8Bit(),
    00279       0, 0, &res );
    00280
    00281   for ( msg = ldap_first_entry( mLdap, res ); msg; msg = ldap_next_entry( mLdap, msg ) ) {
    00282     char *dn = ldap_get_dn( mLdap, msg );
    00283     kdDebug(5700) << "found " << dn << endl;
    00284     if ( ldap_delete_s( mLdap, dn ) != LDAP_SUCCESS )
    00285       addressBook()->error( i18n( "Unable to delete '%1' on server '%2'" ).arg( dn ).arg( mHost ) );
    00286     ldap_memfree( dn );
    00287   }
    00288
    00289   ldap_msgfree( res );
    00290 }
    00291
    00292 QString ResourceLDAP::identifier() const
    00293 {
    00294   return mHost + "_" + mPort + "_" + mDn + "_" + mFilter;
    00295 }
    00296
    00297 void addModOp( LDAPMod ***pmods, const QString &attr, const QString &value )
    00298 {
    00299   if ( value.isNull() )
    00300     return;
    00301
    00302   LDAPMod       **mods;
    00303
    00304   mods = *pmods;
    00305
    00306   uint i = 0;
    00307   if ( mods != 0 )
    00308     for ( ; mods[ i ] != 0; ++i );
    00309
    00310   if (( mods = (LDAPMod **)realloc( mods, (i + 2) * sizeof( LDAPMod * ))) == 0 ) {
    00311     kdError() << "ResourceLDAP: realloc" << endl;
    00312     return;
    00313   }
    00314
    00315   *pmods = mods;
    00316   mods[ i + 1 ] = 0;
    00317
    00318   mods[ i ] = new LDAPMod;
    00319
    00320   mods[ i ]->mod_op = 0;
    00321   mods[ i ]->mod_type = strdup( attr.utf8() );
    00322   mods[ i ]->mod_values = new char*[2];
    00323   mods[ i ]->mod_values[0] = strdup( value.utf8() );
    00324   mods[ i ]->mod_values[1] = 0;
    00325 }

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:29:21 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001