You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2014/10/21 01:07:06 UTC

[49/50] git commit: FC-151 - UnboundID SDK removal preparations continue

FC-151 - UnboundID SDK removal preparations continue


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/39ac2790
Tree: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/tree/39ac2790
Diff: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/diff/39ac2790

Branch: refs/heads/master
Commit: 39ac27903efe58ac6a5a8e259857eb091a5ab8cc
Parents: 6bf332f
Author: Shawn McKinney <sh...@jts.us>
Authored: Mon Oct 20 14:14:35 2014 -0500
Committer: Shawn McKinney <sh...@jts.us>
Committed: Mon Oct 20 14:14:35 2014 -0500

----------------------------------------------------------------------
 .../org/openldap/fortress/GlobalErrIds.java     |   5 +
 .../openldap/fortress/SecurityException.java    |   2 +
 .../org/openldap/fortress/cfg/ConfigDAO.java    | 103 ++++----
 .../fortress/ldap/ApacheDsDataProvider.java     | 121 ++++++++-
 .../ldap/LdapClientTrustStoreManager.java       | 246 +++++++++++++++++++
 .../ldap/container/OrganizationalUnitDAO.java   |  43 ++--
 .../openldap/fortress/ldap/group/GroupDAO.java  | 202 +++++++--------
 .../fortress/ldap/suffix/SuffixDAO.java         |  41 ++--
 .../fortress/rbac/dao/apache/UserDAO.java       |  12 +-
 9 files changed, 569 insertions(+), 206 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/39ac2790/src/main/java/org/openldap/fortress/GlobalErrIds.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/GlobalErrIds.java b/src/main/java/org/openldap/fortress/GlobalErrIds.java
