Remove warnings
[anna.git] / source / ldap / Engine.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
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 //
7
8
9 #include <time.h>
10 #include <signal.h>
11
12 #include <ldap.h>
13 #include <lber.h>
14
15 #include <anna/core/tracing/Logger.hpp>
16 #include <anna/core/tracing/TraceMethod.hpp>
17
18 #include <anna/xml/Node.hpp>
19
20 #include <anna/ldap/internal/sccs.hpp>
21 #include <anna/ldap/Engine.hpp>
22 #include <anna/ldap/Session.hpp>
23
24 using namespace std;
25 using namespace anna;
26 using namespace anna::ldap;
27
28 Engine::Engine() :
29   app::Component(getClassName()),
30   a_autoBind(true) {
31   ldap::sccs::activate();
32   sigset(SIGALRM, alarmnCatcher);
33 }
34
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);
41
42   if(ii == session_end()) {
43     if((result = allocateSession(category)) == NULL)
44       throw RuntimeException("ldap::Engine::allocateSession returns NULL", ANNA_FILE_LOCATION);
45
46     result->a_category = category;
47     result->a_url = url;
48     result->a_externalID = -1;
49
50     if(user && *user != 0)
51       result->a_user = user;
52     else
53       result->a_user.clear();
54
55     if(password && *password != 0)
56       result->a_password = password;
57     else
58       result->a_password.clear();
59
60     session_key key(result->a_url, result->a_keymap = result->a_user);
61     a_sessions.insert(session_value_type(key, result));
62     LOGDEBUG(
63       string msg("ldap::Engine::createSession | ");
64       msg += result->asString();
65       msg += functions::asText(" | AutoBind: ", a_autoBind);
66       Logger::debug(msg, ANNA_FILE_LOCATION);
67     );
68   } else
69     result = session(ii);
70
71   if(result->getState() == Session::State::Closed && a_autoBind == true)
72     result->bind();
73
74   return result;
75 }
76
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);
83
84   if(ii == session_end()) {
85     if((result = allocateSession(category)) == NULL)
86       throw RuntimeException("ldap::Engine::allocateSession returns NULL", ANNA_FILE_LOCATION);
87
88     result->a_category = category;
89     result->a_url = url;
90     result->a_externalID = id;
91
92     if(user && *user != 0)
93       result->a_user = user;
94     else
95       result->a_user.clear();
96
97     if(password && *password != 0)
98       result->a_password = password;
99     else
100       result->a_password.clear();
101
102     session_key key(result->a_url, result->a_keymap = anna::functions::asString(id));
103     a_sessions.insert(session_value_type(key, result));
104     LOGDEBUG(
105       string msg("ldap::Engine::createSession | ");
106       msg += result->asString();
107       msg += functions::asText(" | AutoBind: ", a_autoBind);
108       Logger::debug(msg, ANNA_FILE_LOCATION);
109     );
110   } else {
111     result = session(ii);
112
113     if((result->getUser() != user) || (result->getPassword() != password)) {
114       LOGWARNING(
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);
117       );
118     }
119   }
120
121   if(result->getState() == Session::State::Closed && a_autoBind == true)
122     result->bind();
123
124   return result;
125 }
126
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);
132
133   if(ii != session_end())
134     return session(ii);
135
136   if(emode != Exception::Mode::Ignore) {
137     string msg("ldap::Engine::findSession | URL: ");
138     msg += url;
139     msg += " | User: ";
140     msg += user;
141     msg += " | Session not found";
142     RuntimeException ex(msg, ANNA_FILE_LOCATION);
143
144     if(emode == Exception::Mode::Throw)
145       throw ex;
146
147     ex.trace();
148   }
149
150   return NULL;
151 }
152
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);
157
158   if(ii != session_end())
159     return session(ii);
160
161   if(emode != Exception::Mode::Ignore) {
162     string msg("ldap::Engine::findSession | URL: ");
163     msg += url;
164     msg += functions::asText(" | ID: ", id);
165     msg += " | Session not found";
166     RuntimeException ex(msg, ANNA_FILE_LOCATION);
167
168     if(emode == Exception::Mode::Throw)
169       throw ex;
170
171     ex.trace();
172   }
173
174   return NULL;
175 }
176
177 void Engine::closeSession(Session* session)
178 throw(RuntimeException) {
179   if(session == NULL)
180     return;
181
182   LOGDEBUG(
183     string msg("ldap::Engine::closeSession | ");
184     msg += session->asString();
185     Logger::debug(msg, ANNA_FILE_LOCATION);
186   );
187   Guard guard(this, "ldap::Engine::closeSession");
188   session_iterator ii = session_find(session->a_url, session->a_keymap);
189
190   if(ii == session_end())
191     return;
192
193   try {
194     session->unbind();
195     releaseSession(session);
196   } catch(RuntimeException& ex) {
197     ex.trace();
198   }
199
200   a_sessions.erase(ii);
201 }
202
203 void Engine::do_stop()
204 throw() {
205   LOGMETHOD(TraceMethod tttm("anna::ldap::Engine", "do_stop", ANNA_FILE_LOCATION));
206
207   for(session_iterator ii = session_begin(), maxii = session_end(); ii != maxii; ii ++)
208     session(ii)->unbind();
209 }
210
211 xml::Node* Engine::asXML(xml::Node* parent) const
212 throw() {
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));
217
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);
221   }
222
223   return result;
224 }
225
226 Engine::session_iterator Engine::session_find(const char* url, const int id)
227 throw() {
228   return a_sessions.find(session_key(url, anna::functions::asString(id)));
229 }
230
231 /*static*/
232 int Engine::setDebugLevel(const int level)
233 throw(RuntimeException) {
234   int result(-1);
235 #ifdef LDAP_OPT_DEBUG_LEVEL
236   int _level = htonl(level);
237
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);
240
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);
243
244   ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &_level);
245 #else
246   Logger::error("Can not set debug level", ANNA_FILE_LOCATION);
247 #endif
248   return result;
249 }
250
251 const char* Engine::completeURL(const char* url)
252 throw() {
253   static const char* protocol = "ldap://";
254
255   if(anna_strstr(url, "://") == 0) {
256     a_auxURL = protocol;
257     a_auxURL += url;
258     return a_auxURL.c_str();
259   }
260
261   return url;
262 }
263
264 // static
265 void Engine::alarmnCatcher(int)
266 throw() {
267 }