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