index 03d3055..6c116f5 100755
--- a/src/main/java/org/openldap/fortress/GlobalErrIds.java
+++ b/src/main/java/org/openldap/fortress/GlobalErrIds.java
@@ -166,6 +166,11 @@ public class GlobalErrIds
     public final static int FT_APACHE_LDAP_POOL_INIT_FAILED = 135;
 
     /**
+     * Cannot load JSSE TrustStore because the full-qualified input file name is null.
+     */
+    public final static int FT_CONFIG_JSSE_TRUSTSTORE_NULL = 136;
+
+    /**
      * 1000's - User Entity Rule and LDAP Errors
      */
 

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/39ac2790/src/main/java/org/openldap/fortress/SecurityException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/SecurityException.java b/src/main/java/org/openldap/fortress/SecurityException.java
index 80c467a..b39cb4e 100755
--- a/src/main/java/org/openldap/fortress/SecurityException.java
+++ b/src/main/java/org/openldap/fortress/SecurityException.java
@@ -69,6 +69,8 @@ package org.openldap.fortress;
  * <li> <code>{@link GlobalErrIds#FT_CACHE_FLUSH_ERR} = 133;</code>
  * <li> <code>{@link GlobalErrIds#FT_NULL_CACHE} = 134;</code>
  * <li> <code>{@link GlobalErrIds#FT_APACHE_LDAP_POOL_INIT_FAILED} = 135;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_JSSE_TRUSTSTORE_NULL} = 136;</code>
+ *
  * </ul>
  * <h3>
  * <p/>1000's - User Entity Rule and LDAP Errors

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/39ac2790/src/main/java/org/openldap/fortress/cfg/ConfigDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/cfg/ConfigDAO.java b/src/main/java/org/openldap/fortress/cfg/ConfigDAO.java
index 1565354..ca2d14b 100755
--- a/src/main/java/org/openldap/fortress/cfg/ConfigDAO.java
+++ b/src/main/java/org/openldap/fortress/cfg/ConfigDAO.java
@@ -16,8 +16,18 @@
 package org.openldap.fortress.cfg;
 
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Properties;
 
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+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.exception.LdapEntryAlreadyExistsException;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.openldap.fortress.ldap.ApacheDsDataProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -26,17 +36,9 @@ import org.openldap.fortress.GlobalErrIds;
 import org.openldap.fortress.GlobalIds;
 import org.openldap.fortress.RemoveException;
 import org.openldap.fortress.UpdateException;
-import org.openldap.fortress.ldap.UnboundIdDataProvider;
 import org.openldap.fortress.util.attr.AttrHelper;
 import org.openldap.fortress.util.attr.VUtil;
 
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModificationSet;
-
-
 /**
  * This class provides data access for the standard ldap object device that has been extended to support name/value pairs.
  * Fortress uses this data structure to store its remote cfg parameters.
@@ -72,7 +74,7 @@ import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModificationSet;
  *
  * @author Shawn McKinney
  */
-final class ConfigDAO extends UnboundIdDataProvider
+final class ConfigDAO extends ApacheDsDataProvider
 
 {
     private static final String CLS_NM = ConfigDAO.class.getName();
@@ -91,7 +93,6 @@ final class ConfigDAO extends UnboundIdDataProvider
             GlobalIds.CN, GlobalIds.PROPS
     };
 
-
     /**
      * Package private default constructor.
      */
@@ -99,7 +100,6 @@ final class ConfigDAO extends UnboundIdDataProvider
     {
     }
 
-
     /**
      * @param name
      * @param props
@@ -109,33 +109,28 @@ final class ConfigDAO extends UnboundIdDataProvider
     final Properties create( String name, Properties props )
         throws org.openldap.fortress.CreateException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String dn = getDn( name );
         LOG.info( "create dn [" + dn + "]" );
         try
         {
+            Entry myEntry = new DefaultEntry( dn );
+            myEntry.add( GlobalIds.OBJECT_CLASS, CONFIG_OBJ_CLASS );
             ld = getAdminConnection();
-            LDAPAttributeSet attrs = new LDAPAttributeSet();
-            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS, CONFIG_OBJ_CLASS ) );
-            attrs.add( createAttribute( GlobalIds.CN, name ) );
-            loadProperties( props, attrs, GlobalIds.PROPS );
-            LDAPEntry myEntry = new LDAPEntry( dn, attrs );
+            myEntry.add( GlobalIds.CN, name );
+            loadProperties( props, myEntry, GlobalIds.PROPS );
             add( ld, myEntry );
         }
-        catch ( LDAPException e )
+        catch ( LdapEntryAlreadyExistsException e )
+        {
+            String warning = "create config dn [" + dn + "] caught LdapEntryAlreadyExistsException="
+                + e.getMessage() + " msg=" + e.getMessage();
+            throw new org.openldap.fortress.CreateException( GlobalErrIds.FT_CONFIG_ALREADY_EXISTS, warning );
+        }
+        catch ( LdapException e )
         {
             String error;
-            if ( e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS )
-            {
-                String warning = "create config dn [" + dn + "] caught LDAPException="
-                    + e.getLDAPResultCode() + " msg=" + e.getMessage();
-                throw new org.openldap.fortress.CreateException( GlobalErrIds.FT_CONFIG_ALREADY_EXISTS, warning );
-            }
-            else
-            {
-                error = "create config dn [" + dn + "] caught LDAPException=" + e.getLDAPResultCode()
-                    + " msg=" + e.getMessage();
-            }
+            error = "create config dn [" + dn + "] caught LDAPException=" + e.getMessage();
             LOG.error( error, e );
             throw new org.openldap.fortress.CreateException( GlobalErrIds.FT_CONFIG_CREATE_FAILED, error );
         }
@@ -156,26 +151,26 @@ final class ConfigDAO extends UnboundIdDataProvider
     final Properties update( String name, Properties props )
         throws org.openldap.fortress.UpdateException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String dn = getDn( name );
         LOG.info( "update dn [" + dn + "]" );
         try
         {
-            ld = getAdminConnection();
-            LDAPModificationSet mods = new LDAPModificationSet();
-            if ( org.openldap.fortress.util.attr.VUtil.isNotNullOrEmpty( props ) )
+            List<Modification> mods = new ArrayList<Modification>();
+            if ( VUtil.isNotNullOrEmpty( props ) )
             {
                 loadProperties( props, mods, GlobalIds.PROPS, true );
             }
+            ld = getAdminConnection();
             if ( mods.size() > 0 )
             {
+                ld = getAdminConnection();
                 modify( ld, dn, mods );
             }
         }
-        catch ( LDAPException e )
+        catch ( LdapException e )
         {
-            String error = "update dn [" + dn + "] caught LDAPException=" + e.getLDAPResultCode() + " msg="
-                + e.getMessage();
+            String error = "update dn [" + dn + "] caught LDAPException=" + e.getMessage();
             throw new org.openldap.fortress.UpdateException( GlobalErrIds.FT_CONFIG_UPDATE_FAILED, error );
         }
         finally
@@ -193,7 +188,7 @@ final class ConfigDAO extends UnboundIdDataProvider
     final void remove( String name )
         throws RemoveException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String dn = getDn( name );
         LOG.info( "remove dn [" + dn + "]" );
         try
@@ -201,10 +196,9 @@ final class ConfigDAO extends UnboundIdDataProvider
             ld = getAdminConnection();
             delete( ld, dn );
         }
-        catch ( LDAPException e )
+        catch ( LdapException e )
         {
-            String error = "remove dn [" + dn + "] LDAPException=" + e.getLDAPResultCode() + " msg="
-                + e.getMessage();
+            String error = "remove dn [" + dn + "] LDAPException=" + e.getMessage();
             throw new org.openldap.fortress.RemoveException( GlobalErrIds.FT_CONFIG_DELETE_FAILED, error );
         }
         finally
@@ -223,26 +217,25 @@ final class ConfigDAO extends UnboundIdDataProvider
     final Properties remove( String name, Properties props )
         throws UpdateException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String dn = getDn( name );
         LOG.info( "remove props dn [" + dn + "]" );
         try
         {
-            ld = getAdminConnection();
-            LDAPModificationSet mods = new LDAPModificationSet();
+            List<Modification> mods = new ArrayList<Modification>();
             if ( VUtil.isNotNullOrEmpty( props ) )
             {
                 removeProperties( props, mods, GlobalIds.PROPS );
             }
             if ( mods.size() > 0 )
             {
+                ld = getAdminConnection();
                 modify( ld, dn, mods );
             }
         }
-        catch ( LDAPException e )
+        catch ( LdapException e )
         {
-            String error = "remove props dn [" + dn + "] caught LDAPException=" + e.getLDAPResultCode()
-                + " msg=" + e.getMessage();
+            String error = "remove props dn [" + dn + "] caught LDAPException=" + e.getMessage();
             throw new org.openldap.fortress.UpdateException( GlobalErrIds.FT_CONFIG_DELETE_PROPS_FAILED, error );
         }
         finally
@@ -262,23 +255,23 @@ final class ConfigDAO extends UnboundIdDataProvider
         throws FinderException
     {
         Properties props = null;
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String dn = getDn( name );
         LOG.info( "getConfig dn [" + dn + "]" );
         try
         {
             ld = getAdminConnection();
-            LDAPEntry findEntry = read( ld, dn, CONFIG_ATRS );
+            Entry findEntry = read( ld, dn, CONFIG_ATRS );
             props = AttrHelper.getProperties( getAttributes( findEntry, GlobalIds.PROPS ) );
         }
-        catch ( LDAPException e )
+        catch ( LdapNoSuchObjectException e )
         {
-            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
-            {
-                String warning = "getConfig COULD NOT FIND ENTRY for dn [" + dn + "]";
-                throw new org.openldap.fortress.FinderException( GlobalErrIds.FT_CONFIG_NOT_FOUND, warning );
-            }
-            String error = "getConfig dn [" + dn + "] LEXCD=" + e.getLDAPResultCode() + " LEXMSG=" + e;
+            String warning = "getConfig COULD NOT FIND ENTRY for dn [" + dn + "]";
+            throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getConfig dn [" + dn + "] caught LdapException=" + e.getMessage();
             throw new FinderException( GlobalErrIds.FT_CONFIG_READ_FAILED, error );
         }
         finally

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/39ac2790/src/main/java/org/openldap/fortress/ldap/ApacheDsDataProvider.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/ldap/ApacheDsDataProvider.java b/src/main/java/org/openldap/fortress/ldap/ApacheDsDataProvider.java
index 1400370..aee62b4 100644
--- a/src/main/java/org/openldap/fortress/ldap/ApacheDsDataProvider.java
+++ b/src/main/java/org/openldap/fortress/ldap/ApacheDsDataProvider.java
@@ -68,7 +68,8 @@ import org.openldap.fortress.util.crypto.EncryptUtil;
 import org.openldap.fortress.util.time.CUtil;
 import org.openldap.fortress.util.time.Constraint;
 
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModification;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -84,6 +85,10 @@ import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModification;
  */
 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();
     private static final String LDAP_HOST = "host";
@@ -93,6 +98,40 @@ public abstract class ApacheDsDataProvider
     private static final String LDAP_ADMIN_POOL_UID = "admin.user";
     private static final String LDAP_ADMIN_POOL_PW = "admin.pw";
 
+    // Used for TLS/SSL client-side configs:
+    private static final String ENABLE_LDAP_SSL = "enable.ldap.ssl";
+    private static final String ENABLE_LDAP_SSL_DEBUG = "enable.ldap.ssl.debug";
+    private static final String TRUST_STORE = Config.getProperty( "trust.store" );
+    private static final String TRUST_STORE_PW = Config.getProperty( "trust.store.password" );
+    private static final boolean IS_SSL = (
+        Config.getProperty( ENABLE_LDAP_SSL ) != null   &&
+            Config.getProperty( ENABLE_LDAP_SSL ).equalsIgnoreCase( "true" ) &&
+            TRUST_STORE      != null   &&
+            TRUST_STORE_PW   != null );
+
+    private static final String SET_TRUST_STORE_PROP = "trust.store.set.prop";
+    private static final boolean IS_SET_TRUST_STORE_PROP = (
+        IS_SSL &&
+            Config.getProperty( SET_TRUST_STORE_PROP ) != null   &&
+            Config.getProperty( SET_TRUST_STORE_PROP ).equalsIgnoreCase( "true" ));
+
+    private static final boolean IS_SSL_DEBUG = ( ( Config.getProperty( ENABLE_LDAP_SSL_DEBUG ) != null ) && ( Config
+        .getProperty( ENABLE_LDAP_SSL_DEBUG ).equalsIgnoreCase( "true" ) ) );
+
+    static
+    {
+        if(IS_SET_TRUST_STORE_PROP)
+        {
+            LOG.info( "Set JSSE truststore properties:");
+            LOG.info( "javax.net.ssl.trustStore: " + TRUST_STORE );
+            LOG.info( "javax.net.debug: " + new Boolean( IS_SSL_DEBUG ).toString());
+            System.setProperty( "javax.net.ssl.trustStore", TRUST_STORE );
+            System.setProperty( "javax.net.ssl.trustStorePassword", TRUST_STORE_PW );
+            System.setProperty( "javax.net.debug", new Boolean( IS_SSL_DEBUG ).toString() );
+        }
+    }
+
+
     /**
      * The Admin connection pool
      */
@@ -115,11 +154,29 @@ public abstract class ApacheDsDataProvider
         int min = Config.getInt( LDAP_ADMIN_POOL_MIN, 1 );
         int max = Config.getInt( LDAP_ADMIN_POOL_MAX, 10 );
 
+        if(IS_SET_TRUST_STORE_PROP)
+        {
+            LOG.info( "Set JSSE truststore properties in Apache LDAP client:");
+            LOG.info( "javax.net.ssl.trustStore: " + TRUST_STORE );
+            LOG.info( "javax.net.debug: " + new Boolean( IS_SSL_DEBUG ).toString());
+            System.setProperty( "javax.net.ssl.trustStore", TRUST_STORE );
+            System.setProperty( "javax.net.ssl.trustStorePassword", TRUST_STORE_PW );
+            System.setProperty( "javax.net.debug", new Boolean( IS_SSL_DEBUG ).toString() );
+        }
+
         LdapConnectionConfig config = new LdapConnectionConfig();
         config.setLdapHost( host );
         config.setLdapPort( port );
         config.setName( Config.getProperty( LDAP_ADMIN_POOL_UID, "" ) );
 
+        // added by smckinney for TLS/SSL config:
+        config.setUseSsl( IS_SSL );
+        //config.setTrustManagers( new NoVerificationTrustManager() );
+
+        config.setTrustManagers( new LdapClientTrustStoreManager(
+            TRUST_STORE,
+            TRUST_STORE_PW.toCharArray() , null, true ) );
+
         String adminPw = null;
 
         if ( EncryptUtil.isEnabled() )
@@ -921,7 +978,7 @@ public abstract class ApacheDsDataProvider
     {
         if ( list != null && list.size() > 0 )
         {
-            entry.add( attrName, list.toArray( new String[] {} ) );
+            entry.add( attrName, list.toArray( new String[]{} ) );
         }
     }
 
@@ -1028,11 +1085,28 @@ public abstract class ApacheDsDataProvider
      * @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 LDAPModification#REPLACE} else {@link
-     * LDAPModification#ADD}.
+     * @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 )
@@ -1046,7 +1120,7 @@ public abstract class ApacheDsDataProvider
                 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 + GlobalIds.PROP_SEP + val ) );
