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
};
@@ -186,15 +186,12 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
186
186
}
187
187
188
188
TInitializeLdapConnectionResponse InitializeLDAPConnection (LDAP** ld) {
189
- const TString& host = Settings.GetHost ();
190
- if (host.empty ()) {
191
- return {{TEvLdapAuthProvider::EStatus::UNAVAILABLE, {.Message = " Ldap server host is empty" , .Retryable = false }}};
189
+ if (TInitializeLdapConnectionResponse response = CheckRequiredSettingsParameters (); response.Status != TEvLdapAuthProvider::EStatus::SUCCESS) {
190
+ return response;
192
191
}
193
192
194
- const ui32 port = Settings.GetPort () != 0 ? Settings.GetPort () : NKikimrLdap::GetPort ();
195
-
196
193
int result = 0 ;
197
- if (Settings.GetUseTls ().GetEnable ()) {
194
+ if (Settings.GetScheme () == NKikimrLdap::LDAPS_SCHEME || Settings. GetUseTls ().GetEnable ()) {
198
195
const TString& caCertificateFile = Settings.GetUseTls ().GetCaCertFile ();
199
196
result = NKikimrLdap::SetOption (*ld, NKikimrLdap::EOption::TLS_CACERTFILE, caCertificateFile.c_str ());
200
197
if (!NKikimrLdap::IsSuccess (result)) {
@@ -205,10 +202,12 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
205
202
}
206
203
}
207
204
208
- *ld = NKikimrLdap::Init (host, port);
209
- 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)) {
210
209
return {{TEvLdapAuthProvider::EStatus::UNAVAILABLE,
211
- {.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),
212
211
.Retryable = false }}};
213
212
}
214
213
@@ -220,7 +219,7 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
220
219
.Retryable = NKikimrLdap::IsRetryableError (result)}}};
221
220
}
222
221
223
- if (Settings.GetUseTls ().GetEnable ()) {
222
+ if (Settings.GetScheme () == NKikimrLdap::LDAPS_SCHEME || Settings. GetUseTls ().GetEnable ()) {
224
223
int requireCert = NKikimrLdap::ConvertRequireCert (Settings.GetUseTls ().GetCertRequire ());
225
224
result = NKikimrLdap::SetOption (*ld, NKikimrLdap::EOption::TLS_REQUIRE_CERT, &requireCert);
226
225
if (!NKikimrLdap::IsSuccess (result)) {
@@ -230,21 +229,22 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
230
229
.Retryable = NKikimrLdap::IsRetryableError (result)}}};
231
230
}
232
231
}
232
+
233
233
return {};
234
234
}
235
235
236
236
TAuthenticateUserResponse AuthenticateUser (const TAuthenticateUserRequest& request) {
237
237
char * dn = NKikimrLdap::GetDn (*request.Ld , request.Entry );
238
238
if (dn == nullptr ) {
239
239
return {{TEvLdapAuthProvider::EStatus::UNAUTHORIZED,
240
- {.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 "
241
241
+ NKikimrLdap::LdapError (*request.Ld ),
242
242
.Retryable = false }}};
243
243
}
244
244
TEvLdapAuthProvider::TError error;
245
245
int result = NKikimrLdap::Bind (*request.Ld , dn, request.Password );
246
246
if (!NKikimrLdap::IsSuccess (result)) {
247
- 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 "
248
248
+ NKikimrLdap::ErrorToString ((result));
249
249
error.Retryable = NKikimrLdap::IsRetryableError (result);
250
250
}
@@ -266,7 +266,7 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
266
266
TSearchUserResponse response;
267
267
if (!NKikimrLdap::IsSuccess (result)) {
268
268
response.Status = NKikimrLdap::ErrorToStatus (result);
269
- 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 "
270
270
+ NKikimrLdap::ErrorToString (result),
271
271
.Retryable = NKikimrLdap::IsRetryableError (result)};
272
272
return response;
@@ -275,11 +275,11 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
275
275
if (countEntries != 1 ) {
276
276
if (countEntries == 0 ) {
277
277
response.Error = {.Message = " LDAP user " + request.User + " does not exist. "
278
- " LDAP search for filter " + searchFilter + " on server " + Settings. GetHost () + " return no entries" ,
278
+ " LDAP search for filter " + searchFilter + " on server " + UrisList + " return no entries" ,
279
279
.Retryable = false };
280
280
} else {
281
281
response.Error = {.Message = " LDAP user " + request.User + " is not unique. "
282
- " LDAP search for filter " + searchFilter + " on server " + Settings. GetHost () + " return " + countEntries + " entries" ,
282
+ " LDAP search for filter " + searchFilter + " on server " + UrisList + " return " + countEntries + " entries" ,
283
283
.Retryable = false };
284
284
}
285
285
response.Status = TEvLdapAuthProvider::EStatus::UNAUTHORIZED;
@@ -290,10 +290,58 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped<TLdapAuthProvider>
290
290
return response;
291
291
}
292
292
293
+ TInitializeLdapConnectionResponse CheckRequiredSettingsParameters () const {
294
+ if (Settings.GetHosts ().empty () && Settings.GetHost ().empty ()) {
295
+ return {TEvLdapAuthProvider::EStatus::UNAVAILABLE, {.Message = " List of ldap server hosts is empty" , .Retryable = false }};
296
+ }
297
+ if (Settings.GetBaseDn ().empty ()) {
298
+ return {TEvLdapAuthProvider::EStatus::UNAVAILABLE, {.Message = " Parameter BaseDn is empty" , .Retryable = false }};
299
+ }
300
+ if (Settings.GetBindDn ().empty ()) {
301
+ return {TEvLdapAuthProvider::EStatus::UNAVAILABLE, {.Message = " Parameter BindDn is empty" , .Retryable = false }};
302
+ }
303
+ if (Settings.GetBindPassword ().empty ()) {
304
+ return {TEvLdapAuthProvider::EStatus::UNAVAILABLE, {.Message = " Parameter BindPassword is empty" , .Retryable = false }};
305
+ }
306
+ return {TEvLdapAuthProvider::EStatus::SUCCESS, {}};
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
+
293
340
private:
294
341
const NKikimrProto::TLdapAuthentication Settings;
295
342
const TSearchFilterCreator FilterCreator;
296
343
char * RequestedAttributes[2 ];
344
+ TString UrisList;
297
345
};
298
346
299
347
IActor* CreateLdapAuthProvider (const NKikimrProto::TLdapAuthentication& settings) {
0 commit comments