This is an automated email from the ASF dual-hosted git repository.

jbertram pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/master by this push:
     new d7d11a0  ARTEMIS-2535 Add ignorePartialResultException option to 
LDAPLoginModule
     new c881158  This closes #2879
d7d11a0 is described below

commit d7d11a0c6f9880e3327f067598a66fbf628a7150
Author: Joshua Smith <[email protected]>
AuthorDate: Tue Oct 29 16:27:57 2019 -0700

    ARTEMIS-2535 Add ignorePartialResultException option to LDAPLoginModule
    
    Active Directory servers are unable to handle referrals automatically.
    This causes a PartialResultException to be thrown if a referral is
    encountered beneath the base search DN, even if the LDAPLoginModule is
    set to ignore referrals.
    
    This option may be set to 'true' to ignore these exceptions, allowing
    login to proceed with the query results received before the exception
    was encountered.
    
    Note: there are no tests for this change as I could not reproduce the
    issue with the ApacheDS test server. The issue is specific to directory
    servers that don't support the ManageDsaIT control such as Active
    Directory.
---
 .../spi/core/security/jaas/LDAPLoginModule.java    | 64 +++++++++++++++++-----
 docs/user-manual/en/security.md                    |  6 ++
 2 files changed, 55 insertions(+), 15 deletions(-)

diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java
index b56fde8..ed9b8ba 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java
@@ -23,6 +23,7 @@ import javax.naming.Name;
 import javax.naming.NameParser;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
+import javax.naming.PartialResultException;
 import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
 import javax.naming.directory.DirContext;