+                    key + separator + val ) );
             }
         }
     }
@@ -1113,6 +1187,43 @@ public abstract class ApacheDsDataProvider
 
 
     /**
+     * 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
+     */
+    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 );
+            }
+        }
+    }
+
+
+    /**
      * @param value
      * @param validLen
      * @return String containing encoded data.

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/39ac2790/src/main/java/org/openldap/fortress/ldap/LdapClientTrustStoreManager.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/ldap/LdapClientTrustStoreManager.java b/src/main/java/org/openldap/fortress/ldap/LdapClientTrustStoreManager.java
new file mode 100644
index 0000000..e7631c8
--- /dev/null
+++ b/src/main/java/org/openldap/fortress/ldap/LdapClientTrustStoreManager.java
@@ -0,0 +1,246 @@
+/*
+ * This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2014 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+package org.openldap.fortress.ldap;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import org.openldap.fortress.CfgRuntimeException;
+import org.openldap.fortress.GlobalErrIds;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implement the X509TrustManager interface which will be used during JSSE truststore manager initialization for LDAP
+ * client-to-server communications over TLS/SSL.
+ * It is used during certificate validation operations within JSSE.
+ * <p/>
+ * Note: This class allows self-signed certificates to pass the validation checks.
+ *
+ * @author Shawn McKinney
+ */
+public final class LdapClientTrustStoreManager implements X509TrustManager, Serializable
+{
+    // Logging
+    private static final String CLS_NM = LdapClientTrustStoreManager.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    // Config variables
+    private final boolean isExamineValidityDates;
+    private final char[] trustStorePw;
+    private final String trustStoreFile;
+    private final String trustStoreFormat;
+
+    /**
+     * Constructor used by connection configuration utility to load trust store manager.
+     *
+     * @param trustStoreFile    contains fully qualified name of trust store file.
+     * @param trustStorePw      contains the password for trust store
+     * @param trustStoreFormat  contains the format for trust store
+     * @param isExamineValidity boolean var determines if certificate will be examined for valid dates on load.
+     */
+    public LdapClientTrustStoreManager( final String trustStoreFile, final char[] trustStorePw,
+        final String trustStoreFormat, final boolean isExamineValidity )
+    {
+        if ( trustStoreFile == null )
+        {
+            // Cannot continue, throw an unchecked exception:
+            throw new CfgRuntimeException( GlobalErrIds.FT_CONFIG_JSSE_TRUSTSTORE_NULL,
+                "FortressTrustStoreManager constructor : input file name is null" );
+        }
+        // contains the fully-qualified file name of a valid JSSE TrustStore on local file system:
+        this.trustStoreFile = trustStoreFile;
+        // the password to the JSSE TrustStore:
+        this.trustStorePw = trustStorePw;
+        // If true, verify the current date is within the validity period for every certificate in the TrustStore:
+        this.isExamineValidityDates = isExamineValidity;
+        if ( trustStoreFormat == null )
+        {
+            this.trustStoreFormat = KeyStore.getDefaultType();
+        }
+        else
+        {
+            this.trustStoreFormat = trustStoreFormat;
+        }
+    }
+
+    /**
+     * Determine if client certificate is to be trusted.
+     *
+     * @param x509Chain
+     * @param authNType
+     * @throws CertificateException
+     */
+    public synchronized void checkClientTrusted( final X509Certificate[] x509Chain,
+        final String authNType ) throws CertificateException
+    {
+        // For each certificate in the chain, check validity:
+        for ( final X509TrustManager trustMgr : getTrustManagers( x509Chain ) )
+        {
+            trustMgr.checkClientTrusted( x509Chain, authNType );
+        }
+    }
+
+    /**
+     * Determine if server certificate is to be trusted.
+     *
+     * @param x509Chain
+     * @param authNType
+     * @throws CertificateException
+     */
+    public synchronized void checkServerTrusted( final X509Certificate[] x509Chain, final String authNType ) throws
+        CertificateException
+    {
+        for ( final X509TrustManager trustManager : getTrustManagers( x509Chain ) )
+        {
+            trustManager.checkServerTrusted( x509Chain, authNType );
+        }
+    }
+
+    /**
+     * Return the list of accepted issuers for this trust manager.
+     *
+     * @return array of accepted issuers
+     */
+    public synchronized X509Certificate[] getAcceptedIssuers()
+    {
+        return new X509Certificate[0];
+    }
+
+    /**
+     * Return array of trust managers to caller.  Will verify that current date is within certs validity period.
+     *
+     * @param x509Chain contains input X.509 certificate chain.
+     * @return array of X.509 trust managers.
+     * @throws CertificateException if trustStoreFile instance variable is null.
+     */
+    private synchronized X509TrustManager[] getTrustManagers( final X509Certificate[] x509Chain ) throws
+        CertificateException
+    {
+        // If true, verify the current date is within each certificates validity period.
+        if ( isExamineValidityDates )
+        {
+            final Date currentDate = new Date();
+            for ( final X509Certificate x509Cert : x509Chain )
+            {
+                x509Cert.checkValidity( currentDate );
+            }
+        }
+        // The trustStoreFile should contain the fully-qualified name of a Java TrustStore on local file system.
+        final File trustStoreFile = new File( this.trustStoreFile );
+        if ( !trustStoreFile.exists() )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.getTrustManagers : file not found" );
+        }
+        return loadTrustManagers( getTrustStore() );
+    }
+
+    /**
+     * Return an array of X.509 TrustManagers.
+     *
+     * @param trustStore handle to input trustStore
+     * @return array of trust managers
+     * @throws CertificateException if problem occurs during TrustManager initialization.
+     */
+    private X509TrustManager[] loadTrustManagers( final KeyStore trustStore ) throws CertificateException
+    {
+        final X509TrustManager[] x509TrustManagers;
+        try
+        {
+            final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory
+                .getDefaultAlgorithm() );
+            trustManagerFactory.init( trustStore );
+            final TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
+            x509TrustManagers = new X509TrustManager[trustManagers.length];
+            for ( int i = 0; i < trustManagers.length; i++ )
+            {
+                x509TrustManagers[i] = ( X509TrustManager ) trustManagers[i];
+            }
+        }
+        catch ( NoSuchAlgorithmException e )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.loadTrustManagers caught " +
+                "NoSuchAlgorithmException", e );
+        }
+        catch ( KeyStoreException e )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.loadTrustManagers caught KeyStoreException", e );
+        }
+        return x509TrustManagers;
+    }
+
+    /**
+     * Load the TrustStore file into JSSE KeyStore instance.
+     *
+     * @return instance of JSSE KeyStore containing the LDAP Client's TrustStore file info.     *
+     * @throws CertificateException if cannot process file load.
+     */
+    private KeyStore getTrustStore() throws CertificateException
+    {
+        final KeyStore trustStore;
+        try
+        {
+            trustStore = KeyStore.getInstance( trustStoreFormat );
+        }
+        catch ( KeyStoreException e )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.getTrustManagers caught KeyStoreException", e );
+        }
+        FileInputStream trustStoreInputStream = null;
+        try
+        {
+            trustStoreInputStream = new FileInputStream( trustStoreFile );
+            trustStore.load( trustStoreInputStream, trustStorePw );
+        }
+        catch ( NoSuchAlgorithmException e )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.getTrustManagers caught " +
+                "NoSuchAlgorithmException", e );
+        }
+        catch ( IOException e )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.getTrustManagers caught KeyStoreException", e );
+        }
+        finally
+        {
+            // Close the input stream.
+            if ( trustStoreInputStream != null )
+            {
+                try
+                {
+                    trustStoreInputStream.close();
+                }
+                catch ( IOException e )
+                {
+                    // Eat this ioexception because it shouldn't be a problem, but log just in case:
+                    LOG.warn( "FortressTrustStoreManager.getTrustManagers finally block on input stream close " +
+                        "operation caught IOException=" + e.getMessage() );
+                }
+            }
+        }
+        return trustStore;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/39ac2790/src/main/java/org/openldap/fortress/ldap/container/OrganizationalUnitDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/ldap/container/OrganizationalUnitDAO.java b/src/main/java/org/openldap/fortress/ldap/container/OrganizationalUnitDAO.java
index 88b2faf..af6e94c 100755
--- a/src/main/java/org/openldap/fortress/ldap/container/OrganizationalUnitDAO.java
+++ b/src/main/java/org/openldap/fortress/ldap/container/OrganizationalUnitDAO.java
@@ -16,19 +16,18 @@
 package org.openldap.fortress.ldap.container;
 
 
