KLDAP Library
ldapsearch.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 "ldapsearch.h" 00022 #include "ldapdn.h" 00023 #include "ldapdefs.h" 00024 00025 #include <QtCore/QEventLoop> 00026 #include <QtCore/QTimer> 00027 00028 #include <kdebug.h> 00029 #include <KLocale> 00030 using namespace KLDAP; 00031 00032 //blocking the GUI for xxx milliseconds 00033 #define LDAPSEARCH_BLOCKING_TIMEOUT 10 00034 00035 class LdapSearch::Private 00036 { 00037 public: 00038 Private( LdapSearch *parent ) 00039 : mParent( parent ) 00040 { 00041 } 00042 00043 void result(); 00044 bool connect(); 00045 void closeConnection(); 00046 bool startSearch( const LdapDN &base, LdapUrl::Scope scope, 00047 const QString &filter, const QStringList &attributes, 00048 int pagesize, int count ); 00049 00050 LdapSearch *mParent; 00051 LdapConnection *mConn; 00052 LdapOperation mOp; 00053 bool mOwnConnection, mAbandoned; 00054 int mId, mPageSize; 00055 LdapDN mBase; 00056 QString mFilter; 00057 QStringList mAttributes; 00058 LdapUrl::Scope mScope; 00059 00060 QString mErrorString; 00061 int mError; 00062 int mCount, mMaxCount; 00063 bool mFinished; 00064 }; 00065 00066 void LdapSearch::Private::result() 00067 { 00068 if ( mAbandoned ) { 00069 mOp.abandon( mId ); 00070 return; 00071 } 00072 int res = mOp.waitForResult( mId, LDAPSEARCH_BLOCKING_TIMEOUT ); 00073 00074 kDebug() << "LDAP result:" << res; 00075 00076 if ( res != 0 && 00077 ( res == -1 || 00078 ( mConn->ldapErrorCode() != KLDAP_SUCCESS && 00079 mConn->ldapErrorCode() != KLDAP_SASL_BIND_IN_PROGRESS ) ) ) { 00080 //error happened, but no timeout 00081 mError = mConn->ldapErrorCode(); 00082 mErrorString = mConn->ldapErrorString(); 00083 emit mParent->result( mParent ); 00084 return; 00085 } 00086 00087 //binding 00088 if ( res == LdapOperation::RES_BIND ) { 00089 00090 QByteArray servercc; 00091 servercc = mOp.serverCred(); 00092 00093 kDebug() << "LdapSearch RES_BIND"; 00094 if ( mConn->ldapErrorCode() == KLDAP_SUCCESS ) { //bind succeeded 00095 kDebug() << "bind succeeded"; 00096 LdapControls savedctrls = mOp.serverControls(); 00097 if ( mPageSize ) { 00098 LdapControls ctrls = savedctrls; 00099 LdapControl::insert( ctrls, LdapControl::createPageControl( mPageSize ) ); 00100 mOp.setServerControls( ctrls ); 00101 } 00102 00103 mId = mOp.search( mBase, mScope, mFilter, mAttributes ); 00104 mOp.setServerControls( savedctrls ); 00105 } else { //next bind step 00106 kDebug() << "bind next step"; 00107 mId = mOp.bind( servercc ); 00108 } 00109 if ( mId < 0 ) { 00110 if ( mId == KLDAP_SASL_ERROR ) { 00111 mError = mId; 00112 mErrorString = mConn->saslErrorString(); 00113 } else { 00114 mError = mConn->ldapErrorCode(); 00115 mErrorString = mConn->ldapErrorString(); 00116 } 00117 emit mParent->result( mParent ); 00118 return; 00119 } 00120 QTimer::singleShot( 0, mParent, SLOT(result()) ); 00121 return; 00122 } 00123 00124 //End of entries 00125 if ( res == LdapOperation::RES_SEARCH_RESULT ) { 00126 if ( mPageSize ) { 00127 QByteArray cookie; 00128 int estsize = -1; 00129 const int numberOfControls( mOp.controls().count() ); 00130 for ( int i = 0; i < numberOfControls; ++i ) { 00131 estsize = mOp.controls()[i].parsePageControl( cookie ); 00132 if ( estsize != -1 ) { 00133 break; 00134 } 00135 } 00136 kDebug() << " estimated size:" << estsize; 00137 if ( estsize != -1 && !cookie.isEmpty() ) { 00138 LdapControls ctrls, savedctrls; 00139 savedctrls = mOp.serverControls(); 00140 ctrls = savedctrls; 00141 LdapControl::insert( ctrls, LdapControl::createPageControl ( mPageSize, cookie ) ); 00142 mOp.setServerControls( ctrls ); 00143 mId = mOp.search( mBase, mScope, mFilter, mAttributes ); 00144 mOp.setServerControls( savedctrls ); 00145 if ( mId == -1 ) { 00146 mError = mConn->ldapErrorCode(); 00147 mErrorString = mConn->ldapErrorString(); 00148 emit mParent->result( mParent ); 00149 return; 00150 } 00151 //continue with the next page 00152 QTimer::singleShot( 0, mParent, SLOT(result()) ); 00153 return; 00154 } 00155 } 00156 mFinished = true; 00157 emit mParent->result( mParent ); 00158 return; 00159 } 00160 00161 //Found an entry 00162 if ( res == LdapOperation::RES_SEARCH_ENTRY ) { 00163 emit mParent->data( mParent, mOp.object() ); 00164 mCount++; 00165 } 00166 00167 //If not reached the requested entries, continue 00168 if ( mMaxCount <= 0 || mCount < mMaxCount ) { 00169 QTimer::singleShot( 0, mParent, SLOT(result()) ); 00170 } 00171 //If reached the requested entries, indicate it 00172 if ( mMaxCount > 0 && mCount == mMaxCount ) { 00173 kDebug() << mCount << " entries reached"; 00174 emit mParent->result( mParent ); 00175 } 00176 } 00177 00178 bool LdapSearch::Private::connect() 00179 { 00180 int ret = mConn->connect(); 00181 if ( ret != KLDAP_SUCCESS ) { 00182 mError = ret; 00183 mErrorString = mConn->connectionError(); 00184 closeConnection(); 00185 return false; 00186 } 00187 return true; 00188 } 00189 00190 void LdapSearch::Private::closeConnection() 00191 { 00192 if ( mOwnConnection && mConn ) { 00193 delete mConn; 00194 mConn = 0; 00195 } 00196 } 00197 00198 //This starts the real job 00199 bool LdapSearch::Private::startSearch( const LdapDN &base, LdapUrl::Scope scope, 00200 const QString &filter, 00201 const QStringList &attributes, int pagesize, int count ) 00202 { 00203 kDebug() << "search: base=" << base.toString() << "scope=" << (int)scope 00204 << "filter=" << filter << "attributes=" << attributes 00205 << "pagesize=" << pagesize; 00206 mAbandoned = false; 00207 mError = 0; 00208 mErrorString.clear(); 00209 mOp.setConnection( *mConn ); 00210 mPageSize = pagesize; 00211 mBase = base; 00212 mScope = scope; 00213 mFilter = filter; 00214 mAttributes = attributes; 00215 mMaxCount = count; 00216 mCount = 0; 00217 mFinished = false; 00218 00219 LdapControls savedctrls = mOp.serverControls(); 00220 if ( pagesize ) { 00221 LdapControls ctrls = savedctrls; 00222 mConn->setOption( 0x0008, NULL ); // Disable referals or paging won't work 00223 LdapControl::insert( ctrls, LdapControl::createPageControl( pagesize ) ); 00224 mOp.setServerControls( ctrls ); 00225 } 00226 00227 mId = mOp.bind(); 00228 if ( mId < 0 ) { 00229 if ( mId == KLDAP_SASL_ERROR ) { 00230 mError = mId; 00231 mErrorString = mConn->saslErrorString(); 00232 } else { 00233 mError = mConn->ldapErrorCode(); 00234 mErrorString = mConn->ldapErrorString(); 00235 if ( mError == -1 && mErrorString.isEmpty() ) { 00236 mErrorString = i18n( "Cannot access to server. Please reconfigure it." ); 00237 } 00238 } 00239 return false; 00240 } 00241 kDebug() << "startSearch msg id=" << mId; 00242 00243 //maybe do this with threads?- need thread-safe client libs!!! 00244 QTimer::singleShot( 0, mParent, SLOT(result()) ); 00245 00246 return true; 00247 } 00248 00250 00251 LdapSearch::LdapSearch() 00252 : d( new Private( this ) ) 00253 { 00254 d->mOwnConnection = true; 00255 d->mConn = 0; 00256 } 00257 00258 LdapSearch::LdapSearch( LdapConnection &connection ) 00259 : d( new Private( this ) ) 00260 { 00261 d->mOwnConnection = false; 00262 d->mConn = &connection; 00263 } 00264 00265 LdapSearch::~LdapSearch() 00266 { 00267 d->closeConnection(); 00268 delete d; 00269 } 00270 00271 void LdapSearch::setConnection( LdapConnection &connection ) 00272 { 00273 d->closeConnection(); 00274 d->mOwnConnection = false; 00275 d->mConn = &connection; 00276 } 00277 00278 void LdapSearch::setClientControls( const LdapControls &ctrls ) 00279 { 00280 d->mOp.setClientControls( ctrls ); 00281 } 00282 00283 void LdapSearch::setServerControls( const LdapControls &ctrls ) 00284 { 00285 d->mOp.setServerControls( ctrls ); 00286 } 00287 00288 bool LdapSearch::search( const LdapServer &server, 00289 const QStringList &attributes, int count ) 00290 { 00291 if ( d->mOwnConnection ) { 00292 d->closeConnection(); 00293 d->mConn = new LdapConnection( server ); 00294 if ( !d->connect() ) { 00295 return false; 00296 } 00297 } 00298 return d->startSearch( server.baseDn(), server.scope(), server.filter(), 00299 attributes, server.pageSize(), count ); 00300 } 00301 00302 bool LdapSearch::search( const LdapUrl &url, int count ) 00303 { 00304 if ( d->mOwnConnection ) { 00305 d->closeConnection(); 00306 d->mConn = new LdapConnection( url ); 00307 if ( !d->connect() ) { 00308 return false; 00309 } 00310 } 00311 bool critical; 00312 int pagesize = url.extension( QLatin1String( "x-pagesize" ), critical ).toInt(); 00313 return d->startSearch( url.dn(), url.scope(), url.filter(), 00314 url.attributes(), pagesize, count ); 00315 } 00316 00317 bool LdapSearch::search( const LdapDN &base, LdapUrl::Scope scope, 00318 const QString &filter, const QStringList &attributes, 00319 int pagesize, int count ) 00320 { 00321 Q_ASSERT( !d->mOwnConnection ); 00322 return d->startSearch( base, scope, filter, attributes, pagesize, count ); 00323 } 00324 00325 void LdapSearch::continueSearch() 00326 { 00327 Q_ASSERT( !d->mFinished ); 00328 d->mCount = 0; 00329 QTimer::singleShot( 0, this, SLOT(result()) ); 00330 } 00331 00332 bool LdapSearch::isFinished() 00333 { 00334 return d->mFinished; 00335 } 00336 00337 void LdapSearch::abandon() 00338 { 00339 d->mAbandoned = true; 00340 } 00341 00342 int LdapSearch::error() const 00343 { 00344 return d->mError; 00345 } 00346 00347 QString LdapSearch::errorString() const 00348 { 00349 return d->mErrorString; 00350 } 00351 00352 #include "ldapsearch.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:09:14 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:09:14 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.