1
1
#include < ydb/library/actors/core/actor_bootstrapped.h>
2
2
#include < ydb/library/actors/core/log.h>
3
3
#include < ydb/core/base/ticket_parser.h>
4
- #include " ticket_parser_log.h"
4
+ #include < ydb/core/security/ ticket_parser_log.h>
5
5
#include " ldap_auth_provider.h"
6
6
#include " ldap_utils.h"
7
7
@@ -156,7 +156,7 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
156
156
}
157
157
158
158
int result = 0 ;
159
- if (Settings.GetUseTls ().GetEnable ()) {
159
+ if (Settings.GetScheme () != NKikimrLdap::LDAPS_SCHEME && Settings. GetUseTls ().GetEnable ()) {
160
160
result = NKikimrLdap::StartTLS (*ld);
161
161
if (!NKikimrLdap::IsSuccess (result)) {
162
162
TEvLdapAuthProvider::TError error {
@@ -173,7 +173,7 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
173
173
result = NKikimrLdap::Bind (*ld, Settings.GetBindDn (), Settings.GetBindPassword ());
174
174
if (!NKikimrLdap::IsSuccess (result)) {
175
175
TEvLdapAuthProvider::TError error {
176
- .Message = " Could not perform initial LDAP bind for dn " + Settings.GetBindDn () + " on server " + Settings. GetHost () + " \n "
176
+ .Message = " Could not perform initial LDAP bind for dn " + Settings.GetBindDn () + " on server " + UrisList + " \n "
177
177
+ NKikimrLdap::ErrorToString (result),
178
178
.Retryable = NKikimrLdap::IsRetryableError (result)
179
179
};
@@ -190,10 +190,8 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
190
190
return response;
191
191
}
192
192
193
- const TString& host = Settings.GetHost ();
194
- const ui32 port = Settings.GetPort () != 0 ? Settings.GetPort () : NKikimrLdap::GetPort ();
195
193
int result = 0 ;
196
- if (Settings.GetUseTls ().GetEnable ()) {
194
+ if (Settings.GetScheme () == NKikimrLdap::LDAPS_SCHEME || Settings. GetUseTls ().GetEnable ()) {
197
195
const TString& caCertificateFile = Settings.GetUseTls ().GetCaCertFile ();
198
196
result = NKikimrLdap::SetOption (*ld, NKikimrLdap::EOption::TLS_CACERTFILE, caCertificateFile.c_str ());
199
197
if (!NKikimrLdap::IsSuccess (result)) {
@@ -204,10 +202,12 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
204
202
}
205
203
}
206
204
207
- *ld = NKikimrLdap::Init (host, port);
208
- if (*ld == nullptr ) {
205
+ const ui32 port = Settings.GetPort () != 0 ? Settings.GetPort () : NKikimrLdap::GetPort (Settings.GetScheme ());
206
+ UrisList = GetUris (port);
207
+ result = NKikimrLdap::Init (ld, Settings.GetScheme (), UrisList, port);
208
+ if (!NKikimrLdap::IsSuccess (result)) {
209
209
return {{TEvLdapAuthProvider::EStatus::UNAVAILABLE,
210
- {.Message = " Could not initialize LDAP connection for host : " + host + " , port: " + ToString (port) + " . " + NKikimrLdap::LdapError (*ld),
210
+ {.Message = " Could not initialize LDAP connection for uris : " + UrisList + " . " + NKikimrLdap::LdapError (*ld),
211
211
.Retryable = false }}};
212
212
}
213
213
@@ -219,7 +219,7 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
219
219
.Retryable = NKikimrLdap::IsRetryableError (result)}}};
220
220
}
221
221
222
- if (Settings.GetUseTls ().GetEnable ()) {
222
+ if (Settings.GetScheme () == NKikimrLdap::LDAPS_SCHEME || Settings. GetUseTls ().GetEnable ()) {
223
223
int requireCert = NKikimrLdap::ConvertRequireCert (Settings.GetUseTls ().GetCertRequire ());
224
224
result = NKikimrLdap::SetOption (*ld, NKikimrLdap::EOption::TLS_REQUIRE_CERT, &requireCert);
225
225
if (!NKikimrLdap::IsSuccess (result)) {
@@ -229,21 +229,22 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
229
229
.Retryable = NKikimrLdap::IsRetryableError (result)}}};
230
230
}
231
231
}
232
+
232
233
return {};
233
234
}
234
235
235
236
TAuthenticateUserResponse AuthenticateUser (const TAuthenticateUserRequest& request) {
236
237
char * dn = NKikimrLdap::GetDn (*request.Ld , request.Entry );
237
238
if (dn == nullptr ) {
238
239
return {{TEvLdapAuthProvider::EStatus::UNAUTHORIZED,
239
- {.Message = " Could not get dn for the first entry matching " + FilterCreator.GetFilter (request.Login ) + " on server " + Settings. GetHost () + " \n "
240
+ {.Message = " Could not get dn for the first entry matching " + FilterCreator.GetFilter (request.Login ) + " on server " + UrisList + " \n "
240
241
+ NKikimrLdap::LdapError (*request.Ld ),
241
242
.Retryable = false }}};
242
243
}
243
244
TEvLdapAuthProvider::TError error;
244
245
int result = NKikimrLdap::Bind (*request.Ld , dn, request.Password );
245
246
if (!NKikimrLdap::IsSuccess (result)) {
246
- error.Message = " LDAP login failed for user " + TString (dn) + " on server " + Settings. GetHost () + " \n "
247
+ error.Message = " LDAP login failed for user " + TString (dn) + " on server " + UrisList + " \n "
247
248
+ NKikimrLdap::ErrorToString ((result));
248
249
error.Retryable = NKikimrLdap::IsRetryableError (result);
249
250
}
@@ -265,7 +266,7 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
265
266
TSearchUserResponse response;
266
267
if (!NKikimrLdap::IsSuccess (result)) {
267
268
response.Status = NKikimrLdap::ErrorToStatus (result);
268
- response.Error = {.Message = " Could not search for filter " + searchFilter + " on server " + Settings. GetHost () + " \n "
269
+ response.Error = {.Message = " Could not search for filter " + searchFilter + " on server " + UrisList + " \n "
269
270
+ NKikimrLdap::ErrorToString (result),
270
271
.Retryable = NKikimrLdap::IsRetryableError (result)};
271
272
return response;
@@ -274,11 +275,11 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
274
275
if (countEntries != 1 ) {
275
276
if (countEntries == 0 ) {
276
277
response.Error = {.Message = " LDAP user " + request.User + " does not exist. "
277
- " LDAP search for filter " + searchFilter + " on server " + Settings. GetHost () + " return no entries" ,
278
+ " LDAP search for filter " + searchFilter + " on server " + UrisList + " return no entries" ,
278
279
.Retryable = false };
279
280
} else {
280
281
response.Error = {.Message = " LDAP user " + request.User + " is not unique. "
281
- " LDAP search for filter " + searchFilter + " on server " + Settings. GetHost () + " return " + countEntries + " entries" ,
282
+ " LDAP search for filter " + searchFilter + " on server " + UrisList + " return " + countEntries + " entries" ,
282
283
.Retryable = false };
283
284
}
284
285
response.Status = TEvLdapAuthProvider::EStatus::UNAUTHORIZED;
@@ -290,8 +291,8 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
290
291
}
291
292
292
293
TInitializeLdapConnectionResponse CheckRequiredSettingsParameters () const {
293
- if (Settings.GetHost ().empty ()) {
294
- return {TEvLdapAuthProvider::EStatus::UNAVAILABLE, {.Message = " Ldap server host is empty" , .Retryable = false }};
294
+ if (Settings.GetHosts (). empty () && Settings. GetHost ().empty ()) {
295
+ return {TEvLdapAuthProvider::EStatus::UNAVAILABLE, {.Message = " List of ldap server hosts is empty" , .Retryable = false }};
295
296
}
296
297
if (Settings.GetBaseDn ().empty ()) {
297
298
return {TEvLdapAuthProvider::EStatus::UNAVAILABLE, {.Message = " Parameter BaseDn is empty" , .Retryable = false }};
@@ -305,10 +306,42 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
305
306
return {TEvLdapAuthProvider::EStatus::SUCCESS, {}};
306
307
}
307
308
309
+ TString GetUris (ui32 port) const {
310
+ TStringBuilder uris;
311
+ if (Settings.HostsSize () > 0 ) {
312
+ for (const auto & host : Settings.GetHosts ()) {
313
+ uris << CreateUri (host, port) << " " ;
314
+ }
315
+ uris.remove (uris.size () - 1 );
316
+ } else {
317
+ uris << CreateUri (Settings.GetHost (), port);
318
+ }
319
+ return uris;
320
+ }
321
+
322
+ TString CreateUri (const TString& endpoint, ui32 port) const {
323
+ TStringBuilder uri;
324
+ uri << Settings.GetScheme () << " ://" << endpoint;
325
+ if (!HasEndpointPort (endpoint)) {
326
+ uri << ' :' << port;
327
+ }
328
+ return uri;
329
+ }
330
+
331
+ static bool HasEndpointPort (const TString& endpoint) {
332
+ size_t colonPos = endpoint.rfind (' :' );
333
+ if (colonPos == TString::npos) {
334
+ return false ;
335
+ }
336
+ ++colonPos;
337
+ return (endpoint.size () - colonPos) > 0 ;
338
+ }
339
+
308
340
private:
309
341
const NKikimrProto::TLdapAuthentication Settings;
310
342
const TSearchFilterCreator FilterCreator;
311
343
char * RequestedAttributes[2 ];
344
+ TString UrisList;
312
345
};
313
346
314
347
IActor* CreateLdapAuthProvider (const NKikimrProto::TLdapAuthentication& settings) {
0 commit comments