+import org.apache.directory.api.ldap.model.cursor.CursorException;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.openldap.fortress.ldap.ApacheDsDataProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import org.openldap.fortress.GlobalErrIds;
 import org.openldap.fortress.GlobalIds;
-import org.openldap.fortress.ldap.UnboundIdDataProvider;
 import org.openldap.fortress.util.attr.VUtil;
 
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
-
 
 /**
  * This class provides data access for the standard ldap object class Organizational Unit.  This
@@ -58,7 +57,7 @@ import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
  *
  * @author Shawn McKinney
  */
-final class OrganizationalUnitDAO extends UnboundIdDataProvider
+final class OrganizationalUnitDAO extends ApacheDsDataProvider
 {
     private static final String CLS_NM = OrganizationalUnitDAO.class.getName();
     private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
@@ -90,7 +89,7 @@ final class OrganizationalUnitDAO extends UnboundIdDataProvider
     final void create( OrganizationalUnit oe )
         throws org.openldap.fortress.CreateException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String nodeDn = GlobalIds.OU + "=" + oe.getName() + ",";
         if ( VUtil.isNotNullOrEmpty( oe.getParent() ) )
             nodeDn += GlobalIds.OU + "=" + oe.getParent() + ",";
@@ -98,19 +97,17 @@ final class OrganizationalUnitDAO extends UnboundIdDataProvider
         try
         {
             LOG.info( "create container dn [" + nodeDn + "]" );
-            LDAPAttributeSet attrs = new LDAPAttributeSet();
-            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS,
-                ORGUNIT_OBJ_CLASS ) );
-            attrs.add( createAttribute( GlobalIds.OU, oe.getName() ) );
-            attrs.add( createAttribute( GlobalIds.DESC, oe.getDescription() ) );
-            LDAPEntry myEntry = new LDAPEntry( nodeDn, attrs );
+            Entry myEntry = new DefaultEntry( nodeDn );
+            myEntry.add( GlobalIds.OBJECT_CLASS, ORGUNIT_OBJ_CLASS );
+            myEntry.add( GlobalIds.OU, oe.getName() );
+            myEntry.add( GlobalIds.DESC, oe.getDescription() );
             ld = getAdminConnection();
             add( ld, myEntry );
         }
