1 // $OpenLDAP$
2 /*
3  * Copyright 2000-2021 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 
7 
8 #ifndef LDAP_ASYN_CONNECTION_H
9 #define LDAP_ASYN_CONNECTION_H
10 
11 #include<iostream>
12 #include<string>
13 
14 #include<ldap.h>
15 
16 #include <LDAPEntry.h>
17 #include <LDAPException.h>
18 #include <LDAPMessageQueue.h>
19 #include <LDAPConstraints.h>
20 #include <LDAPModification.h>
21 #include <LDAPModList.h>
22 #include <LDAPUrl.h>
23 #include <LDAPUrlList.h>
24 #include <SaslInteractionHandler.h>
25 #include <TlsOptions.h>
26 
27 //* Main class for an asynchronous LDAP connection
28 /**
29  * This class represents an asynchronous connection to an LDAP-Server. It
30  * provides the methods for authentication, and all other LDAP-Operations
31  * (e.g. search, add, delete, etc.)
32  * All of the LDAP-Operations return a pointer to a LDAPMessageQueue-Object,
33  * which can be used to obtain the results of that operation.
34  * A basic example of this class could be like this:  <BR>
35  * 1. Create a new LDAPAsynConnection Object: <BR>
36  * 2. Use the init-method to initialize the connection <BR>
37  * 3. Call the bind-method to authenticate to the directory <BR>
38  * 4. Obtain the bind results from the return LDAPMessageQueue-Object <BR>
39  * 5. Perform on of the operations on the directory (add, delete, search, ..)
40  *    <BR>
41  * 6. Use the return LDAPMessageQueue to obtain the results of the operation
42  * <BR>
43  * 7. Close the connection (feature not implemented yet :) ) <BR>
44  */
45 class LDAPAsynConnection{
46     public :
47         /**
48          * Constant for the Search-Operation to indicate a Base-Level
49          * Search
50          */
51         static const int SEARCH_BASE=0;
52 
53         /**
54          * Constant for the Search-Operation to indicate a One-Level
55          * Search
56          */
57         static const int SEARCH_ONE=1;
58 
59         /**
60          * Constant for the Search-Operation to indicate a subtree
61          * Search
62          */
63         static const int SEARCH_SUB=2;
64 
65         /** Constructor that initializes a connection to a server
66          * @param hostname Name (or IP-Address) of the destination host
67          * @param port Port the LDAP server is running on
68          * @param cons Default constraints to use with operations over
69          *      this connection
70          */
71         LDAPAsynConnection(const std::string& url=std::string("localhost"),
72                 int port=0, LDAPConstraints *cons=new LDAPConstraints() );
73 
74         //* Destructor
75         virtual ~LDAPAsynConnection();
76         /**
77          * Initializes a connection to a server.
78          *
79          * There actually no
80          * communication to the server. Just the object is initialized
81          * (e.g. this method is called within the
82          * LDAPAsynConnection(char*,int,LDAPConstraints) constructor.)
83          * @param hostname  The Name or IP-Address of the destination
84          *             LDAP-Server
85          * @param port      The Network Port the server is running on
86          */
87         void init(const std::string& hostname, int port);
88 
89         /**
90          * Initializes a connection to a server.
91          *
92          * There actually no communication to the server. Just the
93          * object is initialized
94          * @param uri  The LDAP-Uri for the destination
95          */
96         void initialize(const std::string& uri);
97 
98         /**
99          * Start TLS on this connection.  This isn't in the constructor,
100          * because it could fail (i.e. server doesn't have SSL cert, client
101          * api wasn't compiled against OpenSSL, etc.).
102          * @throws LDAPException if the TLS Layer could not be setup
103          * correctly
104          */
105         void start_tls();
106 
107         /** Simple authentication to a LDAP-Server
108          *
109          * @throws LDAPException If the Request could not be sent to the
110          *      destination server, a LDAPException-object contains the
111          *      error that occurred.
112          * This method does a simple (username, password) bind to the server.
113          * Other, saver, authentcation methods are provided later
114          * @param dn the distinguished name to bind as
115          * @param passwd cleartext password to use
116          */
117         LDAPMessageQueue* bind(const std::string& dn="",
118                 const std::string& passwd="",
119                 const LDAPConstraints *cons=0);
120 
121         LDAPMessageQueue* saslBind(const std::string& mech,
122                 const std::string& cred,
123                 const LDAPConstraints *cons=0);
124 
125         LDAPMessageQueue* saslInteractiveBind(const std::string& mech,
126                 int flags=0,
127                 SaslInteractionHandler *sih=0,
128                 const LDAPConstraints *cons=0);
129 
130         /** Performing a search on a directory tree.
131          *
132          * Use the search method to perform a search on the LDAP-Directory
133          * @throws LDAPException If the Request could not be sent to the
134          *      destination server, a LDAPException-object contains the
135          *      error that occurred.
136          * @param base The distinguished name of the starting point for the
137          *      search operation
138          * @param scope The scope of the search. Possible values: <BR>
139          *      LDAPAsynConnection::SEARCH_BASE, <BR>
140          *      LDAPAsynConnection::SEARCH_ONE, <BR>
141          *      LDAPAsynConnection::SEARCH_SUB
142          * @param filter The std::string representation of a search filter to
143          *      use with this operation
144          * @param attrsOnly true if only the attributes names (no values)
145          *      should be returned
146          * @param cons A set of constraints that should be used with this
147          *      request
148          */
149         LDAPMessageQueue* search(const std::string& base="", int scope=0,
150                                  const std::string& filter="objectClass=*",
151                                  const StringList& attrs=StringList(),
152                                  bool attrsOnly=false,
153                                  const LDAPConstraints *cons=0);
154 
155         /** Delete an entry from the directory
156          *
157          * This method sends a delete request to the server
158          * @throws LDAPException If the Request could not be sent to the
159          *      destination server, a LDAPException-object contains the
160          *      error that occurred.
161          * @param dn    Distinguished name of the entry that should be deleted
162          * @param cons  A set of constraints that should be used with this
163          *              request
164          */
165         LDAPMessageQueue* del(const std::string& dn, const LDAPConstraints *cons=0);
166 
167         /**
168          * Perform the COMPARE-operation on an attribute
169          *
170          * @throws LDAPException If the Request could not be sent to the
171          *      destination server, a LDAPException-object contains the
172          *      error that occurred.
173          * @param dn    Distinguished name of the entry for which the compare
174          *              should be performed
175          * @param attr  An Attribute (one (!) value) to use for the
176          *      compare operation
177          * @param cons  A set of constraints that should be used with this
178          *              request
179          */
180         LDAPMessageQueue* compare(const std::string& dn,
181                 const LDAPAttribute& attr,
182                 const LDAPConstraints *cons=0);
183 
184         /** Add an entry to the directory
185          *
186          * @throws LDAPException If the Request could not be sent to the
187          *      destination server, a LDAPException-object contains the
188          *      error that occurred.
189          * @param le The entry that will be added to the directory
190          */
191         LDAPMessageQueue* add( const LDAPEntry* le,
192                 const LDAPConstraints *const=0);
193 
194         /** Apply modifications to attributes of an entry
195          *
196          * @throws LDAPException If the Request could not be sent to the
197          *      destination server, a LDAPException-object contains the
198          *      error that occurred.
199          * @param dn Distinguished Name of the Entry to modify
200          * @param modlist A set of modification that should be applied
201          *      to the Entry
202          * @param cons  A set of constraints that should be used with this
203          *              request
204          */
205         LDAPMessageQueue* modify(const std::string& dn,
206                 const LDAPModList *modlist,
207                 const LDAPConstraints *cons=0);
208 
209         /** modify the DN of an entry
210          *
211          * @throws LDAPException If the Request could not be sent to the
212          *      destination server, a LDAPException-object contains the
213          *      error that occurred.
214          * @param dn            DN to modify
215          * @param newRDN        The new relative DN for the entry
216          * @param delOldRDN     true=The old RDN will be removed from the
217          *                      attributes <BR>
218          *                      false=The old RDN will still be present in the
219          *                      attributes of the entry
220          * @param newParentDN   The DN of the new parent entry of the entry
221          *                      0 to keep the old one
222          */
223         LDAPMessageQueue* rename(const std::string& dn,
224                 const std::string& newRDN,
225                 bool delOldRDN=false, const std::string& newParentDN="",
226                 const LDAPConstraints* cons=0);
227 
228         /** Perform a LDAP extended Operation
229          *
230          * @throws LDAPException If the Request could not be sent to the
231          *      destination server, a LDAPException-object contains the
232          *      error that occurred.
233          * @param oid The dotted decimal representation of the extended
234          *      Operation that should be performed
235          * @param value The data associated with this operation
236          * @param cons  A set of constraints that should be used with this
237          *              request
238          */
239         LDAPMessageQueue* extOperation(const std::string& oid,
240                 const std::string& value="", const LDAPConstraints *cons=0);
241 
242         /** End an outstanding request
243          *
244          * @param q All outstanding request related to this LDAPMessageQueue
245          *      will be abandoned
246          */
247         void abandon(LDAPMessageQueue *q);
248 
249         /**
250          * Performs the UNBIND-operation on the destination server
251          *
252          * @throws LDAPException in any case of an error
253          */
254         void unbind();
255 
256         /**
257          * @returns The C-APIs LDAP-structure that is associated with the
258          *      current connection
259          */
260         LDAP* getSessionHandle() const ;
261 
262         /**
263          * @returns The Hostname of the destination server of the
264          *      connection.
265          */
266         const std::string& getHost() const;
267 
268         /**
269          * @returns The Port to which this connection is connecting to on
270          *      the remote server.
271          */
272         int getPort() const;
273 
274         /** Change the default constraints of the connection
275          *
276          * @parameter cons cons New LDAPConstraints to use with the connection
277          */
278         void setConstraints(LDAPConstraints *cons);
279 
280         /** Get the default constraints of the connection
281          *
282          * @return Pointer to the LDAPConstraints-Object that is currently
283          *      used with the Connection
284          */
285         const LDAPConstraints* getConstraints() const;
286         TlsOptions getTlsOptions() const;
287         /**
288          * This method is used internally for automatic referral chasing.
289          * It tries to bind to a destination server of the URLs of a
290          * referral.
291          *
292          * @throws LDAPException in any case of an error
293          * @param urls Contains a std::list of LDAP-Urls that indicate the
294          *      destinations of a referral
295          * @param usedUrl After this method has successfully bind to one of
296          *      the Destination URLs this parameter contains the URLs
297          *      which was contacted.
298          * @param cons An LDAPConstraints-Object that should be used for
299          *      the new connection. If this object contains a
300          *      LDAPRebind-object it is used to bind to the new server
301          */
302         LDAPAsynConnection* referralConnect(const LDAPUrlList& urls,
303                 LDAPUrlList::const_iterator& usedUrl,
304                 const LDAPConstraints* cons) const;
305 
306     private :
307         /**
308          * Private copy constructor. So nobody can call it.
309          */
LDAPAsynConnection(const LDAPAsynConnection & lc)310         LDAPAsynConnection(const LDAPAsynConnection& lc){};
311 
312         /**
313          * A pointer to the C-API LDAP-structure that is associated with
314          * this connection
315          */
316         LDAP *cur_session;
317 
318         /**
319          * A pointer to the default LDAPConstrains-object that is used when
320          * no LDAPConstraints-parameter is provided with a call for a
321          * LDAP-operation
322          */
323         LDAPConstraints *m_constr;
324 
325         /**
326          * The URI of this connection
327          */
328         LDAPUrl m_uri;
329 
330     protected:
331         /**
332          * Is caching enabled?
333          */
334         bool m_cacheEnabled;
335 };
336 #endif //LDAP_ASYN_CONNECTION_H
337 
338 
339