You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by lm...@apache.org on 2016/10/02 17:02:22 UTC
knox git commit: KNOX-644 - Limit/page results of LDAP group
membership search (Kevin Risden via lmccay)
Repository: knox
Updated Branches:
refs/heads/master 6eb64e525 -> 62a75e0e0
KNOX-644 - Limit/page results of LDAP group membership search (Kevin Risden via lmccay)
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/62a75e0e
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/62a75e0e
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/62a75e0e
Branch: refs/heads/master
Commit: 62a75e0e015ae35f27a08e156f792b6e5517fb6a
Parents: 6eb64e5
Author: Larry McCay <lm...@hortonworks.com>
Authored: Sun Oct 2 13:01:34 2016 -0400
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Sun Oct 2 13:01:34 2016 -0400
----------------------------------------------------------------------
.../ldap/BaseDirectoryServiceFactory.java | 4 +-
.../ldap/SimpleLdapDirectoryServer.java | 4 +-
.../gateway/shirorealm/KnoxLdapRealm.java | 105 +++++++++++++------
.../apache/hadoop/gateway/GatewayMessages.java | 9 ++
pom.xml | 2 +-
5 files changed, 89 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/62a75e0e/gateway-demo-ldap/src/main/java/org/apache/hadoop/gateway/security/ldap/BaseDirectoryServiceFactory.java
----------------------------------------------------------------------
diff --git a/gateway-demo-ldap/src/main/java/org/apache/hadoop/gateway/security/ldap/BaseDirectoryServiceFactory.java b/gateway-demo-ldap/src/main/java/org/apache/hadoop/gateway/security/ldap/BaseDirectoryServiceFactory.java
index dc3468d..2d2bc1f 100644
--- a/gateway-demo-ldap/src/main/java/org/apache/hadoop/gateway/security/ldap/BaseDirectoryServiceFactory.java
+++ b/gateway-demo-ldap/src/main/java/org/apache/hadoop/gateway/security/ldap/BaseDirectoryServiceFactory.java
@@ -206,7 +206,7 @@ public class BaseDirectoryServiceFactory implements DirectoryServiceFactory
directoryService.setSchemaManager( schemaManager );
// Init the LdifPartition
- LdifPartition ldifPartition = new LdifPartition( schemaManager /*, directoryService.getDnFactory()*/ );
+ LdifPartition ldifPartition = new LdifPartition( schemaManager, directoryService.getDnFactory() );
ldifPartition.setPartitionPath( new File( workingDirectory, "schema" ).toURI() );
SchemaPartition schemaPartition = new SchemaPartition( schemaManager );
schemaPartition.setWrappedPartition( ldifPartition );
@@ -235,7 +235,7 @@ public class BaseDirectoryServiceFactory implements DirectoryServiceFactory
// Inject the System Partition
Partition systemPartition = partitionFactory.createPartition(
directoryService.getSchemaManager(),
- //directoryService.getDnFactory(),
+ directoryService.getDnFactory(),
"system",
ServerDNConstants.SYSTEM_DN,
500,
http://git-wip-us.apache.org/repos/asf/knox/blob/62a75e0e/gateway-demo-ldap/src/main/java/org/apache/hadoop/gateway/security/ldap/SimpleLdapDirectoryServer.java
----------------------------------------------------------------------
diff --git a/gateway-demo-ldap/src/main/java/org/apache/hadoop/gateway/security/ldap/SimpleLdapDirectoryServer.java b/gateway-demo-ldap/src/main/java/org/apache/hadoop/gateway/security/ldap/SimpleLdapDirectoryServer.java
index efa8df8..12fe30d 100644
--- a/gateway-demo-ldap/src/main/java/org/apache/hadoop/gateway/security/ldap/SimpleLdapDirectoryServer.java
+++ b/gateway-demo-ldap/src/main/java/org/apache/hadoop/gateway/security/ldap/SimpleLdapDirectoryServer.java
@@ -57,7 +57,8 @@ public class SimpleLdapDirectoryServer {
enabledPosixSchema( service );
Partition partition = factory.getPartitionFactory().createPartition(
- service.getSchemaManager(), "users", rootDn, 500, service.getInstanceLayout().getInstanceDirectory() );
+ service.getSchemaManager(), service.getDnFactory(), "users", rootDn, 500,
+ service.getInstanceLayout().getInstanceDirectory() );
service.addPartition( partition );
CoreSession session = service.getAdminSession();
@@ -67,7 +68,6 @@ public class SimpleLdapDirectoryServer {
server = new LdapServer();
server.setTransports( transports );
server.setDirectoryService( service );
-
}
private static void enabledPosixSchema( DirectoryService service ) throws LdapException {
http://git-wip-us.apache.org/repos/asf/knox/blob/62a75e0e/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java b/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
index eb1e862..4cfc7e9 100644
--- a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
+++ b/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
@@ -19,6 +19,7 @@
package org.apache.hadoop.gateway.shirorealm;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -33,13 +34,19 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.naming.AuthenticationException;
+import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
+import javax.naming.PartialResultException;
+import javax.naming.SizeLimitExceededException;
import javax.naming.directory.Attribute;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
+import javax.naming.ldap.Control;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.LdapName;
+import javax.naming.ldap.PagedResultsControl;
+import javax.naming.ldap.PagedResultsResponseControl;
import org.apache.hadoop.gateway.GatewayMessages;
import org.apache.hadoop.gateway.audit.api.Action;
@@ -245,43 +252,81 @@ public class KnoxLdapRealm extends JndiLdapRealm {
private Set<String> rolesFor(PrincipalCollection principals, final String userName, final LdapContext ldapCtx,
final LdapContextFactory ldapContextFactory) throws NamingException {
- final Set<String> roleNames = new HashSet();
- final Set<String> groupNames = new HashSet();
- NamingEnumeration<SearchResult> searchResultEnum = null;
- try {
+ final Set<String> roleNames = new HashSet<>();
+ final Set<String> groupNames = new HashSet<>();
+
+ String userDn;
+ if (userSearchAttributeName == null || userSearchAttributeName.isEmpty()) {
+ // memberAttributeValuePrefix and memberAttributeValueSuffix were computed from memberAttributeValueTemplate
+ userDn = memberAttributeValuePrefix + userName + memberAttributeValueSuffix;
+ } else {
+ userDn = getUserDn(userName);
+ }
+
+ // Activate paged results
+ int pageSize = 100;
+ int numResults = 0;
+ byte[] cookie = null;
+ try {
+ ldapCtx.addToEnvironment(Context.REFERRAL, "ignore");
+
+ ldapCtx.setRequestControls(new Control[]{new PagedResultsControl(pageSize, Control.NONCRITICAL)});
+
+ do {
// ldapsearch -h localhost -p 33389 -D uid=guest,ou=people,dc=hadoop,dc=apache,dc=org -w guest-password
// -b dc=hadoop,dc=apache,dc=org -s sub '(objectclass=*)'
- searchResultEnum = ldapCtx.search(
- getGroupSearchBase(),
- "objectClass=" + groupObjectClass,
- SUBTREE_SCOPE);
-
- String userDn = null;
- if (userSearchAttributeName == null || userSearchAttributeName.isEmpty()) {
- // memberAttributeValuePrefix and memberAttributeValueSuffix were computed from memberAttributeValueTemplate
- userDn = memberAttributeValuePrefix + userName + memberAttributeValueSuffix;
- } else {
- userDn = getUserDn(userName);
- }
- while (searchResultEnum.hasMore()) { // searchResults contains all the groups in search scope
+
+ NamingEnumeration<SearchResult> searchResultEnum = null;
+ try {
+ searchResultEnum = ldapCtx.search(
+ getGroupSearchBase(),
+ "objectClass=" + groupObjectClass,
+ SUBTREE_SCOPE);
+
+ while (searchResultEnum != null && searchResultEnum.hasMore()) { // searchResults contains all the groups in search scope
+ numResults++;
final SearchResult group = searchResultEnum.next();
addRoleIfMember(userDn, group, roleNames, groupNames, ldapContextFactory);
+ }
+ } catch (PartialResultException e) {
+ LOG.ignoringPartialResultException();
+ } finally {
+ if (searchResultEnum != null) {
+ searchResultEnum.close();
+ }
}
- // save role names and group names in session so that they can be easily looked up outside of this object
- SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_ROLES, roleNames);
- SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_GROUPS, groupNames);
- if (!groupNames.isEmpty() && (principals instanceof MutablePrincipalCollection)) {
- ((MutablePrincipalCollection)principals).addAll(groupNames, getName());
- }
- LOG.lookedUpUserRoles(roleNames, userName);
- }
- finally {
- if (searchResultEnum != null) {
- searchResultEnum.close();
+ // Examine the paged results control response
+ Control[] controls = ldapCtx.getResponseControls();
+ if (controls != null) {
+ for (Control control : controls) {
+ if (control instanceof PagedResultsResponseControl) {
+ PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
+ cookie = prrc.getCookie();
+ }
+ }
}
- }
- return roleNames;
+
+ // Re-activate paged results
+ ldapCtx.setRequestControls(new Control[]{new PagedResultsControl(pageSize, cookie, Control.CRITICAL)});
+ } while (cookie != null);
+ } catch (SizeLimitExceededException e) {
+ LOG.sizeLimitExceededOnlyRetrieved(numResults);
+// System.out.println("Only retrieved first " + numResults + " groups due to SizeLimitExceededException.");
+ } catch(IOException e) {
+ LOG.unableToSetupPagedResults();
+// System.out.println("Unabled to setup paged results");
+ }
+
+ // save role names and group names in session so that they can be easily looked up outside of this object
+ SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_ROLES, roleNames);
+ SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_GROUPS, groupNames);
+ if (!groupNames.isEmpty() && (principals instanceof MutablePrincipalCollection)) {
+ ((MutablePrincipalCollection)principals).addAll(groupNames, getName());
+ }
+ LOG.lookedUpUserRoles(roleNames, userName);
+
+ return roleNames;
}
private void addRoleIfMember(final String userDn, final SearchResult group,
http://git-wip-us.apache.org/repos/asf/knox/blob/62a75e0e/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
index c9dc3b2..c256a65 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
@@ -412,4 +412,13 @@ public interface GatewayMessages {
@Message( level = MessageLevel.DEBUG, text = "Default topology forward from {0} to {1}" )
void defaultTopologyForward( String oldTarget, String newTarget );
+
+ @Message( level = MessageLevel.ERROR, text = "Unable to setup PagedResults" )
+ void unableToSetupPagedResults();
+
+ @Message( level = MessageLevel.INFO, text = "Ignoring PartialResultException" )
+ void ignoringPartialResultException();
+
+ @Message( level = MessageLevel.WARN, text = "Only retrieved first {0} groups due to SizeLimitExceededException." )
+ void sizeLimitExceededOnlyRetrieved(int numResults);
}
http://git-wip-us.apache.org/repos/asf/knox/blob/62a75e0e/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 50371b1..6746163 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1019,7 +1019,7 @@
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-all</artifactId>
- <version>2.0.0-M15</version>
+ <version>2.0.0-M16</version>
<exclusions>
<exclusion>
<groupId>ldapsdk</groupId>