-        catch ( LDAPException e )
+        catch ( LdapException e )
         {
             String error = "create container node dn [" + nodeDn + "] caught LDAPException="
-                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                + e.getMessage();
             throw new org.openldap.fortress.CreateException( GlobalErrIds.CNTR_CREATE_FAILED, error, e );
         }
         finally
@@ -127,7 +124,7 @@ final class OrganizationalUnitDAO extends UnboundIdDataProvider
     final void remove( OrganizationalUnit oe )
         throws org.openldap.fortress.RemoveException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String nodeDn = GlobalIds.OU + "=" + oe.getName() + ",";
         if ( VUtil.isNotNullOrEmpty( oe.getParent() ) )
             nodeDn += GlobalIds.OU + "=" + oe.getParent() + ",";
@@ -139,10 +136,16 @@ final class OrganizationalUnitDAO extends UnboundIdDataProvider
             ld = getAdminConnection();
             deleteRecursive( ld, nodeDn );
         }
-        catch ( LDAPException e )
+        catch ( CursorException e )
+        {
+            String error = "remove container node dn [" + nodeDn + "] caught CursorException="
+                + e.getMessage();
+            throw new org.openldap.fortress.RemoveException( GlobalErrIds.CNTR_DELETE_FAILED, error, e );
+        }
+        catch ( LdapException e )
         {
             String error = "remove container node dn [" + nodeDn + "] caught LDAPException="
-                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                + e.getMessage();
             throw new org.openldap.fortress.RemoveException( GlobalErrIds.CNTR_DELETE_FAILED, error, e );
         }
         finally

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/39ac2790/src/main/java/org/openldap/fortress/ldap/group/GroupDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/ldap/group/GroupDAO.java b/src/main/java/org/openldap/fortress/ldap/group/GroupDAO.java
index 6c82f74..74fd6d2 100755
--- a/src/main/java/org/openldap/fortress/ldap/group/GroupDAO.java
+++ b/src/main/java/org/openldap/fortress/ldap/group/GroupDAO.java
@@ -16,14 +16,23 @@
 package org.openldap.fortress.ldap.group;
 
 
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttribute;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModification;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModificationSet;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPSearchResults;
+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.DefaultEntry;
+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.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
+import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.ldap.client.api.LdapConnection;
 import org.openldap.fortress.FinderException;
 import org.openldap.fortress.ObjectFactory;
 import org.openldap.fortress.UpdateException;
 import org.openldap.fortress.cfg.Config;
+import org.openldap.fortress.ldap.ApacheDsDataProvider;
 import org.openldap.fortress.rbac.User;
 import org.openldap.fortress.util.attr.AttrHelper;
 import org.slf4j.Logger;
@@ -33,17 +42,10 @@ import org.openldap.fortress.CreateException;
 import org.openldap.fortress.GlobalErrIds;
 import org.openldap.fortress.GlobalIds;
 import org.openldap.fortress.RemoveException;
-import org.openldap.fortress.ldap.UnboundIdDataProvider;
-
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
 import org.openldap.fortress.util.attr.VUtil;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Properties;
 
 /**
  * Contains the Group node for LDAP Directory Information Tree.
@@ -51,7 +53,7 @@ import java.util.Properties;
  *
  * @author Shawn McKinney
  */
-final class GroupDAO extends UnboundIdDataProvider
+final class GroupDAO extends ApacheDsDataProvider
 {
     private static final String CLS_NM = GroupDAO.class.getName();
     private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
@@ -79,30 +81,27 @@ final class GroupDAO extends UnboundIdDataProvider
      */
     final Group create( Group group ) throws org.openldap.fortress.CreateException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String nodeDn = getDn( group.getName(), group.getContextId() );
         try
         {
             LOG.debug( "create group dn {[]}", nodeDn );
-            LDAPAttributeSet attrs = new LDAPAttributeSet();
-            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS, GROUP_OBJ_CLASS ) );
-            attrs.add( createAttribute( GlobalIds.CN, group.getName() ) );
-            attrs.add( createAttribute( GROUP_PROTOCOL_ATTR_IMPL, group.getProtocol() ) );
-            loadAttrs( group.getMembers(), attrs, MEMBER );
-            loadProperties( group.getProperties(), attrs, GROUP_PROPERTY_ATTR_IMPL, '=' );
+            Entry myEntry = new DefaultEntry( nodeDn );
+            myEntry.add( GlobalIds.OBJECT_CLASS, GROUP_OBJ_CLASS );
+            myEntry.add( GlobalIds.CN , group.getName() );
+            myEntry.add( GROUP_PROTOCOL_ATTR_IMPL, group.getProtocol() );
+            loadAttrs( group.getMembers(), myEntry, MEMBER );
+            loadProperties( group.getProperties(), myEntry, GROUP_PROPERTY_ATTR_IMPL, '=' );
             if ( VUtil.isNotNullOrEmpty( group.getDescription() ) )
             {
-                attrs.add( createAttribute( GlobalIds.DESC, group.getDescription() ) );
+                myEntry.add( GlobalIds.DESC, group.getDescription() );
             }
-
-            LDAPEntry myEntry = new LDAPEntry( nodeDn, attrs );
             ld = getAdminConnection();
             add( ld, myEntry );
         }