@@ -84,6 +85,7 @@ public class LDAPLoginModule implements LoginModule {
    private static final String SASL_LOGIN_CONFIG_SCOPE = 
"saslLoginConfigScope";
    private static final String AUTHENTICATE_USER = "authenticateUser";
    private static final String REFERRAL = "referral";
+   private static final String IGNORE_PARTIAL_RESULT_EXCEPTION = 
"ignorePartialResultException";
    private static final String PASSWORD_CODEC = "passwordCodec";
    private static final String CONNECTION_POOL = "connectionPool";
    private static final String CONNECTION_TIMEOUT = "connectionTimeout";
@@ -131,6 +133,7 @@ public class LDAPLoginModule implements LoginModule {
                                        new 
LDAPLoginProperty(SASL_LOGIN_CONFIG_SCOPE, (String) 
options.get(SASL_LOGIN_CONFIG_SCOPE)),
                                        new 
LDAPLoginProperty(AUTHENTICATE_USER, (String) options.get(AUTHENTICATE_USER)),
                                        new LDAPLoginProperty(REFERRAL, 
(String) options.get(REFERRAL)),
+                                       new 
LDAPLoginProperty(IGNORE_PARTIAL_RESULT_EXCEPTION, (String) 
options.get(IGNORE_PARTIAL_RESULT_EXCEPTION)),
                                        new LDAPLoginProperty(CONNECTION_POOL, 
(String) options.get(CONNECTION_POOL)),
                                        new 
LDAPLoginProperty(CONNECTION_TIMEOUT, (String) 
options.get(CONNECTION_TIMEOUT))};
 
@@ -296,6 +299,7 @@ public class LDAPLoginModule implements LoginModule {
 
       MessageFormat userSearchMatchingFormat;
       boolean userSearchSubtreeBool;
+      boolean ignorePartialResultExceptionBool;
 
       if (logger.isDebugEnabled()) {
          logger.debug("Create the LDAP initial context.");
@@ -314,6 +318,7 @@ public class LDAPLoginModule implements LoginModule {
 
       userSearchMatchingFormat = new 
MessageFormat(getLDAPPropertyValue(USER_SEARCH_MATCHING));
       userSearchSubtreeBool = 
Boolean.valueOf(getLDAPPropertyValue(USER_SEARCH_SUBTREE)).booleanValue();
+      ignorePartialResultExceptionBool = 
Boolean.valueOf(getLDAPPropertyValue(IGNORE_PARTIAL_RESULT_EXCEPTION)).booleanValue();
 
       try {
 
@@ -357,8 +362,17 @@ public class LDAPLoginModule implements LoginModule {
 
          SearchResult result = results.next();
 
-         if (results.hasMore()) {
-            // ignore for now
+         try {
+            if (results.hasMore()) {
+               // ignore for now
+            }
+         } catch (PartialResultException e) {
+            // Workaround for AD servers not handling referrals correctly.
+            if (ignorePartialResultExceptionBool) {
+               logger.debug("PartialResultException encountered and ignored", 
e);
+            } else {
+               throw e;
+            }
          }
 
          if (result.isRelative()) {
@@ -447,9 +461,11 @@ public class LDAPLoginModule implements LoginModule {
       MessageFormat roleSearchMatchingFormat;
       boolean roleSearchSubtreeBool;
       boolean expandRolesBool;
+      boolean ignorePartialResultExceptionBool;
       roleSearchMatchingFormat = new 
MessageFormat(getLDAPPropertyValue(ROLE_SEARCH_MATCHING));
       roleSearchSubtreeBool = 
Boolean.valueOf(getLDAPPropertyValue(ROLE_SEARCH_SUBTREE)).booleanValue();
       expandRolesBool = 
Boolean.valueOf(getLDAPPropertyValue(EXPAND_ROLES)).booleanValue();
+      ignorePartialResultExceptionBool = 
Boolean.valueOf(getLDAPPropertyValue(IGNORE_PARTIAL_RESULT_EXCEPTION)).booleanValue();
 
       final String filter = roleSearchMatchingFormat.format(new 
String[]{doRFC2254Encoding(dn), doRFC2254Encoding(username)});
 
@@ -477,13 +493,22 @@ public class LDAPLoginModule implements LoginModule {
          throw ex;
       }
 
-      while (results.hasMore()) {
-         SearchResult result = results.next();
-         if (expandRolesBool) {
-            haveSeenNames.add(result.getNameInNamespace());
-            pendingNameExpansion.add(result.getNameInNamespace());
+      try {
+         while (results.hasMore()) {
+            SearchResult result = results.next();
+            if (expandRolesBool) {
+               haveSeenNames.add(result.getNameInNamespace());
+               pendingNameExpansion.add(result.getNameInNamespace());
+            }
+            addRoleAttribute(result, currentRoles);
+         }
+      } catch (PartialResultException e) {
+         // Workaround for AD servers not handling referrals correctly.
+         if (ignorePartialResultExceptionBool) {
+            logger.debug("PartialResultException encountered and ignored", e);
+         } else {
+            throw e;
          }
-         addRoleAttribute(result, currentRoles);
       }
       if (expandRolesBool) {
          MessageFormat expandRolesMatchingFormat = new 
MessageFormat(getLDAPPropertyValue(EXPAND_ROLES_MATCHING));
@@ -504,13 +529,22 @@ public class LDAPLoginModule implements LoginModule {
                ex.initCause(cause);
                throw ex;
             }
-            while (results.hasMore()) {
-               SearchResult result = results.next();
-               name = result.getNameInNamespace();
-               if (!haveSeenNames.contains(name)) {
-                  addRoleAttribute(result, currentRoles);
-                  haveSeenNames.add(name);
-                  pendingNameExpansion.add(name);
+            try {
+               while (results.hasMore()) {
+                  SearchResult result = results.next();
+                  name = result.getNameInNamespace();
+                  if (!haveSeenNames.contains(name)) {
+                     addRoleAttribute(result, currentRoles);
+                     haveSeenNames.add(name);
+                     pendingNameExpansion.add(name);
+                  }
+               }
+            } catch (PartialResultException e) {
+               // Workaround for AD servers not handling referrals correctly.
+               if (ignorePartialResultExceptionBool) {
+                  logger.debug("PartialResultException encountered and 
ignored", e);
+               } else {
+                  throw e;
                }
             }
          }
diff --git a/docs/user-manual/en/security.md b/docs/user-manual/en/security.md
index 063fc28..140fdc8 100644
--- a/docs/user-manual/en/security.md
+++ b/docs/user-manual/en/security.md
@@ -708,6 +708,12 @@ system. It is implemented by
 
 - `referral` - specify how to handle referrals; valid values: `ignore`,
   `follow`, `throw`; default is `ignore`.
+  
+- `ignorePartialResultException` - boolean flag for use when searching Active
+  Directory (AD). AD servers don't handle referrals automatically, which 
causes 
+  a `PartialResultException` to be thrown when referrals are encountered by a 
+  search, even if `referral` is set to `ignore`. Set to `true` to ignore these 
+  exceptions; default is `false`.
 
 - `expandRoles` - boolean indicating whether to enable the role expansion
   functionality or not; default false. If enabled, then roles within roles will

Reply via email to