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 2014/10/22 19:48:27 UTC

[12/16] Remove the unboundid daos classes and lib, move the apache dao's into rbac package and make its classes and methods package private.

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/PolicyDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/PolicyDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/PolicyDAO.java
new file mode 100755
index 0000000..1a4683b
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PolicyDAO.java
@@ -0,0 +1,685 @@
+/*
+ *   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.rbac;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+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.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.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.rbac.PwPolicy;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * This DAO class maintains the OpenLDAP Password Policy entity which is a composite of the following structural and aux object classes:
+ * <h4>1. organizationalRole Structural Object Class is used to store basic attributes like cn and description</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code> objectclass ( 2.5.6.14 NAME 'device'</code>
+ * <li> <code>DESC 'RFC2256: a device'</code>
+ * <li> <code>SUP top STRUCTURAL</code>
+ * <li> <code>MUST cn</code>
+ * <li> <code>MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>2. pwdPolicy AUXILIARY Object Class is used to store OpenLDAP Password Policies</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 1.3.6.1.4.1.42.2.27.8.2.1</code>
+ * <li> <code>NAME 'pwdPolicy'</code>
+ * <li> <code>SUP top</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MUST ( pwdAttribute )</code>
+ * <li> <code>MAY ( pwdMinAge $ pwdMaxAge $ pwdInHistory $ pwdCheckQuality $</code>
+ * <li> <code>pwdMinLength $ pwdExpireWarning $ pwdGraceAuthNLimit $ pwdLockout $</code>
+ * <li> <code>pwdLockoutDuration $ pwdMaxFailure $ pwdFailureCountInterval $</code>
+ * <li> <code>pwdMustChange $ pwdAllowUserChange $ pwdSafeModify ) )</code>
+ * <li> <code></code>
+ * <li> <code></code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>3. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity</h4>
+ * <ul>
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.4</code>
+ * <li> <code>NAME 'ftMods'</code>
+ * <li> <code>DESC 'Fortress Modifiers AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MAY (</code>
+ * <li> <code>ftModifier $</code>
+ * <li> <code>ftModCode $</code>
+ * <li> <code>ftModId ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+final class PolicyDAO extends ApacheDsDataProvider
+{
+    /*
+      *  *************************************************************************
+      *  **  OPENLDAP PW POLICY ATTRIBUTES AND CONSTANTS
+      *  ************************************************************************
+      */
+    private static final String OLPW_POLICY_EXTENSION = "2.5.4.35";
+    private static final String OLPW_POLICY_CLASS = "pwdPolicy";
+    /**
+     * This object class combines OpenLDAP PW Policy schema with the Fortress audit context.
+     */
+    private static final String OAM_PWPOLICY_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP, "device", OLPW_POLICY_CLASS, GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+
+    private static final String OLPW_ATTRIBUTE = "pwdAttribute";
+    private static final String OLPW_MIN_AGE = "pwdMinAge";
+    private static final String OLPW_MAX_AGE = "pwdMaxAge";
+    private static final String OLPW_IN_HISTORY = "pwdInHistory";
+    private static final String OLPW_CHECK_QUALITY = "pwdCheckQuality";
+    private static final String OLPW_MIN_LENGTH = "pwdMinLength";
+    private static final String OLPW_EXPIRE_WARNING = "pwdExpireWarning";
+    private static final String OLPW_GRACE_LOGIN_LIMIT = "pwdGraceAuthNLimit";
+    private static final String OLPW_LOCKOUT = "pwdLockout";
+    private static final String OLPW_LOCKOUT_DURATION = "pwdLockoutDuration";
+    private static final String OLPW_MAX_FAILURE = "pwdMaxFailure";
+    private static final String OLPW_FAILURE_COUNT_INTERVAL = "pwdFailureCountInterval";
+    private static final String OLPW_MUST_CHANGE = "pwdMustChange";
+    private static final String OLPW_ALLOW_USER_CHANGE = "pwdAllowUserChange";
+    private static final String OLPW_SAFE_MODIFY = "pwdSafeModify";
+    private static final String[] PASSWORD_POLICY_ATRS =
+        {
+            OLPW_MIN_AGE, OLPW_MAX_AGE, OLPW_IN_HISTORY, OLPW_CHECK_QUALITY,
+            OLPW_MIN_LENGTH, OLPW_EXPIRE_WARNING, OLPW_GRACE_LOGIN_LIMIT, OLPW_LOCKOUT,
+            OLPW_LOCKOUT_DURATION, OLPW_MAX_FAILURE, OLPW_FAILURE_COUNT_INTERVAL,
+            OLPW_MUST_CHANGE, OLPW_ALLOW_USER_CHANGE, OLPW_SAFE_MODIFY,
+    };
+
+    private static final String[] PASSWORD_POLICY_NAME_ATR =
+        {
+            GlobalIds.CN
+    };
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    final PwPolicy create( PwPolicy entity )
+        throws CreateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        try
+        {
+            Entry entry = new DefaultEntry( dn );
+            entry.add( GlobalIds.OBJECT_CLASS, OAM_PWPOLICY_OBJ_CLASS );
+            entry.add( GlobalIds.CN, entity.getName() );
+            entry.add( OLPW_ATTRIBUTE, OLPW_POLICY_EXTENSION );
+
+            if ( entity.getMinAge() != null )
+            {
+                entry.add( OLPW_MIN_AGE, entity.getMinAge().toString() );
+            }
+
+            if ( entity.getMaxAge() != null )
+            {
+                entry.add( OLPW_MAX_AGE, entity.getMaxAge().toString() );
+            }
+
+            if ( entity.getInHistory() != null )
+            {
+                entry.add( OLPW_IN_HISTORY, entity.getInHistory().toString() );
+            }
+
+            if ( entity.getCheckQuality() != null )
+            {
+                entry.add( OLPW_CHECK_QUALITY, entity.getCheckQuality().toString() );
+            }
+
+            if ( entity.getMinLength() != null )
+            {
+                entry.add( OLPW_MIN_LENGTH, entity.getMinLength().toString() );
+            }
+
+            if ( entity.getExpireWarning() != null )
+            {
+                entry.add( OLPW_EXPIRE_WARNING, entity.getExpireWarning().toString() );
+            }
+
+            if ( entity.getGraceLoginLimit() != null )
+            {
+                entry.add( OLPW_GRACE_LOGIN_LIMIT, entity.getGraceLoginLimit().toString() );
+            }
+
+            if ( entity.getLockout() != null )
+            {
+                /**
+                 * For some reason OpenLDAP requires the pwdLockout boolean value to be upper case:
+                 */
+                entry.add( OLPW_LOCKOUT, entity.getLockout().toString().toUpperCase() );
+            }
+
+            if ( entity.getLockoutDuration() != null )
+            {
+                entry.add( OLPW_LOCKOUT_DURATION, entity.getLockoutDuration().toString() );
+            }
+
+            if ( entity.getMaxFailure() != null )
+            {
+                entry.add( OLPW_MAX_FAILURE, entity.getMaxFailure().toString() );
+            }
+
+            if ( entity.getFailureCountInterval() != null )
+            {
+                entry.add( OLPW_FAILURE_COUNT_INTERVAL, entity.getFailureCountInterval().toString() );
+            }
+
+            if ( entity.getMustChange() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                entry.add( OLPW_MUST_CHANGE, entity.getMustChange().toString().toUpperCase() );
+            }
+
+            if ( entity.getAllowUserChange() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                entry.add( OLPW_ALLOW_USER_CHANGE, entity.getAllowUserChange().toString()
+                    .toUpperCase() );
+            }
+
+            if ( entity.getSafeModify() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                entry.add( OLPW_SAFE_MODIFY, entity.getSafeModify().toString().toUpperCase() );
+            }
+
+            ld = getAdminConnection();
+            add( ld, entry, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "create name [" + entity.getName() + "] caught LdapException=" + e.getMessage();
+            throw new CreateException( GlobalErrIds.PSWD_CREATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    final void update( PwPolicy entity ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            if ( entity.getMinAge() != null )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_MIN_AGE, entity.getMinAge().toString() ) );
+            }
+
+            if ( entity.getMaxAge() != null )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_MAX_AGE, entity.getMaxAge().toString() ) );
+            }
+
+            if ( entity.getInHistory() != null )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_IN_HISTORY, entity.getInHistory().toString() ) );
+            }
+
+            if ( entity.getCheckQuality() != null )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_CHECK_QUALITY, entity.getCheckQuality().toString() ) );
+            }
+
+            if ( entity.getMinLength() != null )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_MIN_LENGTH, entity.getMinLength().toString() ) );
+            }
+
+            if ( entity.getExpireWarning() != null )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_EXPIRE_WARNING, entity.getExpireWarning().toString() ) );
+            }
+
+            if ( entity.getGraceLoginLimit() != null )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_GRACE_LOGIN_LIMIT, entity.getGraceLoginLimit().toString() ) );
+            }
+
+            if ( entity.getLockout() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_LOCKOUT, entity.getLockout().toString().toUpperCase() ) );
+            }
+
+            if ( entity.getLockoutDuration() != null )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_LOCKOUT_DURATION, entity.getLockoutDuration().toString() ) );
+            }
+
+            if ( entity.getMaxFailure() != null )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_MAX_FAILURE, entity.getMaxFailure().toString() ) );
+            }
+
+            if ( entity.getFailureCountInterval() != null )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_FAILURE_COUNT_INTERVAL, entity.getFailureCountInterval().toString() ) );
+            }
+
+            if ( entity.getMustChange() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_MUST_CHANGE, entity.getMustChange().toString().toUpperCase() ) );
+            }
+
+            if ( entity.getAllowUserChange() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_ALLOW_USER_CHANGE, entity.getAllowUserChange().toString().toUpperCase() ) );
+            }
+
+            if ( entity.getSafeModify() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE,
+                    OLPW_SAFE_MODIFY, entity.getSafeModify().toString().toUpperCase() ) );
+            }
+
+            if ( mods != null && mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods, entity );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "update name [" + entity.getName() + "] caught LdapException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.PSWD_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.RemoveException
+     */
+    final void remove( PwPolicy entity ) throws RemoveException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, dn, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove name [" + entity.getName() + "] caught LdapException=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.PSWD_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param policy
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    final PwPolicy getPolicy( PwPolicy policy ) throws FinderException
+    {
+        PwPolicy entity = null;
+        LdapConnection ld = null;
+        String dn = getDn( policy );
+
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, dn, PASSWORD_POLICY_ATRS );
+            entity = unloadLdapEntry( findEntry, 0 );
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getPolicy Obj COULD NOT FIND ENTRY for dn [" + dn + "]";
+            throw new FinderException( GlobalErrIds.PSWD_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getPolicy name [" + policy.getName() + "] caught LdapException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.PSWD_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     *
+     * @param le
+     * @param sequence
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     * @throws LdapException
+     */
+    private PwPolicy unloadLdapEntry( Entry le, long sequence ) throws LdapInvalidAttributeValueException
+    {
+        PwPolicy entity = new ObjectFactory().createPswdPolicy();
+        entity.setSequenceId( sequence );
+        entity.setName( getRdn( le.getDn().getName() ) );
+        //entity.setAttribute(getAttribute(le, OLPW_ATTRIBUTE));
+        String val = getAttribute( le, OLPW_MIN_AGE );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setMinAge( new Integer( val ) );
+        }
+
+        val = getAttribute( le, OLPW_MAX_AGE );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setMaxAge( new Long( val ) );
+        }
+
+        val = getAttribute( le, OLPW_IN_HISTORY );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setInHistory( new Short( val ) );
+        }
+
+        val = getAttribute( le, OLPW_CHECK_QUALITY );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setCheckQuality( new Short( val ) );
+        }
+
+        val = getAttribute( le, OLPW_MIN_LENGTH );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setMinLength( new Short( val ) );
+        }
+
+        val = getAttribute( le, OLPW_EXPIRE_WARNING );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setExpireWarning( new Long( val ) );
+        }
+
+        val = getAttribute( le, OLPW_GRACE_LOGIN_LIMIT );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setGraceLoginLimit( new Short( val ) );
+        }
+
+        val = getAttribute( le, OLPW_LOCKOUT );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setLockout( Boolean.valueOf( val ) );
+        }
+
+        val = getAttribute( le, OLPW_LOCKOUT_DURATION );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setLockoutDuration( new Integer( val ) );
+        }
+
+        val = getAttribute( le, OLPW_MAX_FAILURE );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setMaxFailure( new Short( val ) );
+        }
+
+        val = getAttribute( le, OLPW_FAILURE_COUNT_INTERVAL );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setFailureCountInterval( new Short( val ) );
+        }
+
+        val = getAttribute( le, OLPW_MUST_CHANGE );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            //noinspection BooleanConstructorCall
+            entity.setMustChange( Boolean.valueOf( val ) );
+        }
+
+        val = getAttribute( le, OLPW_ALLOW_USER_CHANGE );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setAllowUserChange( Boolean.valueOf( val ) );
+        }
+
+        val = getAttribute( le, OLPW_SAFE_MODIFY );
+
+        if ( VUtil.isNotNullOrEmpty( val ) )
+        {
+            entity.setSafeModify( Boolean.valueOf( val ) );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param policy
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    final List<PwPolicy> findPolicy( PwPolicy policy ) throws FinderException
+    {
+        List<PwPolicy> policyArrayList = new ArrayList<>();
+        LdapConnection ld = null;
+        String policyRoot = getPolicyRoot( policy.getContextId() );
+        String searchVal = null;
+
+        try
+        {
+            searchVal = encodeSafeText( policy.getName(), GlobalIds.PWPOLICY_NAME_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + OLPW_POLICY_CLASS + ")("
+                + GlobalIds.POLICY_NODE_TYPE + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, policyRoot,
+                SearchScope.ONELEVEL, filter, PASSWORD_POLICY_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                policyArrayList.add( unloadLdapEntry( searchResults.getEntry(), sequence++ ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findPolicy name [" + searchVal + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PSWD_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findPolicy name [" + searchVal + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PSWD_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return policyArrayList;
+    }
+
+
+    /**
+     * @return
+     * @throws FinderException
+     */
+    final Set<String> getPolicies( String contextId )
+        throws FinderException
+    {
+        Set<String> policySet = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        LdapConnection ld = null;
+        String policyRoot = getPolicyRoot( contextId );
+
+        try
+        {
+            String filter = "(objectclass=" + OLPW_POLICY_CLASS + ")";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, policyRoot,
+                SearchScope.ONELEVEL, filter, PASSWORD_POLICY_NAME_ATR, false, GlobalIds.BATCH_SIZE );
+
+            while ( searchResults.next() )
+            {
+                policySet.add( getAttribute( searchResults.getEntry(), GlobalIds.CN ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "getPolicies caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PSWD_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "getPolicies caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PSWD_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return policySet;
+    }
+
+
+    private String getDn( PwPolicy policy )
+    {
+        return GlobalIds.POLICY_NODE_TYPE + "=" + policy.getName() + "," + getPolicyRoot( policy.getContextId() );
+    }
+
+
+    private String getPolicyRoot( String contextId )
+    {
+        return getRootDn( contextId, GlobalIds.PPOLICY_ROOT );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/PolicyP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/PolicyP.java b/src/main/java/org/apache/directory/fortress/core/rbac/PolicyP.java
index e6f935f..bdd31ba 100755
--- a/src/main/java/org/apache/directory/fortress/core/rbac/PolicyP.java
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PolicyP.java
@@ -30,7 +30,6 @@ import org.apache.directory.fortress.core.GlobalErrIds;
 import org.apache.directory.fortress.core.GlobalIds;
 import org.apache.directory.fortress.core.SecurityException;
 import org.apache.directory.fortress.core.ValidationException;
-import org.apache.directory.fortress.core.rbac.dao.unboundid.PolicyDAO;
 import org.apache.directory.fortress.core.util.attr.VUtil;
 import org.apache.directory.fortress.core.util.cache.Cache;
 import org.apache.directory.fortress.core.util.cache.CacheMgr;

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicyControl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicyControl.java b/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicyControl.java
index 8cc7c51..bbb00e6 100755
--- a/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicyControl.java
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicyControl.java
@@ -20,8 +20,6 @@
 package org.apache.directory.fortress.core.rbac;
 
 
-import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPControl;
-
 
 /**
  * Interface is used to allow pluggable password policy interrogation.
@@ -37,5 +35,5 @@ public interface PwPolicyControl
      * @param isAuthenticated set to 'true' if password checks pass.
      * @param pwMsg describes the outcome of the policy checks.
      */
-    public void checkPasswordPolicy( LDAPControl[] controls, boolean isAuthenticated, PwMessage pwMsg );
+    public void checkPasswordPolicy( Object[] controls, boolean isAuthenticated, PwMessage pwMsg );
 }

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/Role.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Role.java b/src/main/java/org/apache/directory/fortress/core/rbac/Role.java
index 0d9c20a..8651808 100755
--- a/src/main/java/org/apache/directory/fortress/core/rbac/Role.java
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Role.java
@@ -33,8 +33,6 @@ import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
-import org.apache.directory.fortress.core.rbac.dao.RoleDAO;
-import org.apache.directory.fortress.core.rbac.dao.UserDAO;
 import org.apache.directory.fortress.core.util.time.CUtil;
 import org.apache.directory.fortress.core.util.time.Constraint;
 
@@ -48,7 +46,7 @@ import org.apache.directory.fortress.core.util.time.Constraint;
  * <ol>
  * <li>Manager layer:  {@link AdminMgrImpl}, {@link AccessMgrImpl}, {@link ReviewMgrImpl},...</li>
  * <li>Process layer:  {@link UserP}, {@link RoleP}, {@link PermP},...</li>
- * <li>DAO layer: {@link UserDAO}, {@link RoleDAO}, {@link org.apache.directory.fortress.core.rbac.dao.PermDAO},...</li>
+ * <li>DAO layer: {@link UserDAO}, {@link RoleDAO}, {@link org.apache.directory.fortress.core.rbac.PermDAO},...</li>
  * </ol>
  * Fortress clients first instantiate and populate a data entity before invoking any of the Manager APIs.  The caller must
  * provide enough information to uniquely identity the entity target within ldap.<br />

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/RoleDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/RoleDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/RoleDAO.java
new file mode 100755
index 0000000..7b62ba4
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/RoleDAO.java
@@ -0,0 +1,657 @@
+/*
+ *   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.rbac;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.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.rbac.Graphable;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.RoleUtil;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.time.CUtil;
+
+
+/**
+ * This class perform data access for Fortress Role entity.
+ * <p/>
+ * The Fortress Role entity is a composite of the following other Fortress structural and aux object classes:
+ * <h4>1. ftRls Structural objectclass is used to store the Role information like name and temporal constraint attributes</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass	( 1.3.6.1.4.1.38088.2.1</code>
+ * <li> <code>NAME 'ftRls'</code>
+ * <li> <code>DESC 'Fortress Role Object Class'</code>
+ * <li> <code>SUP organizationalrole</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST ( ftId $ ftRoleName )</code>
+ * <li> <code>MAY ( description $ ftCstr ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>2. ftProperties AUXILIARY Object Class is used to store client specific name/value pairs on target entity</h4>
+ * <code># This aux object class can be used to store custom attributes.</code><br />
+ * <code># The properties collections consist of name/value pairs and are not constrainted by Fortress.</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.2</code>
+ * <li> <code>NAME 'ftProperties'</code>
+ * <li> <code>DESC 'Fortress Properties AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MAY ( ftProps ) ) </code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>3. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity</h4>
+ * <ul>
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.4</code>
+ * <li> <code>NAME 'ftMods'</code>
+ * <li> <code>DESC 'Fortress Modifiers AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MAY (</code>
+ * <li> <code>ftModifier $</code>
+ * <li> <code>ftModCode $</code>
+ * <li> <code>ftModId ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Kevin McKinney
+ */
+final class RoleDAO extends ApacheDsDataProvider
+{
+    /*
+      *  *************************************************************************
+      *  **  OpenAccessMgr ROLE STATICS
+      *  ************************************************************************
+      */
+    private static final String ROLE_OCCUPANT = "roleOccupant";
+    private static final String ROLE_NM = "ftRoleName";
+
+    private static final String[] ROLE_NM_ATR =
+        {
+            ROLE_NM
+    };
+
+    private static final String[] ROLE_ATRS =
+        {
+            GlobalIds.FT_IID, ROLE_NM, GlobalIds.DESC, GlobalIds.CONSTRAINT, ROLE_OCCUPANT, GlobalIds.PARENT_NODES
+    };
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws CreateException
+     */
+    final Role create( Role entity ) throws CreateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+
+        try
+        {
+            Entry entry = new DefaultEntry( dn );
+            entry.add( GlobalIds.OBJECT_CLASS, GlobalIds.ROLE_OBJ_CLASS );
+            entity.setId();
+            entry.add( GlobalIds.FT_IID, entity.getId() );
+            entry.add( ROLE_NM, entity.getName() );
+
+            // description field is optional on this object class:
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                entry.add( GlobalIds.DESC, entity.getDescription() );
+            }
+
+            // CN attribute is required for this object class:
+            entry.add( GlobalIds.CN, entity.getName() );
+            entry.add( GlobalIds.CONSTRAINT, CUtil.setConstraint( entity ) );
+
+            // These multi-valued attributes are optional.  The utility function will return quietly if items are not loaded into collection:
+            loadAttrs( entity.getParents(), entry, GlobalIds.PARENT_NODES );
+
+            ld = getAdminConnection();
+            add( ld, entry, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "create role [" + entity.getName() + "] caught LdapException=" + e.getMessage();
+            throw new CreateException( GlobalErrIds.ROLE_ADD_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    final Role update( Role entity ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
+                    GlobalIds.DESC, entity.getDescription() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getOccupants() ) )
+            {
+                for ( String name : entity.getOccupants() )
+                {
+                    mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
+                        ROLE_OCCUPANT, entity.getOccupants().toArray( new String[]
+                            {} ) ) );
+                }
+            }
+
+            if ( entity.isTemporalSet() )
+            {
+                String szRawData = CUtil.setConstraint( entity );
+
+                if ( VUtil.isNotNullOrEmpty( szRawData ) )
+                {
+                    mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
+                        GlobalIds.CONSTRAINT, szRawData ) );
+                }
+            }
+
+            loadAttrs( entity.getParents(), mods, GlobalIds.PARENT_NODES );
+
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods, entity );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "update name [" + entity.getName() + "] caught LdapException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ROLE_UPDATE_FAILED, error, e );
+        }
+        catch ( Exception e )
+        {
+            String error = "update name [" + entity.getName() + "] caught LdapException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ROLE_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            try
+            {
+                closeAdminConnection( ld );
+            }
+            catch ( Exception e )
+            {
+                String error = "update name [" + entity.getName() + "] caught LdapException=" + e.getMessage();
+                throw new UpdateException( GlobalErrIds.ROLE_UPDATE_FAILED, error, e );
+            }
+        }
+
+        return entity;
+    }
+
+
+    /**
+     *
+     * @param entity
+     * @throws UpdateException
+     */
+    final void deleteParent( Role entity ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE,
+                GlobalIds.PARENT_NODES ) );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "deleteParent name [" + entity.getName() + "] caught LdapException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ROLE_REMOVE_PARENT_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param entity
+     * @param userDn
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    final Role assign( Role entity, String userDn ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+
+        try
+        {
+            //ld = getAdminConnection();
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, ROLE_OCCUPANT, userDn ) );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "assign role name [" + entity.getName() + "] user dn [" + userDn + "] caught LdapException="
+                + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ROLE_USER_ASSIGN_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @param userDn
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    final Role deassign( Role entity, String userDn ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, ROLE_OCCUPANT, userDn ) );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "deassign role name [" + entity.getName() + "] user dn [" + userDn
+                + "] caught LdapException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ROLE_USER_DEASSIGN_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param role
+     * @throws RemoveException
+     */
+    final void remove( Role role )
+        throws RemoveException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( role.getName(), role.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, dn, role );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove role name=" + role.getName() + " LdapException=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.ROLE_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    final Role getRole( Role role )
+        throws FinderException
+    {
+        Role entity = null;
+        LdapConnection ld = null;
+        String dn = getDn( role.getName(), role.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, dn, ROLE_ATRS );
+            if(findEntry != null)
+            {
+                entity = unloadLdapEntry( findEntry, 0, role.getContextId() );
+            }
+            if ( entity == null )
+            {
+                String warning = "getRole no entry found dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.ROLE_NOT_FOUND, warning );
+            }
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getRole Obj COULD NOT FIND ENTRY for dn [" + dn + "]";
+            throw new FinderException( GlobalErrIds.ROLE_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getRole dn [" + dn + "] LEXCD=" + e;
+            throw new FinderException( GlobalErrIds.ROLE_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    final List<Role> findRoles( Role role )
+        throws FinderException
+    {
+        List<Role> roleList = new ArrayList<>();
+        LdapConnection ld = null;
+        String roleRoot = getRootDn( role.getContextId(), GlobalIds.ROLE_ROOT );
+        String filter = null;
+
+        try
+        {
+            String searchVal = encodeSafeText( role.getName(), GlobalIds.ROLE_LEN );
+            filter = GlobalIds.FILTER_PREFIX + GlobalIds.ROLE_OBJECT_CLASS_NM + ")("
+                + ROLE_NM + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, roleRoot,
+                SearchScope.ONELEVEL, filter, ROLE_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                roleList.add( unloadLdapEntry( searchResults.getEntry(), sequence++, role.getContextId() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findRoles filter [" + filter + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ROLE_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findRoles filter [" + filter + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ROLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return roleList;
+    }
+
+
+    /**
+     * @param role
+     * @param limit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    final List<String> findRoles( Role role, int limit )
+        throws FinderException
+    {
+        List<String> roleList = new ArrayList<>();
+        LdapConnection ld = null;
+        String roleRoot = getRootDn( role.getContextId(), GlobalIds.ROLE_ROOT );
+        String filter = null;
+
+        try
+        {
+            String searchVal = encodeSafeText( role.getName(), GlobalIds.ROLE_LEN );
+            filter = GlobalIds.FILTER_PREFIX + GlobalIds.ROLE_OBJECT_CLASS_NM + ")("
+                + ROLE_NM + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, roleRoot,
+                SearchScope.ONELEVEL, filter, ROLE_NM_ATR, false, GlobalIds.BATCH_SIZE, limit );
+
+            while ( searchResults.next() )
+            {
+                Entry entry = searchResults.getEntry();
+                roleList.add( getAttribute( entry, ROLE_NM ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findRoles filter [" + filter + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ROLE_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findRoles filter [" + filter + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ROLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return roleList;
+    }
+
+
+    /**
+     *
+     * @param userDn
+     * @param contextId
+     * @return
+     * @throws FinderException
+     */
+    final List<String> findAssignedRoles( String userDn, String contextId )
+        throws FinderException
+    {
+        List<String> roleNameList = new ArrayList<>();
+        LdapConnection ld = null;
+        String roleRoot = getRootDn( contextId, GlobalIds.ROLE_ROOT );
+
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + GlobalIds.ROLE_OBJECT_CLASS_NM + ")";
+            filter += "(" + ROLE_OCCUPANT + "=" + userDn + "))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, roleRoot,
+                SearchScope.ONELEVEL, filter, ROLE_NM_ATR, false, GlobalIds.BATCH_SIZE );
+
+            while ( searchResults.next() )
+            {
+                roleNameList.add( getAttribute( searchResults.getEntry(), ROLE_NM ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findAssignedRoles userDn [" + userDn + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ROLE_OCCUPANT_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findAssignedRoles userDn [" + userDn + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ROLE_OCCUPANT_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return roleNameList;
+    }
+
+
+    /**
+     *
+     * @param contextId
+     * @return
+     * @throws FinderException
+     */
+    final List<Graphable> getAllDescendants( String contextId )
+        throws FinderException
+    {
+        String[] DESC_ATRS =
+            { ROLE_NM, GlobalIds.PARENT_NODES };
+        List<Graphable> descendants = new ArrayList<>();
+        LdapConnection ld = null;
+        String roleRoot = getRootDn( contextId, GlobalIds.ROLE_ROOT );
+        String filter = null;
+
+        try
+        {
+            filter = GlobalIds.FILTER_PREFIX + GlobalIds.ROLE_OBJECT_CLASS_NM + ")("
+                + GlobalIds.PARENT_NODES + "=*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, roleRoot,
+                SearchScope.ONELEVEL, filter, DESC_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                descendants.add( unloadDescendants( searchResults.getEntry(), sequence++, contextId ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "getAllDescendants filter [" + filter + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ROLE_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "getAllDescendants filter [" + filter + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ROLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return descendants;
+    }
+
+
+    /**
+     *
+     * @param le
+     * @param sequence
+     * @param contextId
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     * @throws LdapException
+     */
+    private Graphable unloadDescendants( Entry le, long sequence, String contextId )
+        throws LdapInvalidAttributeValueException
+    {
+        Role entity = new ObjectFactory().createRole();
+        entity.setSequenceId( sequence );
+        entity.setName( getAttribute( le, ROLE_NM ) );
+        entity.setParents( getAttributeSet( le, GlobalIds.PARENT_NODES ) );
+        return entity;
+    }
+
+
+    /**
+     *
+     * @param le
+     * @param sequence
+     * @param contextId
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     * @throws LdapException
+     */
+    private Role unloadLdapEntry( Entry le, long sequence, String contextId ) throws LdapInvalidAttributeValueException
+    {
+        Role entity = new ObjectFactory().createRole();
+        entity.setSequenceId( sequence );
+        entity.setId( getAttribute( le, GlobalIds.FT_IID ) );
+        entity.setName( getAttribute( le, ROLE_NM ) );
+        entity.setDescription( getAttribute( le, GlobalIds.DESC ) );
+        entity.setOccupants( getAttributes( le, ROLE_OCCUPANT ) );
+        //entity.setParents(RoleUtil.getParents(entity.getName().toUpperCase(), contextId));
+        entity.setChildren( RoleUtil.getChildren( entity.getName().toUpperCase(), contextId ) );
+        entity.setParents( getAttributeSet( le, GlobalIds.PARENT_NODES ) );
+        unloadTemporal( le, entity );
+
+        return entity;
+    }
+
+
+    private String getDn( String name, String contextId )
+    {
+        return GlobalIds.CN + "=" + name + "," + getRootDn( contextId, GlobalIds.ROLE_ROOT );
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/RoleP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/RoleP.java b/src/main/java/org/apache/directory/fortress/core/rbac/RoleP.java
index 56e4a13..750c2c8 100755
--- a/src/main/java/org/apache/directory/fortress/core/rbac/RoleP.java
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/RoleP.java
@@ -27,8 +27,6 @@ import org.apache.directory.fortress.core.GlobalErrIds;
 import org.apache.directory.fortress.core.GlobalIds;
 import org.apache.directory.fortress.core.SecurityException;
 import org.apache.directory.fortress.core.ValidationException;
-import org.apache.directory.fortress.core.rbac.dao.DaoFactory;
-import org.apache.directory.fortress.core.rbac.dao.RoleDAO;
 import org.apache.directory.fortress.core.util.attr.VUtil;
 
 
@@ -52,7 +50,7 @@ import org.apache.directory.fortress.core.util.attr.VUtil;
  */
 public final class RoleP
 {
-    private static RoleDAO rDao = DaoFactory.createRoleDAO();
+    private static RoleDAO rDao = new RoleDAO();
 
     /**
      * Package private

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/SdDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/SdDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/SdDAO.java
new file mode 100755
index 0000000..5888f85
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/SdDAO.java
@@ -0,0 +1,633 @@
+/*
+ *   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.rbac;
+
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+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.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.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.rbac.Role;
+import org.apache.directory.fortress.core.rbac.RoleUtil;
+import org.apache.directory.fortress.core.rbac.SDSet;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * This class performs persistence on the RBAC Static Separation of Duties and Dynamic Separation of Duties data sets.
+ * <p/>
+ * The Fortress SDSet entity is a composite of the following other Fortress structural and aux object classes:
+ * <h4>1. organizationalRole Structural Object Class is used to store basic attributes like cn and description</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 2.5.6.8 NAME 'organizationalRole'</code>
+ * <li> <code>DESC 'RFC2256: an organizational role'</code>
+ * <li> <code>SUP top STRUCTURAL</code>
+ * <li> <code>MUST cn</code>
+ * <li> <code>MAY ( x121Address $ registeredAddress $ destinationIndicator $</code>
+ * <li> <code>preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $</code>
+ * <li> <code>telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $</code>
+ * <li> <code>seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $</code>
+ * <li> <code>postOfficeBox $ postalCode $ postalAddress $</code>
+ * <li> <code>physicalDeliveryOfficeName $ ou $ st $ l $ description ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>2. The RBAC Separation of Duties</h4>
+ * <ul>
+ * <li>  ---Static Separation of Duties Set-------
+ * <li> <code>objectclass	( 1.3.6.1.4.1.38088.2.4</code>
+ * <li> <code>NAME 'ftSSDSet'</code>
+ * <li> <code>DESC 'Fortress Role Static Separation of Duty Set Object Class'</code>
+ * <li> <code>SUP organizationalrole</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST ( ftId $ ftSetName $ ftSetCardinality )</code>
+ * <li> <code>MAY ( ftRoles $ description ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <p/>
+ * OR
+ * <h4>Dynamic Separation of Duties Set</h4>
+ * <ul>
+ * <li>
+ * <li> <code>objectclass	( 1.3.6.1.4.1.38088.2.5</code>
+ * <li> <code>NAME 'ftDSDSet'</code>
+ * <li> <code>DESC 'Fortress Role Dynamic Separation of Duty Set Object Class'</code>
+ * <li> <code>SUP organizationalrole</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST ( ftId $ ftSetName $ ftSetCardinality )</code>
+ * <li> <code>MAY ( ftRoles $ description ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>3. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity</h4>
+ * <ul>
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.4</code>
+ * <li> <code>NAME 'ftMods'</code>
+ * <li> <code>DESC 'Fortress Modifiers AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MAY (</code>
+ * <li> <code>ftModifier $</code>
+ * <li> <code>ftModCode $</code>
+ * <li> <code>ftModId ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+final class SdDAO extends ApacheDsDataProvider
+{
+    private static final String SD_SET_NM = "ftSetName";
+    private static final String ROLES = "ftRoles";
+    private static final String SD_SET_CARDINALITY = "ftSetCardinality";
+
+    private static final String SSD_OBJECT_CLASS_NM = "ftSSDSet";
+    private static final String SSD_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP, SSD_OBJECT_CLASS_NM, GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+
+    private static final String DSD_OBJECT_CLASS_NM = "ftDSDSet";
+    private static final String DSD_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP, DSD_OBJECT_CLASS_NM, GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+
+    private static final String[] SD_SET_ATRS =
+        {
+            GlobalIds.FT_IID, SD_SET_NM, GlobalIds.DESC, ROLES, SD_SET_CARDINALITY
+    };
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     */
+    final SDSet create( SDSet entity ) throws CreateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+        String[] objectClass = SSD_OBJ_CLASS;
+
+        if ( entity.getType() == SDSet.SDType.DYNAMIC )
+        {
+            objectClass = DSD_OBJ_CLASS;
+        }
+
+        try
+        {
+            Entry entry = new DefaultEntry( dn );
+            entry.add( createAttributes( GlobalIds.OBJECT_CLASS, objectClass ) );
+            entity.setId();
+            entry.add( GlobalIds.FT_IID, entity.getId() );
+            entry.add( SD_SET_NM, entity.getName() );
+
+            // description field is optional on this object class:
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                entry.add( GlobalIds.DESC, entity.getDescription() );
+            }
+
+            // CN attribute is required for this object class:
+            entry.add( GlobalIds.CN, entity.getName() );
+            loadAttrs( entity.getMembers(), entry, ROLES );
+            entry.add( SD_SET_CARDINALITY, "" + entity.getCardinality() );
+
+            ld = getAdminConnection();
+            add( ld, entry, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "create SD set name [" + entity.getName() + "] type [" + entity.getType()
+                + "] caught LdapException=" + e.getMessage();
+            int errCode;
+            if ( entity.getType() == SDSet.SDType.DYNAMIC )
+            {
+                errCode = GlobalErrIds.DSD_ADD_FAILED;
+            }
+            else
+            {
+                errCode = GlobalErrIds.SSD_ADD_FAILED;
+            }
+
+            throw new CreateException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     */
+    final SDSet update( SDSet entity ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.DESC, entity.getDescription() ) );
+            }
+
+            if ( entity.getCardinality() != null )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, SD_SET_CARDINALITY, entity.getCardinality().toString() ) );
+            }
+
+            loadAttrs( entity.getMembers(), mods, ROLES );
+
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods, entity );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "update name [" + entity.getName() + "] type [" + entity.getType()
+                + "] caught LdapException=" + e.getMessage();
+            int errCode;
+            if ( entity.getType() == SDSet.SDType.DYNAMIC )
+            {
+                errCode = GlobalErrIds.DSD_UPDATE_FAILED;
+            }
+            else
+            {
+                errCode = GlobalErrIds.SSD_UPDATE_FAILED;
+            }
+
+            throw new UpdateException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.RemoveException
+     */
+    final SDSet remove( SDSet entity ) throws RemoveException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, dn, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove SD name=" + entity.getName() + " type [" + entity.getType() + "] LdapException="
+                + e.getMessage();
+            int errCode;
+            if ( entity.getType() == SDSet.SDType.DYNAMIC )
+            {
+                errCode = GlobalErrIds.DSD_DELETE_FAILED;
+            }
+            else
+            {
+                errCode = GlobalErrIds.SSD_DELETE_FAILED;
+            }
+
+            throw new RemoveException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param sdSet
+     * @return
+     * @throws FinderException
+     */
+    final SDSet getSD( SDSet sdSet ) throws FinderException
+    {
+        SDSet entity = null;
+        LdapConnection ld = null;
+        String dn = getDn( sdSet.getName(), sdSet.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, dn, SD_SET_ATRS );
+            entity = unloadLdapEntry( findEntry, 0 );
+
+            if ( entity == null )
+            {
+                String warning = "getSD no entry found dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.SSD_NOT_FOUND, warning );
+            }
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getSD Obj COULD NOT FIND ENTRY for dn [" + dn + "]";
+            throw new FinderException( GlobalErrIds.SSD_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getSSD dn [" + dn + "] LEXCD=" + e;
+            int errCode;
+
+            if ( sdSet.getType() == SDSet.SDType.DYNAMIC )
+            {
+                errCode = GlobalErrIds.DSD_READ_FAILED;
+            }
+            else
+            {
+                errCode = GlobalErrIds.SSD_READ_FAILED;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * Given an SSD name and type, find matching object in the directory.
+     * @param sdset requires name and type.
+     * @return List of matching SDSets.
+     * @throws org.apache.directory.fortress.core.FinderException
+     */
+    final List<SDSet> search( SDSet sdset ) throws FinderException
+    {
+        List<SDSet> sdList = new ArrayList<>();
+        LdapConnection ld = null;
+        String ssdRoot = getSdRoot( sdset.getContextId() );
+        String objectClass = SSD_OBJECT_CLASS_NM;
+
+        if ( sdset.getType() == SDSet.SDType.DYNAMIC )
+        {
+            objectClass = DSD_OBJECT_CLASS_NM;
+        }
+
+        try
+        {
+            String searchVal = encodeSafeText( sdset.getName(), GlobalIds.ROLE_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + objectClass + ")(" + SD_SET_NM + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, ssdRoot,
+                SearchScope.SUBTREE, filter, SD_SET_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                sdList.add( unloadLdapEntry( searchResults.getEntry(), sequence++ ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "search sdset name [" + sdset.getName() + "] type [" + sdset.getType()
+                + "] caught LdapException=" + e.getMessage();
+            int errCode;
+
+            if ( sdset.getType() == SDSet.SDType.DYNAMIC )
+            {
+                errCode = GlobalErrIds.DSD_SEARCH_FAILED;
+            }
+            else
+            {
+                errCode = GlobalErrIds.SSD_SEARCH_FAILED;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "search sdset name [" + sdset.getName() + "] type [" + sdset.getType()
+                + "] caught LdapException=" + e.getMessage();
+            int errCode;
+
+            if ( sdset.getType() == SDSet.SDType.DYNAMIC )
+            {
+                errCode = GlobalErrIds.DSD_SEARCH_FAILED;
+            }
+            else
+            {
+                errCode = GlobalErrIds.SSD_SEARCH_FAILED;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return sdList;
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     */
+    final List<SDSet> search( Role role, SDSet.SDType type ) throws FinderException
+    {
+        List<SDSet> sdList = new ArrayList<>();
+        LdapConnection ld = null;
+        String ssdRoot = getSdRoot( role.getContextId() );
+        String objectClass = SSD_OBJECT_CLASS_NM;
+
+        if ( type == SDSet.SDType.DYNAMIC )
+        {
+            objectClass = DSD_OBJECT_CLASS_NM;
+        }
+
+        try
+        {
+            String roleVal = encodeSafeText( role.getName(), GlobalIds.ROLE_LEN );
+            //String filter = GlobalIds.FILTER_PREFIX + SSD_OBJECT_CLASS_NM + ")(" + ROLES + "=" + roleVal + "))";
+            String filter = GlobalIds.FILTER_PREFIX + objectClass + ")(";
+            // Include any parents target role may have:
+            Set<String> roles = RoleUtil.getAscendants( role.getName(), role.getContextId() );
+
+            if ( VUtil.isNotNullOrEmpty( roles ) )
+            {
+                filter += "|(" + ROLES + "=" + roleVal + ")";
+
+                for ( String uRole : roles )
+                {
+                    filter += "(" + ROLES + "=" + uRole + ")";
+                }
+                filter += ")";
+            }
+            else
+            {
+                filter += ROLES + "=" + roleVal + ")";
+            }
+
+            filter += ")";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, ssdRoot,
+                SearchScope.SUBTREE, filter, SD_SET_ATRS, false, GlobalIds.BATCH_SIZE );
+
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                sdList.add( unloadLdapEntry( searchResults.getEntry(), sequence++ ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "search role [" + role.getName() + "] type [" + type + "] caught LdapException="
+                + e.getMessage();
+            int errCode;
+
+            if ( type == SDSet.SDType.DYNAMIC )
+            {
+                errCode = GlobalErrIds.DSD_SEARCH_FAILED;
+            }
+            else
+            {
+                errCode = GlobalErrIds.SSD_SEARCH_FAILED;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "search role [" + role.getName() + "] type [" + type + "] caught LdapException="
+                + e.getMessage();
+            int errCode;
+
+            if ( type == SDSet.SDType.DYNAMIC )
+            {
+                errCode = GlobalErrIds.DSD_SEARCH_FAILED;
+            }
+            else
+            {
+                errCode = GlobalErrIds.SSD_SEARCH_FAILED;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return sdList;
+    }
+
+
+    /**
+     * @param roles
+     * @param sdSet
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     */
+    final Set<SDSet> search( Set<String> roles, SDSet sdSet ) throws FinderException
+    {
+        Set<SDSet> sdList = new HashSet<>();
+        LdapConnection ld = null;
+        String ssdRoot = getSdRoot( sdSet.getContextId() );
+        String objectClass = SSD_OBJECT_CLASS_NM;
+
+        if ( sdSet.getType() == SDSet.SDType.DYNAMIC )
+        {
+            objectClass = DSD_OBJECT_CLASS_NM;
+        }
+
+        try
+        {
+            if ( VUtil.isNotNullOrEmpty( roles ) )
+            {
+                String filter = GlobalIds.FILTER_PREFIX + objectClass + ")(|";
+                for ( String rle : roles )
+                {
+                    filter += "(" + ROLES + "=" + rle + ")";
+                }
+                filter += "))";
+                ld = getAdminConnection();
+                SearchCursor searchResults = search( ld, ssdRoot,
+                    SearchScope.SUBTREE, filter, SD_SET_ATRS, false, GlobalIds.BATCH_SIZE );
+                long sequence = 0;
+
+                while ( searchResults.next() )
+                {
+                    sdList.add( unloadLdapEntry( searchResults.getEntry(), sequence++ ) );
+                }
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "search type [" + sdSet.getType() + "] caught LdapException=" + e.getMessage();
+            int errCode;
+
+            if ( sdSet.getType() == SDSet.SDType.DYNAMIC )
+            {
+                errCode = GlobalErrIds.DSD_SEARCH_FAILED;
+            }
+            else
+            {
+                errCode = GlobalErrIds.SSD_SEARCH_FAILED;
+            }
+            throw new FinderException( errCode, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "search type [" + sdSet.getType() + "] caught LdapException=" + e.getMessage();
+            int errCode;
+
+            if ( sdSet.getType() == SDSet.SDType.DYNAMIC )
+            {
+                errCode = GlobalErrIds.DSD_SEARCH_FAILED;
+            }
+            else
+            {
+                errCode = GlobalErrIds.SSD_SEARCH_FAILED;
+            }
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return sdList;
+    }
+
+
+    /**
+     * @param le
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     * @throws LdapException
+     */
+    private SDSet unloadLdapEntry( Entry le, long sequence ) throws LdapInvalidAttributeValueException
+    {
+        SDSet entity = new ObjectFactory().createSDset();
+        entity.setSequenceId( sequence );
+        entity.setId( getAttribute( le, GlobalIds.FT_IID ) );
+        entity.setName( getAttribute( le, SD_SET_NM ) );
+        entity.setDescription( getAttribute( le, GlobalIds.DESC ) );
+        entity.setMembers( getAttributeSet( le, ROLES ) );
+        String szCard = getAttribute( le, SD_SET_CARDINALITY );
+        entity.setCardinality( new Integer( szCard ) );
+
+        return entity;
+    }
+
+
+    private String getDn( String name, String contextId )
+    {
+        return GlobalIds.CN + "=" + name + "," + getSdRoot( contextId );
+    }
+
+
+    private String getSdRoot( String contextId )
+    {
+        return getRootDn( contextId, GlobalIds.SD_ROOT );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/SdP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/SdP.java b/src/main/java/org/apache/directory/fortress/core/rbac/SdP.java
index fa06867..0b69838 100755
--- a/src/main/java/org/apache/directory/fortress/core/rbac/SdP.java
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/SdP.java
@@ -25,7 +25,6 @@ import java.util.Set;
 
 import org.apache.directory.fortress.core.GlobalIds;
 import org.apache.directory.fortress.core.SecurityException;
-import org.apache.directory.fortress.core.rbac.dao.unboundid.SdDAO;
 import org.apache.directory.fortress.core.util.attr.VUtil;
 
 
@@ -39,7 +38,7 @@ import org.apache.directory.fortress.core.util.attr.VUtil;
  * This class performs data validations and error mapping in addition to calling DAO methods.  It is typically called
  * by internal Fortress Manager classes ({@link org.apache.directory.fortress.core.AdminMgr}, {@link org.apache.directory.fortress.core.ReviewMgr}) and also by internal SD utils.
  * This class is not intended to be called externally or outside of Fortress Core itself.  This class will accept {@link SDSet},
- * validate its contents and forward on to it's corresponding DAO {@link org.apache.directory.fortress.core.rbac.dao.unboundid.SdDAO}.
+ * validate its contents and forward on to it's corresponding DAO {@link org.apache.directory.fortress.core.rbac.SdDAO}.
  * <p>
  * Class will throw {@link SecurityException} to caller in the event of security policy, data constraint violation or system
  * error internal to DAO object. This class will forward DAO exceptions ({@link org.apache.directory.fortress.core.FinderException},

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/User.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/User.java b/src/main/java/org/apache/directory/fortress/core/rbac/User.java
index 907063e..4f00ac1 100755
--- a/src/main/java/org/apache/directory/fortress/core/rbac/User.java
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/User.java
@@ -34,7 +34,6 @@ import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
-import org.apache.directory.fortress.core.rbac.dao.apache.UserDAO;
 import org.apache.directory.fortress.core.util.time.Constraint;
 
 

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/UserAudit.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/UserAudit.java b/src/main/java/org/apache/directory/fortress/core/rbac/UserAudit.java
index dc98611..1e01e2a 100755
--- a/src/main/java/org/apache/directory/fortress/core/rbac/UserAudit.java
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/UserAudit.java
@@ -25,8 +25,6 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
-import org.apache.directory.fortress.core.rbac.dao.unboundid.AuditDAO;
-
 import java.util.Date;
 
 /**