-        catch ( LDAPException e )
+        catch ( LdapException e )
         {
-            String error = "create group node dn [" + nodeDn + "] caught LDAPException=" + e.getLDAPResultCode() + " " +
-                "msg=" + e.getMessage();
+            String error = "create group node dn [" + nodeDn + "] caught LDAPException=" + e.getMessage();
             throw new CreateException( GlobalErrIds.GROUP_ADD_FAILED, error, e );
         }
         finally
@@ -120,39 +119,33 @@ final class GroupDAO extends UnboundIdDataProvider
      */
     final Group update( Group group ) throws org.openldap.fortress.FinderException, org.openldap.fortress.UpdateException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String nodeDn = getDn( group.getName(), group.getContextId() );
         try
         {
             LOG.debug( "update group dn {[]}", nodeDn );
-            LDAPModificationSet mods = new LDAPModificationSet();
+            List<Modification> mods = new ArrayList<Modification>();
             if ( VUtil.isNotNullOrEmpty( group.getDescription() ) )
             {
-                LDAPAttribute desc = new LDAPAttribute( GlobalIds.DESC, group.getDescription() );
-                mods.add( LDAPModification.REPLACE, desc );
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.DESC, group.getDescription() ) );
             }
             if ( VUtil.isNotNullOrEmpty( group.getProtocol() ) )
             {
-                LDAPAttribute protocol = new LDAPAttribute( GROUP_PROTOCOL_ATTR_IMPL, group.getProtocol() );
-                mods.add( LDAPModification.REPLACE, protocol );
-            }
-/*
-            loadAttrs( group.getMembers(), mods, MEMBER, false );
-            if ( VUtil.isNotNullOrEmpty( group.getProperties() ) )
-            {
-                loadProperties( group.getProperties(), mods, GROUP_PROPERTY_ATTR_IMPL, '=', false );
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GROUP_PROTOCOL_ATTR_IMPL, group.getProtocol() ) );
             }
-*/
+            loadAttrs( group.getMembers(), mods, MEMBER );
+            loadProperties( group.getProperties(), mods, GROUP_PROPERTY_ATTR_IMPL, true, '=' );
             if ( mods.size() > 0 )
             {
                 ld = getAdminConnection();
                 modify( ld, nodeDn, mods, group );
             }
         }
-        catch ( LDAPException e )
+        catch ( LdapException e )
         {
-            String error = "update group node dn [" + nodeDn + "] caught LDAPException=" + e.getLDAPResultCode() + " " +
-                "msg=" + e.getMessage();
+            String error = "update group node dn [" + nodeDn + "] caught LDAPException=" + e.getMessage();
             throw new UpdateException( GlobalErrIds.GROUP_UPDATE_FAILED, error, e );
         }
         finally
@@ -164,21 +157,20 @@ final class GroupDAO extends UnboundIdDataProvider
 
     final Group add( Group group, String key, String value ) throws org.openldap.fortress.FinderException, org.openldap.fortress.CreateException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String nodeDn = getDn( group.getName(), group.getContextId() );
         try
         {
             LOG.debug( "add group property dn {[]}, key {[]}, value {[]}", nodeDn, key, value );
-            LDAPModificationSet mods = new LDAPModificationSet();
-            LDAPAttribute prop = new LDAPAttribute( GROUP_PROPERTY_ATTR_IMPL, key + "=" + value );
-            mods.add( LDAPModification.ADD, prop );
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification(
+                ModificationOperation.ADD_ATTRIBUTE, GROUP_PROPERTY_ATTR_IMPL, key + "=" + value ) );
             ld = getAdminConnection();
             modify( ld, nodeDn, mods, group );
         }
-        catch ( LDAPException e )
+        catch ( LdapException e )
         {
-            String error = "update group property node dn [" + nodeDn + "] caught LDAPException=" + e.getLDAPResultCode() + " " +
-                "msg=" + e.getMessage();
+            String error = "update group property node dn [" + nodeDn + "] caught LDAPException=" + e.getMessage();
             throw new CreateException( GlobalErrIds.GROUP_ADD_PROPERTY_FAILED, error, e );
         }
         finally
@@ -190,21 +182,20 @@ final class GroupDAO extends UnboundIdDataProvider
 
     final Group delete( Group group, String key, String value ) throws org.openldap.fortress.FinderException, org.openldap.fortress.RemoveException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String nodeDn = getDn( group.getName(), group.getContextId() );
         try
         {
             LOG.debug( "delete group property dn {[]}, key {[]}, value {[]}", nodeDn, key, value );
-            LDAPModificationSet mods = new LDAPModificationSet();
-            LDAPAttribute prop = new LDAPAttribute( GROUP_PROPERTY_ATTR_IMPL, key + "=" + value );
-            mods.add( LDAPModification.DELETE, prop );
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification(
+                ModificationOperation.REMOVE_ATTRIBUTE, GROUP_PROPERTY_ATTR_IMPL, key + "=" + value ) );
             ld = getAdminConnection();
             modify( ld, nodeDn, mods, group );
         }
-        catch ( LDAPException e )
+        catch ( LdapException e )
         {
-            String error = "delete group property node dn [" + nodeDn + "] caught LDAPException=" + e.getLDAPResultCode() + " " +
-                "msg=" + e.getMessage();
+            String error = "delete group property node dn [" + nodeDn + "] caught LDAPException=" + e.getMessage();
             throw new RemoveException( GlobalErrIds.GROUP_DELETE_PROPERTY_FAILED, error, e );
         }
         finally
@@ -223,7 +214,7 @@ final class GroupDAO extends UnboundIdDataProvider
      */
     final Group remove( Group group ) throws org.openldap.fortress.RemoveException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String nodeDn = getDn( group.getName(), group.getContextId() );
         LOG.debug( "remove group dn {[]}", nodeDn );
         try
@@ -231,10 +222,15 @@ final class GroupDAO extends UnboundIdDataProvider
             ld = getAdminConnection();
             deleteRecursive( ld, nodeDn );
         }
-        catch ( LDAPException e )
+        catch ( CursorException e )
         {
-            String error = "remove group node dn [" + nodeDn + "] caught LDAPException=" + e.getLDAPResultCode() + " " +
-                "msg=" + e.getMessage();
+            String error = "remove group node dn [" + nodeDn + "] caught CursorException="
+                + e.getMessage();
+            throw new org.openldap.fortress.RemoveException( GlobalErrIds.GROUP_DELETE_FAILED, error, e );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove group node dn [" + nodeDn + "] caught LDAPException=" + e.getMessage();
             throw new RemoveException( GlobalErrIds.GROUP_DELETE_FAILED, error, e );
         }
         finally
