summaryrefslogtreecommitdiffstats
path: root/libkdepim/ldapclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libkdepim/ldapclient.cpp')
-rw-r--r--libkdepim/ldapclient.cpp613
1 files changed, 0 insertions, 613 deletions
diff --git a/libkdepim/ldapclient.cpp b/libkdepim/ldapclient.cpp
deleted file mode 100644
index f8497f084..000000000
--- a/libkdepim/ldapclient.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-/* kldapclient.cpp - LDAP access
- * Copyright (C) 2002 Klarälvdalens Datakonsult AB
- *
- * Author: Steffen Hansen <hansen@kde.org>
- *
- * Ported to KABC by Daniel Molkentin <molkentin@kde.org>
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-
-
-#include <tqfile.h>
-#include <tqimage.h>
-#include <tqlabel.h>
-#include <tqpixmap.h>
-#include <tqtextstream.h>
-#include <tqurl.h>
-
-#include <kabc/ldapurl.h>
-#include <kabc/ldif.h>
-#include <kapplication.h>
-#include <kconfig.h>
-#include <kdebug.h>
-#include <kdirwatch.h>
-#include <kmdcodec.h>
-#include <kprotocolinfo.h>
-#include <kstandarddirs.h>
-#include <kstaticdeleter.h>
-
-#include "ldapclient.h"
-
-using namespace KPIM;
-
-KConfig *KPIM::LdapSearch::s_config = 0L;
-static KStaticDeleter<KConfig> configDeleter;
-
-TQString LdapObject::toString() const
-{
- TQString result = TQString::tqfromLatin1( "\ndn: %1\n" ).tqarg( dn );
- for ( LdapAttrMap::ConstIterator it = attrs.begin(); it != attrs.end(); ++it ) {
- TQString attr = it.key();
- for ( LdapAttrValue::ConstIterator it2 = (*it).begin(); it2 != (*it).end(); ++it2 ) {
- result += TQString::fromUtf8( KABC::LDIF::assembleLine( attr, *it2, 76 ) ) + "\n";
- }
- }
-
- return result;
-}
-
-void LdapObject::clear()
-{
- dn = TQString();
- objectClass = TQString();
- attrs.clear();
-}
-
-void LdapObject::assign( const LdapObject& that )
-{
- if ( &that != this ) {
- dn = that.dn;
- attrs = that.attrs;
- client = that.client;
- }
-}
-
-LdapClient::LdapClient( int clientNumber, TQObject* parent, const char* name )
- : TQObject( parent, name ), mJob( 0 ), mActive( false ), mReportObjectClass( false )
-{
-// d = new LdapClientPrivate;
- mClientNumber = clientNumber;
- mCompletionWeight = 50 - mClientNumber;
-}
-
-LdapClient::~LdapClient()
-{
- cancelQuery();
-// delete d; d = 0;
-}
-
-void LdapClient::setAttrs( const TQStringList& attrs )
-{
- mAttrs = attrs;
- for ( TQStringList::Iterator it = mAttrs.begin(); it != mAttrs.end(); ++it )
- if( (*it).lower() == "objectclass" ){
- mReportObjectClass = true;
- return;
- }
- mAttrs << "objectClass"; // via objectClass we detect distribution lists
- mReportObjectClass = false;
-}
-
-void LdapClient::startQuery( const TQString& filter )
-{
- cancelQuery();
- KABC::LDAPUrl url;
-
- url.setProtocol( ( mServer.security() == LdapServer::SSL ) ? "ldaps" : "ldap" );
- if ( mServer.auth() != LdapServer::Anonymous ) {
- url.setUser( mServer.user() );
- url.setPass( mServer.pwdBindDN() );
- }
- url.setHost( mServer.host() );
- url.setPort( mServer.port() );
- url.setExtension( "x-ver", TQString::number( mServer.version() ) );
- url.setDn( mServer.baseDN() );
- url.setDn( mServer.baseDN() );
- if ( mServer.security() == LdapServer::TLS ) url.setExtension( "x-tls","" );
- if ( mServer.auth() == LdapServer::SASL ) {
- url.setExtension( "x-sasl","" );
- if ( !mServer.bindDN().isEmpty() ) url.setExtension( "x-bindname", mServer.bindDN() );
- if ( !mServer.mech().isEmpty() ) url.setExtension( "x-mech", mServer.mech() );
- }
- if ( mServer.timeLimit() != 0 ) url.setExtension( "x-timelimit",
- TQString::number( mServer.timeLimit() ) );
- if ( mServer.sizeLimit() != 0 ) url.setExtension( "x-sizelimit",
- TQString::number( mServer.sizeLimit() ) );
-
- url.setAttributes( mAttrs );
- url.setScope( mScope == "one" ? KABC::LDAPUrl::One : KABC::LDAPUrl::Sub );
- url.setFilter( "("+filter+")" );
-
- kdDebug(5300) << "LdapClient: Doing query: " << url.prettyURL() << endl;
-
- startParseLDIF();
- mActive = true;
- mJob = KIO::get( url, false, false );
- connect( mJob, TQT_SIGNAL( data( KIO::Job*, const TQByteArray& ) ),
- this, TQT_SLOT( slotData( KIO::Job*, const TQByteArray& ) ) );
- connect( mJob, TQT_SIGNAL( infoMessage( KIO::Job*, const TQString& ) ),
- this, TQT_SLOT( slotInfoMessage( KIO::Job*, const TQString& ) ) );
- connect( mJob, TQT_SIGNAL( result( KIO::Job* ) ),
- this, TQT_SLOT( slotDone() ) );
-}
-
-void LdapClient::cancelQuery()
-{
- if ( mJob ) {
- mJob->kill();
- mJob = 0;
- }
-
- mActive = false;
-}
-
-void LdapClient::slotData( KIO::Job*, const TQByteArray& data )
-{
- parseLDIF( data );
-}
-
-void LdapClient::slotInfoMessage( KIO::Job*, const TQString & )
-{
- //qDebug("Job said \"%s\"", info.latin1());
-}
-
-void LdapClient::slotDone()
-{
- endParseLDIF();
- mActive = false;
-#if 0
- for ( TQValueList<LdapObject>::Iterator it = mObjects.begin(); it != mObjects.end(); ++it ) {
- qDebug( (*it).toString().latin1() );
- }
-#endif
- int err = mJob->error();
- if ( err && err != KIO::ERR_USER_CANCELED ) {
- emit error( mJob->errorString() );
- }
- emit done();
-}
-
-void LdapClient::startParseLDIF()
-{
- mCurrentObject.clear();
- mLdif.startParsing();
-}
-
-void LdapClient::endParseLDIF()
-{
-}
-
-void LdapClient::finishCurrentObject()
-{
- mCurrentObject.dn = mLdif.dn();
- const TQString sClass( mCurrentObject.objectClass.lower() );
- if( sClass == "groupofnames" || sClass == "kolabgroupofnames" ){
- LdapAttrMap::ConstIterator it = mCurrentObject.attrs.find("mail");
- if( it == mCurrentObject.attrs.end() ){
- // No explicit mail address found so far?
- // Fine, then we use the address stored in the DN.
- TQString sMail;
- TQStringList lMail = TQStringList::split(",dc=", mCurrentObject.dn);
- const int n = lMail.count();
- if( n ){
- if( lMail.first().lower().startsWith("cn=") ){
- sMail = lMail.first().simplifyWhiteSpace().mid(3);
- if( 1 < n )
- sMail.append('@');
- for( int i=1; i<n; ++i){
- sMail.append( lMail[i] );
- if( i < n-1 )
- sMail.append('.');
- }
- mCurrentObject.attrs["mail"].append( sMail.utf8() );
- }
- }
- }
- }
- mCurrentObject.client = this;
- emit result( mCurrentObject );
- mCurrentObject.clear();
-}
-
-void LdapClient::parseLDIF( const TQByteArray& data )
-{
- //kdDebug(5300) << "LdapClient::parseLDIF( " << TQCString(data.data(), data.size()+1) << " )" << endl;
- if ( data.size() ) {
- mLdif.setLDIF( data );
- } else {
- mLdif.endLDIF();
- }
-
- KABC::LDIF::ParseVal ret;
- TQString name;
- do {
- ret = mLdif.nextItem();
- switch ( ret ) {
- case KABC::LDIF::Item:
- {
- name = mLdif.attr();
- // Must make a copy! TQByteArray is explicitely shared
- TQByteArray value = mLdif.val().copy();
- bool bIsObjectClass = name.lower() == "objectclass";
- if( bIsObjectClass )
- mCurrentObject.objectClass = TQString::fromUtf8( value, value.size() );
- if( mReportObjectClass || !bIsObjectClass )
- mCurrentObject.attrs[ name ].append( value );
- //kdDebug(5300) << "LdapClient::parseLDIF(): name=" << name << " value=" << TQCString(value.data(), value.size()+1) << endl;
- }
- break;
- case KABC::LDIF::EndEntry:
- finishCurrentObject();
- break;
- default:
- break;
- }
- } while ( ret != KABC::LDIF::MoreData );
-}
-
-int LdapClient::clientNumber() const
-{
- return mClientNumber;
-}
-
-int LdapClient::completionWeight() const
-{
- return mCompletionWeight;
-}
-
-void LdapClient::setCompletionWeight( int weight )
-{
- mCompletionWeight = weight;
-}
-
-void LdapSearch::readConfig( LdapServer &server, KConfig *config, int j, bool active )
-{
- TQString prefix;
- if ( active ) prefix = "Selected";
- TQString host = config->readEntry( prefix + TQString( "Host%1" ).tqarg( j ), "" ).stripWhiteSpace();
- if ( !host.isEmpty() )
- server.setHost( host );
-
- int port = config->readNumEntry( prefix + TQString( "Port%1" ).tqarg( j ), 389 );
- server.setPort( port );
-
- TQString base = config->readEntry( prefix + TQString( "Base%1" ).tqarg( j ), "" ).stripWhiteSpace();
- if ( !base.isEmpty() )
- server.setBaseDN( base );
-
- TQString user = config->readEntry( prefix + TQString( "User%1" ).tqarg( j ) ).stripWhiteSpace();
- if ( !user.isEmpty() )
- server.setUser( user );
-
- TQString bindDN = config->readEntry( prefix + TQString( "Bind%1" ).tqarg( j ) ).stripWhiteSpace();
- if ( !bindDN.isEmpty() )
- server.setBindDN( bindDN );
-
- TQString pwdBindDN = config->readEntry( prefix + TQString( "PwdBind%1" ).tqarg( j ) );
- if ( !pwdBindDN.isEmpty() )
- server.setPwdBindDN( pwdBindDN );
-
- server.setTimeLimit( config->readNumEntry( prefix + TQString( "TimeLimit%1" ).tqarg( j ) ) );
- server.setSizeLimit( config->readNumEntry( prefix + TQString( "SizeLimit%1" ).tqarg( j ) ) );
- server.setVersion( config->readNumEntry( prefix + TQString( "Version%1" ).tqarg( j ), 3 ) );
- server.setSecurity( config->readNumEntry( prefix + TQString( "Security%1" ).tqarg( j ) ) );
- server.setAuth( config->readNumEntry( prefix + TQString( "Auth%1" ).tqarg( j ) ) );
- server.setMech( config->readEntry( prefix + TQString( "Mech%1" ).tqarg( j ) ) );
-}
-
-void LdapSearch::writeConfig( const LdapServer &server, KConfig *config, int j, bool active )
-{
- TQString prefix;
- if ( active ) prefix = "Selected";
- config->writeEntry( prefix + TQString( "Host%1" ).tqarg( j ), server.host() );
- config->writeEntry( prefix + TQString( "Port%1" ).tqarg( j ), server.port() );
- config->writeEntry( prefix + TQString( "Base%1" ).tqarg( j ), server.baseDN() );
- config->writeEntry( prefix + TQString( "User%1" ).tqarg( j ), server.user() );
- config->writeEntry( prefix + TQString( "Bind%1" ).tqarg( j ), server.bindDN() );
- config->writeEntry( prefix + TQString( "PwdBind%1" ).tqarg( j ), server.pwdBindDN() );
- config->writeEntry( prefix + TQString( "TimeLimit%1" ).tqarg( j ), server.timeLimit() );
- config->writeEntry( prefix + TQString( "SizeLimit%1" ).tqarg( j ), server.sizeLimit() );
- config->writeEntry( prefix + TQString( "Version%1" ).tqarg( j ), server.version() );
- config->writeEntry( prefix + TQString( "Security%1" ).tqarg( j ), server.security() );
- config->writeEntry( prefix + TQString( "Auth%1" ).tqarg( j ), server.auth() );
- config->writeEntry( prefix + TQString( "Mech%1" ).tqarg( j ), server.mech() );
-}
-
-KConfig* LdapSearch::config()
-{
- if ( !s_config )
- configDeleter.setObject( s_config, new KConfig( "kabldaprc", false, false ) ); // Open read-write, no kdeglobals
-
- return s_config;
-}
-
-
-LdapSearch::LdapSearch()
- : mActiveClients( 0 ), mNoLDAPLookup( false )
-{
- if ( !KProtocolInfo::isKnownProtocol( KURL("ldap://localhost") ) ) {
- mNoLDAPLookup = true;
- return;
- }
-
- readConfig();
- connect(KDirWatch::self(), TQT_SIGNAL(dirty (const TQString&)),this,
- TQT_SLOT(slotFileChanged(const TQString&)));
-}
-
-void LdapSearch::readWeighForClient( LdapClient *client, KConfig *config, int clientNumber )
-{
- const int completionWeight = config->readNumEntry( TQString( "SelectedCompletionWeight%1" ).tqarg( clientNumber ), -1 );
- if ( completionWeight != -1 )
- client->setCompletionWeight( completionWeight );
-}
-
-void LdapSearch::updateCompletionWeights()
-{
- KConfig *config = KPIM::LdapSearch::config();
- config->setGroup( "LDAP" );
- for ( uint i = 0; i < mClients.size(); i++ ) {
- readWeighForClient( mClients[i], config, i );
- }
-}
-
-void LdapSearch::readConfig()
-{
- cancelSearch();
- TQValueList< LdapClient* >::Iterator it;
- for ( it = mClients.begin(); it != mClients.end(); ++it )
- delete *it;
- mClients.clear();
-
- // stolen from KAddressBook
- KConfig *config = KPIM::LdapSearch::config();
- config->setGroup( "LDAP" );
- int numHosts = config->readUnsignedNumEntry( "NumSelectedHosts");
- if ( !numHosts ) {
- mNoLDAPLookup = true;
- } else {
- for ( int j = 0; j < numHosts; j++ ) {
- LdapClient* ldapClient = new LdapClient( j, this );
- LdapServer server;
- readConfig( server, config, j, true );
- if ( !server.host().isEmpty() ) mNoLDAPLookup = false;
- ldapClient->setServer( server );
-
- readWeighForClient( ldapClient, config, j );
-
- TQStringList attrs;
- // note: we need "objectClass" to detect distribution lists
- attrs << "cn" << "mail" << "givenname" << "sn" << "objectClass";
- ldapClient->setAttrs( attrs );
-
- connect( ldapClient, TQT_SIGNAL( result( const KPIM::LdapObject& ) ),
- this, TQT_SLOT( slotLDAPResult( const KPIM::LdapObject& ) ) );
- connect( ldapClient, TQT_SIGNAL( done() ),
- this, TQT_SLOT( slotLDAPDone() ) );
- connect( ldapClient, TQT_SIGNAL( error( const TQString& ) ),
- this, TQT_SLOT( slotLDAPError( const TQString& ) ) );
-
- mClients.append( ldapClient );
- }
-
- connect( &mDataTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotDataTimer() ) );
- }
- mConfigFile = locateLocal( "config", "kabldaprc" );
- KDirWatch::self()->addFile( mConfigFile );
-}
-
-void LdapSearch::slotFileChanged( const TQString& file )
-{
- if ( file == mConfigFile )
- readConfig();
-}
-
-void LdapSearch::startSearch( const TQString& txt )
-{
- if ( mNoLDAPLookup )
- return;
-
- cancelSearch();
-
- int pos = txt.find( '\"' );
- if( pos >= 0 )
- {
- ++pos;
- int pos2 = txt.find( '\"', pos );
- if( pos2 >= 0 )
- mSearchText = txt.mid( pos , pos2 - pos );
- else
- mSearchText = txt.mid( pos );
- } else
- mSearchText = txt;
-
- /* The reasoning behind this filter is:
- * If it's a person, or a distlist, show it, even if it doesn't have an email address.
- * If it's not a person, or a distlist, only show it if it has an email attribute.
- * This allows both resource accounts with an email address which are not a person and
- * person entries without an email address to show up, while still not showing things
- * like structural entries in the ldap tree. */
- TQString filter = TQString( "&(|(objectclass=person)(objectclass=groupOfNames)(mail=*))(|(cn=%1*)(mail=%2*)(mail=*@%3*)(givenName=%4*)(sn=%5*))" )
- .tqarg( mSearchText ).tqarg( mSearchText ).tqarg( mSearchText ).tqarg( mSearchText ).tqarg( mSearchText );
-
- TQValueList< LdapClient* >::Iterator it;
- for ( it = mClients.begin(); it != mClients.end(); ++it ) {
- (*it)->startQuery( filter );
- kdDebug(5300) << "LdapSearch::startSearch() " << filter << endl;
- ++mActiveClients;
- }
-}
-
-void LdapSearch::cancelSearch()
-{
- TQValueList< LdapClient* >::Iterator it;
- for ( it = mClients.begin(); it != mClients.end(); ++it )
- (*it)->cancelQuery();
-
- mActiveClients = 0;
- mResults.clear();
-}
-
-void LdapSearch::slotLDAPResult( const KPIM::LdapObject& obj )
-{
- mResults.append( obj );
- if ( !mDataTimer.isActive() )
- mDataTimer.start( 500, true );
-}
-
-void LdapSearch::slotLDAPError( const TQString& )
-{
- slotLDAPDone();
-}
-
-void LdapSearch::slotLDAPDone()
-{
- if ( --mActiveClients > 0 )
- return;
-
- finish();
-}
-
-void LdapSearch::slotDataTimer()
-{
- TQStringList lst;
- LdapResultList reslist;
- makeSearchData( lst, reslist );
- if ( !lst.isEmpty() )
- emit searchData( lst );
- if ( !reslist.isEmpty() )
- emit searchData( reslist );
-}
-
-void LdapSearch::finish()
-{
- mDataTimer.stop();
-
- slotDataTimer(); // emit final bunch of data
- emit searchDone();
-}
-
-void LdapSearch::makeSearchData( TQStringList& ret, LdapResultList& resList )
-{
- TQString search_text_upper = mSearchText.upper();
-
- TQValueList< KPIM::LdapObject >::ConstIterator it1;
- for ( it1 = mResults.begin(); it1 != mResults.end(); ++it1 ) {
- TQString name, mail, givenname, sn;
- TQStringList mails;
- bool isDistributionList = false;
- bool wasCN = false;
- bool wasDC = false;
-
- //kdDebug(5300) << "\n\nLdapSearch::makeSearchData()\n\n" << endl;
-
- LdapAttrMap::ConstIterator it2;
- for ( it2 = (*it1).attrs.begin(); it2 != (*it1).attrs.end(); ++it2 ) {
- TQByteArray val = (*it2).first();
- int len = val.size();
- if( len > 0 && '\0' == val[len-1] )
- --len;
- const TQString tmp = TQString::fromUtf8( val, len );
- //kdDebug(5300) << " key: \"" << it2.key() << "\" value: \"" << tmp << "\"" << endl;
- if ( it2.key() == "cn" ) {
- name = tmp;
- if( mail.isEmpty() )
- mail = tmp;
- else{
- if( wasCN )
- mail.prepend( "." );
- else
- mail.prepend( "@" );
- mail.prepend( tmp );
- }
- wasCN = true;
- } else if ( it2.key() == "dc" ) {
- if( mail.isEmpty() )
- mail = tmp;
- else{
- if( wasDC )
- mail.append( "." );
- else
- mail.append( "@" );
- mail.append( tmp );
- }
- wasDC = true;
- } else if( it2.key() == "mail" ) {
- mail = tmp;
- LdapAttrValue::ConstIterator it3 = it2.data().begin();
- for ( ; it3 != it2.data().end(); ++it3 ) {
- mails.append( TQString::fromUtf8( (*it3).data(), (*it3).size() ) );
- }
- } else if( it2.key() == "givenName" )
- givenname = tmp;
- else if( it2.key() == "sn" )
- sn = tmp;
- else if( it2.key() == "objectClass" &&
- (tmp == "groupOfNames" || tmp == "kolabGroupOfNames") ) {
- isDistributionList = true;
- }
- }
-
- if( mails.isEmpty()) {
- if ( !mail.isEmpty() ) mails.append( mail );
- if( isDistributionList ) {
- //kdDebug(5300) << "\n\nLdapSearch::makeSearchData() found a list: " << name << "\n\n" << endl;
- ret.append( name );
- // following lines commented out for bugfixing kolab issue #177:
- //
- // Unlike we thought previously we may NOT append the server name here.
- //
- // The right server is found by the SMTP server instead: Kolab users
- // must use the correct SMTP server, by definition.
- //
- //mail = (*it1).client->base().simplifyWhiteSpace();
- //mail.replace( ",dc=", ".", false );
- //if( mail.startsWith("dc=", false) )
- // mail.remove(0, 3);
- //mail.prepend( '@' );
- //mail.prepend( name );
- //mail = name;
- } else {
- //kdDebug(5300) << "LdapSearch::makeSearchData() found BAD ENTRY: \"" << name << "\"" << endl;
- continue; // nothing, bad entry
- }
- } else if ( name.isEmpty() ) {
- //kdDebug(5300) << "LdapSearch::makeSearchData() mail: \"" << mail << "\"" << endl;
- ret.append( mail );
- } else {
- //kdDebug(5300) << "LdapSearch::makeSearchData() name: \"" << name << "\" mail: \"" << mail << "\"" << endl;
- ret.append( TQString( "%1 <%2>" ).tqarg( name ).tqarg( mail ) );
- }
-
- LdapResult sr;
- sr.clientNumber = (*it1).client->clientNumber();
- sr.completionWeight = (*it1).client->completionWeight();
- sr.name = name;
- sr.email = mails;
- resList.append( sr );
- }
-
- mResults.clear();
-}
-
-bool LdapSearch::isAvailable() const
-{
- return !mNoLDAPLookup;
-}
-
-
-#include "ldapclient.moc"