You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by sm...@apache.org on 2016/04/04 04:52:04 UTC
[1/2] directory-fortress-core git commit: rename to LdapDataProvider
Repository: directory-fortress-core
Updated Branches:
refs/heads/master 5bb8ae34a -> a5dc68e15
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/ldap/LdapDataProvider.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/LdapDataProvider.java b/src/main/java/org/apache/directory/fortress/core/ldap/LdapDataProvider.java
new file mode 100644
index 0000000..35da4f9
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/LdapDataProvider.java
@@ -0,0 +1,1641 @@
+/*
+ * 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.directory.fortress.core.ldap;
+
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.pool.PoolableObjectFactory;
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.apache.directory.api.ldap.codec.api.LdapApiService;
+import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
+import org.apache.directory.api.ldap.codec.standalone.StandaloneLdapApiService;
+import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicy;
+import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyImpl;
+import org.apache.directory.api.ldap.extras.controls.ppolicy_impl.PasswordPolicyDecorator;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.cursor.CursorException;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
+import org.apache.directory.api.ldap.model.entry.DefaultModification;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Modification;
+import org.apache.directory.api.ldap.model.entry.ModificationOperation;
+import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
+import org.apache.directory.api.ldap.model.exception.LdapOperationErrorException;
+import org.apache.directory.api.ldap.model.message.BindRequest;
+import org.apache.directory.api.ldap.model.message.BindRequestImpl;
+import org.apache.directory.api.ldap.model.message.BindResponse;
+import org.apache.directory.api.ldap.model.message.CompareRequest;
+import org.apache.directory.api.ldap.model.message.CompareRequestImpl;
+import org.apache.directory.api.ldap.model.message.CompareResponse;
+import org.apache.directory.api.ldap.model.message.Control;
+import org.apache.directory.api.ldap.model.message.Response;
+import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.message.controls.ProxiedAuthz;
+import org.apache.directory.api.ldap.model.message.controls.ProxiedAuthzImpl;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.fortress.core.CfgRuntimeException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.model.Constraint;
+import org.apache.directory.fortress.core.model.ConstraintUtil;
+import org.apache.directory.fortress.core.model.FortEntity;
+import org.apache.directory.fortress.core.model.Hier;
+import org.apache.directory.fortress.core.model.Relationship;
+import org.apache.directory.fortress.core.util.Config;
+import org.apache.directory.fortress.core.util.crypto.EncryptUtil;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapConnectionPool;
+import org.apache.directory.ldap.client.api.ValidatingPoolableLdapConnectionFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Abstract class contains methods to perform low-level entity to ldap persistence. These methods are called by the
+ * Fortress DAO's, i.e. {@link org.apache.directory.fortress.core.impl.UserDAO}. {@link org.apache.directory.fortress.core.impl.RoleDAO},
+ * {@link org.apache.directory.fortress.core.impl.PermDAO}, ....
+ * These are low-level data utilities, very little if any data validations are performed here.
+ * <p>
+ * This class is thread safe.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public abstract class LdapDataProvider
+{
+ // Logging
+ private static final String CLS_NM = LdapDataProvider.class.getName();
+ private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+ private static final int MAX_DEPTH = 100;
+ private static final LdapCounters COUNTERS = new LdapCounters();
+
+ // Used for slapd access log {@link org.apache.directory.fortress.core.rbacAuditDAO}
+ private static final String LDAP_LOG_POOL_UID = "log.admin.user";
+ private static final String LDAP_LOG_POOL_PW = "log.admin.pw";
+ private static final String LDAP_LOG_POOL_MIN = "min.log.conn";
+ private static final String LDAP_LOG_POOL_MAX = "max.log.conn";
+
+ private static final String ENABLE_LDAP_STARTTLS = "enable.ldap.starttls";
+
+ private static final boolean IS_SSL = (
+ Config.getProperty( GlobalIds.ENABLE_LDAP_SSL ) != null &&
+ Config.getProperty( GlobalIds.ENABLE_LDAP_SSL ).equalsIgnoreCase( "true" ) &&
+ Config.getProperty( GlobalIds.TRUST_STORE ) != null &&
+ Config.getProperty( GlobalIds.TRUST_STORE_PW ) != null );
+
+ private static final boolean IS_SET_TRUST_STORE_PROP = (
+ IS_SSL &&
+ Config.getProperty( GlobalIds.SET_TRUST_STORE_PROP ) != null &&
+ Config.getProperty( GlobalIds.SET_TRUST_STORE_PROP ).equalsIgnoreCase( "true" ) );
+
+ private static final boolean IS_SSL_DEBUG = ( ( Config.getProperty( GlobalIds.ENABLE_LDAP_SSL_DEBUG ) != null ) && ( Config
+ .getProperty( GlobalIds.ENABLE_LDAP_SSL_DEBUG ).equalsIgnoreCase( "true" ) ) );
+
+ /**
+ * The Admin connection pool
+ */
+ private static LdapConnectionPool adminPool;
+
+ /**
+ * The Log connection pool
+ */
+ private static LdapConnectionPool logPool;
+
+ /**
+ * The User connection pool
+ */
+ private static LdapConnectionPool userPool;
+
+ private static final PasswordPolicy PP_REQ_CTRL = new PasswordPolicyImpl();
+
+ private static final char[] LDAP_META_CHARS = loadLdapEscapeChars();
+ private static final String[] LDAP_REPL_VALS = loadValidLdapVals();
+
+ static
+ {
+ String host = Config.getProperty( GlobalIds.LDAP_HOST, "localhost" );
+ int port = Config.getInt( GlobalIds.LDAP_PORT, 389 );
+ int min = Config.getInt( GlobalIds.LDAP_ADMIN_POOL_MIN, 1 );
+ int max = Config.getInt( GlobalIds.LDAP_ADMIN_POOL_MAX, 10 );
+ int logmin = Config.getInt( LDAP_LOG_POOL_MIN, 1 );
+ int logmax = Config.getInt( LDAP_LOG_POOL_MAX, 10 );
+ LOG.info( "LDAP POOL: host=[{}], port=[{}], min=[{}], max=[{}]", host, port, min, max );
+
+ if ( IS_SET_TRUST_STORE_PROP )
+ {
+ LOG.info( "Set JSSE truststore properties in Apache LDAP client:" );
+ LOG.info( "javax.net.ssl.trustStore: {}", Config.getProperty( GlobalIds.TRUST_STORE ) );
+ LOG.info( "javax.net.debug: {}", IS_SSL_DEBUG );
+ System.setProperty( "javax.net.ssl.trustStore", Config.getProperty( GlobalIds.TRUST_STORE ) );
+ System.setProperty( "javax.net.ssl.trustStorePassword", Config.getProperty( GlobalIds.TRUST_STORE_PW ) );
+ System.setProperty( "javax.net.debug", Boolean.valueOf( IS_SSL_DEBUG ).toString() );
+ }
+
+ LdapConnectionConfig config = new LdapConnectionConfig();
+ config.setLdapHost( host );
+ config.setLdapPort( port );
+ config.setName( Config.getProperty( GlobalIds.LDAP_ADMIN_POOL_UID, "" ) );
+
+ config.setUseSsl( IS_SSL );
+ //config.setTrustManagers( new NoVerificationTrustManager() );
+
+ if(Config.getBoolean(ENABLE_LDAP_STARTTLS, false)){
+ config.setUseTls(true);
+ }
+
+ if ( IS_SSL && StringUtils.isNotEmpty( Config.getProperty( GlobalIds.TRUST_STORE ) )
+ && StringUtils.isNotEmpty( Config.getProperty( GlobalIds.TRUST_STORE_PW ) ) )
+ {
+ // validate certificates but allow self-signed certs if within this truststore:
+ config.setTrustManagers( new LdapClientTrustStoreManager( Config.getProperty( GlobalIds.TRUST_STORE ), Config.getProperty( GlobalIds.TRUST_STORE_PW )
+ .toCharArray(), null,
+ true ) );
+ }
+
+ String adminPw;
+ if ( EncryptUtil.isEnabled() )
+ {
+ adminPw = EncryptUtil.decrypt( Config.getProperty( GlobalIds.LDAP_ADMIN_POOL_PW ) );
+ }
+ else
+ {
+ adminPw = Config.getProperty( GlobalIds.LDAP_ADMIN_POOL_PW );
+ }
+
+ config.setCredentials( adminPw );
+ try
+ {
+ List<String> listExOps = new ArrayList<>();
+ listExOps.add( "org.openldap.accelerator.impl.createSession.RbacCreateSessionFactory" );
+ listExOps.add( "org.openldap.accelerator.impl.checkAccess.RbacCheckAccessFactory" );
+ listExOps.add( "org.openldap.accelerator.impl.addRole.RbacAddRoleFactory" );
+ listExOps.add( "org.openldap.accelerator.impl.dropRole.RbacDropRoleFactory" );
+ listExOps.add( "org.openldap.accelerator.impl.deleteSession.RbacDeleteSessionFactory" );
+ listExOps.add( "org.openldap.accelerator.impl.sessionRoles.RbacSessionRolesFactory" );
+ LdapApiService ldapApiService = new StandaloneLdapApiService( new ArrayList<String>(), listExOps );
+
+ if ( !LdapApiServiceFactory.isInitialized() )
+ {
+ LdapApiServiceFactory.initialize( ldapApiService );
+ }
+ config.setLdapApiService( ldapApiService );
+ }
+ catch ( Exception ex )
+ {
+ String error = "Exception caught initializing Admin Pool: " + ex;
+ throw new CfgRuntimeException( GlobalErrIds.FT_APACHE_LDAP_POOL_INIT_FAILED, error, ex );
+ }
+
+ PoolableObjectFactory<LdapConnection> poolFactory = new ValidatingPoolableLdapConnectionFactory( config );
+
+ // Create the Admin pool
+ adminPool = new LdapConnectionPool( poolFactory );
+ adminPool.setTestOnBorrow( true );
+ adminPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
+ adminPool.setMaxActive( max );
+ adminPool.setMinIdle( min );
+ adminPool.setMaxIdle( -1 );
+ //adminPool.setMaxWait( 0 );
+
+ // Create the User pool
+ userPool = new LdapConnectionPool( poolFactory );
+ userPool.setTestOnBorrow( true );
+ userPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
+ userPool.setMaxActive( max );
+ userPool.setMinIdle( min );
+ userPool.setMaxIdle( -1 );
+
+ // This pool of access log connections is used by {@link org.apache.directory.fortress.AuditMgr}.
+ // To enable, set {@code log.admin.user} && {@code log.admin.pw} inside fortress.properties file:
+ if ( StringUtils.isNotEmpty( LDAP_LOG_POOL_UID ) && StringUtils.isNotEmpty( LDAP_LOG_POOL_PW ) )
+ {
+ // Initializing the log pool in static block requires static props set within fortress.properties.
+ // To make this dynamic requires moving this code outside of static block AND storing the connection metadata inside fortress config node (in ldap).
+ LdapConnectionConfig logConfig = new LdapConnectionConfig();
+ logConfig.setLdapHost( host );
+ logConfig.setLdapPort( port );
+ logConfig.setName( Config.getProperty( GlobalIds.LDAP_ADMIN_POOL_UID, "" ) );
+
+ logConfig.setUseSsl( IS_SSL );
+
+ if ( IS_SSL && StringUtils.isNotEmpty( Config.getProperty( GlobalIds.TRUST_STORE ) )
+ && StringUtils.isNotEmpty( Config.getProperty( GlobalIds.TRUST_STORE_PW ) ) )
+ {
+ // validate certificates but allow self-signed certs if within this truststore:
+ logConfig.setTrustManagers( new LdapClientTrustStoreManager( Config.getProperty( GlobalIds.TRUST_STORE ),
+ Config.getProperty( GlobalIds.TRUST_STORE_PW ).toCharArray(),
+ null, true ) );
+ }
+
+ logConfig.setName( Config.getProperty( LDAP_LOG_POOL_UID, "" ) );
+ String logPw;
+ if ( EncryptUtil.isEnabled() )
+ {
+ logPw = EncryptUtil.decrypt( Config.getProperty( LDAP_LOG_POOL_PW ) );
+ }
+ else
+ {
+ logPw = Config.getProperty( LDAP_LOG_POOL_PW );
+ }
+ logConfig.setCredentials( logPw );
+ poolFactory = new ValidatingPoolableLdapConnectionFactory( logConfig );
+ logPool = new LdapConnectionPool( poolFactory );
+ logPool.setTestOnBorrow( true );
+ logPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
+ logPool.setMaxActive( logmax );
+ logPool.setMinIdle( logmin );
+ }
+ }
+
+
+ /**
+ * Given a contextId and a fortress param name return the LDAP dn.
+ *
+ * @param contextId is to determine what sub-tree to use.
+ * @param root contains the fortress parameter name that corresponds with a particular LDAP container.
+ * @return String contains the dn to use for operation.
+ */
+ protected String getRootDn( String contextId, String root )
+ {
+ String szDn = Config.getProperty( root );
+
+ // The contextId must not be null, or "HOME" or "null"
+ if ( StringUtils.isNotEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL ) && !contextId
+ .equals( GlobalIds.HOME ) )
+ {
+ int idx = szDn.indexOf( Config.getProperty( GlobalIds.SUFFIX ) );
+ if ( idx > 0 )
+ {
+ // Found. The DN is ,ou=<contextId>,
+ StringBuilder dn = new StringBuilder();
+ dn.append( szDn.substring( 0, idx - 1 ) ).append( "," ).append( SchemaConstants.OU_AT ).append( "=" )
+ .append(
+ contextId ).append( "," ).append( szDn.substring( idx ) );
+
+ return dn.toString();
+ }
+ else
+ {
+ return "";
+ }
+ }
+ else
+ {
+ return szDn;
+ }
+ }
+
+
+ /**
+ * Given a contextId return the LDAP dn that includes the suffix.
+ *
+ * @param contextId is to determine what sub-tree to use.
+ * @return String contains the dn to use for operation.
+ */
+ protected String getRootDn( String contextId )
+ {
+ StringBuilder dn = new StringBuilder();
+ if ( StringUtils.isNotEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL ) && !contextId
+ .equals( GlobalIds.HOME ) )
+ {
+ dn.append( SchemaConstants.OU_AT ).append( "=" ).append( contextId ).append( "," +
+ "" ).append( Config.getProperty( GlobalIds.SUFFIX ) );
+ }
+ else
+ {
+ dn.append( Config.getProperty( GlobalIds.SUFFIX ) );
+ }
+ return dn.toString();
+ }
+
+
+ /**
+ * Read the ldap record from specified location.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains ldap distinguished name.
+ * @param attrs array contains array names to pull back.
+ * @return ldap entry.
+ * @throws LdapException in the event system error occurs.
+ */
+ protected Entry read( LdapConnection connection, String dn, String[] attrs ) throws LdapException
+ {
+ COUNTERS.incrementRead();
+
+ return connection.lookup( dn, attrs );
+ }
+
+
+ /**
+ * Read the ldap record from specified location.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains ldap distinguished name.
+ * @param attrs array contains array names to pull back.
+ * @return ldap entry.
+ * @throws LdapException in the event system error occurs.
+ */
+ protected Entry read( LdapConnection connection, Dn dn, String[] attrs ) throws LdapException
+ {
+ COUNTERS.incrementRead();
+
+ return connection.lookup( dn, attrs );
+ }
+
+
+ /**
+ * Read the ldap record from specified location with user assertion.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains ldap distinguished name.
+ * @param attrs array contains array names to pull back. ,
+ * PoolMgr.ConnType.USER
+ * @param userDn string value represents the identity of user on who's behalf the request was initiated. The
+ * value will be stored in openldap auditsearch record AuthZID's attribute.
+ * @return ldap entry.
+ * @throws LdapException in the event system error occurs.
+ * @throws UnsupportedEncodingException for search control errors.
+ */
+ protected Entry read( LdapConnection connection, String dn, String[] attrs, String userDn ) throws LdapException
+ {
+ COUNTERS.incrementRead();
+
+ return connection.lookup( dn, attrs );
+ }
+
+
+ /**
+ * Add a new ldap entry to the directory. Do not add audit context.
+ *
+ * @param connection handle to ldap connection.
+ * @param entry contains data to add..
+ * @throws LdapException in the event system error occurs.
+ */
+ protected void add( LdapConnection connection, Entry entry ) throws LdapException
+ {
+ COUNTERS.incrementAdd();
+ connection.add( entry );
+ }
+
+
+ /**
+ * Add a new ldap entry to the directory. Add audit context.
+ *
+ * @param connection handle to ldap connection.
+ * @param entry contains data to add..
+ * @param entity contains audit context.
+ * @throws LdapException in the event system error occurs.
+ */
+ protected void add( LdapConnection connection, Entry entry, FortEntity entity ) throws LdapException
+ {
+ COUNTERS.incrementAdd();
+
+ if ( !GlobalIds.IS_AUDIT_DISABLED && ( entity != null ) && ( entity.getAdminSession() != null ) )
+ {
+ if ( StringUtils.isNotEmpty( entity.getAdminSession().getInternalUserId() ) )
+ {
+ entry.add( GlobalIds.FT_MODIFIER, entity.getAdminSession().getInternalUserId() );
+ }
+
+ if ( StringUtils.isNotEmpty( entity.getModCode() ) )
+ {
+ entry.add( GlobalIds.FT_MODIFIER_CODE, entity.getModCode() );
+ }
+
+ if ( StringUtils.isNotEmpty( entity.getModId() ) )
+ {
+ entry.add( GlobalIds.FT_MODIFIER_ID, entity.getModId() );
+ }
+ }
+
+ connection.add( entry );
+ }
+
+
+ /**
+ * Update exiting ldap entry to the directory. Do not add audit context.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains distinguished node of entry.
+ * @param mods contains data to modify.
+ * @throws LdapException in the event system error occurs.
+ */
+ protected void modify( LdapConnection connection, String dn, List<Modification> mods ) throws LdapException
+ {
+ COUNTERS.incrementMod();
+ connection.modify( dn, mods.toArray( new Modification[]
+ {} ) );
+ }
+
+
+ /**
+ * Update exiting ldap entry to the directory. Do not add audit context.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains distinguished node of entry.
+ * @param mods contains data to modify.
+ * @throws LdapException in the event system error occurs.
+ */
+ protected void modify( LdapConnection connection, Dn dn, List<Modification> mods ) throws LdapException
+ {
+ COUNTERS.incrementMod();
+ connection.modify( dn, mods.toArray( new Modification[]
+ {} ) );
+ }
+
+
+ /**
+ * Update exiting ldap entry to the directory. Add audit context.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains distinguished node of entry.
+ * @param mods contains data to modify.
+ * @param entity contains audit context.
+ * @throws LdapException in the event system error occurs.
+ */
+ protected void modify( LdapConnection connection, String dn, List<Modification> mods,
+ FortEntity entity ) throws LdapException
+ {
+ COUNTERS.incrementMod();
+ audit( mods, entity );
+ connection.modify( dn, mods.toArray( new Modification[]
+ {} ) );
+ }
+
+
+ /**
+ * Update exiting ldap entry to the directory. Add audit context.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains distinguished node of entry.
+ * @param mods contains data to modify.
+ * @param entity contains audit context.
+ * @throws LdapException in the event system error occurs.
+ */
+ protected void modify( LdapConnection connection, Dn dn, List<Modification> mods,
+ FortEntity entity ) throws LdapException
+ {
+ COUNTERS.incrementMod();
+ audit( mods, entity );
+ connection.modify( dn, mods.toArray( new Modification[]
+ {} ) );
+ }
+
+
+ /**
+ * Delete exiting ldap entry from the directory. Do not add audit context.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains distinguished node of entry targeted for removal..
+ * @throws LdapException in the event system error occurs.
+ */
+ protected void delete( LdapConnection connection, String dn ) throws LdapException
+ {
+ COUNTERS.incrementDelete();
+ connection.delete( dn );
+ }
+
+
+ /**
+ * Delete exiting ldap entry from the directory. Add audit context. This method will call modify prior to
+ * delete which will
+ * force corresponding audit record to be written to slapd access log.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains distinguished node of entry targeted for removal..
+ * @param entity contains audit context.
+ * @throws LdapException in the event system error occurs.
+ */
+ protected void delete( LdapConnection connection, String dn, FortEntity entity ) throws LdapException
+ {
+ COUNTERS.incrementDelete();
+ List<Modification> mods = new ArrayList<Modification>();
+ audit( mods, entity );
+
+ if ( mods.size() > 0 )
+ {
+ modify( connection, dn, mods );
+ }
+
+ connection.delete( dn );
+ }
+
+
+ /**
+ * Delete exiting ldap entry from the directory. Add audit context. This method will call modify prior to
+ * delete which will
+ * force corresponding audit record to be written to slapd access log.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains distinguished node of entry targeted for removal..
+ * @param entity contains audit context.
+ * @throws LdapException in the event system error occurs.
+ */
+ protected void delete( LdapConnection connection, Dn dn, FortEntity entity ) throws LdapException
+ {
+ COUNTERS.incrementDelete();
+ List<Modification> mods = new ArrayList<Modification>();
+ audit( mods, entity );
+
+ if ( mods.size() > 0 )
+ {
+ modify( connection, dn, mods );
+ }
+
+ connection.delete( dn );
+ }
+
+
+ /**
+ * Delete exiting ldap entry and all descendants from the directory. Do not add audit context.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains distinguished node of entry targeted for removal..
+ * @throws LdapException in the event system error occurs.
+ * @throws IOException
+ * @throws CursorException
+ */
+ protected void deleteRecursive( LdapConnection connection, String dn ) throws LdapException, CursorException
+ {
+ int recursiveCount = 0;
+ deleteRecursive( dn, connection, recursiveCount );
+ }
+
+
+ /**
+ * Delete exiting ldap entry and all descendants from the directory. Add audit context. This method will call
+ * modify prior to delete which will
+ * force corresponding audit record to be written to slapd access log.
+ *
+ * @param connection handle to ldap connection.
+ * @param dn contains distinguished node of entry targeted for removal..
+ * @param entity contains audit context.
+ * @throws LdapException in the event system error occurs.
+ * @throws CursorException
+ */
+ protected void deleteRecursive( LdapConnection connection, String dn, FortEntity entity ) throws LdapException,
+ CursorException
+ {
+ List<Modification> mods = new ArrayList<Modification>();
+ audit( mods, entity );
+
+ if ( mods.size() > 0 )
+ {
+ modify( connection, dn, mods );
+ }
+
+ deleteRecursive( connection, dn );
+ }
+
+
+ /**
+ * Used to recursively remove all nodes up to record pointed to by dn attribute.
+ *
+ * @param dn contains distinguished node of entry targeted for removal..
+ * @param connection handle to ldap connection.
+ * @param recursiveCount keeps track of how many iterations have been performed.
+ * @throws LdapException in the event system error occurs.
+ * @throws CursorException
+ */
+ private void deleteRecursive( String dn, LdapConnection connection, int recursiveCount ) throws LdapException,
+ CursorException
+ {
+ String method = "deleteRecursive";
+
+ // Sanity check - only allow max tree depth of 100
+ if ( recursiveCount++ > MAX_DEPTH )
+ {
+ // too deep inside of a recursive sequence;
+ String error = "." + method + " dn [" + dn + "] depth error in recursive";
+ throw new LdapOperationErrorException( error );
+ }
+
+ String theDN;
+
+ // Find child nodes
+ SearchCursor cursor = search( connection, dn, SearchScope.ONELEVEL, "(objectclass=*)",
+ SchemaConstants.NO_ATTRIBUTE_ARRAY,
+ false, 0 );
+
+ // Iterate over all entries under this entry
+ while ( cursor.next() )
+ {
+ try
+ {
+ // Next directory entry
+ Entry entry = cursor.getEntry();
+ theDN = entry.getDn().getName();
+ // continue down:
+ deleteRecursive( theDN, connection, recursiveCount );
+ recursiveCount--;
+ }
+ catch ( LdapException le )
+ {
+ // cannot continue;
+ String error = "." + method + " dn [" + dn + "] caught LdapException=" + le.getMessage();
+ throw new LdapException( error );
+ }
+ }
+
+ // delete the node:
+ COUNTERS.incrementDelete();
+ delete( connection, dn );
+ }
+
+
+ /**
+ * Add the audit context variables to the modfication set.
+ *
+ * @param mods used to update ldap attributes.
+ * @param entity contains audit context.
+ */
+ private void audit( List<Modification> mods, FortEntity entity )
+ {
+ if ( !GlobalIds.IS_AUDIT_DISABLED && ( entity != null ) && ( entity.getAdminSession() != null ) )
+ {
+ if ( StringUtils.isNotEmpty( entity.getAdminSession().getInternalUserId() ) )
+ {
+ Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
+ GlobalIds.FT_MODIFIER, entity.getAdminSession().getInternalUserId() );
+ mods.add( modification );
+ }
+
+ if ( StringUtils.isNotEmpty( entity.getModCode() ) )
+ {
+ Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
+ GlobalIds.FT_MODIFIER_CODE, entity.getModCode() );
+ mods.add( modification );
+ }
+
+ if ( StringUtils.isNotEmpty( entity.getModId() ) )
+ {
+ Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
+ GlobalIds.FT_MODIFIER_ID, entity.getModId() );
+ mods.add( modification );
+ }
+ }
+ }
+
+
+ /**
+ * Perform normal ldap search accepting default batch size.
+ *
+ * @param connection is LdapConnection object used for all communication with host.
+ * @param baseDn contains address of distinguished name to begin ldap search
+ * @param scope indicates depth of search starting at basedn. 0 (base dn),
+ * 1 (one level down) or 2 (infinite) are valid values.
+ * @param filter contains the search criteria
+ * @param attrs is the requested list of attritubutes to return from directory search.
+ * @param attrsOnly if true pull back attribute names only.
+ * @return result set containing ldap entries returned from directory.
+ * @throws LdapException thrown in the event of error in ldap client or server code.
+ */
+ protected SearchCursor search( LdapConnection connection, String baseDn, SearchScope scope, String filter,
+ String[] attrs, boolean attrsOnly ) throws LdapException
+ {
+ COUNTERS.incrementSearch();
+
+ SearchRequest searchRequest = new SearchRequestImpl();
+ searchRequest.setBase( new Dn( baseDn ) );
+ searchRequest.setScope( scope );
+ searchRequest.setFilter( filter );
+ searchRequest.setTypesOnly( attrsOnly );
+ searchRequest.addAttributes( attrs );
+
+ return connection.search( searchRequest );
+ }
+
+
+ /**
+ * Perform normal ldap search specifying default batch size and max entries to return.
+ *
+ * @param connection is LdapConnection object used for all communication with host.
+ * @param baseDn contains address of distinguished name to begin ldap search
+ * @param scope indicates depth of search starting at basedn. 0 (base dn),
+ * 1 (one level down) or 2 (infinite) are valid values.
+ * @param filter contains the search criteria
+ * @param attrs is the requested list of attritubutes to return from directory search.
+ * @param attrsOnly if true pull back attribute names only.
+ * @param maxEntries specifies the maximum number of entries to return in this search query.
+ * @return result set containing ldap entries returned from directory.
+ * @throws LdapException thrown in the event of error in ldap client or server code.
+ */
+ protected SearchCursor search( LdapConnection connection, String baseDn, SearchScope scope, String filter,
+ String[] attrs, boolean attrsOnly, int maxEntries ) throws LdapException
+ {
+ COUNTERS.incrementSearch();
+
+ SearchRequest searchRequest = new SearchRequestImpl();
+
+ searchRequest.setBase( new Dn( baseDn ) );
+ searchRequest.setFilter( filter );
+ searchRequest.setScope( scope );
+ searchRequest.setSizeLimit( maxEntries );
+ searchRequest.setTypesOnly( attrsOnly );
+ searchRequest.addAttributes( attrs );
+
+ return connection.search( searchRequest );
+ }
+
+
+ /**
+ * This method will search the directory and return at most one record. If more than one record is found
+ * an ldap exception will be thrown.
+ *
+ * @param connection is LdapConnection object used for all communication with host.
+ * @param baseDn contains address of distinguished name to begin ldap search
+ * @param scope indicates depth of search starting at basedn. 0 (base dn),
+ * 1 (one level down) or 2 (infinite) are valid values.
+ * @param filter contains the search criteria
+ * @param attrs is the requested list of attritubutes to return from directory search.
+ * @param attrsOnly if true pull back attribute names only.
+ * @return entry containing target ldap node.
+ * @throws LdapException thrown in the event of error in ldap client or server code.
+ * @throws CursorException If we weren't able to fetch an element from the search result
+ */
+ protected Entry searchNode( LdapConnection connection, String baseDn, SearchScope scope, String filter,
+ String[] attrs, boolean attrsOnly ) throws LdapException, CursorException
+ {
+ SearchRequest searchRequest = new SearchRequestImpl();
+
+ searchRequest.setBase( new Dn( baseDn ) );
+ searchRequest.setFilter( filter );
+ searchRequest.setScope( scope );
+ searchRequest.setTypesOnly( attrsOnly );
+ searchRequest.addAttributes( attrs );
+
+ SearchCursor result = connection.search( searchRequest );
+
+ Entry entry = result.getEntry();
+
+ if ( result.next() )
+ {
+ throw new LdapException( "searchNode failed to return unique record for LDAP search of base DN [" +
+ baseDn + "] filter [" + filter + "]" );
+ }
+
+ return entry;
+ }
+
+
+ /**
+ * This search method uses OpenLDAP Proxy Authorization Control to assert arbitrary user identity onto connection.
+ *
+ * @param connection is LdapConnection object used for all communication with host.
+ * @param baseDn contains address of distinguished name to begin ldap search
+ * @param scope indicates depth of search starting at basedn. 0 (base dn),
+ * 1 (one level down) or 2 (infinite) are valid values.
+ * @param filter contains the search criteria
+ * @param attrs is the requested list of attritubutes to return from directory search.
+ * @param attrsOnly if true pull back attribute names only.
+ * @param userDn string value represents the identity of user on who's behalf the request was initiated. The
+ * value will be stored in openldap auditsearch record AuthZID's attribute.
+ * @return entry containing target ldap node.
+ * @throws LdapException thrown in the event of error in ldap client or server code.
+ * @throws CursorException If we weren't able to fetch an element from the search result
+ */
+ protected Entry searchNode( LdapConnection connection, String baseDn, SearchScope scope, String filter,
+ String[] attrs, boolean attrsOnly, String userDn ) throws LdapException, CursorException
+ {
+ COUNTERS.incrementSearch();
+
+ SearchRequest searchRequest = new SearchRequestImpl();
+
+ searchRequest.setBase( new Dn( baseDn ) );
+ searchRequest.setFilter( filter );
+ searchRequest.setScope( scope );
+ searchRequest.setTypesOnly( attrsOnly );
+ searchRequest.addAttributes( attrs );
+
+ SearchCursor result = connection.search( searchRequest );
+
+ Entry entry = result.getEntry();
+
+ if ( result.next() )
+ {
+ throw new LdapException( "searchNode failed to return unique record for LDAP search of base DN [" +
+ baseDn + "] filter [" + filter + "]" );
+ }
+
+ return entry;
+ }
+
+
+ /**
+ * This method uses the compare ldap func to assert audit record into the directory server's configured audit
+ * logger.
+ *
+ * This is for one reason - to force the ldap server to maintain an audit trail on checkAccess api.
+ *
+ * Use proxy authz control (RFC4370) to assert the caller's id onto the record.
+ *
+ * @param connection is LdapConnection object used for all communication with host.
+ * @param dn contains address of distinguished name to begin ldap search
+ * @param userDn dn for user node
+ * @param attribute attribute used for compare
+ * @return true if compare operation succeeds
+ * @throws LdapException thrown in the event of error in ldap client or server code.
+ * @throws UnsupportedEncodingException in the event the server cannot perform the operation.
+ */
+ protected boolean compareNode( LdapConnection connection, String dn, String userDn,
+ Attribute attribute ) throws LdapException, UnsupportedEncodingException
+ {
+ COUNTERS.incrementCompare();
+
+ CompareRequest compareRequest = new CompareRequestImpl();
+ compareRequest.setName( new Dn( dn ) );
+ compareRequest.setAttributeId( attribute.getId() );
+ compareRequest.setAssertionValue( attribute.getString() );
+
+ // Assert the end user's dn onto the reqest using proxy authZ control so openldap can log who the user was (for authZ audit trail)
+ ProxiedAuthz proxiedAuthzControl = new ProxiedAuthzImpl();
+ proxiedAuthzControl.setAuthzId( "dn: " + userDn );
+ compareRequest.addControl( proxiedAuthzControl );
+ CompareResponse response = connection.compare( compareRequest );
+ return response.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS;
+ }
+
+
+ /**
+ * Method wraps ldap client to return multi-occurring attribute values by name within a given entry and returns
+ * as a list of strings.
+ *
+ * @param entry contains the target ldap entry.
+ * @param attributeName name of ldap attribute to retrieve.
+ * @return List of type string containing attribute values.
+ */
+ protected List<String> getAttributes( Entry entry, String attributeName )
+ {
+ List<String> attrValues = new ArrayList<>();
+ if ( entry != null )
+ {
+ Attribute attr = entry.get( attributeName );
+ if ( attr != null )
+ {
+ for ( Value<?> value : attr )
+ {
+ attrValues.add( value.getString() );
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ return attrValues;
+ }
+
+
+ /**
+ * Return the image stored on the entry.
+ *
+ * @param entry contains the image target.
+ * @param attributeName to be retrieved.
+ * @return byte array containing image.
+ * @throws LdapInvalidAttributeValueException contains the system error.
+ */
+ protected byte[] getPhoto( Entry entry, String attributeName ) throws LdapInvalidAttributeValueException
+ {
+ byte[] photo = null;
+ Attribute attr = entry.get( attributeName );
+
+ if ( attr != null )
+ {
+ photo = attr.getBytes();
+ }
+
+ return photo;
+ }
+
+
+ /**
+ * Method wraps ldap client to return multi-occurring attribute values by name within a given entry and returns
+ * as a set of strings.
+ *
+ * @param entry contains the target ldap entry.
+ * @param attributeName name of ldap attribute to retrieve.
+ * @return List of type string containing attribute values.
+ */
+ protected Set<String> getAttributeSet( Entry entry, String attributeName )
+ {
+ // create Set with case insensitive comparator:
+ Set<String> attrValues = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+
+ if ( entry != null && entry.containsAttribute( attributeName ) )
+ {
+ for ( Value<?> value : entry.get( attributeName ) )
+ {
+ attrValues.add( value.getString() );
+ }
+ }
+
+ return attrValues;
+ }
+
+
+ /**
+ * Method wraps ldap client to return attribute value by name within a given entry and returns as a string.
+ *
+ * @param entry contains the target ldap entry.
+ * @param attributeName name of ldap attribute to retrieve.
+ * @return value contained in a string variable.
+ * @throws LdapInvalidAttributeValueException When we weren't able to get the attribute from the entry
+ */
+ protected String getAttribute( Entry entry, String attributeName ) throws LdapInvalidAttributeValueException
+ {
+ if ( entry != null )
+ {
+ Attribute attr = entry.get( attributeName );
+
+ if ( attr != null )
+ {
+ return attr.getString();
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+ /**
+ * Method will retrieve the relative distinguished name from a distinguished name variable.
+ *
+ * @param dn contains ldap distinguished name.
+ * @return rDn as string.
+ */
+ protected String getRdn( String dn )
+ {
+ try
+ {
+ return new Dn( dn ).getRdn().getName();
+ }
+ catch ( LdapInvalidDnException lide )
+ {
+ return null;
+ }
+ }
+
+
+ /**
+ * Create multi-occurring ldap attribute given array of strings and attribute name.
+ *
+ * @param name contains attribute name to create.
+ * @param values array of string that contains attribute values.
+ * @return Attribute containing multi-occurring attribute set.
+ * @throws LdapException in the event of ldap client error.
+ */
+ protected Attribute createAttributes( String name, String values[] ) throws LdapException
+ {
+ return new DefaultAttribute( name, values );
+ }
+
+
+ /**
+ * Convert constraint from raw ldap format to application entity.
+ *
+ * @param le ldap entry containing constraint.
+ * @param ftDateTime reference to {@link org.apache.directory.fortress.core.model.Constraint} containing formatted data.
+ * @throws LdapInvalidAttributeValueException
+ *
+ * @throws LdapInvalidAttributeValueException when we weren't able to retrieve the attribute from the entry
+ */
+ protected void unloadTemporal( Entry le, Constraint ftDateTime ) throws LdapInvalidAttributeValueException
+ {
+ String szRawData = getAttribute( le, GlobalIds.CONSTRAINT );
+
+ if ( szRawData != null && szRawData.length() > 0 )
+ {
+ ConstraintUtil.setConstraint( szRawData, ftDateTime );
+ }
+ }
+
+
+ /**
+ * Given an ldap attribute name and a list of attribute values, construct an ldap attribute set to be added to directory.
+ *
+ * @param list list of type string containing attribute values to load into attribute set.
+ * @param entry contains ldap attribute set targeted for adding.
+ * @param attrName name of ldap attribute being added.
+ * @throws LdapException If we weren't able to add the attributes into the entry
+ */
+ protected void loadAttrs( List<String> list, Entry entry, String attrName ) throws LdapException
+ {
+ if ( list != null && list.size() > 0 )
+ {
+ entry.add( attrName, list.toArray( new String[]
+ {} ) );
+ }
+ }
+
+
+ /**
+ * Given an ldap attribute name and a list of attribute values, construct an ldap modification set to be updated
+ * in directory.
+ *
+ * @param list list of type string containing attribute values to load into modification set.
+ * @param mods contains ldap modification set targeted for updating.
+ * @param attrName name of ldap attribute being modified.
+ */
+ protected void loadAttrs( List<String> list, List<Modification> mods, String attrName )
+ {
+ if ( ( list != null ) && ( list.size() > 0 ) )
+ {
+ mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attrName,
+ list.toArray( new String[]
+ {} ) ) );
+ }
+ }
+
+
+ /**
+ * Given a collection of {@link org.apache.directory.fortress.core.model.Relationship}s, convert to raw data name-value format and
+ * load into ldap modification set in preparation for ldap modify.
+ *
+ * @param list contains List of type {@link org.apache.directory.fortress.core.model.Relationship} targeted for updating in ldap.
+ * @param mods ldap modification set containing parent-child relationships in raw ldap format.
+ * @param attrName contains the name of the ldap attribute to be updated.
+ * @param op specifies type of mod: {@link org.apache.directory.fortress.core.model.Hier.Op#ADD},
+ * {@link org.apache.directory.fortress.core.model.Hier.Op#MOD}, {@link org.apache.directory.fortress.core.model.Hier.Op#REM}.
+ */
+ protected void loadRelationshipAttrs( List<Relationship> list, List<Modification> mods, String attrName,
+ Hier.Op op )
+ {
+ if ( list != null )
+ {
+ Attribute attr;
+
+ for ( Relationship rel : list )
+ {
+ // This LDAP attr is stored as a name-value pair separated by a ':'.
+ attr = new DefaultAttribute( attrName, rel.getChild() + GlobalIds.PROP_SEP + rel.getParent() );
+
+ switch ( op )
+ {
+ case ADD:
+ mods.add( new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, attr ) );
+ break;
+
+ case MOD:
+ mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attr ) );
+ break;
+
+ case REM:
+ mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attr ) );
+ break;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Given an ldap attribute name and a set of attribute values, construct an ldap modification set to be updated
+ * in directory.
+ *
+ * @param values set of type string containing attribute values to load into modification set.
+ * @param mods contains ldap modification set targeted for updating.
+ * @param attrName name of ldap attribute being updated.
+ */
+ protected void loadAttrs( Set<String> values, List<Modification> mods, String attrName )
+ {
+ if ( ( values != null ) && ( values.size() > 0 ) )
+ {
+ mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attrName,
+ values.toArray( new String[]
+ {} ) ) );
+ }
+ }
+
+
+ /**
+ * Given an ldap attribute name and a set of attribute values, construct an ldap attribute set to be added to
+ * directory.
+ *
+ * @param values set of type string containing attribute values to load into attribute set.
+ * @param entry contains ldap entry to pull attrs from.
+ * @param attrName name of ldap attribute being added.
+ * @throws LdapException If we weren't able to add the values into the entry
+ */
+ protected void loadAttrs( Set<String> values, Entry entry, String attrName ) throws LdapException
+ {
+ if ( ( values != null ) && ( values.size() > 0 ) )
+ {
+ entry.add( attrName, values.toArray( new String[]
+ {} ) );
+ }
+ }
+
+
+ /**
+ * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
+ * modification set in preparation for ldap modify.
+ *
+ * @param props contains {@link java.util.Properties} targeted for updating in ldap.
+ * @param mods ldap modification set containing name-value pairs in raw ldap format.
+ * @param attrName contains the name of the ldap attribute to be updated.
+ * @param replace boolean variable, if set to true use {@link ModificationOperation#REPLACE_ATTRIBUTE} else {@link
+ * ModificationOperation#ADD_ATTRIBUTE}.
+ */
+ protected void loadProperties( Properties props, List<Modification> mods, String attrName, boolean replace )
+ {
+ loadProperties( props, mods, attrName, replace, GlobalIds.PROP_SEP );
+ }
+
+
+ /**
+ * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
+ * modification set in preparation for ldap modify.
+ *
+ * @param props contains {@link java.util.Properties} targeted for updating in ldap.
+ * @param mods ldap modification set containing name-value pairs in raw ldap format.
+ * @param attrName contains the name of the ldap attribute to be updated.
+ * @param replace boolean variable, if set to true use {@link ModificationOperation#REPLACE_ATTRIBUTE} else {@link
+ * ModificationOperation#ADD_ATTRIBUTE}.
+ * @param separator contains the char value used to separate name and value in ldap raw format.
+ */
+ protected void loadProperties( Properties props, List<Modification> mods, String attrName, boolean replace,
+ char separator )
+ {
+ if ( props != null && props.size() > 0 )
+ {
+ if ( replace )
+ {
+ mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attrName ) );
+ }
+
+ for ( Enumeration<?> e = props.propertyNames(); e.hasMoreElements(); )
+ {
+ String key = ( String ) e.nextElement();
+ String val = props.getProperty( key );
+ // This LDAP attr is stored as a name-value pair separated by a ':'.
+ mods.add( new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, attrName,
+ key + separator + val ) );
+ }
+ }
+ }
+
+
+ /**
+ * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
+ * modification set in preparation for ldap modify.
+ *
+ * @param props contains {@link java.util.Properties} targeted for removal from ldap.
+ * @param mods ldap modification set containing name-value pairs in raw ldap format to be removed.
+ * @param attrName contains the name of the ldap attribute to be removed.
+ */
+ protected void removeProperties( Properties props, List<Modification> mods, String attrName )
+ {
+ if ( props != null && props.size() > 0 )
+ {
+ for ( Enumeration<?> e = props.propertyNames(); e.hasMoreElements(); )
+ {
+ String key = ( String ) e.nextElement();
+ String val = props.getProperty( key );
+
+ // This LDAP attr is stored as a name-value pair separated by a ':'.
+ mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attrName,
+ key + GlobalIds.PROP_SEP + val ) );
+ }
+ }
+ }
+
+
+ /**
+ * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
+ * modification set in preparation for ldap add.
+ *
+ * @param props contains {@link java.util.Properties} targeted for adding to ldap.
+ * @param entry contains ldap entry to pull attrs from.
+ * @param attrName contains the name of the ldap attribute to be added.
+ * @throws LdapException If we weren't able to add the properies into the entry
+ */
+ protected void loadProperties( Properties props, Entry entry, String attrName ) throws LdapException
+ {
+ if ( ( props != null ) && ( props.size() > 0 ) )
+ {
+ Attribute attr = new DefaultAttribute( attrName );
+
+ for ( Enumeration<?> e = props.propertyNames(); e.hasMoreElements(); )
+ {
+ // This LDAP attr is stored as a name-value pair separated by a ':'.
+ String key = ( String ) e.nextElement();
+ String val = props.getProperty( key );
+ String prop = key + GlobalIds.PROP_SEP + val;
+
+ attr.add( prop );
+ }
+
+ if ( attr.size() != 0 )
+ {
+ entry.add( attr );
+ }
+ }
+ }
+
+
+ /**
+ * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap modification set in preparation for ldap add.
+ *
+ * @param props contains {@link java.util.Properties} targeted for adding to ldap.
+ * @param entry contains ldap entry to push attrs into.
+ * @param attrName contains the name of the ldap attribute to be added.
+ * @param separator contains the char value used to separate name and value in ldap raw format.
+ * @throws LdapException If we weren't able to add the properies into the entry
+ */
+ protected void loadProperties( Properties props, Entry entry, String attrName, char separator )
+ throws LdapException
+ {
+ if ( ( props != null ) && ( props.size() > 0 ) )
+ {
+ Attribute attr = null;
+
+ for ( Enumeration<?> e = props.propertyNames(); e.hasMoreElements(); )
+ {
+ // This LDAP attr is stored as a name-value pair separated by a ':'.
+ String key = ( String ) e.nextElement();
+ String val = props.getProperty( key );
+ String prop = key + separator + val;
+
+ if ( attr == null )
+ {
+ attr = new DefaultAttribute( attrName );
+ }
+ else
+ {
+ attr.add( prop );
+ }
+ }
+
+ if ( attr != null )
+ {
+ entry.add( attr );
+ }
+ }
+ }
+
+
+ /**
+ * Encode some text so that it can be used in a LDAP filter.
+ *
+ * @param value The value to encode
+ * @param validLen The maximum accepted length of the value.
+ * @return String containing encoded data.
+ * @throws LdapException If the value is longer than the maximum value
+ */
+ protected String encodeSafeText( String value, int validLen ) throws LdapException
+ {
+ if ( StringUtils.isNotEmpty( value ) )
+ {
+ int length = value.length();
+
+ if ( length > validLen )
+ {
+ String error = "encodeSafeText value [" + value + "] invalid length [" + length + "]";
+ throw new LdapException( error );
+ }
+
+ if ( GlobalIds.LDAP_FILTER_SIZE_FOUND )
+ {
+ value = escapeLDAPSearchFilter( value );
+ }
+ }
+
+ return value;
+ }
+
+
+ /**
+ * Get Password Policy Response Control from LDAP client.
+ *
+ * @param resp contains reference to LDAP pw policy response.
+ * @return PasswordPolicy response control.
+ */
+ protected PasswordPolicy getPwdRespCtrl( Response resp )
+ {
+ Control control = resp.getControls().get( PP_REQ_CTRL.getOid() );
+ if ( control == null )
+ {
+ return null;
+ }
+
+ return ( ( PasswordPolicyDecorator ) control ).getDecorated();
+ }
+
+
+ /**
+ * Calls the PoolMgr to perform an LDAP bind for a user/password combination. This function is valid
+ * if and only if the user entity is a member of the USERS data set.
+ *
+ * @param connection connection to ldap server.
+ * @param szUserDn contains the LDAP dn to the user entry in String format.
+ * @param password contains the password in clear text.
+ * @return bindResponse contains the result of the operation.
+ * @throws LdapException in the event of LDAP error.
+ */
+ protected BindResponse bind( LdapConnection connection, String szUserDn, char[] password ) throws LdapException
+ {
+ COUNTERS.incrementBind();
+ Dn userDn = new Dn( szUserDn );
+ BindRequest bindReq = new BindRequestImpl();
+ bindReq.setDn( userDn );
+ bindReq.setCredentials( new String( password ) );
+ bindReq.addControl( PP_REQ_CTRL );
+ return connection.bind( bindReq );
+ }
+
+
+ /**
+ * Calls the PoolMgr to close the Admin LDAP connection.
+ *
+ * @param connection handle to ldap connection object.
+ */
+ protected void closeAdminConnection( LdapConnection connection )
+ {
+ try
+ {
+ adminPool.releaseConnection( connection );
+ }
+ catch ( Exception e )
+ {
+ throw new RuntimeException( e.getMessage(), e );
+ }
+ }
+
+
+ /**
+ * Calls the PoolMgr to close the Log LDAP connection.
+ *
+ * @param connection handle to ldap connection object.
+ */
+ protected void closeLogConnection( LdapConnection connection )
+ {
+ try
+ {
+ logPool.releaseConnection( connection );
+ }
+ catch ( Exception e )
+ {
+ throw new RuntimeException( e.getMessage(), e );
+ }
+ }
+
+
+ /**
+ * Calls the PoolMgr to close the User LDAP connection.
+ *
+ * @param connection handle to ldap connection object.
+ */
+ protected void closeUserConnection( LdapConnection connection )
+ {
+ try
+ {
+ userPool.releaseConnection( connection );
+ }
+ catch ( Exception e )
+ {
+ throw new RuntimeException( e.getMessage(), e );
+ }
+ }
+
+
+ /**
+ * Calls the PoolMgr to get an Admin connection to the LDAP server.
+ *
+ * @return ldap connection.
+ * @throws LdapException If we had an issue getting an LDAP connection
+ */
+ protected LdapConnection getAdminConnection() throws LdapException
+ {
+ try
+ {
+ return adminPool.getConnection();
+ }
+ catch ( Exception e )
+ {
+ throw new LdapException( e.getMessage(), e );
+ }
+ }
+
+
+ /**
+ * Calls the PoolMgr to get an Log connection to the LDAP server.
+ *
+ * @return ldap connection.
+ * @throws LdapException If we had an issue getting an LDAP connection
+ */
+ protected LdapConnection getLogConnection() throws LdapException
+ {
+ try
+ {
+ return logPool.getConnection();
+ }
+ catch ( Exception e )
+ {
+ throw new LdapException( e.getMessage(), e );
+ }
+ }
+
+
+ /**
+ * Calls the PoolMgr to get an User connection to the LDAP server.
+ *
+ * @return ldap connection.
+ * @throws LdapException If we had an issue getting an LDAP connection
+ */
+ protected LdapConnection getUserConnection() throws LdapException
+ {
+ try
+ {
+ return userPool.getConnection();
+ }
+ catch ( Exception e )
+ {
+ throw new LdapException( e.getMessage(), e );
+ }
+ }
+
+
+ /**
+ * Return to call reference to dao counter object with running totals for ldap operations add, mod, delete, search, etc.
+ *
+ * @return {@link LdapCounters} contains long values of atomic ldap operations for current running process.
+ */
+ public static LdapCounters getLdapCounters()
+ {
+ return COUNTERS;
+ }
+
+
+ /**
+ *
+ */
+ private static char[] loadLdapEscapeChars()
+ {
+ if ( !GlobalIds.LDAP_FILTER_SIZE_FOUND )
+ {
+ return null;
+ }
+
+ char[] ldapMetaChars = new char[GlobalIds.LDAP_FILTER_SIZE];
+
+ for ( int i = 1;; i++ )
+ {
+ String prop = GlobalIds.LDAP_FILTER + i;
+ String value = Config.getProperty( prop );
+
+ if ( value == null )
+ {
+ break;
+ }
+
+ ldapMetaChars[i - 1] = value.charAt( 0 );
+ }
+
+ return ldapMetaChars;
+ }
+
+
+ /**
+ *
+ */
+ private static String[] loadValidLdapVals()
+ {
+ if ( !GlobalIds.LDAP_FILTER_SIZE_FOUND )
+ {
+ return null;
+ }
+
+ String[] ldapReplacements = new String[GlobalIds.LDAP_FILTER_SIZE];
+
+ for ( int i = 1;; i++ )
+ {
+ String prop = GlobalIds.LDAP_SUB + i;
+ String value = Config.getProperty( prop );
+
+ if ( value == null )
+ {
+ break;
+ }
+
+ ldapReplacements[i - 1] = value;
+ }
+
+ return ldapReplacements;
+ }
+
+
+ /**
+ * Perform encoding on supplied input string for certain unsafe ascii characters. These chars may be unsafe
+ * because ldap reserves some characters as operands. Safe encoding safeguards from malicious scripting input errors
+ * that are possible if data filtering did not get performed before being passed into dao layer.
+ *
+ * @param filter contains the data to filter.
+ * @return possibly modified input string for matched characters.
+ */
+ protected static String escapeLDAPSearchFilter( String filter )
+ {
+ StringBuilder sb = new StringBuilder();
+ int filterLen = filter.length();
+
+ for ( int i = 0; i < filterLen; i++ )
+ {
+ boolean found = false;
+ char curChar = filter.charAt( i );
+ int j = 0;
+
+ for ( ; j < GlobalIds.LDAP_FILTER_SIZE; j++ )
+ {
+ if ( LDAP_META_CHARS[j] > curChar )
+ {
+ break;
+ }
+ else if ( curChar == LDAP_META_CHARS[j] )
+ {
+ sb.append( "\\" );
+ sb.append( LDAP_REPL_VALS[j] );
+ found = true;
+ break;
+ }
+ }
+
+ if ( !found )
+ {
+ sb.append( curChar );
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Closes all the ldap connection pools.
+ */
+ public static void closeAllConnectionPools(){
+ try{
+ LOG.info("Closing admin pool");
+ adminPool.close();
+ }
+ catch(Exception e){
+ LOG.warn("Error closing admin pool: " + e.getMessage());
+ }
+
+ try{
+ LOG.info("Closing user pool");
+ userPool.close();
+ }
+ catch(Exception e){
+ LOG.warn("Error closing user pool: " + e.getMessage());
+ }
+
+ try{
+ LOG.info("Closing log pool");
+ logPool.close();
+ }
+ catch(Exception e){
+ LOG.warn("Error closing log pool: " + e.getMessage());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/model/AuthZ.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/model/AuthZ.java b/src/main/java/org/apache/directory/fortress/core/model/AuthZ.java
index b4eac4d..beeed00 100755
--- a/src/main/java/org/apache/directory/fortress/core/model/AuthZ.java
+++ b/src/main/java/org/apache/directory/fortress/core/model/AuthZ.java
@@ -145,7 +145,7 @@ public class AuthZ extends FortEntity implements Serializable
/**
* Return the user dn containing the identity of log user who added the audit record. This will be the system user that
* is configured for performing slapd access log operations on behalf of Fortress.
- * The config property name {@link org.apache.directory.fortress.core.ldap.ApacheDsDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
+ * The config property name {@link org.apache.directory.fortress.core.ldap.LdapDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
*
* @return value that maps to 'creatorsName' attribute on 'auditSearch' object class.
*/
@@ -158,7 +158,7 @@ public class AuthZ extends FortEntity implements Serializable
/**
* Set the user dn containing the identity of log user who added the audit record. This will be the system user that
* is configured for performing slapd access log operations on behalf of Fortress.
- * The config property name {@link org.apache.directory.fortress.core.ldap.ApacheDsDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
+ * The config property name {@link org.apache.directory.fortress.core.ldap.LdapDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
*
* @param creatorsName maps to 'creatorsName' attribute on 'auditSearch' object class.
*/
@@ -259,7 +259,7 @@ public class AuthZ extends FortEntity implements Serializable
/**
* Return the user dn containing the identity of log user who last modified the audit record. This will be the system user that
* is configured for performing slapd access log operations on behalf of Fortress.
- * The config property name {@link org.apache.directory.fortress.core.ldap.ApacheDsDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
+ * The config property name {@link org.apache.directory.fortress.core.ldap.LdapDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
*
* @return value that maps to 'modifiersName' attribute on 'auditSearch' object class.
*/
@@ -272,7 +272,7 @@ public class AuthZ extends FortEntity implements Serializable
/**
* Set the user dn containing the identity of log user who modified the audit record. This will be the system user that
* is configured for performing slapd access log operations on behalf of Fortress.
- * The config property name {@link org.apache.directory.fortress.core.ldap.ApacheDsDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
+ * The config property name {@link org.apache.directory.fortress.core.ldap.LdapDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
*
* @param modifiersName maps to 'modifiersName' attribute on 'auditSearch' object class.
*/
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/model/Bind.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/model/Bind.java b/src/main/java/org/apache/directory/fortress/core/model/Bind.java
index 5f8f821..d3617d1 100755
--- a/src/main/java/org/apache/directory/fortress/core/model/Bind.java
+++ b/src/main/java/org/apache/directory/fortress/core/model/Bind.java
@@ -130,7 +130,7 @@ public class Bind extends FortEntity implements Serializable
/**
* Return the user dn containing the identity of log user who added the audit record. This will be the system user that
* is configured for performing slapd access log operations on behalf of Fortress.
- * The config property name {@link org.apache.directory.fortress.core.ldap.ApacheDsDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
+ * The config property name {@link org.apache.directory.fortress.core.ldap.LdapDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
*
* @return value that maps to 'creatorsName' attribute on 'auditBind' object class.
*/
@@ -143,7 +143,7 @@ public class Bind extends FortEntity implements Serializable
/**
* Set the user dn containing the identity of log user who added the audit record. This will be the system user that
* is configured for performing slapd access log operations on behalf of Fortress.
- * The config property name {@link org.apache.directory.fortress.core.ldap.ApacheDsDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
+ * The config property name {@link org.apache.directory.fortress.core.ldap.LdapDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
*
* @param creatorsName maps to 'creatorsName' attribute on 'auditBind' object class.
*/
@@ -244,7 +244,7 @@ public class Bind extends FortEntity implements Serializable
/**
* Return the user dn containing the identity of log user who last modified the audit record. This will be the system user that
* is configured for performing slapd access log operations on behalf of Fortress.
- * The config property name {@link org.apache.directory.fortress.core.ldap.ApacheDsDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
+ * The config property name {@link org.apache.directory.fortress.core.ldap.LdapDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
*
* @return value that maps to 'modifiersName' attribute on 'auditBind' object class.
*/
@@ -257,7 +257,7 @@ public class Bind extends FortEntity implements Serializable
/**
* Set the user dn containing the identity of log user who modified the audit record. This will be the system user that
* is configured for performing slapd access log operations on behalf of Fortress.
- * The config property name {@link org.apache.directory.fortress.core.ldap.ApacheDsDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
+ * The config property name {@link org.apache.directory.fortress.core.ldap.LdapDataProvider#LDAP_LOG_POOL_UID} contains the audit log system user id.
*
* @param modifiersName maps to 'modifiersName' attribute on 'auditBind' object class.
*/
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/test/java/org/apache/directory/fortress/core/example/ExampleDAO.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/directory/fortress/core/example/ExampleDAO.java b/src/test/java/org/apache/directory/fortress/core/example/ExampleDAO.java
index 1e9b304..fe4c226 100755
--- a/src/test/java/org/apache/directory/fortress/core/example/ExampleDAO.java
+++ b/src/test/java/org/apache/directory/fortress/core/example/ExampleDAO.java
@@ -33,7 +33,7 @@ import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
import org.apache.directory.api.ldap.model.message.SearchScope;
import org.apache.directory.fortress.core.FinderException;
import org.apache.directory.fortress.core.GlobalErrIds;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
import org.apache.directory.fortress.core.model.ConstraintUtil;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.slf4j.LoggerFactory;
@@ -47,7 +47,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-public class ExampleDAO extends ApacheDsDataProvider
+public class ExampleDAO extends LdapDataProvider
{
private static final String CLS_NM = ExampleDAO.class.getName();
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/test/java/org/apache/directory/fortress/core/impl/apacheds/AdminManagerTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/directory/fortress/core/impl/apacheds/AdminManagerTest.java b/src/test/java/org/apache/directory/fortress/core/impl/apacheds/AdminManagerTest.java
index 96f5283..9f94e64 100644
--- a/src/test/java/org/apache/directory/fortress/core/impl/apacheds/AdminManagerTest.java
+++ b/src/test/java/org/apache/directory/fortress/core/impl/apacheds/AdminManagerTest.java
@@ -41,7 +41,7 @@ import org.slf4j.LoggerFactory;
import org.apache.directory.fortress.core.AdminMgr;
import org.apache.directory.fortress.core.AdminMgrFactory;
import org.apache.directory.fortress.core.SecurityException;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
import org.apache.directory.fortress.core.ldap.LdapCounters;
import org.apache.directory.fortress.core.impl.DelegatedMgrImplTest;
import org.apache.directory.fortress.core.impl.FortressJUnitTest;
@@ -81,7 +81,7 @@ public class AdminManagerTest extends AbstractLdapTestUnit
@After
public void displayCounters()
{
- LdapCounters counters = ApacheDsDataProvider.getLdapCounters();
+ LdapCounters counters = LdapDataProvider.getLdapCounters();
System.out.println( "NUMBER OF READS: " + counters.getRead() );
System.out.println( "NUMBER OF SEARCHES: " + counters.getSearch() );
System.out.println( "NUMBER OF COMPARES: " + counters.getCompare() );
[2/2] directory-fortress-core git commit: rename to LdapDataProvider
Posted by sm...@apache.org.
rename to LdapDataProvider
Project: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/commit/a5dc68e1
Tree: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/tree/a5dc68e1
Diff: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/diff/a5dc68e1
Branch: refs/heads/master
Commit: a5dc68e15c92979292f53f12d2aa88346869d048
Parents: 5bb8ae3
Author: Shawn McKinney <sm...@apache.org>
Authored: Sun Apr 3 21:52:02 2016 -0500
Committer: Shawn McKinney <sm...@apache.org>
Committed: Sun Apr 3 21:52:02 2016 -0500
----------------------------------------------------------------------
.../fortress/core/ant/FortressAntTask.java | 2 +
.../fortress/core/impl/AcceleratorDAO.java | 4 +-
.../fortress/core/impl/AdminRoleDAO.java | 4 +-
.../directory/fortress/core/impl/AuditDAO.java | 4 +-
.../directory/fortress/core/impl/ConfigDAO.java | 4 +-
.../directory/fortress/core/impl/GroupDAO.java | 4 +-
.../fortress/core/impl/OrgUnitDAO.java | 4 +-
.../core/impl/OrganizationalUnitDAO.java | 4 +-
.../directory/fortress/core/impl/PermDAO.java | 4 +-
.../directory/fortress/core/impl/PolicyDAO.java | 4 +-
.../directory/fortress/core/impl/RoleDAO.java | 4 +-
.../directory/fortress/core/impl/SdDAO.java | 4 +-
.../directory/fortress/core/impl/SuffixDAO.java | 4 +-
.../directory/fortress/core/impl/UserDAO.java | 4 +-
.../core/ldap/ApacheDsDataProvider.java | 1641 ------------------
.../fortress/core/ldap/LdapDataProvider.java | 1641 ++++++++++++++++++
.../directory/fortress/core/model/AuthZ.java | 8 +-
.../directory/fortress/core/model/Bind.java | 8 +-
.../fortress/core/example/ExampleDAO.java | 4 +-
.../core/impl/apacheds/AdminManagerTest.java | 4 +-
20 files changed, 1681 insertions(+), 1679 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java b/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java
index 5accf15..d6a7b53 100755
--- a/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java
+++ b/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java
@@ -932,6 +932,8 @@ public class FortressAntTask extends Task implements InputHandler
addUserRoles();
testResults();
+
+ System.exit( 0 );
}
/**
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/AcceleratorDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/AcceleratorDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/AcceleratorDAO.java
index 15fcc94..2bf3f7f 100644
--- a/src/main/java/org/apache/directory/fortress/core/impl/AcceleratorDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/AcceleratorDAO.java
@@ -50,7 +50,7 @@ import org.openldap.accelerator.api.sessionRoles.RbacSessionRolesResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.directory.fortress.core.SecurityException;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
import org.apache.directory.ldap.client.api.LdapConnection;
import java.util.ArrayList;
@@ -66,7 +66,7 @@ import java.util.List;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-final class AcceleratorDAO extends ApacheDsDataProvider
+final class AcceleratorDAO extends LdapDataProvider
{
private static final Logger LOG = LoggerFactory.getLogger( AcceleratorDAO.class.getName() );
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/AdminRoleDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/AdminRoleDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/AdminRoleDAO.java
index 7fe3094..c33c029 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/AdminRoleDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/AdminRoleDAO.java
@@ -43,7 +43,7 @@ import org.apache.directory.fortress.core.GlobalErrIds;
import org.apache.directory.fortress.core.GlobalIds;
import org.apache.directory.fortress.core.RemoveException;
import org.apache.directory.fortress.core.UpdateException;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
import org.apache.directory.fortress.core.model.AdminRole;
import org.apache.directory.fortress.core.model.ConstraintUtil;
import org.apache.directory.fortress.core.model.Graphable;
@@ -107,7 +107,7 @@ import org.apache.directory.ldap.client.api.LdapConnection;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-final class AdminRoleDAO extends ApacheDsDataProvider
+final class AdminRoleDAO extends LdapDataProvider
{
private static final String ROLE_OCCUPANT = "roleOccupant";
private static final String ROLE_OSP = "ftOSP";
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/AuditDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/AuditDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/AuditDAO.java
index 77c2200..58a952c 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/AuditDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/AuditDAO.java
@@ -43,7 +43,7 @@ import org.apache.directory.fortress.core.GlobalErrIds;
import org.apache.directory.fortress.core.GlobalIds;
import org.apache.directory.fortress.core.model.ObjectFactory;
import org.apache.directory.fortress.core.util.Config;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
/**
@@ -121,7 +121,7 @@ import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-final class AuditDAO extends ApacheDsDataProvider
+final class AuditDAO extends LdapDataProvider
{
private static final String CREATETIMESTAMP = "createTimestamp";
private static final String CREATORSNAME = "creatorsName";
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/ConfigDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/ConfigDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/ConfigDAO.java
index 021aa29..a3f7a9b 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/ConfigDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/ConfigDAO.java
@@ -35,7 +35,7 @@ import org.apache.directory.fortress.core.CreateException;
import org.apache.directory.fortress.core.util.Config;
import org.apache.directory.fortress.core.model.PropUtil;
import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.directory.fortress.core.FinderException;
@@ -79,7 +79,7 @@ import org.apache.directory.fortress.core.UpdateException;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-final class ConfigDAO extends ApacheDsDataProvider
+final class ConfigDAO extends LdapDataProvider
{
private static final String CLS_NM = ConfigDAO.class.getName();
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/GroupDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/GroupDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/GroupDAO.java
index c3e577b..1bbf25d 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/GroupDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/GroupDAO.java
@@ -41,7 +41,7 @@ import org.apache.directory.fortress.core.FinderException;
import org.apache.directory.fortress.core.model.ObjectFactory;
import org.apache.directory.fortress.core.UpdateException;
import org.apache.directory.fortress.core.util.Config;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
import org.apache.directory.fortress.core.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,7 +60,7 @@ import java.util.List;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-final class GroupDAO extends ApacheDsDataProvider
+final class GroupDAO extends LdapDataProvider
{
private static final String CLS_NM = GroupDAO.class.getName();
private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitDAO.java
index 0d7616e..1ae4ccb 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitDAO.java
@@ -52,7 +52,7 @@ import org.apache.directory.fortress.core.GlobalIds;
import org.apache.directory.fortress.core.model.ObjectFactory;
import org.apache.directory.fortress.core.RemoveException;
import org.apache.directory.fortress.core.UpdateException;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
/**
@@ -103,7 +103,7 @@ import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @created September 18, 2010
*/
-final class OrgUnitDAO extends ApacheDsDataProvider
+final class OrgUnitDAO extends LdapDataProvider
{
private static final String CLS_NM = OrgUnitDAO.class.getName();
private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/OrganizationalUnitDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/OrganizationalUnitDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/OrganizationalUnitDAO.java
index 7155482..e6bf4ca 100644
--- a/src/main/java/org/apache/directory/fortress/core/impl/OrganizationalUnitDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/OrganizationalUnitDAO.java
@@ -30,7 +30,7 @@ import org.apache.directory.fortress.core.CreateException;
import org.apache.directory.fortress.core.RemoveException;
import org.apache.directory.fortress.core.model.OrganizationalUnit;
import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.directory.fortress.core.GlobalErrIds;
@@ -65,7 +65,7 @@ import org.apache.directory.fortress.core.GlobalIds;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-final class OrganizationalUnitDAO extends ApacheDsDataProvider
+final class OrganizationalUnitDAO extends LdapDataProvider
{
private static final String CLS_NM = OrganizationalUnitDAO.class.getName();
private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/PermDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/PermDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/PermDAO.java
index 31b2f3a..a461aac 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/PermDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/PermDAO.java
@@ -58,7 +58,7 @@ import org.apache.directory.fortress.core.GlobalIds;
import org.apache.directory.fortress.core.model.ObjectFactory;
import org.apache.directory.fortress.core.RemoveException;
import org.apache.directory.fortress.core.UpdateException;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
/**
@@ -150,7 +150,7 @@ import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-final class PermDAO extends ApacheDsDataProvider
+final class PermDAO extends LdapDataProvider
{
/*
* *************************************************************************
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/PolicyDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/PolicyDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/PolicyDAO.java
index 42638d0..2e4c15d 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/PolicyDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/PolicyDAO.java
@@ -46,7 +46,7 @@ import org.apache.directory.fortress.core.GlobalIds;
import org.apache.directory.fortress.core.model.ObjectFactory;
import org.apache.directory.fortress.core.RemoveException;
import org.apache.directory.fortress.core.UpdateException;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
import org.apache.directory.fortress.core.model.PwPolicy;
@@ -95,7 +95,7 @@ import org.apache.directory.fortress.core.model.PwPolicy;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-final class PolicyDAO extends ApacheDsDataProvider
+final class PolicyDAO extends LdapDataProvider
{
/*
* *************************************************************************
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/RoleDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/RoleDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/RoleDAO.java
index 6b009a1..d942ad5 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/RoleDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/RoleDAO.java
@@ -46,7 +46,7 @@ import org.apache.directory.fortress.core.GlobalIds;
import org.apache.directory.fortress.core.model.ObjectFactory;
import org.apache.directory.fortress.core.RemoveException;
import org.apache.directory.fortress.core.UpdateException;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
import org.apache.directory.fortress.core.model.Role;
@@ -95,7 +95,7 @@ import org.apache.directory.fortress.core.model.Role;
*
* @author Kevin McKinney
*/
-final class RoleDAO extends ApacheDsDataProvider
+final class RoleDAO extends LdapDataProvider
{
/*
* *************************************************************************
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/SdDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/SdDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/SdDAO.java
index 9ba98e4..53bb1a7 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/SdDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/SdDAO.java
@@ -48,7 +48,7 @@ import org.apache.directory.fortress.core.GlobalIds;
import org.apache.directory.fortress.core.model.ObjectFactory;
import org.apache.directory.fortress.core.RemoveException;
import org.apache.directory.fortress.core.UpdateException;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
import org.apache.directory.fortress.core.model.Role;
@@ -114,7 +114,7 @@ import org.apache.directory.fortress.core.model.Role;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-final class SdDAO extends ApacheDsDataProvider
+final class SdDAO extends LdapDataProvider
{
private static final String SD_SET_NM = "ftSetName";
private static final String ROLES = "ftRoles";
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/SuffixDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/SuffixDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/SuffixDAO.java
index 1dd8a6c..d6f4ba8 100644
--- a/src/main/java/org/apache/directory/fortress/core/impl/SuffixDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/SuffixDAO.java
@@ -28,7 +28,7 @@ import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.fortress.core.model.Suffix;
import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.directory.fortress.core.CreateException;
@@ -65,7 +65,7 @@ import org.apache.directory.fortress.core.RemoveException;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-final class SuffixDAO extends ApacheDsDataProvider
+final class SuffixDAO extends LdapDataProvider
{
private static final String CLS_NM = SuffixDAO.class.getName();
private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/impl/UserDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/UserDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/UserDAO.java
index c5b7bc3..eed8bb4 100755
--- a/src/main/java/org/apache/directory/fortress/core/impl/UserDAO.java
+++ b/src/main/java/org/apache/directory/fortress/core/impl/UserDAO.java
@@ -74,7 +74,7 @@ import org.apache.directory.fortress.core.RemoveException;
import org.apache.directory.fortress.core.SecurityException;
import org.apache.directory.fortress.core.UpdateException;
import org.apache.directory.fortress.core.util.Config;
-import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.LdapDataProvider;
/**
@@ -146,7 +146,7 @@ import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @created August 30, 2009
*/
-final class UserDAO extends ApacheDsDataProvider
+final class UserDAO extends LdapDataProvider
{
private static final String CLS_NM = UserDAO.class.getName();
private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/a5dc68e1/src/main/java/org/apache/directory/fortress/core/ldap/ApacheDsDataProvider.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/ApacheDsDataProvider.java b/src/main/java/org/apache/directory/fortress/core/ldap/ApacheDsDataProvider.java
deleted file mode 100644
index 5e410c7..0000000
--- a/src/main/java/org/apache/directory/fortress/core/ldap/ApacheDsDataProvider.java
+++ /dev/null
@@ -1,1641 +0,0 @@
-/*
- * 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.directory.fortress.core.ldap;
-
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.pool.PoolableObjectFactory;
-import org.apache.commons.pool.impl.GenericObjectPool;
-import org.apache.directory.api.ldap.codec.api.LdapApiService;
-import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
-import org.apache.directory.api.ldap.codec.standalone.StandaloneLdapApiService;
-import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicy;
-import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyImpl;
-import org.apache.directory.api.ldap.extras.controls.ppolicy_impl.PasswordPolicyDecorator;
-import org.apache.directory.api.ldap.model.constants.SchemaConstants;
-import org.apache.directory.api.ldap.model.cursor.CursorException;
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
-import org.apache.directory.api.ldap.model.entry.Attribute;
-import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
-import org.apache.directory.api.ldap.model.entry.DefaultModification;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.entry.Modification;
-import org.apache.directory.api.ldap.model.entry.ModificationOperation;
-import org.apache.directory.api.ldap.model.entry.Value;
-import org.apache.directory.api.ldap.model.exception.LdapException;
-import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
-import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
-import org.apache.directory.api.ldap.model.exception.LdapOperationErrorException;
-import org.apache.directory.api.ldap.model.message.BindRequest;
-import org.apache.directory.api.ldap.model.message.BindRequestImpl;
-import org.apache.directory.api.ldap.model.message.BindResponse;
-import org.apache.directory.api.ldap.model.message.CompareRequest;
-import org.apache.directory.api.ldap.model.message.CompareRequestImpl;
-import org.apache.directory.api.ldap.model.message.CompareResponse;
-import org.apache.directory.api.ldap.model.message.Control;
-import org.apache.directory.api.ldap.model.message.Response;
-import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
-import org.apache.directory.api.ldap.model.message.SearchRequest;
-import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
-import org.apache.directory.api.ldap.model.message.SearchScope;
-import org.apache.directory.api.ldap.model.message.controls.ProxiedAuthz;
-import org.apache.directory.api.ldap.model.message.controls.ProxiedAuthzImpl;
-import org.apache.directory.api.ldap.model.name.Dn;
-import org.apache.directory.fortress.core.CfgRuntimeException;
-import org.apache.directory.fortress.core.GlobalErrIds;
-import org.apache.directory.fortress.core.GlobalIds;
-import org.apache.directory.fortress.core.model.Constraint;
-import org.apache.directory.fortress.core.model.ConstraintUtil;
-import org.apache.directory.fortress.core.model.FortEntity;
-import org.apache.directory.fortress.core.model.Hier;
-import org.apache.directory.fortress.core.model.Relationship;
-import org.apache.directory.fortress.core.util.Config;
-import org.apache.directory.fortress.core.util.crypto.EncryptUtil;
-import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.ldap.client.api.LdapConnectionConfig;
-import org.apache.directory.ldap.client.api.LdapConnectionPool;
-import org.apache.directory.ldap.client.api.ValidatingPoolableLdapConnectionFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/**
- * Abstract class contains methods to perform low-level entity to ldap persistence. These methods are called by the
- * Fortress DAO's, i.e. {@link org.apache.directory.fortress.core.impl.UserDAO}. {@link org.apache.directory.fortress.core.impl.RoleDAO},
- * {@link org.apache.directory.fortress.core.impl.PermDAO}, ....
- * These are low-level data utilities, very little if any data validations are performed here.
- * <p>
- * This class is thread safe.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
-public abstract class ApacheDsDataProvider
-{
- // Logging
- private static final String CLS_NM = ApacheDsDataProvider.class.getName();
- private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
-
- private static final int MAX_DEPTH = 100;
- private static final LdapCounters COUNTERS = new LdapCounters();
-
- // Used for slapd access log {@link org.apache.directory.fortress.core.rbacAuditDAO}
- private static final String LDAP_LOG_POOL_UID = "log.admin.user";
- private static final String LDAP_LOG_POOL_PW = "log.admin.pw";
- private static final String LDAP_LOG_POOL_MIN = "min.log.conn";
- private static final String LDAP_LOG_POOL_MAX = "max.log.conn";
-
- private static final String ENABLE_LDAP_STARTTLS = "enable.ldap.starttls";
-
- private static final boolean IS_SSL = (
- Config.getProperty( GlobalIds.ENABLE_LDAP_SSL ) != null &&
- Config.getProperty( GlobalIds.ENABLE_LDAP_SSL ).equalsIgnoreCase( "true" ) &&
- Config.getProperty( GlobalIds.TRUST_STORE ) != null &&
- Config.getProperty( GlobalIds.TRUST_STORE_PW ) != null );
-
- private static final boolean IS_SET_TRUST_STORE_PROP = (
- IS_SSL &&
- Config.getProperty( GlobalIds.SET_TRUST_STORE_PROP ) != null &&
- Config.getProperty( GlobalIds.SET_TRUST_STORE_PROP ).equalsIgnoreCase( "true" ) );
-
- private static final boolean IS_SSL_DEBUG = ( ( Config.getProperty( GlobalIds.ENABLE_LDAP_SSL_DEBUG ) != null ) && ( Config
- .getProperty( GlobalIds.ENABLE_LDAP_SSL_DEBUG ).equalsIgnoreCase( "true" ) ) );
-
- /**
- * The Admin connection pool
- */
- private static LdapConnectionPool adminPool;
-
- /**
- * The Log connection pool
- */
- private static LdapConnectionPool logPool;
-
- /**
- * The User connection pool
- */
- private static LdapConnectionPool userPool;
-
- private static final PasswordPolicy PP_REQ_CTRL = new PasswordPolicyImpl();
-
- private static final char[] LDAP_META_CHARS = loadLdapEscapeChars();
- private static final String[] LDAP_REPL_VALS = loadValidLdapVals();
-
- static
- {
- String host = Config.getProperty( GlobalIds.LDAP_HOST, "localhost" );
- int port = Config.getInt( GlobalIds.LDAP_PORT, 389 );
- int min = Config.getInt( GlobalIds.LDAP_ADMIN_POOL_MIN, 1 );
- int max = Config.getInt( GlobalIds.LDAP_ADMIN_POOL_MAX, 10 );
- int logmin = Config.getInt( LDAP_LOG_POOL_MIN, 1 );
- int logmax = Config.getInt( LDAP_LOG_POOL_MAX, 10 );
- LOG.info( "LDAP POOL: host=[{}], port=[{}], min=[{}], max=[{}]", host, port, min, max );
-
- if ( IS_SET_TRUST_STORE_PROP )
- {
- LOG.info( "Set JSSE truststore properties in Apache LDAP client:" );
- LOG.info( "javax.net.ssl.trustStore: {}", Config.getProperty( GlobalIds.TRUST_STORE ) );
- LOG.info( "javax.net.debug: {}", IS_SSL_DEBUG );
- System.setProperty( "javax.net.ssl.trustStore", Config.getProperty( GlobalIds.TRUST_STORE ) );
- System.setProperty( "javax.net.ssl.trustStorePassword", Config.getProperty( GlobalIds.TRUST_STORE_PW ) );
- System.setProperty( "javax.net.debug", Boolean.valueOf( IS_SSL_DEBUG ).toString() );
- }
-
- LdapConnectionConfig config = new LdapConnectionConfig();
- config.setLdapHost( host );
- config.setLdapPort( port );
- config.setName( Config.getProperty( GlobalIds.LDAP_ADMIN_POOL_UID, "" ) );
-
- config.setUseSsl( IS_SSL );
- //config.setTrustManagers( new NoVerificationTrustManager() );
-
- if(Config.getBoolean(ENABLE_LDAP_STARTTLS, false)){
- config.setUseTls(true);
- }
-
- if ( IS_SSL && StringUtils.isNotEmpty( Config.getProperty( GlobalIds.TRUST_STORE ) )
- && StringUtils.isNotEmpty( Config.getProperty( GlobalIds.TRUST_STORE_PW ) ) )
- {
- // validate certificates but allow self-signed certs if within this truststore:
- config.setTrustManagers( new LdapClientTrustStoreManager( Config.getProperty( GlobalIds.TRUST_STORE ), Config.getProperty( GlobalIds.TRUST_STORE_PW )
- .toCharArray(), null,
- true ) );
- }
-
- String adminPw;
- if ( EncryptUtil.isEnabled() )
- {
- adminPw = EncryptUtil.decrypt( Config.getProperty( GlobalIds.LDAP_ADMIN_POOL_PW ) );
- }
- else
- {
- adminPw = Config.getProperty( GlobalIds.LDAP_ADMIN_POOL_PW );
- }
-
- config.setCredentials( adminPw );
- try
- {
- List<String> listExOps = new ArrayList<>();
- listExOps.add( "org.openldap.accelerator.impl.createSession.RbacCreateSessionFactory" );
- listExOps.add( "org.openldap.accelerator.impl.checkAccess.RbacCheckAccessFactory" );
- listExOps.add( "org.openldap.accelerator.impl.addRole.RbacAddRoleFactory" );
- listExOps.add( "org.openldap.accelerator.impl.dropRole.RbacDropRoleFactory" );
- listExOps.add( "org.openldap.accelerator.impl.deleteSession.RbacDeleteSessionFactory" );
- listExOps.add( "org.openldap.accelerator.impl.sessionRoles.RbacSessionRolesFactory" );
- LdapApiService ldapApiService = new StandaloneLdapApiService( new ArrayList<String>(), listExOps );
-
- if ( !LdapApiServiceFactory.isInitialized() )
- {
- LdapApiServiceFactory.initialize( ldapApiService );
- }
- config.setLdapApiService( ldapApiService );
- }
- catch ( Exception ex )
- {
- String error = "Exception caught initializing Admin Pool: " + ex;
- throw new CfgRuntimeException( GlobalErrIds.FT_APACHE_LDAP_POOL_INIT_FAILED, error, ex );
- }
-
- PoolableObjectFactory<LdapConnection> poolFactory = new ValidatingPoolableLdapConnectionFactory( config );
-
- // Create the Admin pool
- adminPool = new LdapConnectionPool( poolFactory );
- adminPool.setTestOnBorrow( true );
- adminPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
- adminPool.setMaxActive( max );
- adminPool.setMinIdle( min );
- adminPool.setMaxIdle( -1 );
- //adminPool.setMaxWait( 0 );
-
- // Create the User pool
- userPool = new LdapConnectionPool( poolFactory );
- userPool.setTestOnBorrow( true );
- userPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
- userPool.setMaxActive( max );
- userPool.setMinIdle( min );
- userPool.setMaxIdle( -1 );
-
- // This pool of access log connections is used by {@link org.apache.directory.fortress.AuditMgr}.
- // To enable, set {@code log.admin.user} && {@code log.admin.pw} inside fortress.properties file:
- if ( StringUtils.isNotEmpty( LDAP_LOG_POOL_UID ) && StringUtils.isNotEmpty( LDAP_LOG_POOL_PW ) )
- {
- // Initializing the log pool in static block requires static props set within fortress.properties.
- // To make this dynamic requires moving this code outside of static block AND storing the connection metadata inside fortress config node (in ldap).
- LdapConnectionConfig logConfig = new LdapConnectionConfig();
- logConfig.setLdapHost( host );
- logConfig.setLdapPort( port );
- logConfig.setName( Config.getProperty( GlobalIds.LDAP_ADMIN_POOL_UID, "" ) );
-
- logConfig.setUseSsl( IS_SSL );
-
- if ( IS_SSL && StringUtils.isNotEmpty( Config.getProperty( GlobalIds.TRUST_STORE ) )
- && StringUtils.isNotEmpty( Config.getProperty( GlobalIds.TRUST_STORE_PW ) ) )
- {
- // validate certificates but allow self-signed certs if within this truststore:
- logConfig.setTrustManagers( new LdapClientTrustStoreManager( Config.getProperty( GlobalIds.TRUST_STORE ),
- Config.getProperty( GlobalIds.TRUST_STORE_PW ).toCharArray(),
- null, true ) );
- }
-
- logConfig.setName( Config.getProperty( LDAP_LOG_POOL_UID, "" ) );
- String logPw;
- if ( EncryptUtil.isEnabled() )
- {
- logPw = EncryptUtil.decrypt( Config.getProperty( LDAP_LOG_POOL_PW ) );
- }
- else
- {
- logPw = Config.getProperty( LDAP_LOG_POOL_PW );
- }
- logConfig.setCredentials( logPw );
- poolFactory = new ValidatingPoolableLdapConnectionFactory( logConfig );
- logPool = new LdapConnectionPool( poolFactory );
- logPool.setTestOnBorrow( true );
- logPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
- logPool.setMaxActive( logmax );
- logPool.setMinIdle( logmin );
- }
- }
-
-
- /**
- * Given a contextId and a fortress param name return the LDAP dn.
- *
- * @param contextId is to determine what sub-tree to use.
- * @param root contains the fortress parameter name that corresponds with a particular LDAP container.
- * @return String contains the dn to use for operation.
- */
- protected String getRootDn( String contextId, String root )
- {
- String szDn = Config.getProperty( root );
-
- // The contextId must not be null, or "HOME" or "null"
- if ( StringUtils.isNotEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL ) && !contextId
- .equals( GlobalIds.HOME ) )
- {
- int idx = szDn.indexOf( Config.getProperty( GlobalIds.SUFFIX ) );
- if ( idx > 0 )
- {
- // Found. The DN is ,ou=<contextId>,
- StringBuilder dn = new StringBuilder();
- dn.append( szDn.substring( 0, idx - 1 ) ).append( "," ).append( SchemaConstants.OU_AT ).append( "=" )
- .append(
- contextId ).append( "," ).append( szDn.substring( idx ) );
-
- return dn.toString();
- }
- else
- {
- return "";
- }
- }
- else
- {
- return szDn;
- }
- }
-
-
- /**
- * Given a contextId return the LDAP dn that includes the suffix.
- *
- * @param contextId is to determine what sub-tree to use.
- * @return String contains the dn to use for operation.
- */
- protected String getRootDn( String contextId )
- {
- StringBuilder dn = new StringBuilder();
- if ( StringUtils.isNotEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL ) && !contextId
- .equals( GlobalIds.HOME ) )
- {
- dn.append( SchemaConstants.OU_AT ).append( "=" ).append( contextId ).append( "," +
- "" ).append( Config.getProperty( GlobalIds.SUFFIX ) );
- }
- else
- {
- dn.append( Config.getProperty( GlobalIds.SUFFIX ) );
- }
- return dn.toString();
- }
-
-
- /**
- * Read the ldap record from specified location.
- *
- * @param connection handle to ldap connection.
- * @param dn contains ldap distinguished name.
- * @param attrs array contains array names to pull back.
- * @return ldap entry.
- * @throws LdapException in the event system error occurs.
- */
- protected Entry read( LdapConnection connection, String dn, String[] attrs ) throws LdapException
- {
- COUNTERS.incrementRead();
-
- return connection.lookup( dn, attrs );
- }
-
-
- /**
- * Read the ldap record from specified location.
- *
- * @param connection handle to ldap connection.
- * @param dn contains ldap distinguished name.
- * @param attrs array contains array names to pull back.
- * @return ldap entry.
- * @throws LdapException in the event system error occurs.
- */
- protected Entry read( LdapConnection connection, Dn dn, String[] attrs ) throws LdapException
- {
- COUNTERS.incrementRead();
-
- return connection.lookup( dn, attrs );
- }
-
-
- /**
- * Read the ldap record from specified location with user assertion.
- *
- * @param connection handle to ldap connection.
- * @param dn contains ldap distinguished name.
- * @param attrs array contains array names to pull back. ,
- * PoolMgr.ConnType.USER
- * @param userDn string value represents the identity of user on who's behalf the request was initiated. The
- * value will be stored in openldap auditsearch record AuthZID's attribute.
- * @return ldap entry.
- * @throws LdapException in the event system error occurs.
- * @throws UnsupportedEncodingException for search control errors.
- */
- protected Entry read( LdapConnection connection, String dn, String[] attrs, String userDn ) throws LdapException
- {
- COUNTERS.incrementRead();
-
- return connection.lookup( dn, attrs );
- }
-
-
- /**
- * Add a new ldap entry to the directory. Do not add audit context.
- *
- * @param connection handle to ldap connection.
- * @param entry contains data to add..
- * @throws LdapException in the event system error occurs.
- */
- protected void add( LdapConnection connection, Entry entry ) throws LdapException
- {
- COUNTERS.incrementAdd();
- connection.add( entry );
- }
-
-
- /**
- * Add a new ldap entry to the directory. Add audit context.
- *
- * @param connection handle to ldap connection.
- * @param entry contains data to add..
- * @param entity contains audit context.
- * @throws LdapException in the event system error occurs.
- */
- protected void add( LdapConnection connection, Entry entry, FortEntity entity ) throws LdapException
- {
- COUNTERS.incrementAdd();
-
- if ( !GlobalIds.IS_AUDIT_DISABLED && ( entity != null ) && ( entity.getAdminSession() != null ) )
- {
- if ( StringUtils.isNotEmpty( entity.getAdminSession().getInternalUserId() ) )
- {
- entry.add( GlobalIds.FT_MODIFIER, entity.getAdminSession().getInternalUserId() );
- }
-
- if ( StringUtils.isNotEmpty( entity.getModCode() ) )
- {
- entry.add( GlobalIds.FT_MODIFIER_CODE, entity.getModCode() );
- }
-
- if ( StringUtils.isNotEmpty( entity.getModId() ) )
- {
- entry.add( GlobalIds.FT_MODIFIER_ID, entity.getModId() );
- }
- }
-
- connection.add( entry );
- }
-
-
- /**
- * Update exiting ldap entry to the directory. Do not add audit context.
- *
- * @param connection handle to ldap connection.
- * @param dn contains distinguished node of entry.
- * @param mods contains data to modify.
- * @throws LdapException in the event system error occurs.
- */
- protected void modify( LdapConnection connection, String dn, List<Modification> mods ) throws LdapException
- {
- COUNTERS.incrementMod();
- connection.modify( dn, mods.toArray( new Modification[]
- {} ) );
- }
-
-
- /**
- * Update exiting ldap entry to the directory. Do not add audit context.
- *
- * @param connection handle to ldap connection.
- * @param dn contains distinguished node of entry.
- * @param mods contains data to modify.
- * @throws LdapException in the event system error occurs.
- */
- protected void modify( LdapConnection connection, Dn dn, List<Modification> mods ) throws LdapException
- {
- COUNTERS.incrementMod();
- connection.modify( dn, mods.toArray( new Modification[]
- {} ) );
- }
-
-
- /**
- * Update exiting ldap entry to the directory. Add audit context.
- *
- * @param connection handle to ldap connection.
- * @param dn contains distinguished node of entry.
- * @param mods contains data to modify.
- * @param entity contains audit context.
- * @throws LdapException in the event system error occurs.
- */
- protected void modify( LdapConnection connection, String dn, List<Modification> mods,
- FortEntity entity ) throws LdapException
- {
- COUNTERS.incrementMod();
- audit( mods, entity );
- connection.modify( dn, mods.toArray( new Modification[]
- {} ) );
- }
-
-
- /**
- * Update exiting ldap entry to the directory. Add audit context.
- *
- * @param connection handle to ldap connection.
- * @param dn contains distinguished node of entry.
- * @param mods contains data to modify.
- * @param entity contains audit context.
- * @throws LdapException in the event system error occurs.
- */
- protected void modify( LdapConnection connection, Dn dn, List<Modification> mods,
- FortEntity entity ) throws LdapException
- {
- COUNTERS.incrementMod();
- audit( mods, entity );
- connection.modify( dn, mods.toArray( new Modification[]
- {} ) );
- }
-
-
- /**
- * Delete exiting ldap entry from the directory. Do not add audit context.
- *
- * @param connection handle to ldap connection.
- * @param dn contains distinguished node of entry targeted for removal..
- * @throws LdapException in the event system error occurs.
- */
- protected void delete( LdapConnection connection, String dn ) throws LdapException
- {
- COUNTERS.incrementDelete();
- connection.delete( dn );
- }
-
-
- /**
- * Delete exiting ldap entry from the directory. Add audit context. This method will call modify prior to
- * delete which will
- * force corresponding audit record to be written to slapd access log.
- *
- * @param connection handle to ldap connection.
- * @param dn contains distinguished node of entry targeted for removal..
- * @param entity contains audit context.
- * @throws LdapException in the event system error occurs.
- */
- protected void delete( LdapConnection connection, String dn, FortEntity entity ) throws LdapException
- {
- COUNTERS.incrementDelete();
- List<Modification> mods = new ArrayList<Modification>();
- audit( mods, entity );
-
- if ( mods.size() > 0 )
- {
- modify( connection, dn, mods );
- }
-
- connection.delete( dn );
- }
-
-
- /**
- * Delete exiting ldap entry from the directory. Add audit context. This method will call modify prior to
- * delete which will
- * force corresponding audit record to be written to slapd access log.
- *
- * @param connection handle to ldap connection.
- * @param dn contains distinguished node of entry targeted for removal..
- * @param entity contains audit context.
- * @throws LdapException in the event system error occurs.
- */
- protected void delete( LdapConnection connection, Dn dn, FortEntity entity ) throws LdapException
- {
- COUNTERS.incrementDelete();
- List<Modification> mods = new ArrayList<Modification>();
- audit( mods, entity );
-
- if ( mods.size() > 0 )
- {
- modify( connection, dn, mods );
- }
-
- connection.delete( dn );
- }
-
-
- /**
- * Delete exiting ldap entry and all descendants from the directory. Do not add audit context.
- *
- * @param connection handle to ldap connection.
- * @param dn contains distinguished node of entry targeted for removal..
- * @throws LdapException in the event system error occurs.
- * @throws IOException
- * @throws CursorException
- */
- protected void deleteRecursive( LdapConnection connection, String dn ) throws LdapException, CursorException
- {
- int recursiveCount = 0;
- deleteRecursive( dn, connection, recursiveCount );
- }
-
-
- /**
- * Delete exiting ldap entry and all descendants from the directory. Add audit context. This method will call
- * modify prior to delete which will
- * force corresponding audit record to be written to slapd access log.
- *
- * @param connection handle to ldap connection.
- * @param dn contains distinguished node of entry targeted for removal..
- * @param entity contains audit context.
- * @throws LdapException in the event system error occurs.
- * @throws CursorException
- */
- protected void deleteRecursive( LdapConnection connection, String dn, FortEntity entity ) throws LdapException,
- CursorException
- {
- List<Modification> mods = new ArrayList<Modification>();
- audit( mods, entity );
-
- if ( mods.size() > 0 )
- {
- modify( connection, dn, mods );
- }
-
- deleteRecursive( connection, dn );
- }
-
-
- /**
- * Used to recursively remove all nodes up to record pointed to by dn attribute.
- *
- * @param dn contains distinguished node of entry targeted for removal..
- * @param connection handle to ldap connection.
- * @param recursiveCount keeps track of how many iterations have been performed.
- * @throws LdapException in the event system error occurs.
- * @throws CursorException
- */
- private void deleteRecursive( String dn, LdapConnection connection, int recursiveCount ) throws LdapException,
- CursorException
- {
- String method = "deleteRecursive";
-
- // Sanity check - only allow max tree depth of 100
- if ( recursiveCount++ > MAX_DEPTH )
- {
- // too deep inside of a recursive sequence;
- String error = "." + method + " dn [" + dn + "] depth error in recursive";
- throw new LdapOperationErrorException( error );
- }
-
- String theDN;
-
- // Find child nodes
- SearchCursor cursor = search( connection, dn, SearchScope.ONELEVEL, "(objectclass=*)",
- SchemaConstants.NO_ATTRIBUTE_ARRAY,
- false, 0 );
-
- // Iterate over all entries under this entry
- while ( cursor.next() )
- {
- try
- {
- // Next directory entry
- Entry entry = cursor.getEntry();
- theDN = entry.getDn().getName();
- // continue down:
- deleteRecursive( theDN, connection, recursiveCount );
- recursiveCount--;
- }
- catch ( LdapException le )
- {
- // cannot continue;
- String error = "." + method + " dn [" + dn + "] caught LdapException=" + le.getMessage();
- throw new LdapException( error );
- }
- }
-
- // delete the node:
- COUNTERS.incrementDelete();
- delete( connection, dn );
- }
-
-
- /**
- * Add the audit context variables to the modfication set.
- *
- * @param mods used to update ldap attributes.
- * @param entity contains audit context.
- */
- private void audit( List<Modification> mods, FortEntity entity )
- {
- if ( !GlobalIds.IS_AUDIT_DISABLED && ( entity != null ) && ( entity.getAdminSession() != null ) )
- {
- if ( StringUtils.isNotEmpty( entity.getAdminSession().getInternalUserId() ) )
- {
- Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
- GlobalIds.FT_MODIFIER, entity.getAdminSession().getInternalUserId() );
- mods.add( modification );
- }
-
- if ( StringUtils.isNotEmpty( entity.getModCode() ) )
- {
- Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
- GlobalIds.FT_MODIFIER_CODE, entity.getModCode() );
- mods.add( modification );
- }
-
- if ( StringUtils.isNotEmpty( entity.getModId() ) )
- {
- Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
- GlobalIds.FT_MODIFIER_ID, entity.getModId() );
- mods.add( modification );
- }
- }
- }
-
-
- /**
- * Perform normal ldap search accepting default batch size.
- *
- * @param connection is LdapConnection object used for all communication with host.
- * @param baseDn contains address of distinguished name to begin ldap search
- * @param scope indicates depth of search starting at basedn. 0 (base dn),
- * 1 (one level down) or 2 (infinite) are valid values.
- * @param filter contains the search criteria
- * @param attrs is the requested list of attritubutes to return from directory search.
- * @param attrsOnly if true pull back attribute names only.
- * @return result set containing ldap entries returned from directory.
- * @throws LdapException thrown in the event of error in ldap client or server code.
- */
- protected SearchCursor search( LdapConnection connection, String baseDn, SearchScope scope, String filter,
- String[] attrs, boolean attrsOnly ) throws LdapException
- {
- COUNTERS.incrementSearch();
-
- SearchRequest searchRequest = new SearchRequestImpl();
- searchRequest.setBase( new Dn( baseDn ) );
- searchRequest.setScope( scope );
- searchRequest.setFilter( filter );
- searchRequest.setTypesOnly( attrsOnly );
- searchRequest.addAttributes( attrs );
-
- return connection.search( searchRequest );
- }
-
-
- /**
- * Perform normal ldap search specifying default batch size and max entries to return.
- *
- * @param connection is LdapConnection object used for all communication with host.
- * @param baseDn contains address of distinguished name to begin ldap search
- * @param scope indicates depth of search starting at basedn. 0 (base dn),
- * 1 (one level down) or 2 (infinite) are valid values.
- * @param filter contains the search criteria
- * @param attrs is the requested list of attritubutes to return from directory search.
- * @param attrsOnly if true pull back attribute names only.
- * @param maxEntries specifies the maximum number of entries to return in this search query.
- * @return result set containing ldap entries returned from directory.
- * @throws LdapException thrown in the event of error in ldap client or server code.
- */
- protected SearchCursor search( LdapConnection connection, String baseDn, SearchScope scope, String filter,
- String[] attrs, boolean attrsOnly, int maxEntries ) throws LdapException
- {
- COUNTERS.incrementSearch();
-
- SearchRequest searchRequest = new SearchRequestImpl();
-
- searchRequest.setBase( new Dn( baseDn ) );
- searchRequest.setFilter( filter );
- searchRequest.setScope( scope );
- searchRequest.setSizeLimit( maxEntries );
- searchRequest.setTypesOnly( attrsOnly );
- searchRequest.addAttributes( attrs );
-
- return connection.search( searchRequest );
- }
-
-
- /**
- * This method will search the directory and return at most one record. If more than one record is found
- * an ldap exception will be thrown.
- *
- * @param connection is LdapConnection object used for all communication with host.
- * @param baseDn contains address of distinguished name to begin ldap search
- * @param scope indicates depth of search starting at basedn. 0 (base dn),
- * 1 (one level down) or 2 (infinite) are valid values.
- * @param filter contains the search criteria
- * @param attrs is the requested list of attritubutes to return from directory search.
- * @param attrsOnly if true pull back attribute names only.
- * @return entry containing target ldap node.
- * @throws LdapException thrown in the event of error in ldap client or server code.
- * @throws CursorException If we weren't able to fetch an element from the search result
- */
- protected Entry searchNode( LdapConnection connection, String baseDn, SearchScope scope, String filter,
- String[] attrs, boolean attrsOnly ) throws LdapException, CursorException
- {
- SearchRequest searchRequest = new SearchRequestImpl();
-
- searchRequest.setBase( new Dn( baseDn ) );
- searchRequest.setFilter( filter );
- searchRequest.setScope( scope );
- searchRequest.setTypesOnly( attrsOnly );
- searchRequest.addAttributes( attrs );
-
- SearchCursor result = connection.search( searchRequest );
-
- Entry entry = result.getEntry();
-
- if ( result.next() )
- {
- throw new LdapException( "searchNode failed to return unique record for LDAP search of base DN [" +
- baseDn + "] filter [" + filter + "]" );
- }
-
- return entry;
- }
-
-
- /**
- * This search method uses OpenLDAP Proxy Authorization Control to assert arbitrary user identity onto connection.
- *
- * @param connection is LdapConnection object used for all communication with host.
- * @param baseDn contains address of distinguished name to begin ldap search
- * @param scope indicates depth of search starting at basedn. 0 (base dn),
- * 1 (one level down) or 2 (infinite) are valid values.
- * @param filter contains the search criteria
- * @param attrs is the requested list of attritubutes to return from directory search.
- * @param attrsOnly if true pull back attribute names only.
- * @param userDn string value represents the identity of user on who's behalf the request was initiated. The
- * value will be stored in openldap auditsearch record AuthZID's attribute.
- * @return entry containing target ldap node.
- * @throws LdapException thrown in the event of error in ldap client or server code.
- * @throws CursorException If we weren't able to fetch an element from the search result
- */
- protected Entry searchNode( LdapConnection connection, String baseDn, SearchScope scope, String filter,
- String[] attrs, boolean attrsOnly, String userDn ) throws LdapException, CursorException
- {
- COUNTERS.incrementSearch();
-
- SearchRequest searchRequest = new SearchRequestImpl();
-
- searchRequest.setBase( new Dn( baseDn ) );
- searchRequest.setFilter( filter );
- searchRequest.setScope( scope );
- searchRequest.setTypesOnly( attrsOnly );
- searchRequest.addAttributes( attrs );
-
- SearchCursor result = connection.search( searchRequest );
-
- Entry entry = result.getEntry();
-
- if ( result.next() )
- {
- throw new LdapException( "searchNode failed to return unique record for LDAP search of base DN [" +
- baseDn + "] filter [" + filter + "]" );
- }
-
- return entry;
- }
-
-
- /**
- * This method uses the compare ldap func to assert audit record into the directory server's configured audit
- * logger.
- *
- * This is for one reason - to force the ldap server to maintain an audit trail on checkAccess api.
- *
- * Use proxy authz control (RFC4370) to assert the caller's id onto the record.
- *
- * @param connection is LdapConnection object used for all communication with host.
- * @param dn contains address of distinguished name to begin ldap search
- * @param userDn dn for user node
- * @param attribute attribute used for compare
- * @return true if compare operation succeeds
- * @throws LdapException thrown in the event of error in ldap client or server code.
- * @throws UnsupportedEncodingException in the event the server cannot perform the operation.
- */
- protected boolean compareNode( LdapConnection connection, String dn, String userDn,
- Attribute attribute ) throws LdapException, UnsupportedEncodingException
- {
- COUNTERS.incrementCompare();
-
- CompareRequest compareRequest = new CompareRequestImpl();
- compareRequest.setName( new Dn( dn ) );
- compareRequest.setAttributeId( attribute.getId() );
- compareRequest.setAssertionValue( attribute.getString() );
-
- // Assert the end user's dn onto the reqest using proxy authZ control so openldap can log who the user was (for authZ audit trail)
- ProxiedAuthz proxiedAuthzControl = new ProxiedAuthzImpl();
- proxiedAuthzControl.setAuthzId( "dn: " + userDn );
- compareRequest.addControl( proxiedAuthzControl );
- CompareResponse response = connection.compare( compareRequest );
- return response.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS;
- }
-
-
- /**
- * Method wraps ldap client to return multi-occurring attribute values by name within a given entry and returns
- * as a list of strings.
- *
- * @param entry contains the target ldap entry.
- * @param attributeName name of ldap attribute to retrieve.
- * @return List of type string containing attribute values.
- */
- protected List<String> getAttributes( Entry entry, String attributeName )
- {
- List<String> attrValues = new ArrayList<>();
- if ( entry != null )
- {
- Attribute attr = entry.get( attributeName );
- if ( attr != null )
- {
- for ( Value<?> value : attr )
- {
- attrValues.add( value.getString() );
- }
- }
- else
- {
- return null;
- }
- }
-
- return attrValues;
- }
-
-
- /**
- * Return the image stored on the entry.
- *
- * @param entry contains the image target.
- * @param attributeName to be retrieved.
- * @return byte array containing image.
- * @throws LdapInvalidAttributeValueException contains the system error.
- */
- protected byte[] getPhoto( Entry entry, String attributeName ) throws LdapInvalidAttributeValueException
- {
- byte[] photo = null;
- Attribute attr = entry.get( attributeName );
-
- if ( attr != null )
- {
- photo = attr.getBytes();
- }
-
- return photo;
- }
-
-
- /**
- * Method wraps ldap client to return multi-occurring attribute values by name within a given entry and returns
- * as a set of strings.
- *
- * @param entry contains the target ldap entry.
- * @param attributeName name of ldap attribute to retrieve.
- * @return List of type string containing attribute values.
- */
- protected Set<String> getAttributeSet( Entry entry, String attributeName )
- {
- // create Set with case insensitive comparator:
- Set<String> attrValues = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
-
- if ( entry != null && entry.containsAttribute( attributeName ) )
- {
- for ( Value<?> value : entry.get( attributeName ) )
- {
- attrValues.add( value.getString() );
- }
- }
-
- return attrValues;
- }
-
-
- /**
- * Method wraps ldap client to return attribute value by name within a given entry and returns as a string.
- *
- * @param entry contains the target ldap entry.
- * @param attributeName name of ldap attribute to retrieve.
- * @return value contained in a string variable.
- * @throws LdapInvalidAttributeValueException When we weren't able to get the attribute from the entry
- */
- protected String getAttribute( Entry entry, String attributeName ) throws LdapInvalidAttributeValueException
- {
- if ( entry != null )
- {
- Attribute attr = entry.get( attributeName );
-
- if ( attr != null )
- {
- return attr.getString();
- }
- else
- {
- return null;
- }
- }
- else
- {
- return null;
- }
- }
-
-
- /**
- * Method will retrieve the relative distinguished name from a distinguished name variable.
- *
- * @param dn contains ldap distinguished name.
- * @return rDn as string.
- */
- protected String getRdn( String dn )
- {
- try
- {
- return new Dn( dn ).getRdn().getName();
- }
- catch ( LdapInvalidDnException lide )
- {
- return null;
- }
- }
-
-
- /**
- * Create multi-occurring ldap attribute given array of strings and attribute name.
- *
- * @param name contains attribute name to create.
- * @param values array of string that contains attribute values.
- * @return Attribute containing multi-occurring attribute set.
- * @throws LdapException in the event of ldap client error.
- */
- protected Attribute createAttributes( String name, String values[] ) throws LdapException
- {
- return new DefaultAttribute( name, values );
- }
-
-
- /**
- * Convert constraint from raw ldap format to application entity.
- *
- * @param le ldap entry containing constraint.
- * @param ftDateTime reference to {@link org.apache.directory.fortress.core.model.Constraint} containing formatted data.
- * @throws LdapInvalidAttributeValueException
- *
- * @throws LdapInvalidAttributeValueException when we weren't able to retrieve the attribute from the entry
- */
- protected void unloadTemporal( Entry le, Constraint ftDateTime ) throws LdapInvalidAttributeValueException
- {
- String szRawData = getAttribute( le, GlobalIds.CONSTRAINT );
-
- if ( szRawData != null && szRawData.length() > 0 )
- {
- ConstraintUtil.setConstraint( szRawData, ftDateTime );
- }
- }
-
-
- /**
- * Given an ldap attribute name and a list of attribute values, construct an ldap attribute set to be added to directory.
- *
- * @param list list of type string containing attribute values to load into attribute set.
- * @param entry contains ldap attribute set targeted for adding.
- * @param attrName name of ldap attribute being added.
- * @throws LdapException If we weren't able to add the attributes into the entry
- */
- protected void loadAttrs( List<String> list, Entry entry, String attrName ) throws LdapException
- {
- if ( list != null && list.size() > 0 )
- {
- entry.add( attrName, list.toArray( new String[]
- {} ) );
- }
- }
-
-
- /**
- * Given an ldap attribute name and a list of attribute values, construct an ldap modification set to be updated
- * in directory.
- *
- * @param list list of type string containing attribute values to load into modification set.
- * @param mods contains ldap modification set targeted for updating.
- * @param attrName name of ldap attribute being modified.
- */
- protected void loadAttrs( List<String> list, List<Modification> mods, String attrName )
- {
- if ( ( list != null ) && ( list.size() > 0 ) )
- {
- mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attrName,
- list.toArray( new String[]
- {} ) ) );
- }
- }
-
-
- /**
- * Given a collection of {@link org.apache.directory.fortress.core.model.Relationship}s, convert to raw data name-value format and
- * load into ldap modification set in preparation for ldap modify.
- *
- * @param list contains List of type {@link org.apache.directory.fortress.core.model.Relationship} targeted for updating in ldap.
- * @param mods ldap modification set containing parent-child relationships in raw ldap format.
- * @param attrName contains the name of the ldap attribute to be updated.
- * @param op specifies type of mod: {@link org.apache.directory.fortress.core.model.Hier.Op#ADD},
- * {@link org.apache.directory.fortress.core.model.Hier.Op#MOD}, {@link org.apache.directory.fortress.core.model.Hier.Op#REM}.
- */
- protected void loadRelationshipAttrs( List<Relationship> list, List<Modification> mods, String attrName,
- Hier.Op op )
- {
- if ( list != null )
- {
- Attribute attr;
-
- for ( Relationship rel : list )
- {
- // This LDAP attr is stored as a name-value pair separated by a ':'.
- attr = new DefaultAttribute( attrName, rel.getChild() + GlobalIds.PROP_SEP + rel.getParent() );
-
- switch ( op )
- {
- case ADD:
- mods.add( new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, attr ) );
- break;
-
- case MOD:
- mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attr ) );
- break;
-
- case REM:
- mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attr ) );
- break;
- }
- }
- }
- }
-
-
- /**
- * Given an ldap attribute name and a set of attribute values, construct an ldap modification set to be updated
- * in directory.
- *
- * @param values set of type string containing attribute values to load into modification set.
- * @param mods contains ldap modification set targeted for updating.
- * @param attrName name of ldap attribute being updated.
- */
- protected void loadAttrs( Set<String> values, List<Modification> mods, String attrName )
- {
- if ( ( values != null ) && ( values.size() > 0 ) )
- {
- mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attrName,
- values.toArray( new String[]
- {} ) ) );
- }
- }
-
-
- /**
- * Given an ldap attribute name and a set of attribute values, construct an ldap attribute set to be added to
- * directory.
- *
- * @param values set of type string containing attribute values to load into attribute set.
- * @param entry contains ldap entry to pull attrs from.
- * @param attrName name of ldap attribute being added.
- * @throws LdapException If we weren't able to add the values into the entry
- */
- protected void loadAttrs( Set<String> values, Entry entry, String attrName ) throws LdapException
- {
- if ( ( values != null ) && ( values.size() > 0 ) )
- {
- entry.add( attrName, values.toArray( new String[]
- {} ) );
- }
- }
-
-
- /**
- * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
- * modification set in preparation for ldap modify.
- *
- * @param props contains {@link java.util.Properties} targeted for updating in ldap.
- * @param mods ldap modification set containing name-value pairs in raw ldap format.
- * @param attrName contains the name of the ldap attribute to be updated.
- * @param replace boolean variable, if set to true use {@link ModificationOperation#REPLACE_ATTRIBUTE} else {@link
- * ModificationOperation#ADD_ATTRIBUTE}.
- */
- protected void loadProperties( Properties props, List<Modification> mods, String attrName, boolean replace )
- {
- loadProperties( props, mods, attrName, replace, GlobalIds.PROP_SEP );
- }
-
-
- /**
- * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
- * modification set in preparation for ldap modify.
- *
- * @param props contains {@link java.util.Properties} targeted for updating in ldap.
- * @param mods ldap modification set containing name-value pairs in raw ldap format.
- * @param attrName contains the name of the ldap attribute to be updated.
- * @param replace boolean variable, if set to true use {@link ModificationOperation#REPLACE_ATTRIBUTE} else {@link
- * ModificationOperation#ADD_ATTRIBUTE}.
- * @param separator contains the char value used to separate name and value in ldap raw format.
- */
- protected void loadProperties( Properties props, List<Modification> mods, String attrName, boolean replace,
- char separator )
- {
- if ( props != null && props.size() > 0 )
- {
- if ( replace )
- {
- mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attrName ) );
- }
-
- for ( Enumeration<?> e = props.propertyNames(); e.hasMoreElements(); )
- {
- String key = ( String ) e.nextElement();
- String val = props.getProperty( key );
- // This LDAP attr is stored as a name-value pair separated by a ':'.
- mods.add( new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, attrName,
- key + separator + val ) );
- }
- }
- }
-
-
- /**
- * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
- * modification set in preparation for ldap modify.
- *
- * @param props contains {@link java.util.Properties} targeted for removal from ldap.
- * @param mods ldap modification set containing name-value pairs in raw ldap format to be removed.
- * @param attrName contains the name of the ldap attribute to be removed.
- */
- protected void removeProperties( Properties props, List<Modification> mods, String attrName )
- {
- if ( props != null && props.size() > 0 )
- {
- for ( Enumeration<?> e = props.propertyNames(); e.hasMoreElements(); )
- {
- String key = ( String ) e.nextElement();
- String val = props.getProperty( key );
-
- // This LDAP attr is stored as a name-value pair separated by a ':'.
- mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attrName,
- key + GlobalIds.PROP_SEP + val ) );
- }
- }
- }
-
-
- /**
- * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
- * modification set in preparation for ldap add.
- *
- * @param props contains {@link java.util.Properties} targeted for adding to ldap.
- * @param entry contains ldap entry to pull attrs from.
- * @param attrName contains the name of the ldap attribute to be added.
- * @throws LdapException If we weren't able to add the properies into the entry
- */
- protected void loadProperties( Properties props, Entry entry, String attrName ) throws LdapException
- {
- if ( ( props != null ) && ( props.size() > 0 ) )
- {
- Attribute attr = new DefaultAttribute( attrName );
-
- for ( Enumeration<?> e = props.propertyNames(); e.hasMoreElements(); )
- {
- // This LDAP attr is stored as a name-value pair separated by a ':'.
- String key = ( String ) e.nextElement();
- String val = props.getProperty( key );
- String prop = key + GlobalIds.PROP_SEP + val;
-
- attr.add( prop );
- }
-
- if ( attr.size() != 0 )
- {
- entry.add( attr );
- }
- }
- }
-
-
- /**
- * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap modification set in preparation for ldap add.
- *
- * @param props contains {@link java.util.Properties} targeted for adding to ldap.
- * @param entry contains ldap entry to push attrs into.
- * @param attrName contains the name of the ldap attribute to be added.
- * @param separator contains the char value used to separate name and value in ldap raw format.
- * @throws LdapException If we weren't able to add the properies into the entry
- */
- protected void loadProperties( Properties props, Entry entry, String attrName, char separator )
- throws LdapException
- {
- if ( ( props != null ) && ( props.size() > 0 ) )
- {
- Attribute attr = null;
-
- for ( Enumeration<?> e = props.propertyNames(); e.hasMoreElements(); )
- {
- // This LDAP attr is stored as a name-value pair separated by a ':'.
- String key = ( String ) e.nextElement();
- String val = props.getProperty( key );
- String prop = key + separator + val;
-
- if ( attr == null )
- {
- attr = new DefaultAttribute( attrName );
- }
- else
- {
- attr.add( prop );
- }
- }
-
- if ( attr != null )
- {
- entry.add( attr );
- }
- }
- }
-
-
- /**
- * Encode some text so that it can be used in a LDAP filter.
- *
- * @param value The value to encode
- * @param validLen The maximum accepted length of the value.
- * @return String containing encoded data.
- * @throws LdapException If the value is longer than the maximum value
- */
- protected String encodeSafeText( String value, int validLen ) throws LdapException
- {
- if ( StringUtils.isNotEmpty( value ) )
- {
- int length = value.length();
-
- if ( length > validLen )
- {
- String error = "encodeSafeText value [" + value + "] invalid length [" + length + "]";
- throw new LdapException( error );
- }
-
- if ( GlobalIds.LDAP_FILTER_SIZE_FOUND )
- {
- value = escapeLDAPSearchFilter( value );
- }
- }
-
- return value;
- }
-
-
- /**
- * Get Password Policy Response Control from LDAP client.
- *
- * @param resp contains reference to LDAP pw policy response.
- * @return PasswordPolicy response control.
- */
- protected PasswordPolicy getPwdRespCtrl( Response resp )
- {
- Control control = resp.getControls().get( PP_REQ_CTRL.getOid() );
- if ( control == null )
- {
- return null;
- }
-
- return ( ( PasswordPolicyDecorator ) control ).getDecorated();
- }
-
-
- /**
- * Calls the PoolMgr to perform an LDAP bind for a user/password combination. This function is valid
- * if and only if the user entity is a member of the USERS data set.
- *
- * @param connection connection to ldap server.
- * @param szUserDn contains the LDAP dn to the user entry in String format.
- * @param password contains the password in clear text.
- * @return bindResponse contains the result of the operation.
- * @throws LdapException in the event of LDAP error.
- */
- protected BindResponse bind( LdapConnection connection, String szUserDn, char[] password ) throws LdapException
- {
- COUNTERS.incrementBind();
- Dn userDn = new Dn( szUserDn );
- BindRequest bindReq = new BindRequestImpl();
- bindReq.setDn( userDn );
- bindReq.setCredentials( new String( password ) );
- bindReq.addControl( PP_REQ_CTRL );
- return connection.bind( bindReq );
- }
-
-
- /**
- * Calls the PoolMgr to close the Admin LDAP connection.
- *
- * @param connection handle to ldap connection object.
- */
- protected void closeAdminConnection( LdapConnection connection )
- {
- try
- {
- adminPool.releaseConnection( connection );
- }
- catch ( Exception e )
- {
- throw new RuntimeException( e.getMessage(), e );
- }
- }
-
-
- /**
- * Calls the PoolMgr to close the Log LDAP connection.
- *
- * @param connection handle to ldap connection object.
- */
- protected void closeLogConnection( LdapConnection connection )
- {
- try
- {
- logPool.releaseConnection( connection );
- }
- catch ( Exception e )
- {
- throw new RuntimeException( e.getMessage(), e );
- }
- }
-
-
- /**
- * Calls the PoolMgr to close the User LDAP connection.
- *
- * @param connection handle to ldap connection object.
- */
- protected void closeUserConnection( LdapConnection connection )
- {
- try
- {
- userPool.releaseConnection( connection );
- }
- catch ( Exception e )
- {
- throw new RuntimeException( e.getMessage(), e );
- }
- }
-
-
- /**
- * Calls the PoolMgr to get an Admin connection to the LDAP server.
- *
- * @return ldap connection.
- * @throws LdapException If we had an issue getting an LDAP connection
- */
- protected LdapConnection getAdminConnection() throws LdapException
- {
- try
- {
- return adminPool.getConnection();
- }
- catch ( Exception e )
- {
- throw new LdapException( e.getMessage(), e );
- }
- }
-
-
- /**
- * Calls the PoolMgr to get an Log connection to the LDAP server.
- *
- * @return ldap connection.
- * @throws LdapException If we had an issue getting an LDAP connection
- */
- protected LdapConnection getLogConnection() throws LdapException
- {
- try
- {
- return logPool.getConnection();
- }
- catch ( Exception e )
- {
- throw new LdapException( e.getMessage(), e );
- }
- }
-
-
- /**
- * Calls the PoolMgr to get an User connection to the LDAP server.
- *
- * @return ldap connection.
- * @throws LdapException If we had an issue getting an LDAP connection
- */
- protected LdapConnection getUserConnection() throws LdapException
- {
- try
- {
- return userPool.getConnection();
- }
- catch ( Exception e )
- {
- throw new LdapException( e.getMessage(), e );
- }
- }
-
-
- /**
- * Return to call reference to dao counter object with running totals for ldap operations add, mod, delete, search, etc.
- *
- * @return {@link LdapCounters} contains long values of atomic ldap operations for current running process.
- */
- public static LdapCounters getLdapCounters()
- {
- return COUNTERS;
- }
-
-
- /**
- *
- */
- private static char[] loadLdapEscapeChars()
- {
- if ( !GlobalIds.LDAP_FILTER_SIZE_FOUND )
- {
- return null;
- }
-
- char[] ldapMetaChars = new char[GlobalIds.LDAP_FILTER_SIZE];
-
- for ( int i = 1;; i++ )
- {
- String prop = GlobalIds.LDAP_FILTER + i;
- String value = Config.getProperty( prop );
-
- if ( value == null )
- {
- break;
- }
-
- ldapMetaChars[i - 1] = value.charAt( 0 );
- }
-
- return ldapMetaChars;
- }
-
-
- /**
- *
- */
- private static String[] loadValidLdapVals()
- {
- if ( !GlobalIds.LDAP_FILTER_SIZE_FOUND )
- {
- return null;
- }
-
- String[] ldapReplacements = new String[GlobalIds.LDAP_FILTER_SIZE];
-
- for ( int i = 1;; i++ )
- {
- String prop = GlobalIds.LDAP_SUB + i;
- String value = Config.getProperty( prop );
-
- if ( value == null )
- {
- break;
- }
-
- ldapReplacements[i - 1] = value;
- }
-
- return ldapReplacements;
- }
-
-
- /**
- * Perform encoding on supplied input string for certain unsafe ascii characters. These chars may be unsafe
- * because ldap reserves some characters as operands. Safe encoding safeguards from malicious scripting input errors
- * that are possible if data filtering did not get performed before being passed into dao layer.
- *
- * @param filter contains the data to filter.
- * @return possibly modified input string for matched characters.
- */
- protected static String escapeLDAPSearchFilter( String filter )
- {
- StringBuilder sb = new StringBuilder();
- int filterLen = filter.length();
-
- for ( int i = 0; i < filterLen; i++ )
- {
- boolean found = false;
- char curChar = filter.charAt( i );
- int j = 0;
-
- for ( ; j < GlobalIds.LDAP_FILTER_SIZE; j++ )
- {
- if ( LDAP_META_CHARS[j] > curChar )
- {
- break;
- }
- else if ( curChar == LDAP_META_CHARS[j] )
- {
- sb.append( "\\" );
- sb.append( LDAP_REPL_VALS[j] );
- found = true;
- break;
- }
- }
-
- if ( !found )
- {
- sb.append( curChar );
- }
- }
-
- return sb.toString();
- }
-
- /**
- * Closes all the ldap connection pools.
- */
- public static void closeAllConnectionPools(){
- try{
- LOG.info("Closing admin pool");
- adminPool.close();
- }
- catch(Exception e){
- LOG.warn("Error closing admin pool: " + e.getMessage());
- }
-
- try{
- LOG.info("Closing user pool");
- userPool.close();
- }
- catch(Exception e){
- LOG.warn("Error closing user pool: " + e.getMessage());
- }
-
- try{
- LOG.info("Closing log pool");
- logPool.close();
- }
- catch(Exception e){
- LOG.warn("Error closing log pool: " + e.getMessage());
- }
- }
-
-}