11#include < ydb/library/actors/core/actor_bootstrapped.h>
22#include < ydb/library/actors/core/log.h>
33#include < ydb/core/base/ticket_parser.h>
4- #include " ticket_parser_log.h"
4+ #include < ydb/core/security/ ticket_parser_log.h>
55#include " ldap_auth_provider.h"
66#include " ldap_utils.h"
77
@@ -156,7 +156,7 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
156156 }
157157
158158 int result = 0 ;
159- if (Settings.GetUseTls ().GetEnable ()) {
159+ if (Settings.GetScheme () != NKikimrLdap::LDAPS_SCHEME && Settings. GetUseTls ().GetEnable ()) {
160160 result = NKikimrLdap::StartTLS (*ld);
161161 if (!NKikimrLdap::IsSuccess (result)) {
162162 TEvLdapAuthProvider::TError error {
@@ -173,7 +173,7 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
173173 result = NKikimrLdap::Bind (*ld, Settings.GetBindDn (), Settings.GetBindPassword ());
174174 if (!NKikimrLdap::IsSuccess (result)) {
175175 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 "
177177 + NKikimrLdap::ErrorToString (result),
178178 .Retryable = NKikimrLdap::IsRetryableError (result)
179179 };
@@ -190,10 +190,8 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
190190 return response;
191191 }
192192
193- const TString& host = Settings.GetHost ();
194- const ui32 port = Settings.GetPort () != 0 ? Settings.GetPort () : NKikimrLdap::GetPort ();
195193 int result = 0 ;
196- if (Settings.GetUseTls ().GetEnable ()) {
194+ if (Settings.GetScheme () == NKikimrLdap::LDAPS_SCHEME || Settings. GetUseTls ().GetEnable ()) {
197195 const TString& caCertificateFile = Settings.GetUseTls ().GetCaCertFile ();
198196 result = NKikimrLdap::SetOption (*ld, NKikimrLdap::EOption::TLS_CACERTFILE, caCertificateFile.c_str ());
199197 if (!NKikimrLdap::IsSuccess (result)) {
@@ -204,10 +202,12 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
204202 }
205203 }
206204
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)) {
209209 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),
211211 .Retryable = false }}};
212212 }
213213
@@ -219,7 +219,7 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
219219 .Retryable = NKikimrLdap::IsRetryableError (result)}}};
220220 }
221221
222- if (Settings.GetUseTls ().GetEnable ()) {
222+ if (Settings.GetScheme () == NKikimrLdap::LDAPS_SCHEME || Settings. GetUseTls ().GetEnable ()) {
223223 int requireCert = NKikimrLdap::ConvertRequireCert (Settings.GetUseTls ().GetCertRequire ());
224224 result = NKikimrLdap::SetOption (*ld, NKikimrLdap::EOption::TLS_REQUIRE_CERT, &requireCert);
225225 if (!NKikimrLdap::IsSuccess (result)) {
@@ -229,21 +229,22 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
229229 .Retryable = NKikimrLdap::IsRetryableError (result)}}};
230230 }
231231 }
232+
232233 return {};
233234 }
234235
235236 TAuthenticateUserResponse AuthenticateUser (const TAuthenticateUserRequest& request) {
236237 char * dn = NKikimrLdap::GetDn (*request.Ld , request.Entry );
237238 if (dn == nullptr ) {
238239 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 "
240241 + NKikimrLdap::LdapError (*request.Ld ),
241242 .Retryable = false }}};
242243 }
243244 TEvLdapAuthProvider::TError error;
244245 int result = NKikimrLdap::Bind (*request.Ld , dn, request.Password );
245246 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 "
247248 + NKikimrLdap::ErrorToString ((result));
248249 error.Retryable = NKikimrLdap::IsRetryableError (result);
249250 }
@@ -265,7 +266,7 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
265266 TSearchUserResponse response;
266267 if (!NKikimrLdap::IsSuccess (result)) {
267268 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 "
269270 + NKikimrLdap::ErrorToString (result),
270271 .Retryable = NKikimrLdap::IsRetryableError (result)};
271272 return response;
@@ -274,11 +275,11 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
274275 if (countEntries != 1 ) {
275276 if (countEntries == 0 ) {
276277 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" ,
278279 .Retryable = false };
279280 } else {
280281 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" ,
282283 .Retryable = false };
283284 }
284285 response.Status = TEvLdapAuthProvider::EStatus::UNAUTHORIZED;
@@ -290,8 +291,8 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
290291 }
291292
292293 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 }};
295296 }
296297 if (Settings.GetBaseDn ().empty ()) {
297298 return {TEvLdapAuthProvider::EStatus::UNAVAILABLE, {.Message = " Parameter BaseDn is empty" , .Retryable = false }};
@@ -305,10 +306,42 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
305306 return {TEvLdapAuthProvider::EStatus::SUCCESS, {}};
306307 }
307308
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+
308340private:
309341 const NKikimrProto::TLdapAuthentication Settings;
310342 const TSearchFilterCreator FilterCreator;
311343 char * RequestedAttributes[2 ];
344+ TString UrisList;
312345};
313346
314347IActor* CreateLdapAuthProvider (const NKikimrProto::TLdapAuthentication& settings) {
0 commit comments