From c3ffdd7b9cafbbee2f1a57367d1e65d7102052bc Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 26 Jan 2026 15:02:43 +0300 Subject: [PATCH 01/30] feat: add property to manage usage of empty pass for login --- conf/ldap.conf | 3 +++ .../src/main/java/org/apache/doris/common/LdapConfig.java | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/conf/ldap.conf b/conf/ldap.conf index 9388ae7ee50b1e..15a62c9134f159 100644 --- a/conf/ldap.conf +++ b/conf/ldap.conf @@ -47,6 +47,9 @@ ldap_group_basedn = ou=group,dc=domain,dc=com ## ldap_use_ssl - use secured connection to LDAP server if required (disabled by default). Note: When enabling SSL, ensure ldap_port is set appropriately (typically 636 for LDAPS instead of 389 for LDAP). # ldap_use_ssl = false +## ldap_allow_empty_pass - allow to connect to ldap with empty pass (enabled by default) +# ldap_allow_empty_pass = true + # LDAP pool configuration # https://docs.spring.io/spring-ldap/docs/2.3.3.RELEASE/reference/#pool-configuration # ldap_pool_max_active = 8 diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java b/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java index 881840696dcde8..d169d93cbd5382 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java @@ -175,4 +175,10 @@ public class LdapConfig extends ConfigBase { public static String getConnectionURL(String hostPortInAccessibleFormat) { return ((LdapConfig.ldap_use_ssl ? "ldaps" : "ldap") + "://" + hostPortInAccessibleFormat); } + + /** + * Flag to enable login with empty pass. + */ + @ConfigBase.ConfField + public static boolean ldap_allow_empty_pass = true; } From f04ba72af572251d69f6db920294123fa5d690dc Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 26 Jan 2026 15:54:10 +0300 Subject: [PATCH 02/30] feat: added logic and test to support allow_empty_pass mode --- .../org/apache/doris/common/ErrorCode.java | 5 +++- .../authenticate/ldap/LdapAuthenticator.java | 10 ++++++- .../apache/doris/mysql/privilege/Auth.java | 7 +++++ .../ldap/LdapAuthenticatorTest.java | 26 +++++++++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java b/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java index a678c2b38f9562..c60088c41fc3ac 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java @@ -1233,7 +1233,10 @@ public enum ErrorCode { ERR_NO_CLUSTER_ERROR(5099, new byte[]{'4', '2', '0', '0', '0'}, "No compute group (cloud cluster) selected"), ERR_NOT_CLOUD_MODE(6000, new byte[]{'4', '2', '0', '0', '0'}, - "Command only support in cloud mode."); + "Command only support in cloud mode."), + + ERR_EMPTY_PASSWORD(6001, new byte[]{'4', '2', '0', '0', '0'}, + "Access with empty password is prohibited for user %s because of current mode"); // This is error code private final int code; diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java index d9e27e4a9fb02f..2fdcb2e6aa9a58 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java @@ -21,6 +21,7 @@ import org.apache.doris.catalog.Env; import org.apache.doris.common.ErrorCode; import org.apache.doris.common.ErrorReport; +import org.apache.doris.common.LdapConfig; import org.apache.doris.mysql.authenticate.AuthenticateRequest; import org.apache.doris.mysql.authenticate.AuthenticateResponse; import org.apache.doris.mysql.authenticate.Authenticator; @@ -83,7 +84,7 @@ public boolean canDeal(String qualifiedUser) { /** * The LDAP authentication process is as follows: - * step1: Check the LDAP password. + * step1: Check the LDAP password (depending on value of property LdapConfig.ldap_allow_empty_pass login with empty pass can be prohibited). * step2: Get the LDAP groups privileges as a role, saved into ConnectContext. * step3: Set current userIdentity. If the user account does not exist in Doris, login as a temporary user. * Otherwise, login to the Doris account. @@ -95,6 +96,13 @@ private AuthenticateResponse internalAuthenticate(String password, String qualif LOG.debug("user:{}", userName); } + //not allow to login in case when empty password is specified but such mode is disabled by configuration + if (Strings.isNullOrEmpty(password) && !LdapConfig.ldap_allow_empty_pass) { + LOG.info("user:{} is not allowed to login with LDAP with empty password because of ldap_allow_empty_pass is {}", userName, LdapConfig.ldap_allow_empty_pass); + ErrorReport.report(ErrorCode.ERR_EMPTY_PASSWORD, qualifiedUser + "@" + remoteIp); + return AuthenticateResponse.failedResponse; + } + // check user password by ldap server. try { if (!Env.getCurrentEnv().getAuth().getLdapManager().checkUserPasswd(qualifiedUser, password)) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java index 63262aaf0b493b..6b15c27af2b226 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java @@ -38,6 +38,7 @@ import org.apache.doris.common.ErrorCode; import org.apache.doris.common.ErrorReport; import org.apache.doris.common.FeConstants; +import org.apache.doris.common.LdapConfig; import org.apache.doris.common.Pair; import org.apache.doris.common.PatternMatcherException; import org.apache.doris.common.UserException; @@ -45,6 +46,7 @@ import org.apache.doris.datasource.CatalogIf; import org.apache.doris.datasource.InternalCatalog; import org.apache.doris.mysql.MysqlPassword; +import org.apache.doris.mysql.authenticate.AuthenticateResponse; import org.apache.doris.mysql.authenticate.AuthenticateType; import org.apache.doris.mysql.authenticate.ldap.LdapManager; import org.apache.doris.mysql.authenticate.ldap.LdapUserInfo; @@ -227,6 +229,11 @@ public void checkPlainPassword(String remoteUser, String remoteHost, String remo List currentUser) throws AuthenticationException { // Check the LDAP password when the user exists in the LDAP service. if (ldapManager.doesUserExist(remoteUser)) { + //not allow to login in case when empty password is specified but such mode is disabled by configuration + if (Strings.isNullOrEmpty(remotePasswd) && !LdapConfig.ldap_allow_empty_pass) { + throw new AuthenticationException(ErrorCode.ERR_EMPTY_PASSWORD, remoteUser + "@" + remoteHost); + } + if (!ldapManager.checkUserPasswd(remoteUser, remotePasswd, remoteHost, currentUser)) { throw new AuthenticationException(ErrorCode.ERR_ACCESS_DENIED_ERROR, remoteUser + "@" + remoteHost, Strings.isNullOrEmpty(remotePasswd) ? "NO" : "YES"); diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 99cbcdb5fad643..d7bee2514ba6ce 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -18,6 +18,7 @@ package org.apache.doris.mysql.authenticate.ldap; import org.apache.doris.analysis.UserIdentity; +import org.apache.doris.common.LdapConfig; import org.apache.doris.mysql.authenticate.AuthenticateRequest; import org.apache.doris.mysql.authenticate.AuthenticateResponse; import org.apache.doris.mysql.authenticate.password.ClearPassword; @@ -27,6 +28,8 @@ import com.google.common.collect.Lists; import mockit.Expectations; import mockit.Mocked; + +import org.junit.After; import org.junit.Assert; import org.junit.Test; @@ -143,4 +146,27 @@ public void testCanDeal() { public void testGetPasswordResolver() { Assert.assertTrue(ldapAuthenticator.getPasswordResolver() instanceof ClearPasswordResolver); } + + @Test + public void testEmptyPassword() throws IOException { + setCheckPassword(true); + setGetUserInDoris(true); + AuthenticateRequest request = new AuthenticateRequest(USER_NAME, new ClearPassword(""), IP); + //running test with non-specified value - ldap_allow_empty_pass should be true + AuthenticateResponse response = ldapAuthenticator.authenticate(request); + Assert.assertTrue(response.isSuccess()); + //running test with specified value - true - ldap_allow_empty_pass is explicitly set to true + LdapConfig.ldap_allow_empty_pass = true; + response = ldapAuthenticator.authenticate(request); + Assert.assertTrue(response.isSuccess()); + //running test with specified value - false - ldap_allow_empty_pass is explicitly set to false + LdapConfig.ldap_allow_empty_pass = false; + response = ldapAuthenticator.authenticate(request); + Assert.assertFalse(response.isSuccess()); + } + + @After + public void tearDown() { + LdapConfig.ldap_allow_empty_pass = true; // restoring default value for other tests + } } From ab5be69cca38312c7676155352ec53d9017b4164 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Thu, 29 Jan 2026 18:28:29 +0300 Subject: [PATCH 03/30] fix: fixing indentation --- .../src/main/java/org/apache/doris/common/ErrorCode.java | 2 +- .../doris/mysql/authenticate/ldap/LdapAuthenticator.java | 5 +++-- .../src/main/java/org/apache/doris/mysql/privilege/Auth.java | 1 - .../doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java | 3 +-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java b/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java index c60088c41fc3ac..0707a2ccfe7631 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java @@ -1236,7 +1236,7 @@ public enum ErrorCode { "Command only support in cloud mode."), ERR_EMPTY_PASSWORD(6001, new byte[]{'4', '2', '0', '0', '0'}, - "Access with empty password is prohibited for user %s because of current mode"); + "Access with empty password is prohibited for user %s because of current mode"); // This is error code private final int code; diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java index 2fdcb2e6aa9a58..638903490bb784 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java @@ -84,7 +84,7 @@ public boolean canDeal(String qualifiedUser) { /** * The LDAP authentication process is as follows: - * step1: Check the LDAP password (depending on value of property LdapConfig.ldap_allow_empty_pass login with empty pass can be prohibited). + * step1: Check the LDAP password (if ldap_allow_empty_pass is false login with empty pass is prohibited). * step2: Get the LDAP groups privileges as a role, saved into ConnectContext. * step3: Set current userIdentity. If the user account does not exist in Doris, login as a temporary user. * Otherwise, login to the Doris account. @@ -98,7 +98,8 @@ private AuthenticateResponse internalAuthenticate(String password, String qualif //not allow to login in case when empty password is specified but such mode is disabled by configuration if (Strings.isNullOrEmpty(password) && !LdapConfig.ldap_allow_empty_pass) { - LOG.info("user:{} is not allowed to login with LDAP with empty password because of ldap_allow_empty_pass is {}", userName, LdapConfig.ldap_allow_empty_pass); + LOG.info("user:{} is not allowed to login to LDAP with empty password because ldap_allow_empty_pass:{}", + userName, LdapConfig.ldap_allow_empty_pass); ErrorReport.report(ErrorCode.ERR_EMPTY_PASSWORD, qualifiedUser + "@" + remoteIp); return AuthenticateResponse.failedResponse; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java index 6b15c27af2b226..5dbf4c940ff6de 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java @@ -46,7 +46,6 @@ import org.apache.doris.datasource.CatalogIf; import org.apache.doris.datasource.InternalCatalog; import org.apache.doris.mysql.MysqlPassword; -import org.apache.doris.mysql.authenticate.AuthenticateResponse; import org.apache.doris.mysql.authenticate.AuthenticateType; import org.apache.doris.mysql.authenticate.ldap.LdapManager; import org.apache.doris.mysql.authenticate.ldap.LdapUserInfo; diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index d7bee2514ba6ce..17dea744b17d73 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -28,7 +28,6 @@ import com.google.common.collect.Lists; import mockit.Expectations; import mockit.Mocked; - import org.junit.After; import org.junit.Assert; import org.junit.Test; @@ -162,7 +161,7 @@ public void testEmptyPassword() throws IOException { //running test with specified value - false - ldap_allow_empty_pass is explicitly set to false LdapConfig.ldap_allow_empty_pass = false; response = ldapAuthenticator.authenticate(request); - Assert.assertFalse(response.isSuccess()); + Assert.assertFalse(response.isSuccess()); } @After From f9742cb693264501c9b15e934c55aefd9482b302 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Fri, 30 Jan 2026 10:04:53 +0300 Subject: [PATCH 04/30] fix: fix indentation --- .../doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 17dea744b17d73..86fd577021df4b 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -161,7 +161,7 @@ public void testEmptyPassword() throws IOException { //running test with specified value - false - ldap_allow_empty_pass is explicitly set to false LdapConfig.ldap_allow_empty_pass = false; response = ldapAuthenticator.authenticate(request); - Assert.assertFalse(response.isSuccess()); + Assert.assertFalse(response.isSuccess()); } @After From ca64c42ea6e4153986106bddf86da0db2efdec21 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Fri, 6 Feb 2026 13:49:43 +0300 Subject: [PATCH 05/30] fix: improve test to restore property before test --- .../mysql/authenticate/ldap/LdapAuthenticatorTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 86fd577021df4b..4a1a96c1ddaf8b 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -29,6 +29,7 @@ import mockit.Expectations; import mockit.Mocked; import org.junit.After; +import org.junit.Before; import org.junit.Assert; import org.junit.Test; @@ -168,4 +169,9 @@ public void testEmptyPassword() throws IOException { public void tearDown() { LdapConfig.ldap_allow_empty_pass = true; // restoring default value for other tests } + + @Before + public void setUp() { + LdapConfig.ldap_allow_empty_pass = true; //restoring default value for other tests + } } From 267c2e3a5255bebae3e9602648a40909c394aee5 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Fri, 6 Feb 2026 19:22:43 +0300 Subject: [PATCH 06/30] fix import order --- .../doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 4a1a96c1ddaf8b..5a17a3caa80f31 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -29,8 +29,8 @@ import mockit.Expectations; import mockit.Mocked; import org.junit.After; -import org.junit.Before; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import java.io.IOException; From 9150fc73434ad62f03cb8ecd4631a5348f96cd7e Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Thu, 26 Mar 2026 14:53:46 +0300 Subject: [PATCH 07/30] review: introduced changes suggested by copilot review --- .../src/main/java/org/apache/doris/common/ErrorCode.java | 2 +- .../src/main/java/org/apache/doris/common/LdapConfig.java | 2 +- .../doris/mysql/authenticate/ldap/LdapAuthenticator.java | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java b/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java index 0707a2ccfe7631..711235f935d383 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/ErrorCode.java @@ -1236,7 +1236,7 @@ public enum ErrorCode { "Command only support in cloud mode."), ERR_EMPTY_PASSWORD(6001, new byte[]{'4', '2', '0', '0', '0'}, - "Access with empty password is prohibited for user %s because of current mode"); + "Access with empty password is prohibited for LDAP user '%s'. Set ldap_allow_empty_pass=true to allow."); // This is error code private final int code; diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java b/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java index d169d93cbd5382..8ebba10313f66c 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java @@ -179,6 +179,6 @@ public static String getConnectionURL(String hostPortInAccessibleFormat) { /** * Flag to enable login with empty pass. */ - @ConfigBase.ConfField + @ConfigBase.ConfField(mutable = true) public static boolean ldap_allow_empty_pass = true; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java index 638903490bb784..5b39bc7d890b97 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java @@ -98,8 +98,7 @@ private AuthenticateResponse internalAuthenticate(String password, String qualif //not allow to login in case when empty password is specified but such mode is disabled by configuration if (Strings.isNullOrEmpty(password) && !LdapConfig.ldap_allow_empty_pass) { - LOG.info("user:{} is not allowed to login to LDAP with empty password because ldap_allow_empty_pass:{}", - userName, LdapConfig.ldap_allow_empty_pass); + LOG.info("user:{} login rejected: empty LDAP password is prohibited (ldap_allow_empty_pass=false)", userName); ErrorReport.report(ErrorCode.ERR_EMPTY_PASSWORD, qualifiedUser + "@" + remoteIp); return AuthenticateResponse.failedResponse; } From b5be138161b2e1b3624fa31b1cb63e300aa07061 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Thu, 26 Mar 2026 15:24:59 +0300 Subject: [PATCH 08/30] review: line was too long --- .../doris/mysql/authenticate/ldap/LdapAuthenticator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java index 5b39bc7d890b97..e64885bd55d7b2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java @@ -98,7 +98,8 @@ private AuthenticateResponse internalAuthenticate(String password, String qualif //not allow to login in case when empty password is specified but such mode is disabled by configuration if (Strings.isNullOrEmpty(password) && !LdapConfig.ldap_allow_empty_pass) { - LOG.info("user:{} login rejected: empty LDAP password is prohibited (ldap_allow_empty_pass=false)", userName); + LOG.info("user:{} login rejected: empty LDAP password is prohibited (ldap_allow_empty_pass=false)", + userName); ErrorReport.report(ErrorCode.ERR_EMPTY_PASSWORD, qualifiedUser + "@" + remoteIp); return AuthenticateResponse.failedResponse; } From 76a24b2932f25a47a13172f9675a95b2f8ee4cfe Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Thu, 26 Mar 2026 16:27:05 +0300 Subject: [PATCH 09/30] review: indentantion was fixed --- .../doris/mysql/authenticate/ldap/LdapAuthenticator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java index e64885bd55d7b2..719af9d47ea83e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java @@ -98,8 +98,8 @@ private AuthenticateResponse internalAuthenticate(String password, String qualif //not allow to login in case when empty password is specified but such mode is disabled by configuration if (Strings.isNullOrEmpty(password) && !LdapConfig.ldap_allow_empty_pass) { - LOG.info("user:{} login rejected: empty LDAP password is prohibited (ldap_allow_empty_pass=false)", - userName); + LOG.info("user:{} login rejected: empty LDAP password is prohibited (ldap_allow_empty_pass=false)", + userName); ErrorReport.report(ErrorCode.ERR_EMPTY_PASSWORD, qualifiedUser + "@" + remoteIp); return AuthenticateResponse.failedResponse; } From f17892a4318fe0f1a81a40ece3335b817632a2a4 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Thu, 26 Mar 2026 17:59:57 +0300 Subject: [PATCH 10/30] review: introduced test for null values and checkPlainPassword() method --- .../ldap/LdapAuthenticatorTest.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 5a17a3caa80f31..210a32f848c990 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -33,6 +33,8 @@ import org.junit.Before; import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertThrows; + import java.io.IOException; import java.util.List; @@ -165,6 +167,53 @@ public void testEmptyPassword() throws IOException { Assert.assertFalse(response.isSuccess()); } + @Test + public void testNullPassword() throws IOException { + setCheckPassword(true); + setGetUserInDoris(true); + AuthenticateRequest request = new AuthenticateRequest(USER_NAME, new ClearPassword(null), IP); + //according to LdapManager:106 - login with null password is prohibitted at all + //need to validate that with all possible options - login with null password is not allowed + //test with default value - ldap_allow_empty_pass is true, password is null => no login + AuthenticateResponse response = ldapAuthenticator.authenticate(request); + Assert.assertFalse(response.isSuccess()); + //test with true value - ldap_allow_empty_pass is true, password is null => no login + LdapConfig.ldap_allow_empty_pass = true; + response = ldapAuthenticator.authenticate(request); + Assert.assertFalse(response.isSuccess()); + //test with false value - ldap_allow_empty_pass is false, password is null => no login + LdapConfig.ldap_allow_empty_pass = false; + response = ldapAuthenticator.authenticate(request); + Assert.assertFalse(response.isSuccess()); + } + + @Test + public void testAuthCheckPlainPasswordWithEmptyPassword() throws Exception { + setLdapUserExist(true); + setCheckPassword(true); + + //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed + Auth.checkPlainPassword(USER_NAME, IP, "", null); + + //test with true and empty pass: login is allowed + LdapConfig.ldap_allow_empty_pass = true; + Auth.checkPlainPassword(USER_NAME, IP, "", null); + + //test with true value and non-empty pass: login is allowed + LdapConfig.ldap_allow_empty_pass = true; + Auth.checkPlainPassword(USER_NAME, IP, "testPass", null); + + //test with false and empty pass: login is not allowed + LdapConfig.ldap_allow_empty_pass = false; + assertThrows(AuthenticationException.class, () -> { + Auth.checkPlainPassword(USER_NAME, IP, "", null); + }); + + //test with false value and non-empty pass: login is allowed + LdapConfig.ldap_allow_empty_pass = false; + Auth.checkPlainPassword(USER_NAME, IP, "testPass", null); + } + @After public void tearDown() { LdapConfig.ldap_allow_empty_pass = true; // restoring default value for other tests From 02961ea0223a98b4fe06e7f907e19bbd5e9cfde0 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Thu, 26 Mar 2026 19:15:11 +0300 Subject: [PATCH 11/30] review: fix indents and imports --- .../ldap/LdapAuthenticatorTest.java | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 210a32f848c990..694db30a8e21d5 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -32,8 +32,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; - -import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.Assertions; import java.io.IOException; import java.util.List; @@ -189,30 +188,30 @@ public void testNullPassword() throws IOException { @Test public void testAuthCheckPlainPasswordWithEmptyPassword() throws Exception { - setLdapUserExist(true); - setCheckPassword(true); + setLdapUserExist(true); + setCheckPassword(true); - //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed - Auth.checkPlainPassword(USER_NAME, IP, "", null); + //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed + Auth.checkPlainPassword(USER_NAME, IP, "", null); - //test with true and empty pass: login is allowed - LdapConfig.ldap_allow_empty_pass = true; - Auth.checkPlainPassword(USER_NAME, IP, "", null); + //test with true and empty pass: login is allowed + LdapConfig.ldap_allow_empty_pass = true; + Auth.checkPlainPassword(USER_NAME, IP, "", null); - //test with true value and non-empty pass: login is allowed - LdapConfig.ldap_allow_empty_pass = true; - Auth.checkPlainPassword(USER_NAME, IP, "testPass", null); + //test with true value and non-empty pass: login is allowed + LdapConfig.ldap_allow_empty_pass = true; + Auth.checkPlainPassword(USER_NAME, IP, "testPass", null); - //test with false and empty pass: login is not allowed - LdapConfig.ldap_allow_empty_pass = false; - assertThrows(AuthenticationException.class, () -> { - Auth.checkPlainPassword(USER_NAME, IP, "", null); - }); + //test with false and empty pass: login is not allowed + LdapConfig.ldap_allow_empty_pass = false; + assertThrows(AuthenticationException.class, () -> { + Auth.checkPlainPassword(USER_NAME, IP, "", null); + }); //test with false value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = false; Auth.checkPlainPassword(USER_NAME, IP, "testPass", null); - } + } @After public void tearDown() { From 4ed376417ecb5a2afeea2faa4f205b0e15fbf89c Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Thu, 26 Mar 2026 20:23:49 +0300 Subject: [PATCH 12/30] review: fix indents and imports --- .../mysql/authenticate/ldap/LdapAuthenticatorTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 694db30a8e21d5..7c71c6f0d8c6cc 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -198,7 +198,7 @@ public void testAuthCheckPlainPasswordWithEmptyPassword() throws Exception { LdapConfig.ldap_allow_empty_pass = true; Auth.checkPlainPassword(USER_NAME, IP, "", null); - //test with true value and non-empty pass: login is allowed + //test with true value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = true; Auth.checkPlainPassword(USER_NAME, IP, "testPass", null); @@ -208,9 +208,9 @@ public void testAuthCheckPlainPasswordWithEmptyPassword() throws Exception { Auth.checkPlainPassword(USER_NAME, IP, "", null); }); - //test with false value and non-empty pass: login is allowed - LdapConfig.ldap_allow_empty_pass = false; - Auth.checkPlainPassword(USER_NAME, IP, "testPass", null); + //test with false value and non-empty pass: login is allowed + LdapConfig.ldap_allow_empty_pass = false; + Auth.checkPlainPassword(USER_NAME, IP, "testPass", null); } @After From 3b9f87b2677b2a18f2e5d105fe9412716f1550bf Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Thu, 26 Mar 2026 21:36:17 +0300 Subject: [PATCH 13/30] review: fix indents and imports v2 --- .../mysql/authenticate/ldap/LdapAuthenticatorTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 7c71c6f0d8c6cc..5e86dda454f2f0 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -190,7 +190,7 @@ public void testNullPassword() throws IOException { public void testAuthCheckPlainPasswordWithEmptyPassword() throws Exception { setLdapUserExist(true); setCheckPassword(true); - + //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed Auth.checkPlainPassword(USER_NAME, IP, "", null); @@ -204,7 +204,7 @@ public void testAuthCheckPlainPasswordWithEmptyPassword() throws Exception { //test with false and empty pass: login is not allowed LdapConfig.ldap_allow_empty_pass = false; - assertThrows(AuthenticationException.class, () -> { + Assertions.assertThrows(AuthenticationException.class, () -> { Auth.checkPlainPassword(USER_NAME, IP, "", null); }); @@ -212,7 +212,7 @@ public void testAuthCheckPlainPasswordWithEmptyPassword() throws Exception { LdapConfig.ldap_allow_empty_pass = false; Auth.checkPlainPassword(USER_NAME, IP, "testPass", null); } - + @After public void tearDown() { LdapConfig.ldap_allow_empty_pass = true; // restoring default value for other tests From 46fbe18760685c9a40b2fdb5c13393702fe1dc86 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Fri, 27 Mar 2026 11:39:29 +0300 Subject: [PATCH 14/30] review: fixed imports v2 --- .../authenticate/ldap/LdapAuthenticatorTest.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 5e86dda454f2f0..37598fd3e5d5e0 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -19,6 +19,7 @@ import org.apache.doris.analysis.UserIdentity; import org.apache.doris.common.LdapConfig; +import org.apache.doris.common.AuthenticationException; import org.apache.doris.mysql.authenticate.AuthenticateRequest; import org.apache.doris.mysql.authenticate.AuthenticateResponse; import org.apache.doris.mysql.authenticate.password.ClearPassword; @@ -192,25 +193,25 @@ public void testAuthCheckPlainPasswordWithEmptyPassword() throws Exception { setCheckPassword(true); //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed - Auth.checkPlainPassword(USER_NAME, IP, "", null); + auth.checkPlainPassword(USER_NAME, IP, "", null); //test with true and empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = true; - Auth.checkPlainPassword(USER_NAME, IP, "", null); + auth.checkPlainPassword(USER_NAME, IP, "", null); //test with true value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = true; - Auth.checkPlainPassword(USER_NAME, IP, "testPass", null); + auth.checkPlainPassword(USER_NAME, IP, "testPass", null); //test with false and empty pass: login is not allowed LdapConfig.ldap_allow_empty_pass = false; Assertions.assertThrows(AuthenticationException.class, () -> { - Auth.checkPlainPassword(USER_NAME, IP, "", null); + auth.checkPlainPassword(USER_NAME, IP, "", null); }); //test with false value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = false; - Auth.checkPlainPassword(USER_NAME, IP, "testPass", null); + auth.checkPlainPassword(USER_NAME, IP, "testPass", null); } @After From 3935ab700303c37f923f4156052514f5815f7746 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Fri, 27 Mar 2026 12:18:55 +0300 Subject: [PATCH 15/30] review: fixed imports v3 --- .../doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 37598fd3e5d5e0..1638701ceec85d 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -18,8 +18,8 @@ package org.apache.doris.mysql.authenticate.ldap; import org.apache.doris.analysis.UserIdentity; +import org.apache.doris.common.AuthenticateException; import org.apache.doris.common.LdapConfig; -import org.apache.doris.common.AuthenticationException; import org.apache.doris.mysql.authenticate.AuthenticateRequest; import org.apache.doris.mysql.authenticate.AuthenticateResponse; import org.apache.doris.mysql.authenticate.password.ClearPassword; From 9cd5bf3825029bda21979ca04b66a15ed138b07d Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Fri, 27 Mar 2026 13:04:11 +0300 Subject: [PATCH 16/30] review: fixed imports v3 --- .../doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 1638701ceec85d..644ef51e9f65b3 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -18,7 +18,7 @@ package org.apache.doris.mysql.authenticate.ldap; import org.apache.doris.analysis.UserIdentity; -import org.apache.doris.common.AuthenticateException; +import org.apache.doris.common.AuthenticationException; import org.apache.doris.common.LdapConfig; import org.apache.doris.mysql.authenticate.AuthenticateRequest; import org.apache.doris.mysql.authenticate.AuthenticateResponse; From ed848d9ed1f465a00104d9aa137c9f43c4dcef66 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Fri, 27 Mar 2026 15:38:12 +0300 Subject: [PATCH 17/30] review: tests reworked v1 --- .../ldap/LdapAuthenticatorTest.java | 48 ------- ...PlainAuthWithEmptyPasswordAndLdapTest.java | 119 ++++++++++++++++++ 2 files changed, 119 insertions(+), 48 deletions(-) create mode 100644 fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 644ef51e9f65b3..4081aa87ef6645 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -18,7 +18,6 @@ package org.apache.doris.mysql.authenticate.ldap; import org.apache.doris.analysis.UserIdentity; -import org.apache.doris.common.AuthenticationException; import org.apache.doris.common.LdapConfig; import org.apache.doris.mysql.authenticate.AuthenticateRequest; import org.apache.doris.mysql.authenticate.AuthenticateResponse; @@ -167,53 +166,6 @@ public void testEmptyPassword() throws IOException { Assert.assertFalse(response.isSuccess()); } - @Test - public void testNullPassword() throws IOException { - setCheckPassword(true); - setGetUserInDoris(true); - AuthenticateRequest request = new AuthenticateRequest(USER_NAME, new ClearPassword(null), IP); - //according to LdapManager:106 - login with null password is prohibitted at all - //need to validate that with all possible options - login with null password is not allowed - //test with default value - ldap_allow_empty_pass is true, password is null => no login - AuthenticateResponse response = ldapAuthenticator.authenticate(request); - Assert.assertFalse(response.isSuccess()); - //test with true value - ldap_allow_empty_pass is true, password is null => no login - LdapConfig.ldap_allow_empty_pass = true; - response = ldapAuthenticator.authenticate(request); - Assert.assertFalse(response.isSuccess()); - //test with false value - ldap_allow_empty_pass is false, password is null => no login - LdapConfig.ldap_allow_empty_pass = false; - response = ldapAuthenticator.authenticate(request); - Assert.assertFalse(response.isSuccess()); - } - - @Test - public void testAuthCheckPlainPasswordWithEmptyPassword() throws Exception { - setLdapUserExist(true); - setCheckPassword(true); - - //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed - auth.checkPlainPassword(USER_NAME, IP, "", null); - - //test with true and empty pass: login is allowed - LdapConfig.ldap_allow_empty_pass = true; - auth.checkPlainPassword(USER_NAME, IP, "", null); - - //test with true value and non-empty pass: login is allowed - LdapConfig.ldap_allow_empty_pass = true; - auth.checkPlainPassword(USER_NAME, IP, "testPass", null); - - //test with false and empty pass: login is not allowed - LdapConfig.ldap_allow_empty_pass = false; - Assertions.assertThrows(AuthenticationException.class, () -> { - auth.checkPlainPassword(USER_NAME, IP, "", null); - }); - - //test with false value and non-empty pass: login is allowed - LdapConfig.ldap_allow_empty_pass = false; - auth.checkPlainPassword(USER_NAME, IP, "testPass", null); - } - @After public void tearDown() { LdapConfig.ldap_allow_empty_pass = true; // restoring default value for other tests diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java new file mode 100644 index 00000000000000..ae4531907053e3 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java @@ -0,0 +1,119 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.doris.mysql.privilege; + +import org.apache.doris.catalog.Env; +import org.apache.doris.common.LdapConfig; +import org.apache.doris.mysql.authenticate.ldap.LdapManager; +import org.apache.doris.utframe.TestWithFeService; + +import mockit.Expectations; +import mockit.Mocked; +import org.junit.After; +import org.junit.Before; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class PlainAuthWithEmptyPasswordAndLdapTest extends TestWithFeService { + private static final String USER_NAME = "user"; + private static final String IP = "192.168.1.1"; + + @Mocked + private LdapManager ldapManager; + + private void setLdapUserExist(boolean res) { + new Expectations() { + { + ldapManager.doesUserExist(anyString); + minTimes = 0; + result = res; + } + }; + } + + private void setCheckPassword(boolean res) { + new Expectations() { + { + ldapManager.checkUserPasswd(anyString, anyString); + minTimes = 0; + result = res; + } + }; + } + + @Test + public void testPlainPasswordAuthWithNonEmptyPassword() throws Exception { + setLdapUserExist(true); + setCheckPassword(true); + + //test with true value and non-empty pass: login is allowed + LdapConfig.ldap_allow_empty_pass = true; + Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "testPass", null); + + //test with false value and non-empty pass: login is allowed + LdapConfig.ldap_allow_empty_pass = false; + Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "testPass", null); + } + + + @Test + public void testPlainPasswordAuthWithEmptyPasswordAllowed() throws Exception { + setLdapUserExist(true); + setCheckPassword(true); + + //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed + Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); + + //test with true and empty pass: login is allowed + LdapConfig.ldap_allow_empty_pass = true; + Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); + } + + @Test + public void testPlainPasswordAuthWithEmptyPasswordProhibitted() throws Exception { + setLdapUserExist(true); + setCheckPassword(true); + + //test with false and empty pass: login is not allowed + LdapConfig.ldap_allow_empty_pass = false; + Assertions.assertThrows(AuthenticationException.class, () -> { + Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, null, null); + }); + + //test with false and null pass: login is not allowed + LdapConfig.ldap_allow_empty_pass = false; + Assertions.assertThrows(AuthenticationException.class, () -> { + Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); + }); + + //test with false and pass with space only: login is not allowed + LdapConfig.ldap_allow_empty_pass = false; + Assertions.assertThrows(AuthenticationException.class, () -> { + Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, " ", null); + }); + } + + @After + public void tearDown() { + LdapConfig.ldap_allow_empty_pass = true; // restoring default value for other tests + } + + @Before + public void setUp() { + LdapConfig.ldap_allow_empty_pass = true; //restoring default value for other tests + } +} From d1e504b56e2e44251565a005e2477ef300b92e54 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Fri, 27 Mar 2026 15:43:49 +0300 Subject: [PATCH 18/30] review: tests reworked v2 --- .../doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 4081aa87ef6645..5a17a3caa80f31 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -32,7 +32,6 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.junit.jupiter.api.Assertions; import java.io.IOException; import java.util.List; From 92c296f37e8ade44f3c5f5db618ca72d02bf57f1 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Fri, 27 Mar 2026 16:43:04 +0300 Subject: [PATCH 19/30] review: tests reworked v3 --- .../mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java index ae4531907053e3..afd46cb5f46237 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java @@ -14,6 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. + package org.apache.doris.mysql.privilege; import org.apache.doris.catalog.Env; @@ -54,7 +55,7 @@ private void setCheckPassword(boolean res) { } }; } - + @Test public void testPlainPasswordAuthWithNonEmptyPassword() throws Exception { setLdapUserExist(true); From afca8a536539dd9ea930dd58fc336110252418fe Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Fri, 27 Mar 2026 17:18:13 +0300 Subject: [PATCH 20/30] review: fixed imports v4 --- .../mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java index afd46cb5f46237..4c533085d28b86 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java @@ -18,6 +18,7 @@ package org.apache.doris.mysql.privilege; import org.apache.doris.catalog.Env; +import org.apache.doris.common.AuthenticationException; import org.apache.doris.common.LdapConfig; import org.apache.doris.mysql.authenticate.ldap.LdapManager; import org.apache.doris.utframe.TestWithFeService; From ac74562b3d994a0f656698b7efe3c6997c78c7d0 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 30 Mar 2026 10:45:57 +0300 Subject: [PATCH 21/30] review: fix tests for plain auth --- .../mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java index 4c533085d28b86..fe5fc5f4099412 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java @@ -55,6 +55,7 @@ private void setCheckPassword(boolean res) { result = res; } }; + } @Test From 2629f6b379b6165569068ec83215f4b2f86e4f3e Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 30 Mar 2026 10:48:48 +0300 Subject: [PATCH 22/30] review: fix tests for plain auth v2 --- .../mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java index fe5fc5f4099412..84e5f523a5487e 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java @@ -50,12 +50,11 @@ private void setLdapUserExist(boolean res) { private void setCheckPassword(boolean res) { new Expectations() { { - ldapManager.checkUserPasswd(anyString, anyString); + ldapManager.checkUserPasswd(anyString, anyString, anyString, null); minTimes = 0; result = res; } }; - } @Test From a65fad17305d3bbb03069ca2fd79916c3129ea50 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 30 Mar 2026 12:20:41 +0300 Subject: [PATCH 23/30] review: fix tests for plain auth v3 --- .../PlainAuthWithEmptyPasswordAndLdapTest.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java index 84e5f523a5487e..1781ff5e97750d 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java @@ -59,63 +59,68 @@ private void setCheckPassword(boolean res) { @Test public void testPlainPasswordAuthWithNonEmptyPassword() throws Exception { + System.out.println("1.0 [" + LdapConfig.ldap_allow_empty_pass + "]") setLdapUserExist(true); setCheckPassword(true); //test with true value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = true; + System.out.println("1.1 [" + LdapConfig.ldap_allow_empty_pass + "]") Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "testPass", null); //test with false value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = false; + System.out.println("1.2 [" + LdapConfig.ldap_allow_empty_pass + "]") Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "testPass", null); } @Test public void testPlainPasswordAuthWithEmptyPasswordAllowed() throws Exception { + System.out.println("2.0 [" + LdapConfig.ldap_allow_empty_pass + "]") setLdapUserExist(true); setCheckPassword(true); + System.out.println("2.1 [" + LdapConfig.ldap_allow_empty_pass + "]") //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); //test with true and empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = true; + System.out.println("2.2 [" + LdapConfig.ldap_allow_empty_pass + "]") Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); } @Test public void testPlainPasswordAuthWithEmptyPasswordProhibitted() throws Exception { + System.out.println("3.0 [" + LdapConfig.ldap_allow_empty_pass + "]") setLdapUserExist(true); setCheckPassword(true); //test with false and empty pass: login is not allowed LdapConfig.ldap_allow_empty_pass = false; + System.out.println("3.1 [" + LdapConfig.ldap_allow_empty_pass + "]") Assertions.assertThrows(AuthenticationException.class, () -> { Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, null, null); }); //test with false and null pass: login is not allowed LdapConfig.ldap_allow_empty_pass = false; + System.out.println("3.2 [" + LdapConfig.ldap_allow_empty_pass + "]") Assertions.assertThrows(AuthenticationException.class, () -> { Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); }); - - //test with false and pass with space only: login is not allowed - LdapConfig.ldap_allow_empty_pass = false; - Assertions.assertThrows(AuthenticationException.class, () -> { - Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, " ", null); - }); } @After public void tearDown() { + System.out.println("4.0 [" + LdapConfig.ldap_allow_empty_pass + "]") LdapConfig.ldap_allow_empty_pass = true; // restoring default value for other tests } @Before public void setUp() { + System.out.println("5.0 [" + LdapConfig.ldap_allow_empty_pass + "]") LdapConfig.ldap_allow_empty_pass = true; //restoring default value for other tests } } From 23634038ec56f28525a0c45ee54acb84eafe3f68 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 30 Mar 2026 12:38:27 +0300 Subject: [PATCH 24/30] review: fix tests for plain auth v4 --- ...PlainAuthWithEmptyPasswordAndLdapTest.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java index 1781ff5e97750d..e77402cb549b44 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java @@ -59,54 +59,54 @@ private void setCheckPassword(boolean res) { @Test public void testPlainPasswordAuthWithNonEmptyPassword() throws Exception { - System.out.println("1.0 [" + LdapConfig.ldap_allow_empty_pass + "]") + System.out.println("1.0 [" + LdapConfig.ldap_allow_empty_pass + "]"); setLdapUserExist(true); setCheckPassword(true); //test with true value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = true; - System.out.println("1.1 [" + LdapConfig.ldap_allow_empty_pass + "]") + System.out.println("1.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "testPass", null); //test with false value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = false; - System.out.println("1.2 [" + LdapConfig.ldap_allow_empty_pass + "]") + System.out.println("1.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "testPass", null); } @Test public void testPlainPasswordAuthWithEmptyPasswordAllowed() throws Exception { - System.out.println("2.0 [" + LdapConfig.ldap_allow_empty_pass + "]") + System.out.println("2.0 [" + LdapConfig.ldap_allow_empty_pass + "]"); setLdapUserExist(true); setCheckPassword(true); - System.out.println("2.1 [" + LdapConfig.ldap_allow_empty_pass + "]") + System.out.println("2.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); //test with true and empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = true; - System.out.println("2.2 [" + LdapConfig.ldap_allow_empty_pass + "]") + System.out.println("2.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); } @Test public void testPlainPasswordAuthWithEmptyPasswordProhibitted() throws Exception { - System.out.println("3.0 [" + LdapConfig.ldap_allow_empty_pass + "]") + System.out.println("3.0 [" + LdapConfig.ldap_allow_empty_pass + "]"); setLdapUserExist(true); setCheckPassword(true); //test with false and empty pass: login is not allowed LdapConfig.ldap_allow_empty_pass = false; - System.out.println("3.1 [" + LdapConfig.ldap_allow_empty_pass + "]") + System.out.println("3.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); Assertions.assertThrows(AuthenticationException.class, () -> { Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, null, null); }); //test with false and null pass: login is not allowed LdapConfig.ldap_allow_empty_pass = false; - System.out.println("3.2 [" + LdapConfig.ldap_allow_empty_pass + "]") + System.out.println("3.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); Assertions.assertThrows(AuthenticationException.class, () -> { Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); }); @@ -114,13 +114,13 @@ public void testPlainPasswordAuthWithEmptyPasswordProhibitted() throws Exception @After public void tearDown() { - System.out.println("4.0 [" + LdapConfig.ldap_allow_empty_pass + "]") + System.out.println("4.0 [" + LdapConfig.ldap_allow_empty_pass + "]"); LdapConfig.ldap_allow_empty_pass = true; // restoring default value for other tests } @Before public void setUp() { - System.out.println("5.0 [" + LdapConfig.ldap_allow_empty_pass + "]") + System.out.println("5.0 [" + LdapConfig.ldap_allow_empty_pass + "]"); LdapConfig.ldap_allow_empty_pass = true; //restoring default value for other tests } } From 364de1c8ab07ebb9da4af133480d5c3a23099095 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 30 Mar 2026 13:54:02 +0300 Subject: [PATCH 25/30] review: fix tests for plain auth v4 --- .../java/org/apache/doris/mysql/privilege/Auth.java | 2 ++ .../PlainAuthWithEmptyPasswordAndLdapTest.java | 13 ++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java index 5dbf4c940ff6de..c981d2aeb3bcc4 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java @@ -230,6 +230,8 @@ public void checkPlainPassword(String remoteUser, String remoteHost, String remo if (ldapManager.doesUserExist(remoteUser)) { //not allow to login in case when empty password is specified but such mode is disabled by configuration if (Strings.isNullOrEmpty(remotePasswd) && !LdapConfig.ldap_allow_empty_pass) { + LOG.info("empty pass branch was activated: for user {}, pass {}, mode {}", + remoteUser, remotePasswd, LdapConfig.ldap_allow_empty_pass); throw new AuthenticationException(ErrorCode.ERR_EMPTY_PASSWORD, remoteUser + "@" + remoteHost); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java index e77402cb549b44..a662328aa1468c 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java @@ -31,7 +31,6 @@ import org.junit.jupiter.api.Test; public class PlainAuthWithEmptyPasswordAndLdapTest extends TestWithFeService { - private static final String USER_NAME = "user"; private static final String IP = "192.168.1.1"; @Mocked @@ -66,12 +65,12 @@ public void testPlainPasswordAuthWithNonEmptyPassword() throws Exception { //test with true value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = true; System.out.println("1.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); - Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "testPass", null); + Env.getCurrentEnv().getAuth().checkPlainPassword("user1.1", IP, "testPass", null); //test with false value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = false; System.out.println("1.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); - Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "testPass", null); + Env.getCurrentEnv().getAuth().checkPlainPassword("user1.2", IP, "testPass", null); } @@ -83,12 +82,12 @@ public void testPlainPasswordAuthWithEmptyPasswordAllowed() throws Exception { System.out.println("2.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed - Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); + Env.getCurrentEnv().getAuth().checkPlainPassword("user2.1", IP, "", null); //test with true and empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = true; System.out.println("2.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); - Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); + Env.getCurrentEnv().getAuth().checkPlainPassword("user2.2", IP, "", null); } @Test @@ -101,14 +100,14 @@ public void testPlainPasswordAuthWithEmptyPasswordProhibitted() throws Exception LdapConfig.ldap_allow_empty_pass = false; System.out.println("3.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); Assertions.assertThrows(AuthenticationException.class, () -> { - Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, null, null); + Env.getCurrentEnv().getAuth().checkPlainPassword("user3.1", IP, null, null); }); //test with false and null pass: login is not allowed LdapConfig.ldap_allow_empty_pass = false; System.out.println("3.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); Assertions.assertThrows(AuthenticationException.class, () -> { - Env.getCurrentEnv().getAuth().checkPlainPassword(USER_NAME, IP, "", null); + Env.getCurrentEnv().getAuth().checkPlainPassword("user3.2", IP, "", null); }); } From 5c6340fd2f3bce836627efdac45de820ef9ca412 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 30 Mar 2026 14:12:49 +0300 Subject: [PATCH 26/30] review: fix tests for plain auth v5 --- .../src/main/java/org/apache/doris/mysql/privilege/Auth.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java index c981d2aeb3bcc4..dd8c1e0779aed8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java @@ -230,7 +230,7 @@ public void checkPlainPassword(String remoteUser, String remoteHost, String remo if (ldapManager.doesUserExist(remoteUser)) { //not allow to login in case when empty password is specified but such mode is disabled by configuration if (Strings.isNullOrEmpty(remotePasswd) && !LdapConfig.ldap_allow_empty_pass) { - LOG.info("empty pass branch was activated: for user {}, pass {}, mode {}", + LOG.info("empty pass branch was activated: for user {}, pass {}, mode {}", remoteUser, remotePasswd, LdapConfig.ldap_allow_empty_pass); throw new AuthenticationException(ErrorCode.ERR_EMPTY_PASSWORD, remoteUser + "@" + remoteHost); } From b3499d9fc4bc43b2da58121834abbbab2e2db3ea Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 30 Mar 2026 15:14:29 +0300 Subject: [PATCH 27/30] review: fix tests for plain auth v6 --- .../privilege/PlainAuthWithEmptyPasswordAndLdapTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java index a662328aa1468c..7315500ca59ba3 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java @@ -26,6 +26,7 @@ import mockit.Expectations; import mockit.Mocked; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -64,11 +65,13 @@ public void testPlainPasswordAuthWithNonEmptyPassword() throws Exception { //test with true value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = true; + Assert.assertTrue(LdapConfig.ldap_allow_empty_pass); System.out.println("1.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); Env.getCurrentEnv().getAuth().checkPlainPassword("user1.1", IP, "testPass", null); //test with false value and non-empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = false; + Assert.assertFalse(LdapConfig.ldap_allow_empty_pass); System.out.println("1.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); Env.getCurrentEnv().getAuth().checkPlainPassword("user1.2", IP, "testPass", null); } @@ -82,11 +85,13 @@ public void testPlainPasswordAuthWithEmptyPasswordAllowed() throws Exception { System.out.println("2.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed + Assert.assertTrue(LdapConfig.ldap_allow_empty_pass); Env.getCurrentEnv().getAuth().checkPlainPassword("user2.1", IP, "", null); //test with true and empty pass: login is allowed LdapConfig.ldap_allow_empty_pass = true; System.out.println("2.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); + Assert.assertTrue(LdapConfig.ldap_allow_empty_pass); Env.getCurrentEnv().getAuth().checkPlainPassword("user2.2", IP, "", null); } @@ -99,6 +104,7 @@ public void testPlainPasswordAuthWithEmptyPasswordProhibitted() throws Exception //test with false and empty pass: login is not allowed LdapConfig.ldap_allow_empty_pass = false; System.out.println("3.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); + Assert.assertFalse(LdapConfig.ldap_allow_empty_pass); Assertions.assertThrows(AuthenticationException.class, () -> { Env.getCurrentEnv().getAuth().checkPlainPassword("user3.1", IP, null, null); }); @@ -106,6 +112,7 @@ public void testPlainPasswordAuthWithEmptyPasswordProhibitted() throws Exception //test with false and null pass: login is not allowed LdapConfig.ldap_allow_empty_pass = false; System.out.println("3.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); + Assert.assertFalse(LdapConfig.ldap_allow_empty_pass); Assertions.assertThrows(AuthenticationException.class, () -> { Env.getCurrentEnv().getAuth().checkPlainPassword("user3.2", IP, "", null); }); From 994a50d1be6758cf7482d4b0e6d8110a565ef1b2 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 30 Mar 2026 16:09:04 +0300 Subject: [PATCH 28/30] review: fix tests for plain auth v7 - without mutable --- .../src/main/java/org/apache/doris/common/LdapConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java b/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java index 8ebba10313f66c..d169d93cbd5382 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java @@ -179,6 +179,6 @@ public static String getConnectionURL(String hostPortInAccessibleFormat) { /** * Flag to enable login with empty pass. */ - @ConfigBase.ConfField(mutable = true) + @ConfigBase.ConfField public static boolean ldap_allow_empty_pass = true; } From eeb5271a8b2e80046d7329775675a5893f2d1c6a Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 30 Mar 2026 17:11:35 +0300 Subject: [PATCH 29/30] review: fix tests for plain auth v7 - with mutable and junit5 --- .../org/apache/doris/common/LdapConfig.java | 2 +- .../ldap/LdapAuthenticatorTest.java | 45 ++++++++++-- ...PlainAuthWithEmptyPasswordAndLdapTest.java | 69 ++++++++----------- 3 files changed, 70 insertions(+), 46 deletions(-) diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java b/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java index d169d93cbd5382..8ebba10313f66c 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java @@ -179,6 +179,6 @@ public static String getConnectionURL(String hostPortInAccessibleFormat) { /** * Flag to enable login with empty pass. */ - @ConfigBase.ConfField + @ConfigBase.ConfField(mutable = true) public static boolean ldap_allow_empty_pass = true; } diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java index 5a17a3caa80f31..d6b41d1113cf93 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java @@ -148,21 +148,56 @@ public void testGetPasswordResolver() { } @Test - public void testEmptyPassword() throws IOException { + public void testEmptyPasswordWithAllowEmptyPassDefault() throws IOException { setCheckPassword(true); setGetUserInDoris(true); - AuthenticateRequest request = new AuthenticateRequest(USER_NAME, new ClearPassword(""), IP); //running test with non-specified value - ldap_allow_empty_pass should be true + //test with empty pass - success + AuthenticateRequest request = new AuthenticateRequest("user1.1", new ClearPassword(""), IP); + Assert.assertTrue(LdapConfig.ldap_allow_empty_pass); AuthenticateResponse response = ldapAuthenticator.authenticate(request); Assert.assertTrue(response.isSuccess()); - //running test with specified value - true - ldap_allow_empty_pass is explicitly set to true + //test with non empty pass - success + request = new AuthenticateRequest("user1.2", new ClearPassword("pass"), IP); + Assert.assertTrue(LdapConfig.ldap_allow_empty_pass); + response = ldapAuthenticator.authenticate(request); + Assert.assertTrue(response.isSuccess()); + } + + @Test + public void testEmptyPasswordWithAllowEmptyPassTrue() throws IOException { + setCheckPassword(true); + setGetUserInDoris(true); + //running test with specified value - ldap_allow_empty_pass is true LdapConfig.ldap_allow_empty_pass = true; + //test with empty pass - success + AuthenticateRequest request = new AuthenticateRequest("user2.1", new ClearPassword(""), IP); + Assert.assertTrue(LdapConfig.ldap_allow_empty_pass); + AuthenticateResponse response = ldapAuthenticator.authenticate(request); + Assert.assertTrue(response.isSuccess()); + //test with non empty pass - success + request = new AuthenticateRequest("user2.2", new ClearPassword("pass"), IP); + Assert.assertTrue(LdapConfig.ldap_allow_empty_pass); response = ldapAuthenticator.authenticate(request); Assert.assertTrue(response.isSuccess()); - //running test with specified value - false - ldap_allow_empty_pass is explicitly set to false + } + + @Test + public void testEmptyPasswordWithAllowEmptyPassFalse() throws IOException { + setCheckPassword(true); + setGetUserInDoris(true); + //running test with specified value - ldap_allow_empty_pass is false LdapConfig.ldap_allow_empty_pass = false; - response = ldapAuthenticator.authenticate(request); + //test with empty pass - failure + AuthenticateRequest request = new AuthenticateRequest("user3.1", new ClearPassword(""), IP); + Assert.assertFalse(LdapConfig.ldap_allow_empty_pass); + AuthenticateResponse response = ldapAuthenticator.authenticate(request); Assert.assertFalse(response.isSuccess()); + //test with non empty pass - success + request = new AuthenticateRequest("user3.2", new ClearPassword("pass"), IP); + Assert.assertFalse(LdapConfig.ldap_allow_empty_pass); + response = ldapAuthenticator.authenticate(request); + Assert.assertTrue(response.isSuccess()); } @After diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java index 7315500ca59ba3..f5833166a510e8 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java @@ -25,10 +25,9 @@ import mockit.Expectations; import mockit.Mocked; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class PlainAuthWithEmptyPasswordAndLdapTest extends TestWithFeService { @@ -58,73 +57,63 @@ private void setCheckPassword(boolean res) { } @Test - public void testPlainPasswordAuthWithNonEmptyPassword() throws Exception { - System.out.println("1.0 [" + LdapConfig.ldap_allow_empty_pass + "]"); + public void testPlainPasswordAuthWithAllowEmptyPassDefault() throws Exception { setLdapUserExist(true); setCheckPassword(true); - //test with true value and non-empty pass: login is allowed - LdapConfig.ldap_allow_empty_pass = true; - Assert.assertTrue(LdapConfig.ldap_allow_empty_pass); - System.out.println("1.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); - Env.getCurrentEnv().getAuth().checkPlainPassword("user1.1", IP, "testPass", null); - - //test with false value and non-empty pass: login is allowed - LdapConfig.ldap_allow_empty_pass = false; - Assert.assertFalse(LdapConfig.ldap_allow_empty_pass); - System.out.println("1.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); + //running test with non-specified value - ldap_allow_empty_pass should be true + //empty pass - success + Assertions.assertTrue(LdapConfig.ldap_allow_empty_pass); + Env.getCurrentEnv().getAuth().checkPlainPassword("user1.1", IP, "", null); + //non empty pass - success + Assertions.assertTrue(LdapConfig.ldap_allow_empty_pass); Env.getCurrentEnv().getAuth().checkPlainPassword("user1.2", IP, "testPass", null); } @Test - public void testPlainPasswordAuthWithEmptyPasswordAllowed() throws Exception { - System.out.println("2.0 [" + LdapConfig.ldap_allow_empty_pass + "]"); + public void testPlainPasswordAuthWithAllowEmptyPassTrue() throws Exception { setLdapUserExist(true); setCheckPassword(true); - System.out.println("2.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); - //test default (ldap_allow_empty_pass=true) and empty pass: login is allowed - Assert.assertTrue(LdapConfig.ldap_allow_empty_pass); + //running test with specified value - ldap_allow_empty_pass is be true + LdapConfig.ldap_allow_empty_pass = true; + + //empty pass - success + Assertions.assertTrue(LdapConfig.ldap_allow_empty_pass); Env.getCurrentEnv().getAuth().checkPlainPassword("user2.1", IP, "", null); - //test with true and empty pass: login is allowed - LdapConfig.ldap_allow_empty_pass = true; - System.out.println("2.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); - Assert.assertTrue(LdapConfig.ldap_allow_empty_pass); - Env.getCurrentEnv().getAuth().checkPlainPassword("user2.2", IP, "", null); + //non empty pass - success + Assertions.assertTrue(LdapConfig.ldap_allow_empty_pass); + Env.getCurrentEnv().getAuth().checkPlainPassword("user2.2", IP, "testPass", null); } @Test - public void testPlainPasswordAuthWithEmptyPasswordProhibitted() throws Exception { - System.out.println("3.0 [" + LdapConfig.ldap_allow_empty_pass + "]"); + public void testPlainPasswordAuthWithAllowEmptyPassFalse() throws Exception { setLdapUserExist(true); setCheckPassword(true); - //test with false and empty pass: login is not allowed + //running test with specified value - ldap_allow_empty_pass is false LdapConfig.ldap_allow_empty_pass = false; - System.out.println("3.1 [" + LdapConfig.ldap_allow_empty_pass + "]"); - Assert.assertFalse(LdapConfig.ldap_allow_empty_pass); - Assertions.assertThrows(AuthenticationException.class, () -> { - Env.getCurrentEnv().getAuth().checkPlainPassword("user3.1", IP, null, null); - }); - //test with false and null pass: login is not allowed - LdapConfig.ldap_allow_empty_pass = false; - System.out.println("3.2 [" + LdapConfig.ldap_allow_empty_pass + "]"); - Assert.assertFalse(LdapConfig.ldap_allow_empty_pass); + //empty pass - failure + Assertions.assertFalse(LdapConfig.ldap_allow_empty_pass); Assertions.assertThrows(AuthenticationException.class, () -> { - Env.getCurrentEnv().getAuth().checkPlainPassword("user3.2", IP, "", null); + Env.getCurrentEnv().getAuth().checkPlainPassword("user3.1", IP, "", null); }); + + //non empty pass - success + Assertions.assertFalse(LdapConfig.ldap_allow_empty_pass); + Env.getCurrentEnv().getAuth().checkPlainPassword("user3.2", IP, "testPass", null); } - @After + @AfterEach public void tearDown() { System.out.println("4.0 [" + LdapConfig.ldap_allow_empty_pass + "]"); LdapConfig.ldap_allow_empty_pass = true; // restoring default value for other tests } - @Before + @BeforeEach public void setUp() { System.out.println("5.0 [" + LdapConfig.ldap_allow_empty_pass + "]"); LdapConfig.ldap_allow_empty_pass = true; //restoring default value for other tests From 5f5fc352e90fb5ccf2194308e9db2f8edf0c72e2 Mon Sep 17 00:00:00 2001 From: Ivan Orekhov Date: Mon, 30 Mar 2026 17:36:32 +0300 Subject: [PATCH 30/30] review: fix tests for plain auth v8 - without spaces --- .../mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java index f5833166a510e8..6ba04ebc36d740 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/privilege/PlainAuthWithEmptyPasswordAndLdapTest.java @@ -104,7 +104,7 @@ public void testPlainPasswordAuthWithAllowEmptyPassFalse() throws Exception { //non empty pass - success Assertions.assertFalse(LdapConfig.ldap_allow_empty_pass); - Env.getCurrentEnv().getAuth().checkPlainPassword("user3.2", IP, "testPass", null); + Env.getCurrentEnv().getAuth().checkPlainPassword("user3.2", IP, "testPass", null); } @AfterEach