From c143dd8dca2a7db2ffa00e3e0d42a878d5c9829b Mon Sep 17 00:00:00 2001 From: Andrey Molotkov Date: Tue, 15 Oct 2024 11:32:09 +0300 Subject: [PATCH] [ldap] Prohibit requests with empty password (#10401) --- .../ldap_auth_provider/ldap_auth_provider.cpp | 6 +++ ydb/services/ydb/ydb_ldap_login_ut.cpp | 42 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/ydb/core/security/ldap_auth_provider/ldap_auth_provider.cpp b/ydb/core/security/ldap_auth_provider/ldap_auth_provider.cpp index baf841dbf0dc..857015d85c8e 100644 --- a/ydb/core/security/ldap_auth_provider/ldap_auth_provider.cpp +++ b/ydb/core/security/ldap_auth_provider/ldap_auth_provider.cpp @@ -257,6 +257,12 @@ class TLdapAuthProvider : public NActors::TActorBootstrapped + NKikimrLdap::LdapError(*request.Ld), .Retryable = false}}}; } + if (request.Password.Empty()) { + NKikimrLdap::MemFree(dn); + return {{TEvLdapAuthProvider::EStatus::UNAUTHORIZED, + {.Message = "LDAP login failed. Empty password", + .Retryable = false}}}; + } TEvLdapAuthProvider::TError error; int result = NKikimrLdap::Bind(*request.Ld, dn, request.Password); if (!NKikimrLdap::IsSuccess(result)) { diff --git a/ydb/services/ydb/ydb_ldap_login_ut.cpp b/ydb/services/ydb/ydb_ldap_login_ut.cpp index cf685d3b6f92..02e7e4010882 100644 --- a/ydb/services/ydb/ydb_ldap_login_ut.cpp +++ b/ydb/services/ydb/ydb_ldap_login_ut.cpp @@ -380,6 +380,48 @@ Y_UNIT_TEST_SUITE(TGRpcLdapAuthentication) { ldapServer.Stop(); } + Y_UNIT_TEST(LdapAuthWithEmptyPassword) { + TString login = "ldapUser"; + TString password = ""; + + LdapMock::TLdapMockResponses responses; + responses.BindResponses.push_back({{{.Login = "cn=robouser,dc=search,dc=yandex,dc=net", .Password = "robouserPassword"}}, {.Status = LdapMock::EStatus::SUCCESS}}); + + LdapMock::TSearchRequestInfo fetchUserSearchRequestInfo { + { + .BaseDn = "dc=search,dc=yandex,dc=net", + .Scope = 2, + .DerefAliases = 0, + .Filter = {.Type = LdapMock::EFilterType::LDAP_FILTER_EQUALITY, .Attribute = "uid", .Value = login}, + .Attributes = {"1.1"} + } + }; + + std::vector fetchUserSearchResponseEntries { + { + .Dn = "uid=" + login + ",dc=search,dc=yandex,dc=net" + } + }; + + LdapMock::TSearchResponseInfo fetchUserSearchResponseInfo { + .ResponseEntries = fetchUserSearchResponseEntries, + .ResponseDone = {.Status = LdapMock::EStatus::SUCCESS} + }; + responses.SearchResponses.push_back({fetchUserSearchRequestInfo, fetchUserSearchResponseInfo}); + + TLoginClientConnection loginConnection(InitLdapSettings); + LdapMock::TLdapSimpleServer ldapServer(loginConnection.GetLdapPort(), responses); + + auto factory = CreateLoginCredentialsProviderFactory({.User = login + "@ldap", .Password = password}); + auto loginProvider = factory->CreateProvider(loginConnection.GetCoreFacility()); + TStringBuilder expectedErrorMessage; + expectedErrorMessage << "LDAP login failed. Empty password"; + UNIT_ASSERT_EXCEPTION_CONTAINS(loginProvider->GetAuthInfo(), yexception, expectedErrorMessage); + + loginConnection.Stop(); + ldapServer.Stop(); + } + Y_UNIT_TEST(LdapAuthSetIncorrectDomain) { TString login = "ldapuser"; TString password = "ldapUserPassword";