6
6
#include < queue>
7
7
#include " ldap_auth_provider.h"
8
8
#include " ldap_utils.h"
9
+ #include " ldap_auth_provider_log.h"
9
10
10
11
// This temporary solution
11
12
// These lines should be declared outside ldap_compat.h
@@ -172,11 +173,12 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
172
173
173
174
int result = 0 ;
174
175
if (Settings.GetScheme () != NKikimrLdap::LDAPS_SCHEME && Settings.GetUseTls ().GetEnable ()) {
176
+ LDAP_LOG_D (" start TLS" );
175
177
result = NKikimrLdap::StartTLS (*ld);
176
178
if (!NKikimrLdap::IsSuccess (result)) {
179
+ LDAP_LOG_D (" Could not start TLS. " << NKikimrLdap::ErrorToString (result));
177
180
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)
180
182
};
181
183
// The Unbind operation is not the antithesis of the Bind operation as the name implies.
182
184
// Close the LDAP connection, free the resources contained in the LDAP structure
@@ -185,12 +187,13 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
185
187
}
186
188
}
187
189
190
+ LDAP_LOG_D (" bind: bindDn: " << Settings.GetBindDn ());
188
191
result = NKikimrLdap::Bind (*ld, Settings.GetBindDn (), Settings.GetBindPassword ());
189
192
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));
190
195
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)
194
197
};
195
198
// The Unbind operation is not the antithesis of the Bind operation as the name implies.
196
199
// Close the LDAP connection, free the resources contained in the LDAP structure
@@ -210,36 +213,37 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
210
213
const TString& caCertificateFile = Settings.GetUseTls ().GetCaCertFile ();
211
214
result = NKikimrLdap::SetOption (*ld, NKikimrLdap::EOption::TLS_CACERTFILE, caCertificateFile.c_str ());
212
215
if (!NKikimrLdap::IsSuccess (result)) {
216
+ LDAP_LOG_D (" Could not set LDAP ca certificate file \" " << caCertificateFile + " \" : " << NKikimrLdap::ErrorToString (result));
213
217
NKikimrLdap::Unbind (*ld);
214
218
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)}}};
217
220
}
218
221
}
219
222
223
+ LDAP_LOG_D (" init: scheme: " << Settings.GetScheme () << " , uris: " << UrisCreator.GetUris () << " , port: " << UrisCreator.GetConfiguredPort ());
220
224
result = NKikimrLdap::Init (ld, Settings.GetScheme (), UrisCreator.GetUris (), UrisCreator.GetConfiguredPort ());
221
225
if (!NKikimrLdap::IsSuccess (result)) {
226
+ LDAP_LOG_D (" Could not initialize LDAP connection for uris: " << UrisCreator.GetUris () << " . " << NKikimrLdap::LdapError (*ld));
222
227
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 }}};
225
229
}
226
230
227
231
result = NKikimrLdap::SetProtocolVersion (*ld);
228
232
if (!NKikimrLdap::IsSuccess (result)) {
229
233
NKikimrLdap::Unbind (*ld);
234
+ LDAP_LOG_D (" Could not set LDAP protocol version: " << NKikimrLdap::ErrorToString (result));
230
235
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)}}};
233
237
}
234
238
235
239
if (Settings.GetScheme () == NKikimrLdap::LDAPS_SCHEME || Settings.GetUseTls ().GetEnable ()) {
236
240
int requireCert = NKikimrLdap::ConvertRequireCert (Settings.GetUseTls ().GetCertRequire ());
237
241
result = NKikimrLdap::SetOption (*ld, NKikimrLdap::EOption::TLS_REQUIRE_CERT, &requireCert);
238
242
if (!NKikimrLdap::IsSuccess (result)) {
239
243
NKikimrLdap::Unbind (*ld);
244
+ LDAP_LOG_D (" Could not set require certificate option: " << NKikimrLdap::ErrorToString (result));
240
245
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)}}};
243
247
}
244
248
}
245
249
@@ -249,16 +253,18 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
249
253
TAuthenticateUserResponse AuthenticateUser (const TAuthenticateUserRequest& request) {
250
254
char * dn = NKikimrLdap::GetDn (*request.Ld , request.Entry );
251
255
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 ));
252
258
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 }}};
256
260
}
257
261
TEvLdapAuthProvider::TError error;
262
+ LDAP_LOG_D (" bind: bindDn: " << dn);
258
263
int result = NKikimrLdap::Bind (*request.Ld , dn, request.Password );
259
264
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;
262
268
error.Retryable = NKikimrLdap::IsRetryableError (result);
263
269
}
264
270
NKikimrLdap::MemFree (dn);
@@ -269,6 +275,10 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
269
275
LDAPMessage* searchMessage = nullptr ;
270
276
const TString searchFilter = FilterCreator.GetFilter (request.User );
271
277
278
+ LDAP_LOG_D (" search: baseDn: " << Settings.GetBaseDn ()
279
+ << " , scope: " << ConvertSearchScopeToString (NKikimrLdap::EScope::SUBTREE)
280
+ << " , filter: " << searchFilter
281
+ << " , attributes: " << GetStringOfRequestedAttributes (request.RequestedAttributes ));
272
282
int result = NKikimrLdap::Search (request.Ld ,
273
283
Settings.GetBaseDn (),
274
284
NKikimrLdap::EScope::SUBTREE,
@@ -278,23 +288,22 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
278
288
&searchMessage);
279
289
TSearchUserResponse response;
280
290
if (!NKikimrLdap::IsSuccess (result)) {
291
+ LDAP_LOG_D (" Could not search for filter " << searchFilter << " on server " << UrisCreator.GetUris () << " . "
292
+ << NKikimrLdap::ErrorToString (result));
281
293
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)};
285
295
return response;
286
296
}
287
297
const int countEntries = NKikimrLdap::CountEntries (request.Ld , searchMessage);
288
298
if (countEntries != 1 ) {
289
299
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" );
293
302
} 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" );
297
305
}
306
+ response.Error = {.Message = ERROR_MESSAGE, .Retryable = false };
298
307
response.Status = TEvLdapAuthProvider::EStatus::UNAUTHORIZED;
299
308
NKikimrLdap::MsgFree (searchMessage);
300
309
return response;
@@ -306,7 +315,14 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
306
315
std::vector<TString> TryToGetGroupsUseMatchingRuleInChain (LDAP* ld, LDAPMessage* entry) const {
307
316
static const TString matchingRuleInChain = " 1.2.840.113556.1.4.1941" ; // Only Active Directory supports
308
317
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));
310
326
LDAPMessage* searchMessage = nullptr ;
311
327
int result = NKikimrLdap::Search (ld, Settings.GetBaseDn (), NKikimrLdap::EScope::SUBTREE, filter, NKikimrLdap::noAttributes, 0 , &searchMessage);
312
328
if (!NKikimrLdap::IsSuccess (result)) {
@@ -320,13 +336,18 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
320
336
std::vector<TString> groups;
321
337
groups.reserve (countEntries);
322
338
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 ;
324
343
}
325
344
NKikimrLdap::MsgFree (searchMessage);
326
345
return groups;
327
346
}
328
347
329
348
void GetNestedGroups (LDAP* ld, std::vector<TString>* groups) {
349
+ LDAP_LOG_D (" Try to get nested groups - tree traversal" );
350
+
330
351
std::unordered_set<TString> viewedGroups (groups->cbegin (), groups->cend ());
331
352
std::queue<TString> queue;
332
353
for (const auto & group : *groups) {
@@ -344,6 +365,10 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
344
365
queue.pop ();
345
366
}
346
367
filter << ' )' ;
368
+ LDAP_LOG_D (" search: baseDn: " << Settings.GetBaseDn ()
369
+ << " , scope: " << ConvertSearchScopeToString (NKikimrLdap::EScope::SUBTREE)
370
+ << " , filter: " << filter
371
+ << " , attributes: " << GetStringOfRequestedAttributes (RequestedAttributes));
347
372
LDAPMessage* searchMessage = nullptr ;
348
373
int result = NKikimrLdap::Search (ld, Settings.GetBaseDn (), NKikimrLdap::EScope::SUBTREE, filter, RequestedAttributes, 0 , &searchMessage);
349
374
if (!NKikimrLdap::IsSuccess (result)) {
@@ -392,7 +417,35 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
392
417
return {TEvLdapAuthProvider::EStatus::SUCCESS, {}};
393
418
}
394
419
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
+
395
446
private:
447
+ static constexpr const char * ERROR_MESSAGE = " User is unauthorized in LDAP server" ;
448
+
396
449
const NKikimrProto::TLdapAuthentication Settings;
397
450
const TSearchFilterCreator FilterCreator;
398
451
const TLdapUrisCreator UrisCreator;
0 commit comments