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