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