xref: /netbsd-src/external/bsd/openldap/dist/contrib/ldapc++/src/LDAPAsynConnection.cpp (revision b5677b36047b601b9addaaa494a58ceae82c2a6c)
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