This is an automated email from the ASF dual-hosted git repository.
remm pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new 130843d 65033: Fix JNDI realm error handling
130843d is described below
commit 130843d0126f84e4027cdb858f77c55bb54ffe3f
Author: remm <[email protected]>
AuthorDate: Tue Dec 29 09:44:41 2020 +0100
65033: Fix JNDI realm error handling
Connecting to a failed server when pooling was not enabled would cause
threads to hang in authenticate since unlocking was not done. Closing
the connection was correctly present in that case before the refactoring
that added pooling.
---
java/org/apache/catalina/realm/JNDIRealm.java | 15 ++++++++++++---
test/org/apache/catalina/realm/TestJNDIRealm.java | 21 +++++++++++++++++++++
webapps/docs/changelog.xml | 4 ++++
3 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/java/org/apache/catalina/realm/JNDIRealm.java
b/java/org/apache/catalina/realm/JNDIRealm.java
index 3d952c0..7e2d578 100644
--- a/java/org/apache/catalina/realm/JNDIRealm.java
+++ b/java/org/apache/catalina/realm/JNDIRealm.java
@@ -1301,10 +1301,11 @@ public class JNDIRealm extends RealmBase {
// Ensure that we have a directory context available
connection = get();
- // Occasionally the directory context will timeout. Try one more
- // time before giving up.
try {
+ // Occasionally the directory context will timeout. Try one
more
+ // time before giving up.
+
// Authenticate the specified username if possible
principal = authenticate(connection, username, credentials);
@@ -1350,6 +1351,10 @@ public class JNDIRealm extends RealmBase {
// Log the problem for posterity
containerLog.error(sm.getString("jndiRealm.exception"), e);
+ // close the connection so we know it will be reopened.
+ close(connection);
+ closePooledConnections();
+
// Return "not authenticated" for this request
if (containerLog.isDebugEnabled())
containerLog.debug("Returning null principal.");
@@ -2192,8 +2197,12 @@ public class JNDIRealm extends RealmBase {
protected void close(JNDIConnection connection) {
// Do nothing if there is no opened connection
- if (connection.context == null)
+ if (connection == null || connection.context == null) {
+ if (connectionPool == null) {
+ singleConnectionLock.unlock();
+ }
return;
+ }
// Close tls startResponse if used
if (tls != null) {
diff --git a/test/org/apache/catalina/realm/TestJNDIRealm.java
b/test/org/apache/catalina/realm/TestJNDIRealm.java
index 00180e1..62a7495 100644
--- a/test/org/apache/catalina/realm/TestJNDIRealm.java
+++ b/test/org/apache/catalina/realm/TestJNDIRealm.java
@@ -112,6 +112,27 @@ public class TestJNDIRealm {
Assert.assertEquals(ha1(),
((GenericPrincipal)principal).getPassword());
}
+ volatile int count = 0;
+
+ @Test
+ public void testErrorRealm() throws Exception {
+ Context context = new TesterContext();
+ JNDIRealm realm = new JNDIRealm();
+ realm.setContainer(context);
+ realm.setUserSearch("");
+ // Connect to something that will fail
+ realm.setConnectionURL("ldap://127.0.0.1:12345");
+ realm.start();
+
+ count = 0;
+ (new Thread(() -> { realm.authenticate("foo", "bar"); count++;
})).start();
+ (new Thread(() -> { realm.authenticate("foo", "bar"); count++;
})).start();
+ (new Thread(() -> { realm.authenticate("foo", "bar"); count++;
})).start();
+ Thread.sleep(10);
+
+ Assert.assertEquals(3, count);
+ }
+
private JNDIRealm buildRealm(String password) throws
javax.naming.NamingException,
NoSuchFieldException, IllegalAccessException, LifecycleException {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index da0a0d0..6fed570 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -142,6 +142,10 @@
Avoid uncaught InaccessibleObjectException on Java 16 trying to clear
references threads. (remm)
</fix>
+ <fix>
+ <bug>65033</bug>: Fix JNDI realm error handling when connecting to a
+ failed server when pooling was not enabled. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]