1// OpenLDAP: pkg/ldap/contrib/ldapc++/src/LDAPAsynConnection.cpp,v 1.13.2.7 2010/04/14 23:50:44 quanah Exp 2/* 3 * Copyright 2000-2006, OpenLDAP Foundation, All Rights Reserved. 4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file 5 */ 6 7 8#include "config.h" 9#include "debug.h" 10#include "LDAPAsynConnection.h" 11 12#include "LDAPAddRequest.h" 13#include "LDAPBindRequest.h" 14#include "LDAPCompareRequest.h" 15#include "LDAPDeleteRequest.h" 16#include "LDAPExtRequest.h" 17#include "LDAPEntry.h" 18#include "LDAPModDNRequest.h" 19#include "LDAPModifyRequest.h" 20#include "LDAPRequest.h" 21#include "LDAPRebind.h" 22#include "LDAPRebindAuth.h" 23#include "LDAPSearchRequest.h" 24#include <lber.h> 25#include <sstream> 26 27using namespace std; 28 29LDAPAsynConnection::LDAPAsynConnection(const string& url, int port, 30 LDAPConstraints *cons ){ 31 DEBUG(LDAP_DEBUG_CONSTRUCT,"LDAPAsynConnection::LDAPAsynConnection()" 32 << endl); 33 DEBUG(LDAP_DEBUG_CONSTRUCT | LDAP_DEBUG_PARAMETER, 34 " URL:" << url << endl << " port:" << port << endl); 35 cur_session=0; 36 m_constr = 0; 37 // Is this an LDAP URI? 38 if ( url.find("://") == std::string::npos ) { 39 this->init(url, port); 40 } else { 41 this->initialize(url); 42 } 43 this->setConstraints(cons); 44} 45 46LDAPAsynConnection::~LDAPAsynConnection(){} 47 48void LDAPAsynConnection::init(const string& hostname, int port){ 49 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::init" << endl); 50 DEBUG(LDAP_DEBUG_TRACE | LDAP_DEBUG_PARAMETER, 51 " hostname:" << hostname << endl 52 << " port:" << port << endl); 53 54 m_uri.setScheme("ldap"); 55 m_uri.setHost(hostname); 56 m_uri.setPort(port); 57 58 const char *ldapuri = m_uri.getURLString().c_str(); 59 int ret = ldap_initialize(&cur_session, ldapuri); 60 if ( ret != LDAP_SUCCESS ) { 61 throw LDAPException( ret ); 62 } 63 int opt=3; 64 ldap_set_option(cur_session, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); 65 ldap_set_option(cur_session, LDAP_OPT_PROTOCOL_VERSION, &opt); 66} 67 68void LDAPAsynConnection::initialize(const std::string& uri){ 69 m_uri.setURLString(uri); 70 int ret = ldap_initialize(&cur_session, m_uri.getURLString().c_str()); 71 if ( ret != LDAP_SUCCESS ) { 72 throw LDAPException( ret ); 73 } 74 int opt=3; 75 ldap_set_option(cur_session, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); 76 ldap_set_option(cur_session, LDAP_OPT_PROTOCOL_VERSION, &opt); 77} 78 79void LDAPAsynConnection::start_tls(){ 80 int ret = ldap_start_tls_s( cur_session, NULL, NULL ); 81 if( ret != LDAP_SUCCESS ) { 82 throw LDAPException(this); 83 } 84} 85 86LDAPMessageQueue* LDAPAsynConnection::bind(const string& dn, 87 const string& passwd, const LDAPConstraints *cons){ 88 DEBUG(LDAP_DEBUG_TRACE, "LDAPAsynConnection::bind()" << endl); 89 DEBUG(LDAP_DEBUG_TRACE | LDAP_DEBUG_PARAMETER, " dn:" << dn << endl 90 << " passwd:" << passwd << endl); 91 LDAPBindRequest *req = new LDAPBindRequest(dn,passwd,this,cons); 92 try{ 93 LDAPMessageQueue *ret = req->sendRequest(); 94 return ret; 95 }catch(LDAPException e){ 96 delete req; 97 throw; 98 } 99} 100 101LDAPMessageQueue* LDAPAsynConnection::saslBind(const std::string &mech, 102 const std::string &cred, 103 const LDAPConstraints *cons) 104{ 105 DEBUG(LDAP_DEBUG_TRACE, "LDAPAsynConnection::saslBind()" << endl); 106 LDAPSaslBindRequest *req = new LDAPSaslBindRequest(mech, cred, this, cons); 107 try{ 108 LDAPMessageQueue *ret = req->sendRequest(); 109 return ret; 110 }catch(LDAPException e){ 111 delete req; 112 throw; 113 } 114 115} 116 117LDAPMessageQueue* LDAPAsynConnection::saslInteractiveBind( 118 const std::string &mech, 119 int flags, 120 SaslInteractionHandler *sih, 121 const LDAPConstraints *cons) 122{ 123 DEBUG(LDAP_DEBUG_TRACE, "LDAPAsynConnection::saslInteractiveBind" 124 << std::endl); 125 LDAPSaslInteractiveBind *req = 126 new LDAPSaslInteractiveBind(mech, flags, sih, this, cons); 127 try { 128 LDAPMessageQueue *ret = req->sendRequest(); 129 return ret; 130 }catch(LDAPException e){ 131 delete req; 132 throw; 133 } 134} 135 136LDAPMessageQueue* LDAPAsynConnection::search(const string& base,int scope, 137 const string& filter, 138 const StringList& attrs, 139 bool attrsOnly, 140 const LDAPConstraints *cons){ 141 DEBUG(LDAP_DEBUG_TRACE, "LDAPAsynConnection::search()" << endl); 142 DEBUG(LDAP_DEBUG_TRACE | LDAP_DEBUG_PARAMETER, " base:" << base << endl 143 << " scope:" << scope << endl 144 << " filter:" << filter << endl ); 145 LDAPSearchRequest *req = new LDAPSearchRequest(base, scope,filter, attrs, 146 attrsOnly, this, cons); 147 try{ 148 LDAPMessageQueue *ret = req->sendRequest(); 149 return ret; 150 }catch(LDAPException e){ 151 delete req; 152 throw; 153 } 154} 155 156LDAPMessageQueue* LDAPAsynConnection::del(const string& dn, 157 const LDAPConstraints *cons){ 158 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::del()" << endl); 159 DEBUG(LDAP_DEBUG_TRACE | LDAP_DEBUG_PARAMETER," dn:" << dn << endl); 160 LDAPDeleteRequest *req = new LDAPDeleteRequest(dn, this, cons); 161 try{ 162 LDAPMessageQueue *ret = req->sendRequest(); 163 return ret; 164 }catch(LDAPException e){ 165 delete req; 166 throw; 167 } 168} 169 170LDAPMessageQueue* LDAPAsynConnection::compare(const string& dn, 171 const LDAPAttribute& attr, const LDAPConstraints *cons){ 172 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::compare()" << endl); 173 DEBUG(LDAP_DEBUG_TRACE | LDAP_DEBUG_PARAMETER," dn:" << dn << endl 174 << " attr:" << attr << endl); 175 LDAPCompareRequest *req = new LDAPCompareRequest(dn, attr, this, cons); 176 try{ 177 LDAPMessageQueue *ret = req->sendRequest(); 178 return ret; 179 }catch(LDAPException e){ 180 delete req; 181 throw; 182 } 183} 184 185LDAPMessageQueue* LDAPAsynConnection::add( const LDAPEntry* le, 186 const LDAPConstraints *cons){ 187 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::add()" << endl); 188 DEBUG(LDAP_DEBUG_TRACE | LDAP_DEBUG_PARAMETER," entry:" << *le << endl); 189 LDAPAddRequest *req = new LDAPAddRequest(le, this, cons); 190 try{ 191 LDAPMessageQueue *ret = req->sendRequest(); 192 return ret; 193 }catch(LDAPException e){ 194 delete req; 195 throw; 196 } 197} 198 199LDAPMessageQueue* LDAPAsynConnection::modify(const string& dn, 200 const LDAPModList *mod, const LDAPConstraints *cons){ 201 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::modify()" << endl); 202 DEBUG(LDAP_DEBUG_TRACE | LDAP_DEBUG_PARAMETER," dn:" << dn << endl); 203 LDAPModifyRequest *req = new LDAPModifyRequest(dn, mod, this, cons); 204 try{ 205 LDAPMessageQueue *ret = req->sendRequest(); 206 return ret; 207 }catch(LDAPException e){ 208 delete req; 209 throw; 210 } 211} 212 213LDAPMessageQueue* LDAPAsynConnection::rename(const string& dn, 214 const string& newRDN, bool delOldRDN, const string& newParentDN, 215 const LDAPConstraints *cons ){ 216 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::rename()" << endl); 217 DEBUG(LDAP_DEBUG_TRACE | LDAP_DEBUG_PARAMETER," dn:" << dn << endl 218 << " newRDN:" << newRDN << endl 219 << " newParentDN:" << newParentDN << endl 220 << " delOldRDN:" << delOldRDN << endl); 221 LDAPModDNRequest *req = new LDAPModDNRequest(dn, newRDN, delOldRDN, 222 newParentDN, this, cons ); 223 try{ 224 LDAPMessageQueue *ret = req->sendRequest(); 225 return ret; 226 }catch(LDAPException e){ 227 delete req; 228 throw; 229 } 230} 231 232 233LDAPMessageQueue* LDAPAsynConnection::extOperation(const string& oid, 234 const string& value, const LDAPConstraints *cons ){ 235 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::extOperation()" << endl); 236 DEBUG(LDAP_DEBUG_TRACE | LDAP_DEBUG_PARAMETER," oid:" << oid << endl); 237 LDAPExtRequest *req = new LDAPExtRequest(oid, value, this,cons); 238 try{ 239 LDAPMessageQueue *ret = req->sendRequest(); 240 return ret; 241 }catch(LDAPException e){ 242 delete req; 243 throw; 244 } 245} 246 247 248void LDAPAsynConnection::abandon(LDAPMessageQueue *q){ 249 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::abandon()" << endl); 250 LDAPRequestStack *reqStack=q->getRequestStack(); 251 LDAPRequest *req; 252 while(! reqStack->empty()){ 253 req=reqStack->top(); 254 if (ldap_abandon_ext(cur_session, req->getMsgID(), 0, 0) 255 != LDAP_SUCCESS){ 256 throw LDAPException(this); 257 } 258 delete req; 259 reqStack->pop(); 260 } 261} 262 263void LDAPAsynConnection::unbind(){ 264 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::unbind()" << endl); 265 if(cur_session){ 266 LDAPControl** tmpSrvCtrls=m_constr->getSrvCtrlsArray(); 267 LDAPControl** tmpClCtrls=m_constr->getClCtrlsArray(); 268 int err=ldap_unbind_ext(cur_session, tmpSrvCtrls, tmpClCtrls); 269 cur_session=0; 270 LDAPControlSet::freeLDAPControlArray(tmpSrvCtrls); 271 LDAPControlSet::freeLDAPControlArray(tmpClCtrls); 272 if(err != LDAP_SUCCESS){ 273 throw LDAPException(err); 274 } 275 } 276} 277 278void LDAPAsynConnection::setConstraints(LDAPConstraints *cons){ 279 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::setConstraints()" << endl); 280 m_constr=cons; 281} 282 283const LDAPConstraints* LDAPAsynConnection::getConstraints() const { 284 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::getConstraints()" << endl); 285 return m_constr; 286} 287 288TlsOptions LDAPAsynConnection::getTlsOptions() const { 289 return TlsOptions( cur_session ); 290} 291 292LDAP* LDAPAsynConnection::getSessionHandle() const{ 293 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::getSessionHandle()" << endl); 294 return cur_session; 295} 296 297const string& LDAPAsynConnection::getHost() const{ 298 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::setHost()" << endl); 299 return m_uri.getHost(); 300} 301 302int LDAPAsynConnection::getPort() const{ 303 DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::getPort()" << endl); 304 return m_uri.getPort(); 305} 306 307LDAPAsynConnection* LDAPAsynConnection::referralConnect( 308 const LDAPUrlList& urls, LDAPUrlList::const_iterator& usedUrl, 309 const LDAPConstraints* cons) const { 310 DEBUG(LDAP_DEBUG_TRACE, "LDAPAsynConnection::referralConnect()" << endl) 311 LDAPUrlList::const_iterator conUrl; 312 LDAPAsynConnection* tmpConn=0; 313 const LDAPRebind* rebind = cons->getReferralRebind(); 314 LDAPRebindAuth* auth = 0; 315 316 for(conUrl=urls.begin(); conUrl!=urls.end(); conUrl++){ 317 string host= conUrl->getHost(); 318 int port= conUrl->getPort(); 319 DEBUG(LDAP_DEBUG_TRACE," connecting to: " << host << ":" << 320 port << endl); 321 //Set the new connection's constraints-object ? 322 tmpConn=new LDAPAsynConnection(host.c_str(),port); 323 int err=0; 324 325 if(rebind){ 326 auth=rebind->getRebindAuth(host, port); 327 } 328 if(auth){ 329 string dn = auth->getDN(); 330 string passwd = auth->getPassword(); 331 const char* c_dn=0; 332 struct berval c_passwd = { 0, 0 }; 333 if(dn != ""){ 334 c_dn = dn.c_str(); 335 } 336 if(passwd != ""){ 337 c_passwd.bv_val = const_cast<char*>(passwd.c_str()); 338 c_passwd.bv_len = passwd.size(); 339 } 340 err = ldap_sasl_bind_s(tmpConn->getSessionHandle(), c_dn, 341 LDAP_SASL_SIMPLE, &c_passwd, NULL, NULL, NULL); 342 } else { 343 // Do anonymous bind 344 err = ldap_sasl_bind_s(tmpConn->getSessionHandle(),NULL, 345 LDAP_SASL_SIMPLE, NULL, NULL, NULL, NULL); 346 } 347 if( err == LDAP_SUCCESS ){ 348 usedUrl=conUrl; 349 return tmpConn; 350 }else{ 351 delete tmpConn; 352 tmpConn=0; 353 } 354 auth=0; 355 } 356 return 0; 357} 358 359