1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
9 #ifndef anna_ldap_Session_hpp
10 #define anna_ldap_Session_hpp
14 #include <anna/core/util/SortedVector.hpp>
16 #include <anna/comm/Handler.hpp>
18 #include <anna/ldap/defines.hpp>
19 #include <anna/ldap/ClassCode.hpp>
36 Modela la conexion realizada contra una servidor LDAP.
38 class Session : public comm::Handler {
41 Define los estados en los que puede estar una sesion LDAP.
42 \see ldap::Session::getState
46 Closed, /**< Cerrada */
47 WaitingBind, /**< Pendiente de confirmacion de conexion */
48 Bound /**< Conectada al servidor LDAP */
53 Opciones disponibles para ajustar el comporamiento de nuestra sesion.
58 Modos de interpretar las referencias.
63 Never, /**< Valor por defecto */
64 Searching, /**< Indica que los valores son interpretados durante la busqueda, pero no cuando localiza el objeto base de la misma */
65 Finding, /**< Indica que los valores son interpretados cuando se localiza el objeto base, pero no durante la busqueda */
70 Determina si la biblioteca LDAP realiza de forma automatica el siguimiento de las referencias retornadas
71 por los servidores LDAP.
74 struct Referral { enum _v { Off, On }; };
78 * Periodo de espera por defecto para cada una de las peticiones de esta sesión.
80 static const Millisecond DefaultTimeout;
83 Devuelve la direccion del servidor LDAP. Coincidira con la indicada en ldap::Engine::createSession.
84 \return La direccion del servidor LDAP. Coincidira con la indicada en ldap::Engine::createSession.
86 const std::string& getURL() const throw() { return a_url; }
89 Devuelve el usuario de esta sesion. Coincidira con la indicada en ldap::Engine::createSession.
90 \return El usuario de esta sesion. Coincidira con la indicada en ldap::Engine::createSession.
92 const std::string& getUser() const throw() { return a_user; }
95 Devuelve el password de esta sesion. Coincidira con la indicada en ldap::Engine::createSession.
96 \return El password de esta sesion. Coincidira con la indicada en ldap::Engine::createSession.
98 const std::string& getPassword() const throw() { return a_password; }
101 Devuelve la categoria de esta sesion. Coincidira con la indicada en ldap::Engine::createSession.
102 \return La categoria de esta sesion. Coincidira con la indicada en ldap::Engine::createSession.
104 int getCategory() const throw() { return a_category; }
107 * Devuelve la clave externa con la que fué creada esta sesión.
109 int getExternalID() const throw() { return a_externalID; }
112 Devuelve el manejador usado para conectar con el servidor LDAP.
113 \warning Exclusivamente uso interno.
115 void* getLDAP() throw() { return a_ldap; }
118 * Devuelve el fd asociado a esta sesión de LDAP.
119 * \return el fd asociado a esta sesión de LDAP.
120 * \warning Las operaciones sobre este fd podrían influir negativamente en el sistema.
122 int getDangerousFileDescriptor() const throw(RuntimeException);
125 Devuelve el modo de interpretar las referencias establecido en esta sesion.
126 \return El modo de interpretar las referencias establecido en esta sesion.
128 Option::Defer::_v getDefer() const throw() { return a_defer; }
131 Devuelve \em true si la biblioteca LDAP realiza de forma automatica el siguimiento de las referencias
132 retornadas por los servidores LDAP o \em false en otro caso.
133 \return \em true si la biblioteca LDAP realiza de forma automatica el siguimiento de las referencias
134 retornadas por los servidores LDAP o \em false en otro caso.
136 Option::Referral::_v getReferral() const throw() { return a_referral; }
139 Devuelve el estado de esta sesion.
140 \return El estado de esta sesion.
142 State::_v getState() const throw() { return a_state; }
145 * Devuelve el periodo de espera establecido para las peticiones del tipo \em v.
146 * \return el periodo de espera establecido para las peticiones del tipo \em v.
148 const Millisecond &getTimeout(const ClassCode::_v v) const throw() { return a_timeouts [v]; }
151 * Devuelve el valor establecido en #setNetworkTimeout
152 * \return Los miligundos establecidos por #setNetworkTimeout.
153 * \warning El valor retornado sólo tendrá valided si #hasNetworkTimeout devolvió \em true.
155 Millisecond getNetworkTimeout() const throw() {
156 Millisecond result(1000 * a_networkTimeout.tv_sec);
157 return Millisecond(result + a_networkTimeout.tv_usec / 1000);
161 * Devuelve \em true si se estableció el tiempo de espera de conexión o \em false en otro caso.
162 * \return \em true si se estableció el tiempo de espera de conexión o \em false en otro caso.
164 bool hasNetworkTimeout() const throw() { return a_networkTimeout.tv_sec != -1; }
167 Solicita la conexion al servidor asociado a esta sesion.
169 \warning Solo deberia invocarse directamente este metodo en caso de que el #eventResponse
170 notifique no ha sido posible contactar con el servidor indicado.
172 void bind() throw(RuntimeException);
175 Devuelve \em true si la sesion esta conectada al servidor LDAP o \em false en otro caso.
176 \return \em true si la sesion esta conectada al servidor LDAP o \em false en otro caso.
178 bool isBound() const throw() { return a_state == State::Bound; }
181 Establece el modo de interpretar las referencias.
182 \param defer Indica el modo de interpretar las referencias.
184 void setOption(const Option::Defer::_v defer) throw() { a_defer = defer; }
187 Establece el modo en que la biblioteca LDAP actua a la hora de realizar el siguimiento de las referencias.
188 \param referral Indica el modo de realizar el seguimiento de las referncias.
190 void setOption(const Option::Referral::_v referral) throw() { a_referral = referral; }
193 * Establece el periodo de tiempo máximo que esperará la conexión a un servidor LDAP antes de considerar que
194 * éste no es alcanzable.
196 * \param timeout Milisegundos que esperará la conexión a un servidor LDAP antes de considerar que no es alcanzable.
198 * \see http://manpages.courier-mta.org/htmlman3/ldap_get_option.3.html
199 * \warning Sólo tiene efecto antes de invocar al #bind, por lo que habrá que desactivar la auto conexión, para establecer el valor.
201 void setNetworkTimeout(const Millisecond &timeout) throw() { a_networkTimeout.tv_sec = timeout / 1000; a_networkTimeout.tv_usec = (timeout % 1000) * 1000; }
204 * Elimina el tiempo asignado en #setNetworkTimeout.
206 * \see http://manpages.courier-mta.org/htmlman3/ldap_get_option.3.html
207 * \warning Sólo tiene efecto antes de invocar al #bind
209 void clearNetworkTimeout() throw() { a_networkTimeout.tv_sec = -1; a_networkTimeout.tv_usec = 0; }
212 Establece el tiempo de espera maximo antes de considerar fallida una peticion LDAP.
213 \param v Tipo de peticion LDAP.
214 \param millisecond Milisegundos esperados antes de considerar fallida la peticion LDAP.
216 Los temporizadores correspondientes las peticiones LDAP se activaran automaticamente al
217 invocar a los distintos métodos de esta clase.
219 void setTimeout(const ClassCode::_v v, const Millisecond &millisecond) throw() { a_timeouts [v] = millisecond; }
222 Envia la peticion recibida como parametro al servidor con el que estamos conectados mediante esta
225 Una vez enviada la peticion se activara automaticamente un temporizador. Si este llegara a caducar
226 se cancelara la busqueda y se invocara al metodo Session::eventResponse indicado que se ha producido
227 un error de temporización. La duracion del temporizador sera la establecida por
228 ldap::TimerManager::setTimeout o el valor defecto.
230 \param request Peticion a enviar al servidor LDAP con el que estamos conectados.
231 \return La instancia de la respuesta LDAP asociada la peticion realizada.
232 \warning Solo se podra hacer uso de este metodo cuando el metodo #isBound devuelva \em true.
234 const Response* send(const Request* request) throw(RuntimeException);
237 Envia la peticion recibida como parametro al servidor con el que estamos conectados mediante esta
240 Una vez enviada la peticion se activara automaticamente un temporizador. Si este llegara a caducar
241 se cancelara la busqueda y se invocara al metodo Session::eventResponse indicado que se ha producido
242 un error de temporización. La duracion del temporizador sera la establecida por
243 ldap::TimerManager::setTimeout o el valor defecto.
245 \param request Peticion a enviar al servidor LDAP con el que estamos conectados.
246 \return La instancia de la respuesta LDAP asociada la peticion realizada.
247 \warning Solo se podra hacer uso de este metodo cuando el metodo #isBound devuelva \em true.
249 const Response* send(const Request& request) throw(RuntimeException) { return send(&request); }
252 * Desconecta este cliente LDAP del servidor LDAP.
253 * Se notifica la terminación de cada una de las peticiones pendientes invocando al método Session::eventResponse
254 * indicando un error y se cancelan en el servidor LDAP.
255 * \warning Después de invocar a este método habría que volver a invocar a ldap::Session::bind y esperar la conexión
256 * antes de volver a usar esta sessión.
258 void unbind() throw(RuntimeException);
261 Devuelve una cadena con la informacion relevante sobre esta instancia.
262 \return Una cadena con la informacion relevante sobre esta instancia.
264 std::string asString() const throw();
267 Devuelve un documento XML con la informacion relevante sobre esta instancia.
268 \param parent Nodo XML del que colgar la informacion referente a esta instancia.
269 \return Un documento XML con la informacion relevante sobre esta instancia.
271 xml::Node* asXML(xml::Node* parent) const throw();
276 \see ldap::Engine::createSession
281 Metodo-manejador que informa de que el servidor LDAP con el que estaba conectado esta sesion
282 ha dejado de dar servicio.
284 Una vez que se ha notificado la caida de la sesion, el nucleo de ANNA.ldap genera un
285 ldap::Session::eventResponse para cada una de las peticiones que hay pendientes de contestar.
287 virtual void eventServerShutdown() throw() {;}
290 Metodo-manejador de las respuestas provenientes del servidor LDAP.
292 \param response Objeto que contiene la respuesta correspondiente a la peticion LDAP realizada.
294 virtual void eventResponse(const Response& response) throw(RuntimeException) = 0;
297 Metodo-manejador de los errores provenientes del servidor LDAP.
298 \param resultCode Instancia que contiene la información sobre el error recibido.
299 \param disconnect Incicador que informa al nivel de aplicación sobre cómo actuará la ANNA.ldap
300 para recuperar este error, si vale \em true la conexión se cerrará o \em false en otro caso.
302 virtual void eventResponseError(const ResultCode& resultCode, const bool disconnect) throw() {;}
305 * Método-manejador que se invoca cuando alguno de los mensajes intermedios requeridos para formar
306 * la contestación completa no se puede interpretar correctamente.
308 \param response Objeto que contiene la respuesta correspondiente a la peticion LDAP realizada.
310 virtual void eventIntermediateResponseError(const Response& response) throw() {;}
314 static IdMessage value(const Response*) throw();
316 typedef SortedVector <Response, SortById, IdMessage> response_container;
317 typedef response_container::iterator response_iterator;
318 typedef response_container::const_iterator const_response_iterator;
320 typedef void* HandleLDAP;
321 typedef void* HandleMessage;
328 std::string a_password;
329 Option::Defer::_v a_defer;
330 Option::Referral::_v a_referral;
331 response_container a_responses;
333 Millisecond a_timeouts [ClassCode::Max];
334 struct timeval a_networkTimeout;
336 /* Dependiendo de cómo se cree la sesión este miembro puede ser una copia de a_user
337 * o el identificador numérico que pasaron como parámetro al crear la sesión
339 std::string a_keymap;
341 void apply() throw(RuntimeException);
342 void receiveBind(const IdMessage, HandleMessage) throw(RuntimeException);
343 void receiveEntry(const IdMessage, HandleMessage) throw(RuntimeException);
344 void receiveReference(const IdMessage, HandleMessage) throw(RuntimeException);
345 void receiveResult(const IdMessage, HandleMessage) throw(RuntimeException);
346 void expireResponse(Response*) throw();
348 void finalize() throw();
350 response_iterator response_begin() throw() { return a_responses.begin(); }
351 response_iterator response_end() throw() { return a_responses.end(); }
352 void response_add(Response* response) throw();
353 void response_erase(Response* response) throw();
354 Response* response_find(const IdMessage idMessage) throw(RuntimeException);
356 static Response* response(response_iterator ii) throw() { return response_container::data(ii); }
358 const_response_iterator response_begin() const throw() { return a_responses.begin(); }
359 const_response_iterator response_end() const throw() { return a_responses.end(); }
360 static const Response* response(const_response_iterator ii) throw() { return response_container::data(ii); }
362 static const char* asText(const State::_v) throw();