]> git.sur5r.net Git - openldap/blob - contrib/ldapc++/src/LDAPAsynConnection.cpp
Merge remote-tracking branch 'origin/mdb.master'
[openldap] / contrib / ldapc++ / src / LDAPAsynConnection.cpp
1 // $OpenLDAP$
2 /*
3  * Copyright 2000-2013 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
48 void 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
68 void 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
79 void 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
86 LDAPMessageQueue* 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
101 LDAPMessageQueue* 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
117 LDAPMessageQueue* 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
136 LDAPMessageQueue* 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
156 LDAPMessageQueue* 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
170 LDAPMessageQueue* 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
185 LDAPMessageQueue* 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
199 LDAPMessageQueue* 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
213 LDAPMessageQueue* 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
233 LDAPMessageQueue* 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
248 void 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
263 void 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
278 void LDAPAsynConnection::setConstraints(LDAPConstraints *cons){
279     DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::setConstraints()" << endl);
280     m_constr=cons;
281 }
282
283 const LDAPConstraints* LDAPAsynConnection::getConstraints() const {
284     DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::getConstraints()" << endl);
285     return m_constr;
286 }
287  
288 TlsOptions LDAPAsynConnection::getTlsOptions() const {
289     return TlsOptions( cur_session );
290 }
291
292 LDAP* LDAPAsynConnection::getSessionHandle() const{ 
293     DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::getSessionHandle()" << endl);
294     return cur_session;
295 }
296
297 const string& LDAPAsynConnection::getHost() const{
298     DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::setHost()" << endl);
299     return m_uri.getHost();
300 }
301
302 int LDAPAsynConnection::getPort() const{
303     DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::getPort()" << endl);
304     return m_uri.getPort();
305 }
306
307 LDAPAsynConnection* 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