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 //
15 #include <anna/core/tracing/Logger.hpp>
16 #include <anna/core/tracing/TraceMethod.hpp>
18 #include <anna/xml/Node.hpp>
20 #include <anna/ldap/internal/sccs.hpp>
21 #include <anna/ldap/Engine.hpp>
22 #include <anna/ldap/Session.hpp>
26 using namespace anna::ldap;
29 app::Component(getClassName()),
31 ldap::sccs::activate();
32 sigset(SIGALRM, alarmnCatcher);
35 Session* Engine::createSession(const char* url, const char* user, const char* password, const int category)
36 throw(RuntimeException) {
37 ldap::Session* result(NULL);
38 Guard guard(this, "ldap::Engine::createSession");
39 url = completeURL(url);
40 session_iterator ii = session_find(url, (user == NULL) ? "" : user);
42 if(ii == session_end()) {
43 if((result = allocateSession(category)) == NULL)
44 throw RuntimeException("ldap::Engine::allocateSession returns NULL", ANNA_FILE_LOCATION);
46 result->a_category = category;
48 result->a_externalID = -1;
50 if(user && *user != 0)
51 result->a_user = user;
53 result->a_user.clear();
55 if(password && *password != 0)
56 result->a_password = password;
58 result->a_password.clear();
60 session_key key(result->a_url, result->a_keymap = result->a_user);
61 a_sessions.insert(session_value_type(key, result));
63 string msg("ldap::Engine::createSession | ");
64 msg += result->asString();
65 msg += functions::asText(" | AutoBind: ", a_autoBind);
66 Logger::debug(msg, ANNA_FILE_LOCATION);
71 if(result->getState() == Session::State::Closed && a_autoBind == true)
77 Session* Engine::createSession(const char* url, const int id, const char* user, const char* password, const int category)
78 throw(RuntimeException) {
79 ldap::Session* result(NULL);
80 Guard guard(this, "ldap::Engine::createSession");
81 url = completeURL(url);
82 session_iterator ii = session_find(url, id);
84 if(ii == session_end()) {
85 if((result = allocateSession(category)) == NULL)
86 throw RuntimeException("ldap::Engine::allocateSession returns NULL", ANNA_FILE_LOCATION);
88 result->a_category = category;
90 result->a_externalID = id;
92 if(user && *user != 0)
93 result->a_user = user;
95 result->a_user.clear();
97 if(password && *password != 0)
98 result->a_password = password;
100 result->a_password.clear();
102 session_key key(result->a_url, result->a_keymap = anna::functions::asString(id));
103 a_sessions.insert(session_value_type(key, result));
105 string msg("ldap::Engine::createSession | ");
106 msg += result->asString();
107 msg += functions::asText(" | AutoBind: ", a_autoBind);
108 Logger::debug(msg, ANNA_FILE_LOCATION);
111 result = session(ii);
113 if((result->getUser() != user) || (result->getPassword() != password)) {
115 std::string msg = "Returned session already existed but with different credentiales regarding provided ones. Reuse could be inappropiate.";
116 Logger::warning(msg, ANNA_FILE_LOCATION);
121 if(result->getState() == Session::State::Closed && a_autoBind == true)
127 Session* Engine::findSession(const char* url, const char* user, Exception::Mode::_v emode)
128 throw(RuntimeException) {
129 Guard guard(this, "ldap::Engine::findSession");
130 url = completeURL(url);
131 session_iterator ii = session_find(url, user);
133 if(ii != session_end())
136 if(emode != Exception::Mode::Ignore) {
137 string msg("ldap::Engine::findSession | URL: ");
141 msg += " | Session not found";
142 RuntimeException ex(msg, ANNA_FILE_LOCATION);
144 if(emode == Exception::Mode::Throw)
153 Session* Engine::findSession(const char* url, const int id, Exception::Mode::_v emode)
154 throw(RuntimeException) {
155 Guard guard(this, "ldap::Engine::findSession (int)");
156 session_iterator ii = session_find(url, id);
158 if(ii != session_end())
161 if(emode != Exception::Mode::Ignore) {
162 string msg("ldap::Engine::findSession | URL: ");
164 msg += functions::asText(" | ID: ", id);
165 msg += " | Session not found";
166 RuntimeException ex(msg, ANNA_FILE_LOCATION);
168 if(emode == Exception::Mode::Throw)
177 void Engine::closeSession(Session* session)
178 throw(RuntimeException) {
183 string msg("ldap::Engine::closeSession | ");
184 msg += session->asString();
185 Logger::debug(msg, ANNA_FILE_LOCATION);
187 Guard guard(this, "ldap::Engine::closeSession");
188 session_iterator ii = session_find(session->a_url, session->a_keymap);
190 if(ii == session_end())
195 releaseSession(session);
196 } catch(RuntimeException& ex) {
200 a_sessions.erase(ii);
203 void Engine::do_stop()
205 LOGMETHOD(TraceMethod tttm("anna::ldap::Engine", "do_stop", ANNA_FILE_LOCATION));
207 for(session_iterator ii = session_begin(), maxii = session_end(); ii != maxii; ii ++)
208 session(ii)->unbind();
211 xml::Node* Engine::asXML(xml::Node* parent) const
213 parent = app::Component::asXML(parent);
214 xml::Node* result = parent->createChild("ldap.Engine");
215 const Session* session;
216 result->createAttribute("AutoBind", functions::asString(a_autoBind));
218 for(const_session_iterator ii = session_begin(), maxii = session_end(); ii != maxii; ii ++) {
219 Guard guard(session = Engine::session(ii));
220 session->asXML(result);
226 Engine::session_iterator Engine::session_find(const char* url, const int id)
228 return a_sessions.find(session_key(url, anna::functions::asString(id)));
232 int Engine::setDebugLevel(const int level)
233 throw(RuntimeException) {
235 #ifdef LDAP_OPT_DEBUG_LEVEL
236 int _level = htonl(level);
238 if(ldap_get_option(NULL, LDAP_OPT_DEBUG_LEVEL, &result) != LDAP_OPT_SUCCESS)
239 throw RuntimeException("Can not get LDAP_OPT_DEBUG_LEVEL", ANNA_FILE_LOCATION);
241 if(ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &_level) != LDAP_OPT_SUCCESS)
242 throw RuntimeException("Can not set LDAP_OPT_DEBUG_LEVEL", ANNA_FILE_LOCATION);
244 ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &_level);
246 Logger::error("Can not set debug level", ANNA_FILE_LOCATION);
251 const char* Engine::completeURL(const char* url)
253 static const char* protocol = "ldap://";
254 static const int protocolLen = anna_strlen(protocol);
256 if(anna_strstr(url, "://") == 0) {
259 return a_auxURL.c_str();
266 void Engine::alarmnCatcher(int)