@@ -253,21 +249,21 @@ final class GroupDAO extends UnboundIdDataProvider
      */
     final Group assign( Group entity, String userDn ) throws org.openldap.fortress.FinderException, UpdateException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String dn = getDn( entity.getName(), entity.getContextId() );
         LOG.debug( "assign group property dn {[]}, member dn {[]}", dn, userDn );
         try
         {
-            LDAPModificationSet mods = new LDAPModificationSet();
-            LDAPAttribute member = new LDAPAttribute( MEMBER, userDn );
-            mods.add( LDAPModification.ADD, member );
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification(
+                ModificationOperation.ADD_ATTRIBUTE, MEMBER, userDn ) );
             ld = getAdminConnection();
             modify( ld, dn, mods, entity );
         }
-        catch ( LDAPException e )
+        catch ( LdapException e )
         {
             String error = "assign group name [" + entity.getName() + "] user dn [" + userDn + "] caught " +
-                "LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                "LDAPException=" + e.getMessage();
             throw new UpdateException( GlobalErrIds.GROUP_USER_ASSIGN_FAILED, error, e );
         }
         finally
@@ -286,21 +282,22 @@ final class GroupDAO extends UnboundIdDataProvider
      */
     final Group deassign( Group entity, String userDn ) throws org.openldap.fortress.FinderException, UpdateException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String dn = getDn( entity.getName(), entity.getContextId() );
         LOG.debug( "deassign group property dn {[]}, member dn {[]}", dn, userDn );
         try
         {
-            LDAPModificationSet mods = new LDAPModificationSet();
-            LDAPAttribute member = new LDAPAttribute( MEMBER, userDn );
-            mods.add( LDAPModification.DELETE, member );
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification(
+                ModificationOperation.REMOVE_ATTRIBUTE, MEMBER, userDn ) );
+
             ld = getAdminConnection();
             modify( ld, dn, mods, entity );
         }
-        catch ( LDAPException e )
+        catch ( LdapException e )
         {
             String error = "deassign group name [" + entity.getName() + "] user dn [" + userDn + "] caught " +
-                "LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                "LDAPException=" + e.getMessage();
             throw new UpdateException( GlobalErrIds.GROUP_USER_DEASSIGN_FAILED, error, e );
         }
         finally
