]> git.sur5r.net Git - openldap/blob - contrib/ldapc++/src/LDAPAsynConnection.cpp
Move tmpluser to authz call; add ppolicy support to authc
[openldap] / contrib / ldapc++ / src / LDAPAsynConnection.cpp
1 // $OpenLDAP$
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