66#include < queue>
77#include " ldap_auth_provider.h"
88#include " ldap_utils.h"
9+ #include " ldap_auth_provider_log.h"
910
1011// This temporary solution
1112// These lines should be declared outside ldap_compat.h
@@ -172,11 +173,12 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
172173
173174 int result = 0 ;
174175 if (Settings.GetScheme () != NKikimrLdap::LDAPS_SCHEME && Settings.GetUseTls ().GetEnable ()) {
176+ LDAP_LOG_D (" start TLS" );
175177 result = NKikimrLdap::StartTLS (*ld);
176178 if (!NKikimrLdap::IsSuccess (result)) {
179+ LDAP_LOG_D (" Could not start TLS. " << NKikimrLdap::ErrorToString (result));
177180 TEvLdapAuthProvider::TError error {
178- .Message = " Could not start TLS\n " + NKikimrLdap::ErrorToString (result),
179- .Retryable = NKikimrLdap::IsRetryableError (result)
181+ .Message = ERROR_MESSAGE, .Retryable = NKikimrLdap::IsRetryableError (result)
180182 };
181183 // The Unbind operation is not the antithesis of the Bind operation as the name implies.
182184 // Close the LDAP connection, free the resources contained in the LDAP structure
@@ -185,12 +187,13 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
185187 }
186188 }
187189
190+ LDAP_LOG_D (" bind: bindDn: " << Settings.GetBindDn ());
188191 result = NKikimrLdap::Bind (*ld, Settings.GetBindDn (), Settings.GetBindPassword ());
189192 if (!NKikimrLdap::IsSuccess (result)) {
193+ LDAP_LOG_D (" Could not perform initial LDAP bind for dn " << Settings.GetBindDn () << " on server " + UrisCreator.GetUris () << " . "
194+ << NKikimrLdap::ErrorToString (result));
190195 TEvLdapAuthProvider::TError error {
191- .Message = " Could not perform initial LDAP bind for dn " + Settings.GetBindDn () + " on server " + UrisCreator.GetUris () + " \n "
192- + NKikimrLdap::ErrorToString (result),
193- .Retryable = NKikimrLdap::IsRetryableError (result)
196+ .Message = ERROR_MESSAGE, .Retryable = NKikimrLdap::IsRetryableError (result)
194197 };
195198 // The Unbind operation is not the antithesis of the Bind operation as the name implies.
196199 // Close the LDAP connection, free the resources contained in the LDAP structure
@@ -210,36 +213,37 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
210213 const TString& caCertificateFile = Settings.GetUseTls ().GetCaCertFile ();
211214 result = NKikimrLdap::SetOption (*ld, NKikimrLdap::EOption::TLS_CACERTFILE, caCertificateFile.c_str ());
212215 if (!NKikimrLdap::IsSuccess (result)) {
216+ LDAP_LOG_D (" Could not set LDAP ca certificate file \" " << caCertificateFile + " \" : " << NKikimrLdap::ErrorToString (result));
213217 NKikimrLdap::Unbind (*ld);
214218 return {{NKikimrLdap::ErrorToStatus (result),
215- {.Message = " Could not set LDAP ca certificate file \" " + caCertificateFile + " \" : " + NKikimrLdap::ErrorToString (result),
216- .Retryable = NKikimrLdap::IsRetryableError (result)}}};
219+ {.Message = ERROR_MESSAGE, .Retryable = NKikimrLdap::IsRetryableError (result)}}};
217220 }
218221 }
219222
223+ LDAP_LOG_D (" init: scheme: " << Settings.GetScheme () << " , uris: " << UrisCreator.GetUris () << " , port: " << UrisCreator.GetConfiguredPort ());
220224 result = NKikimrLdap::Init (ld, Settings.GetScheme (), UrisCreator.GetUris (), UrisCreator.GetConfiguredPort ());
221225 if (!NKikimrLdap::IsSuccess (result)) {
226+ LDAP_LOG_D (" Could not initialize LDAP connection for uris: " << UrisCreator.GetUris () << " . " << NKikimrLdap::LdapError (*ld));
222227 return {{TEvLdapAuthProvider::EStatus::UNAVAILABLE,
223- {.Message = " Could not initialize LDAP connection for uris: " + UrisCreator.GetUris () + " . " + NKikimrLdap::LdapError (*ld),
224- .Retryable = false }}};
228+ {.Message = ERROR_MESSAGE, .Retryable = false }}};
225229 }
226230
227231 result = NKikimrLdap::SetProtocolVersion (*ld);
228232 if (!NKikimrLdap::IsSuccess (result)) {
229233 NKikimrLdap::Unbind (*ld);
234+ LDAP_LOG_D (" Could not set LDAP protocol version: " << NKikimrLdap::ErrorToString (result));
230235 return {{NKikimrLdap::ErrorToStatus (result),
231- {.Message = " Could not set LDAP protocol version: " + NKikimrLdap::ErrorToString (result),
232- .Retryable = NKikimrLdap::IsRetryableError (result)}}};
236+ {.Message = ERROR_MESSAGE, .Retryable = NKikimrLdap::IsRetryableError (result)}}};
233237 }
234238
235239 if (Settings.GetScheme () == NKikimrLdap::LDAPS_SCHEME || Settings.GetUseTls ().GetEnable ()) {
236240 int requireCert = NKikimrLdap::ConvertRequireCert (Settings.GetUseTls ().GetCertRequire ());
237241 result = NKikimrLdap::SetOption (*ld, NKikimrLdap::EOption::TLS_REQUIRE_CERT, &requireCert);
238242 if (!NKikimrLdap::IsSuccess (result)) {
239243 NKikimrLdap::Unbind (*ld);
244+ LDAP_LOG_D (" Could not set require certificate option: " << NKikimrLdap::ErrorToString (result));
240245 return {{NKikimrLdap::ErrorToStatus (result),
241- {.Message = " Could not set require certificate option: " + NKikimrLdap::ErrorToString (result),
242- .Retryable = NKikimrLdap::IsRetryableError (result)}}};
246+ {.Message = ERROR_MESSAGE, .Retryable = NKikimrLdap::IsRetryableError (result)}}};
243247 }
244248 }
245249
@@ -249,16 +253,18 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
249253 TAuthenticateUserResponse AuthenticateUser (const TAuthenticateUserRequest& request) {
250254 char * dn = NKikimrLdap::GetDn (*request.Ld , request.Entry );
251255 if (dn == nullptr ) {
256+ LDAP_LOG_D (" Could not get dn for the first entry matching " << FilterCreator.GetFilter (request.Login ) << " on server " << UrisCreator.GetUris () << " . "
257+ << NKikimrLdap::LdapError (*request.Ld ));
252258 return {{TEvLdapAuthProvider::EStatus::UNAUTHORIZED,
253- {.Message = " Could not get dn for the first entry matching " + FilterCreator.GetFilter (request.Login ) + " on server " + UrisCreator.GetUris () + " \n "
254- + NKikimrLdap::LdapError (*request.Ld ),
255- .Retryable = false }}};
259+ {.Message = ERROR_MESSAGE, .Retryable = false }}};
256260 }
257261 TEvLdapAuthProvider::TError error;
262+ LDAP_LOG_D (" bind: bindDn: " << dn);
258263 int result = NKikimrLdap::Bind (*request.Ld , dn, request.Password );
259264 if (!NKikimrLdap::IsSuccess (result)) {
260- error.Message = " LDAP login failed for user " + TString (dn) + " on server " + UrisCreator.GetUris () + " \n "
261- + NKikimrLdap::ErrorToString ((result));
265+ LDAP_LOG_D (" LDAP login failed for user " << TString (dn) << " on server " << UrisCreator.GetUris () << " . "
266+ << NKikimrLdap::ErrorToString ((result)));
267+ error.Message = ERROR_MESSAGE;
262268 error.Retryable = NKikimrLdap::IsRetryableError (result);
263269 }
264270 NKikimrLdap::MemFree (dn);
@@ -269,6 +275,10 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
269275 LDAPMessage* searchMessage = nullptr ;
270276 const TString searchFilter = FilterCreator.GetFilter (request.User );
271277
278+ LDAP_LOG_D (" search: baseDn: " << Settings.GetBaseDn ()
279+ << " , scope: " << ConvertSearchScopeToString (NKikimrLdap::EScope::SUBTREE)
280+ << " , filter: " << searchFilter
281+ << " , attributes: " << GetStringOfRequestedAttributes (request.RequestedAttributes ));
272282 int result = NKikimrLdap::Search (request.Ld ,
273283 Settings.GetBaseDn (),
274284 NKikimrLdap::EScope::SUBTREE,
@@ -278,23 +288,22 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
278288 &searchMessage);
279289 TSearchUserResponse response;
280290 if (!NKikimrLdap::IsSuccess (result)) {
291+ LDAP_LOG_D (" Could not search for filter " << searchFilter << " on server " << UrisCreator.GetUris () << " . "
292+ << NKikimrLdap::ErrorToString (result));
281293 response.Status = NKikimrLdap::ErrorToStatus (result);
282- response.Error = {.Message = " Could not search for filter " + searchFilter + " on server " + UrisCreator.GetUris () + " \n "
283- + NKikimrLdap::ErrorToString (result),
284- .Retryable = NKikimrLdap::IsRetryableError (result)};
294+ response.Error = {.Message = ERROR_MESSAGE, .Retryable = NKikimrLdap::IsRetryableError (result)};
285295 return response;
286296 }
287297 const int countEntries = NKikimrLdap::CountEntries (request.Ld , searchMessage);
288298 if (countEntries != 1 ) {
289299 if (countEntries == 0 ) {
290- response.Error = {.Message = " LDAP user " + request.User + " does not exist. "
291- " LDAP search for filter " + searchFilter + " on server " + UrisCreator.GetUris () + " return no entries" ,
292- .Retryable = false };
300+ LDAP_LOG_D (" LDAP user " << request.User << " does not exist. "
301+ " LDAP search for filter " << searchFilter << " on server " << UrisCreator.GetUris () << " return no entries" );
293302 } else {
294- response.Error = {.Message = " LDAP user " + request.User + " is not unique. "
295- " LDAP search for filter " + searchFilter + " on server " + UrisCreator.GetUris () + " return " + countEntries + " entries" ,
296- .Retryable = false };
303+ LDAP_LOG_D (" LDAP user " << request.User << " is not unique. "
304+ " LDAP search for filter " << searchFilter << " on server " << UrisCreator.GetUris () << " return " << countEntries << " entries" );
297305 }
306+ response.Error = {.Message = ERROR_MESSAGE, .Retryable = false };
298307 response.Status = TEvLdapAuthProvider::EStatus::UNAUTHORIZED;
299308 NKikimrLdap::MsgFree (searchMessage);
300309 return response;
@@ -306,7 +315,14 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
306315 std::vector<TString> TryToGetGroupsUseMatchingRuleInChain (LDAP* ld, LDAPMessage* entry) const {
307316 static const TString matchingRuleInChain = " 1.2.840.113556.1.4.1941" ; // Only Active Directory supports
308317 TStringBuilder filter;
309- filter << " (member:" << matchingRuleInChain << " :=" << NKikimrLdap::GetDn (ld, entry) << ' )' ;
318+ char * dn = NKikimrLdap::GetDn (ld, entry);
319+ filter << " (member:" << matchingRuleInChain << " :=" << dn << ' )' ;
320+ NKikimrLdap::MemFree (dn);
321+ dn = nullptr ;
322+ LDAP_LOG_D (" search: baseDn: " << Settings.GetBaseDn ()
323+ << " , scope: " << ConvertSearchScopeToString (NKikimrLdap::EScope::SUBTREE)
324+ << " , filter: " << filter
325+ << " , attributes: " << GetStringOfRequestedAttributes (NKikimrLdap::noAttributes));
310326 LDAPMessage* searchMessage = nullptr ;
311327 int result = NKikimrLdap::Search (ld, Settings.GetBaseDn (), NKikimrLdap::EScope::SUBTREE, filter, NKikimrLdap::noAttributes, 0 , &searchMessage);
312328 if (!NKikimrLdap::IsSuccess (result)) {
@@ -320,13 +336,18 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
320336 std::vector<TString> groups;
321337 groups.reserve (countEntries);
322338 for (LDAPMessage* groupEntry = NKikimrLdap::FirstEntry (ld, searchMessage); groupEntry != nullptr ; groupEntry = NKikimrLdap::NextEntry (ld, groupEntry)) {
323- groups.push_back (NKikimrLdap::GetDn (ld, groupEntry));
339+ dn = NKikimrLdap::GetDn (ld, groupEntry);
340+ groups.push_back (dn);
341+ NKikimrLdap::MemFree (dn);
342+ dn = nullptr ;
324343 }
325344 NKikimrLdap::MsgFree (searchMessage);
326345 return groups;
327346 }
328347
329348 void GetNestedGroups (LDAP* ld, std::vector<TString>* groups) {
349+ LDAP_LOG_D (" Try to get nested groups - tree traversal" );
350+
330351 std::unordered_set<TString> viewedGroups (groups->cbegin (), groups->cend ());
331352 std::queue<TString> queue;
332353 for (const auto & group : *groups) {
@@ -344,6 +365,10 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
344365 queue.pop ();
345366 }
346367 filter << ' )' ;
368+ LDAP_LOG_D (" search: baseDn: " << Settings.GetBaseDn ()
369+ << " , scope: " << ConvertSearchScopeToString (NKikimrLdap::EScope::SUBTREE)
370+ << " , filter: " << filter
371+ << " , attributes: " << GetStringOfRequestedAttributes (RequestedAttributes));
347372 LDAPMessage* searchMessage = nullptr ;
348373 int result = NKikimrLdap::Search (ld, Settings.GetBaseDn (), NKikimrLdap::EScope::SUBTREE, filter, RequestedAttributes, 0 , &searchMessage);
349374 if (!NKikimrLdap::IsSuccess (result)) {
@@ -392,7 +417,35 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
392417 return {TEvLdapAuthProvider::EStatus::SUCCESS, {}};
393418 }
394419
420+ static TString ConvertSearchScopeToString (const NKikimrLdap::EScope& scope) {
421+ switch (scope) {
422+ case NKikimrLdap::EScope::BASE:
423+ return " base" ;
424+ case NKikimrLdap::EScope::ONE_LEVEL:
425+ return " one level" ;
426+ case NKikimrLdap::EScope::SUBTREE:
427+ return " subtree" ;
428+ }
429+ }
430+
431+ static TString GetStringOfRequestedAttributes (char ** attributes) {
432+ if (!attributes) {
433+ return " " ;
434+ }
435+ TStringBuilder result;
436+ char * firstAttribute = *attributes;
437+ if (firstAttribute) {
438+ result << firstAttribute;
439+ for (char * currentAttribute = *(++attributes); currentAttribute != nullptr ; currentAttribute = *(++attributes)) {
440+ result << " , " << currentAttribute;
441+ }
442+ }
443+ return result;
444+ }
445+
395446private:
447+ static constexpr const char * ERROR_MESSAGE = " User is unauthorized in LDAP server" ;
448+
396449 const NKikimrProto::TLdapAuthentication Settings;
397450 const TSearchFilterCreator FilterCreator;
398451 const TLdapUrisCreator UrisCreator;
0 commit comments