@@ -319,12 +316,12 @@ final class GroupDAO extends UnboundIdDataProvider
     final Group get( Group group ) throws FinderException
     {
         Group entity = null;
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String dn = getDn( group.getName(), group.getContextId() );
         try
         {
             ld = getAdminConnection();
-            LDAPEntry findEntry = read( ld, dn, GROUP_ATRS );
+            Entry findEntry = read( ld, dn, GROUP_ATRS );
             entity = unloadLdapEntry( findEntry, 0 );
             if ( entity == null )
             {
@@ -332,14 +329,14 @@ final class GroupDAO extends UnboundIdDataProvider
                 throw new FinderException( GlobalErrIds.GROUP_NOT_FOUND, warning );
             }
         }
-        catch ( LDAPException e )
+        catch ( LdapNoSuchObjectException e )
         {
-            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
-            {
-                String warning = "read Obj COULD NOT FIND ENTRY for dn [" + dn + "]";
-                throw new FinderException( GlobalErrIds.GROUP_NOT_FOUND, warning );
-            }
-            String error = "read dn [" + dn + "] LEXCD=" + e.getLDAPResultCode() + " LEXMSG=" + e;
+            String warning = "read Obj COULD NOT FIND ENTRY for dn [" + dn + "]";
+            throw new FinderException( GlobalErrIds.GROUP_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "read dn [" + dn + "] LdapException=" + e.getMessage();
             throw new FinderException( GlobalErrIds.GROUP_READ_FAILED, error, e );
         }
         finally
@@ -358,8 +355,8 @@ final class GroupDAO extends UnboundIdDataProvider
     final List<Group> find( Group group ) throws FinderException
     {
         List<Group> groupList = new ArrayList<>();
-        LDAPConnection ld = null;
-        LDAPSearchResults searchResults;
+        LdapConnection ld = null;
+        SearchCursor searchResults;
         String groupRoot = getRootDn( group.getContextId(), GlobalIds.GROUP_ROOT );
         String filter = null;
         try
@@ -367,18 +364,22 @@ final class GroupDAO extends UnboundIdDataProvider
             String searchVal = encodeSafeText( group.getName(), GlobalIds.ROLE_LEN );
             filter = GlobalIds.FILTER_PREFIX + GROUP_OBJECT_CLASS_IMPL + ")(" + GlobalIds.CN + "=" + searchVal + "*))";
             ld = getAdminConnection();
-            searchResults = search( ld, groupRoot, LDAPConnection.SCOPE_ONE, filter, GROUP_ATRS, false,
+            searchResults = search( ld, groupRoot, SearchScope.ONELEVEL, filter, GROUP_ATRS, false,
                 GlobalIds.BATCH_SIZE );
             long sequence = 0;
-            while ( searchResults.hasMoreElements() )
+            while ( searchResults.next() )
             {
-                groupList.add( unloadLdapEntry( searchResults.next(), sequence++ ) );
+                groupList.add( unloadLdapEntry( searchResults.getEntry(), sequence++ ) );
             }
         }
-        catch ( LDAPException e )
+        catch ( CursorException e )
         {
-            String error = "find filter [" + filter + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e
-                .getMessage();
+            String error = "find filter [" + filter + "] caught CursorException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.GROUP_SEARCH_FAILED, error, e );
+        }
+        catch ( LdapException e )
+        {
+            String error = "find filter [" + filter + "] caught LDAPException=" + e.getMessage();
             throw new FinderException( GlobalErrIds.GROUP_SEARCH_FAILED, error, e );
         }
         finally
@@ -397,8 +398,8 @@ final class GroupDAO extends UnboundIdDataProvider
     final List<Group> find( User user ) throws FinderException
     {
         List<Group> groupList = new ArrayList<>();
-        LDAPConnection ld = null;
-        LDAPSearchResults searchResults;
+        LdapConnection ld = null;
+        SearchCursor searchResults;
         String groupRoot = getRootDn( user.getContextId(), GlobalIds.GROUP_ROOT );
         String filter = null;
         try
@@ -406,18 +407,22 @@ final class GroupDAO extends UnboundIdDataProvider
             String searchVal = encodeSafeText( user.getUserId(), GlobalIds.USERID_LEN );
             filter = GlobalIds.FILTER_PREFIX + GROUP_OBJECT_CLASS_IMPL + ")(" + MEMBER + "=" + user.getDn() + "))";
             ld = getAdminConnection();
-            searchResults = search( ld, groupRoot, LDAPConnection.SCOPE_ONE, filter, GROUP_ATRS, false,
+            searchResults = search( ld, groupRoot, SearchScope.ONELEVEL, filter, GROUP_ATRS, false,
                 GlobalIds.BATCH_SIZE );
             long sequence = 0;
-            while ( searchResults.hasMoreElements() )
+            while ( searchResults.next() )
             {
-                groupList.add( unloadLdapEntry( searchResults.next(), sequence++ ) );
+                groupList.add( unloadLdapEntry( searchResults.getEntry(), sequence++ ) );
             }
         }
-        catch ( LDAPException e )
+        catch ( CursorException e )
+        {
+            String error = "find filter [" + filter + "] caught CursorException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.GROUP_SEARCH_FAILED, error, e );
+        }
+        catch ( LdapException e )
         {
-            String error = "find filter [" + filter + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e
-                .getMessage();
+            String error = "find filter [" + filter + "] caught LDAPException=" + e.getMessage();
             throw new FinderException( GlobalErrIds.GROUP_SEARCH_FAILED, error, e );
         }
         finally
@@ -431,9 +436,10 @@ final class GroupDAO extends UnboundIdDataProvider
      * @param le
      * @param sequence
      * @return
-     * @throws LDAPException
+     * @throws LdapException
      */
-    private Group unloadLdapEntry( LDAPEntry le, long sequence )
+    private Group unloadLdapEntry( Entry le, long sequence )
+        throws LdapInvalidAttributeValueException
     {
         Group entity = new ObjectFactory().createGroup();
         entity.setName( getAttribute( le, GlobalIds.CN ) );

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/39ac2790/src/main/java/org/openldap/fortress/ldap/suffix/SuffixDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/ldap/suffix/SuffixDAO.java b/src/main/java/org/openldap/fortress/ldap/suffix/SuffixDAO.java
index c1aa67a..770f2e1 100755
--- a/src/main/java/org/openldap/fortress/ldap/suffix/SuffixDAO.java
+++ b/src/main/java/org/openldap/fortress/ldap/suffix/SuffixDAO.java
@@ -16,6 +16,12 @@
 package org.openldap.fortress.ldap.suffix;
 
 
+import org.apache.directory.api.ldap.model.cursor.CursorException;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.openldap.fortress.ldap.ApacheDsDataProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -23,12 +29,6 @@ import org.openldap.fortress.CreateException;
 import org.openldap.fortress.GlobalErrIds;
 import org.openldap.fortress.GlobalIds;
 import org.openldap.fortress.RemoveException;
-import org.openldap.fortress.ldap.UnboundIdDataProvider;
-
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
 import org.openldap.fortress.util.attr.VUtil;
 
 
@@ -61,7 +61,7 @@ import org.openldap.fortress.util.attr.VUtil;
  *
  * @author Shawn McKinney
  */
-final class SuffixDAO extends UnboundIdDataProvider
+final class SuffixDAO extends ApacheDsDataProvider
 {
     private static final String CLS_NM = SuffixDAO.class.getName();
     private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
@@ -88,23 +88,22 @@ final class SuffixDAO extends UnboundIdDataProvider
     final void create( Suffix se )
         throws org.openldap.fortress.CreateException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String nodeDn = getDn( se );
         try
         {
             LOG.info( "create suffix dn [" + nodeDn + "]" );
-            LDAPAttributeSet attrs = new LDAPAttributeSet();
-            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS, SUFFIX_OBJ_CLASS ) );
-            attrs.add( createAttribute( DC, se.getName() ) );
-            attrs.add( createAttribute( O, se.getDescription() ) );
-            LDAPEntry myEntry = new LDAPEntry( nodeDn, attrs );
+            Entry myEntry = new DefaultEntry( nodeDn );
+            myEntry.add( GlobalIds.OBJECT_CLASS, SUFFIX_OBJ_CLASS );
+            myEntry.add( DC, se.getName() );
+            myEntry.add( O, se.getDescription() );
             ld = getAdminConnection();
             add( ld, myEntry );
         }
-        catch ( LDAPException e )
+        catch ( LdapException e )
         {
             String error = "create container node dn [" + nodeDn + "] caught LDAPException="
-                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                + e.getMessage();
             throw new CreateException( GlobalErrIds.SUFX_CREATE_FAILED, error, e );
         }
         finally
@@ -129,7 +128,7 @@ final class SuffixDAO extends UnboundIdDataProvider
     final void remove( Suffix se )
         throws org.openldap.fortress.RemoveException
     {
-        LDAPConnection ld = null;
+        LdapConnection ld = null;
         String nodeDn = getDn( se );
         LOG.info( "remove suffix dn [" + nodeDn + "]" );
         try
@@ -137,10 +136,16 @@ final class SuffixDAO extends UnboundIdDataProvider
             ld = getAdminConnection();
             deleteRecursive( ld, nodeDn );
         }
-        catch ( LDAPException e )
+        catch ( CursorException e )
+        {
+            String error = "remove suffix node dn [" + nodeDn + "] caught CursorException="
+                + e.getMessage();
+            throw new org.openldap.fortress.RemoveException( GlobalErrIds.SUFX_DELETE_FAILED, error, e );
+        }
+        catch ( LdapException e )
         {
             String error = "remove suffix node dn [" + nodeDn + "] caught LDAPException="
-                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                + e.getMessage();
             throw new RemoveException( GlobalErrIds.SUFX_DELETE_FAILED, error, e );
         }
         finally

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/39ac2790/src/main/java/org/openldap/fortress/rbac/dao/apache/UserDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/rbac/dao/apache/UserDAO.java b/src/main/java/org/openldap/fortress/rbac/dao/apache/UserDAO.java
index cf6e233..2f3a6d1 100755
--- a/src/main/java/org/openldap/fortress/rbac/dao/apache/UserDAO.java
+++ b/src/main/java/org/openldap/fortress/rbac/dao/apache/UserDAO.java
@@ -381,19 +381,11 @@ public final class UserDAO extends ApacheDsDataProvider implements org.openldap.
                 myEntry.add( EMPLOYEE_TYPE, entity.getEmployeeType() );
             }
 
-            // These are multi-valued attributes, use the util function to load:
-            // These items are optional.  The utility function will return quietly if no items are loaded into collection:
+            // These are multi-valued attributes, use the util function to load.
+            // These items are optional.  The utility function will return quietly if item list is empty:
             loadAttrs( entity.getPhones(), myEntry, TELEPHONE_NUMBER );
             loadAttrs( entity.getMobiles(), myEntry, MOBILE );
             loadAttrs( entity.getEmails(), myEntry, MAIL );
-/*
-            myEntry.add( TELEPHONE_NUMBER, entity.getPhones().toArray( new String[]
-                {} ) );
-            myEntry.add( MOBILE, entity.getMobiles().toArray( new String[]
-                {} ) );
-            myEntry.add( MAIL, entity.getEmails().toArray( new String[]
-                {} ) );
-*/
 
             // The following attributes are optional:
             if ( VUtil.isNotNullOrEmpty( entity.isSystem() ) )