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 17:44:38 UTC

[19/51] [partial] Rename packages from org.openldap.fortress to org.apache.directory.fortress.core. Change default suffix to org.apache. Switch default ldap api from unbound to apache ldap.

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/UserP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/UserP.java b/src/main/java/org/apache/directory/fortress/core/rbac/UserP.java
new file mode 100755
index 0000000..5d100b6
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/UserP.java
@@ -0,0 +1,843 @@
+/*
+ *   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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.PasswordException;
+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.UserDAO;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.time.CUtil;
+
+
+/**
+ * Process module for the User entity.  This class performs data validations and error mapping.  It is typically called
+ * by internal Fortress manager classes ({@link AdminMgrImpl}, {@link AccessMgrImpl},
+ * {@link ReviewMgrImpl}, ...) and not intended for external non-Fortress clients.  This class will accept,
+ * {@link org.apache.directory.fortress.core.rbac.User}, validate its contents and forward on to it's corresponding DAO class {@link org.apache.directory.fortress.core.rbac.dao.UserDAO}.
+ * <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},
+ * {@link org.apache.directory.fortress.core.CreateException},{@link org.apache.directory.fortress.core.UpdateException},{@link org.apache.directory.fortress.core.RemoveException}),
+ *  or {@link org.apache.directory.fortress.core.ValidationException} as {@link SecurityException}s with appropriate
+ * error id from {@link org.apache.directory.fortress.core.GlobalErrIds}.
+ * <p>
+ * This class is thread safe.
+ * </p>
+ *
+ * @author Shawn McKinney
+ */
+public final class UserP
+{
+    //private static final boolean IS_SESSION_PROPS_ENABLED = Config.getBoolean( "user.session.props.enabled", false );
+    private static final String CLS_NM = UserP.class.getName();
+    private static UserDAO uDao = DaoFactory.createUserDAO();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final PolicyP policyP = new PolicyP();
+    private static final AdminRoleP admRoleP = new AdminRoleP();
+    private static final OrgUnitP orgUnitP = new OrgUnitP();
+
+
+    /**
+     * Package private constructor.
+     */
+    UserP()
+    {
+    }
+
+
+    /**
+     * Takes a User entity that contains full or partial userId OR a full internal userId for search.
+     *
+     * @param user contains all or partial userId or full internal userId.
+     * @return List of type User containing fully populated matching User entities.  If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<User> search( User user ) throws SecurityException
+    {
+        return uDao.findUsers( user );
+    }
+
+
+    final List<User> search( OrgUnit ou, boolean limitSize ) throws SecurityException
+    {
+        return uDao.findUsers( ou, limitSize );
+    }
+
+
+    /**
+     * Search according to full or partial search string that maps to Fortress userid.
+     * This search is used by RealmMgr for Websphere.
+     *
+     * @param user contains full or partial userId.
+     * @param limit     specify the max number of records to return in result set.
+     * @return List of type String containing userId of all matching User entities. If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<String> search( User user, int limit ) throws SecurityException
+    {
+        return uDao.findUsers( user, limit );
+    }
+
+
+    /**
+     * Return a list of Users that are authorized the given Role.
+     *
+     * @param role contains the role name targeted for search.
+     * @return List of type User containing fully populated matching User entities. If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<User> getAuthorizedUsers( Role role ) throws SecurityException
+    {
+        return uDao.getAuthorizedUsers( role );
+    }
+
+
+    /**
+     * Return a list of Users that are authorized the given Role.
+     *
+     * @param roles contains the set of role names targeted for search.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of type String containing the userId's for matching User entities. If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final Set<String> getAssignedUsers( Set<String> roles, String contextId ) throws SecurityException
+    {
+        return uDao.getAssignedUsers( roles, contextId );
+    }
+
+
+    /**
+     * Return a list of Users that are authorized the given Role.
+     * In RBAC the word "authorized" implies the hierarchical role relations graph is considered in result set.
+     * This search is used by RealmMgr for Websphere.
+     *
+     * @param role
+     * @param limit specify the max number of records to return in result set.
+     * @return list of type String of userIds. If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<String> getAuthorizedUsers( Role role, int limit ) throws SecurityException
+    {
+        return uDao.getAuthorizedUsers( role, limit );
+    }
+
+
+    /**
+     * Return a list of Users assigned the given RBAC role.
+     * "Assigned" implies the hierarchical role relation graph will NOT be considered in result set.
+     *
+     * @param role contains name of RBAC role used for search.
+     * @return List of fully populated User entities matching target search. If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<User> getAssignedUsers( Role role ) throws SecurityException
+    {
+        return uDao.getAssignedUsers( role );
+    }
+
+
+    /**
+     * Return a list of Users assigned the given Administrative role.
+     * "Assigned" implies the hierarchical role relation graph will NOT be considered in result set.
+     *
+     * @param role contains name of Admin role used for search.
+     * @return List of fully populated User entities matching target search.  If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<User> getAssignedUsers( AdminRole role ) throws SecurityException
+    {
+        return uDao.getAssignedUsers( role );
+    }
+
+
+    /**
+     * Return the list of User's RBAC roles.
+     *
+     * @param user contains full userId for target operation.
+     * @return List of type String containing RBAC role names.  If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<String> getAssignedRoles( User user ) throws SecurityException
+    {
+        return uDao.getRoles( user );
+    }
+
+
+    /**
+     * Return a fully populated User entity for a given userId.  If the User entry is not found a SecurityException
+     * will be thrown.
+     *
+     * @param user  contains full userId value.
+     * @param isRoles return user's assigned roles if "true".
+     * @return User entity containing all attributes associated with User in directory.
+     * @throws SecurityException in the event of User not found or DAO search error.
+     */
+    final User read( User user, boolean isRoles ) throws SecurityException
+    {
+        return uDao.getUser( user, isRoles );
+    }
+
+
+    /**
+     * Adds a new User entity to directory.  The User entity input object will be validated to ensure that:
+     * userId is present, orgUnitId is valid, roles (optiona) are valid, reasonability checks on all of the
+     * other populated values.
+     *
+     * @param entity User entity contains data targeted for insertion.
+     * @return User entity copy of input + additional attributes (internalId) that were added by op.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final User add( User entity ) throws SecurityException
+    {
+        return add( entity, true );
+    }
+
+
+    /**
+     * Adds a new User entity to directory.
+     * The User entity input object will be validated to ensure that: userId is present, orgUnitId is valid,
+     * roles (optiona) are valid, reasonability checks on all of the other populated values.
+     *
+     * @param entity   User entity contains data targeted for insertion.
+     * @param validate if false will skip the validations described above.
+     * @return User entity copy of input + additional attributes (internalId)
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final User add( User entity, boolean validate ) throws SecurityException
+    {
+        if ( validate )
+        {
+            // Ensure the input data is valid.
+            validate( entity, false );
+        }
+
+        entity = uDao.create( entity );
+
+        return entity;
+    }
+
+
+    /**
+     * Update existing user's attributes with the input entity.  Null or empty attributes will be ignored.
+     * This method will ignore userId as input as change userId is not allowed.  If password is changed
+     * OpenLDAP password policy will not be evaluated on behalf of the user.
+     * Other User entity input data can be changed and will also be validated beforehand to ensure that:
+     * orgUnitId is valid, roles (optional) are valid, reasonability checks will be performed on all of the populated fields.
+     *
+     * @param entity User entity contains data targeted for insertion.
+     * @return User entity copy of input
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final User update( User entity ) throws SecurityException
+    {
+        return update( entity, true );
+    }
+
+
+    /**
+     * Update existing user's attributes with the input entity.  Null or empty attributes will be ignored.
+     * This method will ignore userId or password as input.  The former is not allowed and latter is performed by other
+     * methods in this class.
+     * Other User entity input data can be changed and will also be validated beforehand to ensure that:
+     * orgUnitId is valid, roles (optional) are valid, reasonability checks will be performed on all of the populated fields.
+     *
+     * @param entity   User entity contains data targeted for insertion.
+     * @param validate if false will skip the validations described above.
+     * @return User entity copy of input
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    /**
+     * Update existing user's attributes with the input entity.  Null or empty attributes will be ignored.
+     * This method will ignore userId or password as input.  The former is not allowed and latter is performed by other
+     * methods in this class.
+     * Other User entity input data can be changed and will also be validated beforehand to ensure that:
+     * orgUnitId is valid, roles (optional) are valid, reasonability checks will be performed on all of the populated fields.
+     *
+     * @param entity   User entity contains data targeted for insertion.
+     * @param validate if false will skip the validations described above.
+     * @return User entity copy of input
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final User update( User entity, boolean validate ) throws SecurityException
+    {
+        if ( validate )
+        {
+            // Ensure the input data is valid.
+            validate( entity, true );
+        }
+        entity = uDao.update( entity );
+        return entity;
+    }
+
+
+    /**
+     * Method performs a "soft" delete.  It disables User entity and flags as "deleted".  User must exist in directory
+     * prior to making this call.
+     *
+     * @param user Contains the userId of the user targeted for deletion.
+     * @return String contains user DN
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final String softDelete( User user ) throws SecurityException
+    {
+        // Ensure this user isn't listed in Fortress config as a system user that can't be removed via API.
+        // Is there a match between this userId and a Fortress system user?
+        User checkUser = read( user, true );
+        if ( VUtil.isNotNullOrEmpty( checkUser.isSystem() ) && checkUser.isSystem() )
+        {
+            String warning = "softDelete userId [" + user.getUserId()
+                + "] can't be removed due to policy violation, rc=" + GlobalErrIds.USER_PLCY_VIOLATION;
+            throw new SecurityException( GlobalErrIds.USER_PLCY_VIOLATION, warning );
+        }
+        user.setDescription( "DELETED" );
+        User outUser = uDao.update( user );
+        return outUser.getDn();
+    }
+
+
+    /**
+     * This method performs a "hard" delete.  It completely removes all data associated with this user from the directory.
+     * User entity must exist in directory prior to making this call else exception will be thrown.
+     *
+     * @param user Contains the userid of the user targeted for deletion.
+     * @return String contains user DN
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final String delete( User user ) throws SecurityException
+    {
+        // Ensure this user isn't listed in Fortress config as a system user that can't be removed via API.
+        // Is there a match between this userId and a Fortress system user?
+        User checkUser = read( user, true );
+        if ( VUtil.isNotNullOrEmpty( checkUser.isSystem() ) && checkUser.isSystem() )
+        {
+            String warning = "delete userId [" + user.getUserId()
+                + "] can't be removed due to policy violation, rc=" + GlobalErrIds.USER_PLCY_VIOLATION;
+            throw new SecurityException( GlobalErrIds.USER_PLCY_VIOLATION, warning );
+        }
+        return uDao.remove( user );
+    }
+
+
+    /**
+     * Removes the user's association from OpenLDAP password policy.  Once this association is removed, the User
+     * password policy will default to that which is default for ldap server.
+     *
+     * @param user contains the userId for target user.
+     * @throws SecurityException in the event of DAO error.
+     */
+    final void deletePwPolicy( User user ) throws SecurityException
+    {
+        uDao.deletePwPolicy( user );
+    }
+
+
+    /**
+     * This method performs authentication only.  It does not activate RBAC roles in session.  It will evaluate
+     * password policies.
+     *
+     * @param user  Contains the userid of the user signing on along with password.
+     * @return Session object will be returned if authentication successful.  This will not contain user's roles.
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    final Session authenticate( User user ) throws SecurityException
+    {
+        Session session;
+        session = uDao.checkPassword( user );
+
+        if ( session == null )
+        { // This should not happen, ever:
+            String error = "UserP.authenticate failed - null session detected for userId [" + user.getUserId() + "]";
+            throw new SecurityException( GlobalErrIds.USER_SESS_CREATE_FAILED, error );
+        }
+        else if ( !session.isAuthenticated() )
+        {
+            String info = "UserP.authenticate failed  for userId [" + user.getUserId() + "] reason code ["
+                + session.getErrorId() + "] msg [" + session.getMsg() + "]";
+            throw new PasswordException( session.getErrorId(), info );
+        }
+
+        CUtil.validateConstraints( session, CUtil.ConstraintType.USER, false );
+
+        return session;
+    }
+
+
+    /**
+     * CreateSession
+     * <p>
+     * This method is called by AccessMgr and is not intended for use outside Fortress core.  The successful
+     * result is Session object that contains target user's RBAC and Admin role activations.  In addition to checking
+     * user password validity it will apply configured password policy checks.  Method may also store parms passed in for
+     * audit trail..
+     * <ul>
+     * <li> authenticate user password
+     * <li> password policy evaluation with OpenLDAP PwPolicy
+     * <li> evaluate temporal constraints on User and UserRole entities.
+     * <li> allow selective role activations into User RBAC Session.
+     * <li> require valid password if trusted == false.
+     * <li> will disallow any user who is locked out due to OpenLDAP pw policy, regardless of trusted flag being set as parm on API.
+     * <li> return User's RBAC Session containing User and UserRole attributes.
+     * <li> throw a SecurityException for authentication failures, other policy violations, data validation errors or system failure.
+     * </ul>
+     * </p>
+     * <p>
+     * The function is valid if and only if:
+     * <ul>
+     * <li> the user is a member of the USERS data set
+     * <li> the password is supplied (unless trusted).
+     * <li> the (optional) active role set is a subset of the roles authorized for that user.
+     * </ul>
+     * </p>
+     * <p>
+     * The User parm contains the following (* indicates required)
+     * <ul>
+     * <li> String userId*
+     * <li> char[] password
+     * <li> List<UserRole> userRoles contains a list of RBAC role names authorized for user and targeted for activation within this session.
+     * <li> List<UserAdminRole> userAdminRoles contains a list of Admin role names authorized for user and targeted for activation.
+     * <li> Properties logonProps collection of auditable name/value pairs to store.  For example hostname:myservername or ip:192.168.1.99
+     * </ul>
+     * </p>
+     * <p>
+     * Notes:
+     * <ul>
+     * <li> roles that violate Dynamic Separation of Duty Relationships will not be activated into session.
+     * <li> role activations will proceed in same order as supplied to User entity setter.
+     * </ul>
+     * </p>
+     *
+     * @param user    Contains userId, password (optional if "trusted"), optional User RBAC Roles: List<UserRole> rolesToBeActivated., optional User Admin Roles: List<UserAdminRole> adminRolesToBeActivated.
+     * @param trusted if true password is not required.
+     * @return Session object will contain authentication result code, RBAC and Admin role activations, OpenLDAP pw policy output and more.
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    final Session createSession( User user, boolean trusted ) throws SecurityException
+    {
+        Session session;
+        if ( trusted )
+        {
+            // Create the rbac session without authentication of password.
+            session = createSessionTrusted( user );
+            // Check user temporal constraints.  This op usually performed during authentication.
+            CUtil.validateConstraints( session, CUtil.ConstraintType.USER, false );
+        }
+        else
+        {
+            // Create the rbac session if the user authentication succeeds:
+            VUtil.assertNotNullOrEmpty( user.getPassword(), GlobalErrIds.USER_PW_NULL, CLS_NM + ".createSession" );
+            session = createSession( user );
+        }
+        // Did the caller pass in a set of roles for selective activation?
+        if ( VUtil.isNotNullOrEmpty( user.getRoles() ) )
+        {
+            // Process selective activation of user's RBAC roles into session:
+            List<UserRole> rlsActual = session.getRoles();
+            List<UserRole> rlsFinal = new ArrayList<>();
+            session.setRoles( rlsFinal );
+            // Activate only the intersection between assigned and roles passed into this method:
+            for ( UserRole role : user.getRoles() )
+            {
+                int indx = rlsActual.indexOf( role );
+                if ( indx != -1 )
+                {
+                    UserRole candidateRole = rlsActual.get( indx );
+                    rlsFinal.add( candidateRole );
+                }
+            }
+        }
+        // Check role temporal constraints + activate roles:
+        CUtil.validateConstraints( session, CUtil.ConstraintType.ROLE, true );
+        return session;
+    }
+
+
+    /**
+     * Called internal to this class only.  Will do all of the session activations of the public method
+     * in addition to the password validation.
+     *
+     * @param inUser   Contains userId that represents rDn of node in ldap directory.
+     * @return Session object will contain authentication result code, RBAC and Admin role activations, OpenLDAP pw policy output and more.
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    private Session createSession( User inUser )
+        throws SecurityException
+    {
+        // read user entity:
+        User user = read( inUser, true );
+        user.setContextId( inUser.getContextId() );
+
+        // authenticate password, check pw policies and validate user temporal constraints:
+        Session session = authenticate( inUser );
+
+        // Set the user entity into the session object:
+        session.setUser( user );
+        return session;
+    }
+
+
+    /**
+     * Trusted session creation method called internal to this class only.  Will do all of the session activations of the public method
+     *
+     * @param inUser Contains userId that represents rDn of node in ldap directory.
+     * @return Session object will contain authentication result code, RBAC and Admin role activations, OpenLDAP pw policy output and more.
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    private Session createSessionTrusted( User inUser )
+        throws SecurityException
+    {
+        User user = read( inUser, true );
+        user.setContextId( inUser.getContextId() );
+
+        if ( user.isLocked() )
+        {
+            String warning = "createSession failed for userId [" + inUser.getUserId()
+                + "] reason user is locked";
+            LOG.warn( warning );
+            throw new SecurityException( GlobalErrIds.USER_LOCKED_BY_CONST, warning );
+        }
+
+        Session session = new ObjectFactory().createSession();
+        session.setUserId( inUser.getUserId() );
+        // Set this flag to false because user's password was not authenticated.
+        session.setAuthenticated( false );
+        session.setUser( user );
+        return session;
+    }
+
+
+    /**
+     * Method will set the OpenLDAP pwlocked attribute which will lock user from being able to signon to the system.
+     *
+     * @param user Contains userId that represents rDn of node in ldap directory.
+     * @throws SecurityException in the event of DAO error.
+     */
+    final void lock( User user ) throws SecurityException
+    {
+        uDao.lock( user );
+    }
+
+
+    /**
+     * Method will reset the OpenLDAP pwlocked attribute which will unlock user and allow to signon to the system.
+     *
+     * @param user Contains userId that represents rDn of node in ldap directory.
+     * @throws SecurityException in the event of DAO  error.
+     */
+    final void unlock( User user ) throws SecurityException
+    {
+        uDao.unlock( user );
+    }
+
+
+    /**
+     * Method will change the user's password and validate user's pw policy in OpenLDAP.
+     *
+     * @param entity      contains userId and old password.
+     * @param newPassword contains the new password which must pass the password policy constraints.
+     * @throws SecurityException in the event of data validation failure, password policy violation or DAO error.
+     */
+    final void changePassword( User entity, char[] newPassword ) throws SecurityException
+    {
+        String userId = entity.getUserId();
+        boolean result = uDao.changePassword( entity, newPassword );
+        if ( !result )
+        {
+            LOG.warn( "changePassword failed for user [" + userId + "]" );
+        }
+    }
+
+
+    /**
+     * Perform password reset on user entity.  This will change the User password and set the reset flag
+     * in OpenLDAP will will force the user to change their password at next logon time.
+     *
+     * @param user contains the userId and the new password.
+     * @throws SecurityException in the event of DAO error.
+     */
+    final void resetPassword( User user ) throws SecurityException
+    {
+        uDao.resetUserPassword( user );
+    }
+
+
+    /**
+     * This command assigns a user to a role.
+     * <p>
+     * <ul>
+     * <li> The command is valid if and only if:
+     * <li> The user is a member of the USERS data set
+     * <li> The role is a member of the ROLES data set
+     * <li> The user is not already assigned to the role
+     * <li> The SSD constraints are satisfied after assignment.
+     * </ul>
+     * </p>
+     * <p>
+     * Successful completion of this op, the following occurs:
+     * </p>
+     * <ul>
+     * <li> User entity (resides in people container) has role assignment added to aux object class attached to actual user record.
+     * <li> Role entity (resides in role container) has userId added as role occupant.
+     * <li> (optional) Temporal constraints may be associated with <code>ftUserAttrs</code> aux object class based on:
+     * <ul>
+     * <li> timeout - number in seconds of session inactivity time allowed.
+     * <li> beginDate - YYYYMMDD - determines date when role may be activated.
+     * <li> endDate - YYMMDD - indicates latest date role may be activated.
+     * <li> beginLockDate - YYYYMMDD - determines beginning of enforced inactive status
+     * <li> endLockDate - YYMMDD - determines end of enforced inactive status.
+     * <li> beginTime - HHMM - determines begin hour role may be activated in user's session.
+     * <li> endTime - HHMM - determines end hour role may be activated in user's session.*
+     * <li> dayMask - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of week role may be activated.
+     * </ul>
+     * </ul>
+     *
+     * @param uRole entity contains userId and role name for targeted assignment.
+     * @return String containing the user's DN.  This value is used to update the "roleOccupant" attribute on associated role entity.
+     * @throws SecurityException in the event data error in user or role objects or system error.
+     */
+    final String assign( UserRole uRole ) throws SecurityException
+    {
+        // "assign" custom Fortress role data, i.e. temporal constraints, onto the user node:
+        return uDao.assign( uRole );
+    }
+
+
+    /**
+     * This command deletes the assignment of the User from the Role entities. The command is
+     * valid if and only if the user is a member of the USERS data set, the role is a member of
+     * the ROLES data set, and the user is assigned to the role.
+     * Any sessions that currently have this role activated will not be effected.
+     * Successful completion includes:
+     * User entity in USER data set has role assignment removed.
+     * Role entity in ROLE data set has userId removed as role occupant.
+     * (optional) Temporal constraints will be removed from user aux object if set prior to call.
+     *
+     * @param uRole entity contains userId and RBAC Role name for targeted assignment.
+     * @return String containing the user's DN.  This value is used to remove the "roleOccupant" attribute on associated RBAC Role entity.
+     * @throws SecurityException - in the event data error in user or role objects or system error.
+     */
+    final String deassign( UserRole uRole ) throws SecurityException
+    {
+        // "deassign" custom Fortress role data from the user's node:
+        return uDao.deassign( uRole );
+    }
+
+
+    /**
+     * This command assigns a user to an admin role.
+     * Successful completion of this op, the following occurs:
+     * </p>
+     * <ul>
+     * <li> User entity (resides in people container) has role assignment added to aux object class attached to actual user record.
+     * <li> AdminRole entity (resides in admin role container) has userId added as role occupant.
+     * <li> (optional) Temporal constraints may be associated with <code>ftUserAttrs</code> aux object class based on:
+     * <ul>
+     * <li> timeout - number in seconds of session inactivity time allowed.
+     * <li> beginDate - YYYYMMDD - determines date when role may be activated.
+     * <li> endDate - YYMMDD - indicates latest date role may be activated.
+     * <li> beginLockDate - YYYYMMDD - determines beginning of enforced inactive status
+     * <li> endLockDate - YYMMDD - determines end of enforced inactive status.
+     * <li> beginTime - HHMM - determines begin hour role may be activated in user's session.
+     * <li> endTime - HHMM - determines end hour role may be activated in user's session.*
+     * <li> dayMask - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of week role may be activated.
+     * </ul>
+     * </ul>
+     *
+     * @param uRole entity contains userId and Admin Role name for targeted assignment.
+     * @return String containing the user's DN.  This value is used to update the "roleOccupant" attribute on associated Admin Role entity.
+     * @throws SecurityException in the event data error in user or role objects or system error.
+     */
+    final String assign( UserAdminRole uRole ) throws SecurityException
+    {
+        // Assign custom Fortress role data, i.e. temporal constraints, onto the user node:
+        return uDao.assign( uRole );
+    }
+
+
+    /**
+     * This method removes assigned admin role from user entity.  Both user and admin role entities must exist and have role relationship
+     * before calling this method.
+     * Successful completion:
+     * del Role to User assignment in User data set
+     * AND
+     * User to Role assignment in Admin Role data set.
+     *
+     * @param uRole entity contains userId and Admin Role name for targeted assignment.
+     * @return String containing the user's DN.  This value is used to remove the "roleOccupant" attribute on associated Admin Role entity.
+     * @throws SecurityException - in the event data error in user or role objects or system error.
+     */
+    final String deassign( UserAdminRole uRole ) throws SecurityException
+    {
+        // Deassign custom Fortress role data from the user's node:
+        return uDao.deassign( uRole );
+    }
+
+
+    /**
+     * Method will perform various validations to ensure the integrity of the User entity targeted for insertion
+     * or updating in directory.  For example the ou attribute will be "read" from the OrgUnit dataset to ensure
+     * that it is valid.  Data reasonability checks will be performed on all non-null attributes.
+     * This method will also copy the source constraints to target entity iff the target input entity does not have set
+     * prior to calling.
+     *
+     * @param entity   User entity contains data targeted for insertion or update.  The input role constraints will be accepted.
+     * @param isUpdate if true update operation is being performed which specifies a different set of targeted attributes.
+     * @throws SecurityException in the event of data validation error or DAO error on Org validation.
+     */
+    private void validate( User entity, boolean isUpdate )
+        throws SecurityException
+    {
+        if ( !isUpdate )
+        {
+            // the UserId attribute is required on User:
+            VUtil.userId( entity.getUserId() );
+
+            // the cn attribute is optional as input.  entity will default to userId if cn not set by caller on add:
+            if ( VUtil.isNotNullOrEmpty( entity.getCn() ) )
+            {
+                VUtil.safeText( entity.getCn(), GlobalIds.CN_LEN );
+            }
+            // the sn attribute is optional as input.  entity will default to userId if sn not set by caller on add:
+            if ( VUtil.isNotNullOrEmpty( entity.getSn() ) )
+            {
+                VUtil.safeText( entity.getSn(), GlobalIds.SN_LEN );
+            }
+            // password is not required on user object but user cannot execute AccessMgr or DelAccessMgr methods w/out pw.
+            if ( VUtil.isNotNullOrEmpty( entity.getPassword() ) )
+            {
+                VUtil.password( entity.getPassword() );
+            }
+            // the OU attribute is required:
+            if ( !VUtil.isNotNullOrEmpty( entity.getOu() ) )
+            {
+                String error = "OU validation failed, null or empty value";
+                throw new ValidationException( GlobalErrIds.ORG_NULL_USER, error );
+            }
+            VUtil.orgUnit( entity.getOu() );
+            // ensure ou exists in the OS-U pool:
+            OrgUnit ou = new OrgUnit( entity.getOu(), OrgUnit.Type.USER );
+            ou.setContextId( entity.getContextId() );
+            if ( !orgUnitP.isValid( ou ) )
+            {
+                String error = "validate detected invalid orgUnit name [" + entity.getOu()
+                    + "] adding user with userId [" + entity.getUserId() + "]";
+                throw new ValidationException( GlobalErrIds.USER_OU_INVALID, error );
+            }
+            // description attribute is optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                VUtil.description( entity.getDescription() );
+            }
+        }
+        else
+        {
+            // on User update, all attributes are optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getCn() ) )
+            {
+                VUtil.safeText( entity.getCn(), GlobalIds.CN_LEN );
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getSn() ) )
+            {
+                VUtil.safeText( entity.getSn(), GlobalIds.SN_LEN );
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getPassword() ) )
+            {
+                VUtil.password( entity.getPassword() );
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getOu() ) )
+            {
+                VUtil.orgUnit( entity.getOu() );
+                // ensure ou exists in the OS-U pool:
+                OrgUnit ou = new OrgUnit( entity.getOu(), OrgUnit.Type.USER );
+                ou.setContextId( entity.getContextId() );
+                if ( !orgUnitP.isValid( ou ) )
+                {
+                    String error = "validate detected invalid orgUnit name [" + entity.getOu()
+                        + "] updating user wth userId [" + entity.getUserId() + "]";
+                    throw new ValidationException( GlobalErrIds.USER_OU_INVALID, error );
+                }
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                VUtil.description( entity.getDescription() );
+            }
+        }
+
+        // 1 OpenLDAP password policy name must be valid if set:
+        if ( VUtil.isNotNullOrEmpty( entity.getPwPolicy() ) )
+        {
+            PwPolicy policy = new PwPolicy( entity.getPwPolicy() );
+            policy.setContextId( entity.getContextId() );
+            if ( !policyP.isValid( policy ) )
+            {
+                String error = "validate detected invalid OpenLDAP policy name [" + entity.getPwPolicy()
+                    + "] for userId [" + entity.getUserId()
+                    + "]. Assignment is optional for User but must be valid if specified.";
+                throw new ValidationException( GlobalErrIds.USER_PW_PLCY_INVALID, error );
+            }
+        }
+
+        // 2 Validate constraints on User object:
+        CUtil.validate( entity );
+
+        // 3 Validate or copy constraints on RBAC roles:
+        if ( VUtil.isNotNullOrEmpty( entity.getRoles() ) )
+        {
+            RoleP rp = new RoleP();
+            List<UserRole> roles = entity.getRoles();
+            for ( UserRole ure : roles )
+            {
+                Role inRole = new Role( ure.getName() );
+                inRole.setContextId( entity.getContextId() );
+                Role role = rp.read( inRole );
+                CUtil.validateOrCopy( role, ure );
+            }
+        }
+
+        // 4 Validate and copy constraints on Administrative roles:
+        if ( VUtil.isNotNullOrEmpty( entity.getAdminRoles() ) )
+        {
+            List<UserAdminRole> uRoles = entity.getAdminRoles();
+            for ( UserAdminRole uare : uRoles )
+            {
+                AdminRole inRole = new AdminRole( uare.getName() );
+                inRole.setContextId( entity.getContextId() );
+                AdminRole outRole = admRoleP.read( inRole );
+                CUtil.validateOrCopy( outRole, uare );
+
+                // copy the ARBAC AdminRole attributes to UserAdminRole:
+                AttrHelper.copyAdminAttrs( outRole, uare );
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/UserRole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/UserRole.java b/src/main/java/org/apache/directory/fortress/core/rbac/UserRole.java
new file mode 100755
index 0000000..bd619e0
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/UserRole.java
@@ -0,0 +1,618 @@
+/*
+ *   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.Set;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.time.CUtil;
+import org.apache.directory.fortress.core.util.time.Constraint;
+
+
+/**
+ * The Fortress UserRole entity is used to store an RBAC User to Role assignment along with its temporal constraint
+ * values.
+ * The contents of the UserRole entity will be stored on the User entity in the 'ftRA' (Role name) and 'ftRC'
+ * (Temporal Constraints) attributes on the 'ftUserAttrs' object class.
+ * The UserRole entity carries elements of {@link org.apache.directory.fortress.core.util.time.Constraint}.  Any attributes of
+ * Constraint not set within this entity
+ * will use same attribute from the {@link org.apache.directory.fortress.core.rbac.Role} entity.  Thus the UserRole can override
+ * Constraint attributes from it's corresponding Role if required by caller.
+ * <p/>
+ * <h4>UserRole Schema</h4>
+ * ftUserAttrs is used to store RBAC and ARBAC Role role assignments and other security attributes on User entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress User Attributes Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.1
+ *  NAME 'ftUserAttrs'
+ *  DESC 'Fortress User Attribute AUX Object Class'
+ *  AUXILIARY
+ *  MUST (
+ *      ftId
+ *  )
+ *  MAY (
+ *      ftRC $
+ *      ftRA $
+ *      ftARC $
+ *      ftARA $
+ *      ftCstr $
+ *      ftSystem
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement( name = "fortUserRole" )
+@XmlAccessorType( XmlAccessType.FIELD )
+@XmlType( name = "userRole", propOrder = {"name", "userId", "parents", "beginDate", "beginLockDate", "beginTime",
+    "dayMask", "endDate", "endLockDate", "endTime", "timeout"} )
+@XmlSeeAlso( {UserAdminRole.class} )
+public class UserRole extends FortEntity implements java.io.Serializable, Constraint
+{
+    protected String userId;
+    protected String name;
+    private Integer timeout;
+    private String beginTime;
+    private String endTime;
+    private String beginDate;
+    private String endDate;
+    private String beginLockDate;
+    private String endLockDate;
+    private String dayMask;
+    @XmlElement( nillable = true )
+    private Set<String> parents;
+
+
+    /**
+     * Default constructor is used by internal Fortress classes.
+     */
+    public UserRole()
+    {
+    }
+
+
+    /**
+     * Construct a UserRole entity given the required attributes 'userId' and 'role' name.
+     *
+     * @param userId maps to the 'uid' attribute on the 'inetOrgPerson' object class.
+     * @param role   maps to the 'ftRA' attribute on the 'ftUserAttrs' object class.
+     */
+    public UserRole( String userId, String role )
+    {
+        this.userId = userId;
+        name = role;
+
+    }
+
+
+    /**
+     * Construct an RBAC Role with required attribute 'userId' and optional temporal constraint.
+     *
+     * @param userId maps to the 'uid' attribute on the 'inetOrgPerson' object class.
+     * @param con    maps to 'ftRC' attribute in 'ftUserAttrs' object class.
+     */
+    public UserRole( String userId, Constraint con )
+    {
+        this.userId = userId;
+        CUtil.copy( con, this );
+    }
+
+
+    /**
+     * Construct a UserRole entity given the required attribute role' name.
+     *
+     * @param role maps to the 'ftRA' attribute on the 'ftUserAttrs' object class.
+     */
+    public UserRole( String role )
+    {
+        name = role;
+    }
+
+    /**
+     * This method loads UserRole entity temporal constraint instance variables with data that was retrieved from the
+     * 'ftRC' attribute on the 'ftUserAttrs' object class.  This is the raw format that Fortress uses to condense the
+     * temporal data into
+     * a compact String for efficient storage and retrieval and is not intended to be called by external programs.
+     *
+     * @param szRawData contains a raw formatted String that maps to 'ftRC' attribute on 'ftUserAttrs' object class
+     */
+    public void load( String szRawData, String contextId )
+    {
+        if ( ( szRawData != null ) && ( szRawData.length() > 0 ) )
+        {
+            String[] tokens = StringUtils.splitPreserveAllTokens( szRawData, GlobalIds.DELIMITER );
+            for ( int i = 0; i < tokens.length; i++ )
+            {
+                if ( VUtil.isNotNullOrEmpty( tokens[i] ) )
+                {
+                    switch ( i )
+                    {
+                        case 0:
+                            name = tokens[i];
+                            parents = RoleUtil.getParents( name.toUpperCase(), contextId );
+                            break;
+
+                        case 1:
+                            timeout = Integer.parseInt( tokens[i] );
+                            break;
+
+                        case 2:
+                            beginTime = tokens[i];
+                            break;
+
+                        case 3:
+                            endTime = tokens[i];
+                            break;
+
+                        case 4:
+                            beginDate = tokens[i];
+                            break;
+
+                        case 5:
+                            endDate = tokens[i];
+                            break;
+
+                        case 6:
+                            beginLockDate = tokens[i];
+                            break;
+
+                        case 7:
+                            endLockDate = tokens[i];
+                            break;
+
+                        case 8:
+                            dayMask = tokens[i];
+                            break;
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Required on DAO classes convert Temporal attributes stored on entity to raw data object format needed for ldap
+     * .  For internal use only.
+     *
+     * @return String that maps to 'ftRA' attribute on the 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getRawData()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( name );
+        sb.append( GlobalIds.DELIMITER );
+        sb.append( timeout );
+        sb.append( GlobalIds.DELIMITER );
+
+        if ( beginTime != null )
+        {
+            sb.append( beginTime );
+        }
+
+        sb.append( GlobalIds.DELIMITER );
+
+        if ( endTime != null )
+        {
+            sb.append( endTime );
+        }
+
+        sb.append( GlobalIds.DELIMITER );
+
+        if ( beginDate != null )
+        {
+            sb.append( beginDate );
+        }
+
+        sb.append( GlobalIds.DELIMITER );
+
+        if ( endDate != null )
+        {
+            sb.append( endDate );
+        }
+
+        sb.append( GlobalIds.DELIMITER );
+
+        if ( beginLockDate != null )
+        {
+            sb.append( beginLockDate );
+        }
+
+        sb.append( GlobalIds.DELIMITER );
+
+        if ( endLockDate != null )
+        {
+            sb.append( endLockDate );
+        }
+
+        sb.append( GlobalIds.DELIMITER );
+
+        if ( dayMask != null )
+        {
+            sb.append( dayMask );
+        }
+
+        return sb.toString();
+    }
+
+
+    /**
+     * Used to retrieve UserRole Role name attribute.  The Fortress UserRole name maps to 'ftRA' attribute on
+     * 'ftUserAttrs' object class.
+     */
+    @Override
+    public String toString()
+    {
+        return name;
+    }
+
+
+    /**
+     * Return the userId that is associated with UserRole.  UserId is required attribute and must be set on all
+     * UserRole assignment operations.
+     *
+     * @return attribute maps to 'uid' in 'inetOrgPerson' object class.
+     */
+    public String getUserId()
+    {
+        return userId;
+    }
+
+
+    /**
+     * Set the userId that is associated with UserRole.  UserId is required attribute and must be set on all UserRole
+     * assignment operations.
+     *
+     * @param userId maps to 'uid' in 'inetOrgPerson' object class.
+     */
+    public void setUserId( String userId )
+    {
+        this.userId = userId;
+    }
+
+
+    /**
+     * Get the Role name required attribute of the UserRole object
+     *
+     * @param name maps to 'ftRC' and 'ftRA' attributes on 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * Set the Role name required attribute of the UserRole object
+     *
+     * @return attribute maps to 'ftRC' and 'ftRA' attributes on 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getName()
+    {
+        return name;
+    }
+
+
+    /**
+     * temporal boolean flag is used by internal Fortress components.
+     *
+     * @return boolean indicating if temporal constraints are placed on UserRole.
+     */
+    @Override
+    public boolean isTemporalSet()
+    {
+        return ( beginTime != null || endTime != null || beginDate != null || endDate != null || beginLockDate !=
+            null || endLockDate != null || dayMask != null );
+    }
+
+
+    /**
+     * Set the integer timeout that contains max time (in seconds) that entity may remain inactive.
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param timeout maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setTimeout( Integer timeout )
+    {
+        this.timeout = timeout;
+    }
+
+
+    /**
+     * Set the begin time of day entity is allowed to be activated in system.  The format is military time - HHMM,
+     * i.e. 0800 (8:00 am) or 1700 (5:00 p.m.).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param beginTime maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setBeginTime( String beginTime )
+    {
+        this.beginTime = beginTime;
+    }
+
+
+    /**
+     * Set the end time of day entity is allowed to be activated in system.  The format is military time - HHMM,
+     * i.e. 0000 (12:00 am) or 2359 (11:59 p.m.).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param endTime maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setEndTime( String endTime )
+    {
+        this.endTime = endTime;
+    }
+
+
+    /**
+     * Set the beginDate when entity is allowed to be activated in system.  The format is - YYYYMMDD,
+     * i.e. 20100101 (January 1, 2001).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param beginDate maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setBeginDate( String beginDate )
+    {
+        this.beginDate = beginDate;
+    }
+
+
+    /**
+     * Set the end date when entity is not allowed to be activated in system.  The format is - YYYYMMDD,
+     * i.e. 20100101 (January 1. 2010).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param endDate maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setEndDate( String endDate )
+    {
+        this.endDate = endDate;
+    }
+
+
+    /**
+     * Set the daymask that specifies what days of week entity is allowed to be activated in system.  The format is
+     * 1234567, i.e. 23456 (Monday, Tuesday, Wednesday, Thursday, Friday).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param dayMask maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setDayMask( String dayMask )
+    {
+        this.dayMask = dayMask;
+    }
+
+
+    /**
+     * Set the begin lock date when entity is temporarily not allowed to be activated in system.  The format is -
+     * YYYYMMDD, 20100101 (January 1. 2010).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param beginLockDate maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setBeginLockDate( String beginLockDate )
+    {
+        this.beginLockDate = beginLockDate;
+    }
+
+
+    /**
+     * Set the end lock date when entity is allowed to be activated in system once again.  The format is - YYYYMMDD,
+     * i.e. 20100101 (January 1. 2010).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param endLockDate maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setEndLockDate( String endLockDate )
+    {
+        this.endLockDate = endLockDate;
+    }
+
+
+    /**
+     * Return the integer timeout that contains total time (in seconds) that entity may remain inactive.
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return int that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public Integer getTimeout()
+    {
+        return timeout;
+    }
+
+
+    /**
+     * Contains the begin time of day entity is allowed to be activated in system.  The format is military time -
+     * HHMM, i.e. 0800 (8:00 am) or 1700 (5:00 p.m.).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getBeginTime()
+    {
+        return beginTime;
+    }
+
+
+    /**
+     * Contains the end time of day entity is allowed to be activated in system.  The format is military time - HHMM,
+     * i.e. 0000 (12:00 am) or 2359 (11:59 p.m.).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getEndTime()
+    {
+        return endTime;
+    }
+
+
+    /**
+     * Contains the begin date when entity is allowed to be activated in system.  The format is - YYYYMMDD,
+     * i.e. 20100101 (January 1. 2010).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getBeginDate()
+    {
+        return beginDate;
+    }
+
+
+    /**
+     * Contains the end date when entity is allowed to be activated in system.  The format is - YYYYMMDD,
+     * i.e. 20101231 (December 31, 2011).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getEndDate()
+    {
+        return endDate;
+    }
+
+
+    /**
+     * Contains the begin lock date when entity is temporarily not allowed to activated in system.  The format is -
+     * YYYYMMDD, i.e. 20100101 (January 1. 2010).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getBeginLockDate()
+    {
+        return beginLockDate;
+    }
+
+
+    /**
+     * Contains the end lock date when entity is allowed to be activated in system once again.  The format is -
+     * YYYYMMDD, i.e. 20100101 (January 1. 2010).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getEndLockDate()
+    {
+        return endLockDate;
+    }
+
+
+    /**
+     * Get the daymask that indicates what days of week entity is allowed to be activated in system.  The format is 1234567, i.e. 23456 (Monday, Tuesday, Wednesday, Thursday, Friday).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return String that maps to 'ftRC', attribute on 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getDayMask()
+    {
+        return dayMask;
+    }
+
+
+    /**
+     * Get the names of roles that are parents (direct ascendants) of this role.
+     *
+     * @return Set of parent role names assigned to this role.
+     */
+    public Set<String> getParents()
+    {
+        return parents;
+    }
+
+
+    /**
+     * Set the names of roles names that are parents (direct ascendants) of this role.
+     *
+     * @param parents contains the Set of parent role names assigned to this role.
+     */
+    public void setParents( Set<String> parents )
+    {
+        this.parents = parents;
+    }
+
+
+    /**
+     * Matches the userId and role name from two UserRole entities.
+     *
+     * @param thatObj contains a UserRole entity.
+     * @return boolean indicating both objects contain matching userId and Role names.
+     */
+    public boolean equals( Object thatObj )
+    {
+        if ( this == thatObj )
+        {
+            return true;
+        }
+
+        if ( name == null )
+        {
+            return false;
+        }
+
+        if ( !( thatObj instanceof UserRole ) )
+        {
+            return false;
+        }
+
+        UserRole thatRole = ( UserRole ) thatObj;
+
+        if ( thatRole.getName() == null )
+        {
+            return false;
+        }
+
+        return ( thatRole.getName().equalsIgnoreCase( name ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/UsoUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/UsoUtil.java b/src/main/java/org/apache/directory/fortress/core/rbac/UsoUtil.java
new file mode 100755
index 0000000..6a7c30b
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/UsoUtil.java
@@ -0,0 +1,262 @@
+/*
+ *   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.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.jgrapht.graph.SimpleDirectedGraph;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.cache.Cache;
+import org.apache.directory.fortress.core.util.cache.CacheMgr;
+
+
+/**
+ * This utility wraps {@link HierUtil} methods to provide hierarchical functionality using the {@link org.apache.directory.fortress.core.rbac.OrgUnit} data set for User type {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER}.
+ * The {@code cn=Hierarchies, ou=OS-U} data contains User OU pools is stored within a data cache, {@link #usoCache}, contained within this class.  The parent-child edges are contained in LDAP,
+ * in {@code ftParents} attribute.  The ldap data is retrieved {@link OrgUnitP#getAllDescendants(org.apache.directory.fortress.core.rbac.OrgUnit)} and loaded into {@code org.jgrapht.graph.SimpleDirectedGraph}.
+ * The graph...
+ * <ol>
+ * <li>is stored as singleton in this class with vertices of {@code String}, and edges, as {@link Relationship}s</li>
+ * <li>utilizes open source library, see <a href="http://www.jgrapht.org/">JGraphT</a>.</li>
+ * <li>contains a general hierarchical data structure i.e. allows multiple inheritance with parents.</li>
+ * <li>is a simple directed graph thus does not allow cycles.</li>
+ * </ol>
+ * After update is performed to ldap, the singleton is refreshed with latest info.
+ * <p/>
+ * Static methods on this class are intended for use by other Fortress classes, i.e. {@link DelAdminMgrImpl}.
+ * and cannot be directly invoked by outside programs.
+ * <p/>
+ * This class contains singleton that can be updated but is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public final class UsoUtil
+{
+    private static final Cache usoCache;
+    private static final OrgUnitP orgUnitP = new OrgUnitP();
+    private static final String CLS_NM = UsoUtil.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    /**
+     * Initialize the User OU hierarchies.  This will read the {@link org.apache.directory.fortress.core.rbac.Hier} data set from ldap and load into
+     * the JGraphT simple digraph that referenced statically within this class.
+     */
+    static
+    {
+        CacheMgr cacheMgr = CacheMgr.getInstance();
+        usoCache = cacheMgr.getCache( "fortress.uso" );
+    }
+
+
+    /**
+     * Recursively traverse the {@link org.apache.directory.fortress.core.rbac.OrgUnit} graph and return all of the descendants of a given parent {@link org.apache.directory.fortress.core.rbac.OrgUnit#name}.
+     *
+     * @param name {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} on 'ftOrgUnit' object class.
+     * @return Set of names of descendants {@link org.apache.directory.fortress.core.rbac.OrgUnit}s of given parent.
+     */
+    static Set<String> getDescendants( String name, String contextId )
+    {
+        return HierUtil.getDescendants( name, getGraph( contextId ) );
+    }
+
+
+    /**
+     * Recursively traverse the {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} graph and return all of the ascendants of a given child ou.
+     *
+     * @param name maps to logical {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} on 'ftOrgUnit' object class.
+     * @return Set of ou names that are ascendants of given child.
+     */
+    static Set<String> getAscendants( String name, String contextId )
+    {
+        return HierUtil.getAscendants( name, getGraph( contextId ) );
+    }
+
+
+    /**
+     * Traverse one level of the {@link org.apache.directory.fortress.core.rbac.OrgUnit} graph and return all of the children (direct descendants) of a given parent {@link org.apache.directory.fortress.core.rbac.OrgUnit#name}.
+     *
+     * @param name {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} maps on 'ftOrgUnit' object class.
+     * @return Set of names of children {@link org.apache.directory.fortress.core.rbac.OrgUnit}s of given parent.
+     */
+    public static Set<String> getChildren( String name, String contextId )
+    {
+        return HierUtil.getChildren( name, getGraph( contextId ) );
+    }
+
+
+    /**
+     * Traverse one level of the {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} graph and return all of the parents (direct ascendants) of a given child ou.
+     *
+     * @param name maps to logical {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} on 'ftOrgUnit' object class.
+     * @return Set of ou names that are parents of given child.
+     */
+    static Set<String> getParents( String name, String contextId )
+    {
+        return HierUtil.getParents( name, getGraph( contextId ) );
+    }
+
+
+    /**
+     * Recursively traverse the {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} graph and return number of children a given parent ou has.
+     *
+     * @param name maps to logical {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} on 'ftOrgUnit' object class.
+     * @return int value contains the number of children of a given parent ou.
+     */
+    static int numChildren( String name, String contextId )
+    {
+        return HierUtil.numChildren( name, getGraph( contextId ) );
+    }
+
+
+    /**
+     * Return Set of {@link org.apache.directory.fortress.core.rbac.OrgUnit#name}s ascendants contained within {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER}.
+     *
+     * @param ous contains list of {@link org.apache.directory.fortress.core.rbac.OrgUnit}s.
+     * @return contains Set of all descendants.
+     */
+    static Set<String> getInherited( List<OrgUnit> ous, String contextId )
+    {
+        // create Set with case insensitive comparator:
+        Set<String> iOUs = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        if ( VUtil.isNotNullOrEmpty( ous ) )
+        {
+            for ( OrgUnit ou : ous )
+            {
+                String name = ou.getName();
+                iOUs.add( name );
+                Set<String> parents = HierUtil.getAscendants( name, getGraph( contextId ) );
+                if ( VUtil.isNotNullOrEmpty( parents ) )
+                    iOUs.addAll( parents );
+            }
+        }
+        return iOUs;
+    }
+
+
+    /**
+     * This api is used by {@link DelAdminMgrImpl} to determine parentage for User OU processing.
+     * It calls {@link HierUtil#validateRelationship(org.jgrapht.graph.SimpleDirectedGraph, String, String, boolean)} to evaluate three OU relationship expressions:
+     * <ol>
+     * <li>If child equals parent</li>
+     * <li>If mustExist true and parent-child relationship exists</li>
+     * <li>If mustExist false and parent-child relationship does not exist</li>
+     * </ol>
+     * Method will throw {@link org.apache.directory.fortress.core.ValidationException} if rule check fails meaning caller failed validation
+     * attempt to add/remove hierarchical relationship failed.
+     *
+     * @param child     contains {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} of child.
+     * @param parent    contains {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} of parent.
+     * @param mustExist boolean is used to specify if relationship must be true.
+     * @throws org.apache.directory.fortress.core.ValidationException
+     *          in the event it fails one of the 3 checks.
+     */
+    static void validateRelationship( OrgUnit child, OrgUnit parent, boolean mustExist )
+        throws ValidationException
+    {
+        HierUtil.validateRelationship( getGraph( child.getContextId() ), child.getName(), parent.getName(), mustExist );
+    }
+
+
+    /**
+     * This api allows synchronized access to allow updates to hierarchical relationships.
+     * Method will update the hierarchical data set and reload the JGraphT simple digraph with latest.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @param relationship contains parent-child relationship targeted for addition.
+     * @param op   used to pass the ldap op {@link org.apache.directory.fortress.core.rbac.Hier.Op#ADD}, {@link org.apache.directory.fortress.core.rbac.Hier.Op#MOD}, {@link org.apache.directory.fortress.core.rbac.Hier.Op#REM}
+     * @throws org.apache.directory.fortress.core.SecurityException in the event of a system error.
+     */
+    static void updateHier( String contextId, Relationship relationship, Hier.Op op ) throws SecurityException
+    {
+        HierUtil.updateHier( getGraph( contextId ), relationship, op );
+    }
+
+
+    /**
+     * Read this ldap record,{@code cn=Hierarchies, ou=OS-P} into this entity, {@link Hier}, before loading into this collection class,{@code org.jgrapht.graph.SimpleDirectedGraph}
+     * using 3rd party lib, <a href="http://www.jgrapht.org/">JGraphT</a>.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return
+     */
+    private static SimpleDirectedGraph<String, Relationship> loadGraph( String contextId )
+    {
+        Hier inHier = new Hier( Hier.Type.ROLE );
+        inHier.setContextId( contextId );
+        LOG.info( "loadGraph initializing USO context [" + inHier.getContextId() + "]" );
+        List<Graphable> descendants = null;
+        try
+        {
+            OrgUnit orgUnit = new OrgUnit();
+            orgUnit.setType( OrgUnit.Type.USER );
+            orgUnit.setContextId( contextId );
+            descendants = orgUnitP.getAllDescendants( orgUnit );
+        }
+        catch ( SecurityException se )
+        {
+            LOG.info( "loadGraph caught SecurityException=" + se );
+        }
+        Hier hier = HierUtil.loadHier( contextId, descendants );
+        SimpleDirectedGraph<String, Relationship> graph;
+        synchronized ( HierUtil.getLock( contextId, HierUtil.Type.USO ) )
+        {
+            graph = HierUtil.buildGraph( hier );
+        }
+        usoCache.put( getKey( contextId ), graph );
+        return graph;
+    }
+
+
+    /**
+     *
+     * @return
+     */
+    private static SimpleDirectedGraph<String, Relationship> getGraph( String contextId )
+    {
+        SimpleDirectedGraph<String, Relationship> graph = ( SimpleDirectedGraph<String, Relationship> ) usoCache
+            .get( getKey( contextId ) );
+        if ( graph == null )
+        {
+            graph = loadGraph( contextId );
+        }
+        return graph;
+    }
+
+
+    private static String getKey( String contextId )
+    {
+        String key = HierUtil.Type.USO.toString();
+        if ( VUtil.isNotNullOrEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL ) )
+        {
+            key += ":" + contextId;
+        }
+        return key;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/Warning.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Warning.java b/src/main/java/org/apache/directory/fortress/core/rbac/Warning.java
new file mode 100644
index 0000000..b6a8d2f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Warning.java
@@ -0,0 +1,157 @@
+/*
+ *   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 javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import java.io.Serializable;
+
+/**
+ * This class contains messages that map to warning that occur during role activation and password policy validation.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+/**
+ * This entity is stored on {@link org.apache.directory.fortress.core.rbac.Session} and is used to pass warnings that occur during role activation and password policy validation.
+ * <p/>
+ * Contains data from event that occurs during session initialization:
+ * <p/>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>id</code>
+ * <li> <code>msg</code>
+ * <li> <code>type</code>
+ * <li> <code>name</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortWarning")
+@XmlAccessorType( XmlAccessType.FIELD)
+@XmlType(name = "warning", propOrder =
+    {
+        "id",
+        "msg",
+        "type",
+        "name"
+    })
+public class Warning implements Serializable
+{
+    public Warning()
+    {
+    }
+
+    /**
+     *
+     * @param id
+     * @param msg
+     * @param type
+     */
+    public Warning(int id, String msg, Type type)
+    {
+        this.id = id;
+        this.msg = msg;
+        this.type = type;
+    }
+
+    /**
+     *
+     * @param id
+     * @param msg
+     * @param type
+     * @param name
+     */
+    public Warning(int id, String msg, Type type, String name)
+    {
+        this.id = id;
+        this.msg = msg;
+        this.name = name;
+        this.type = type;
+    }
+
+    /**
+     * Type determines if warning is of type Role or Password Policy.
+     */
+    @XmlType(name = "warnType")
+    @XmlEnum
+    public enum Type
+    {
+        /**
+         * Problem during role activation.
+         */
+        ROLE,
+
+        /**
+         * Problem during password policy validation.
+         */
+        PASSWORD
+    }
+
+    private int id;
+    private String msg;
+    private String name;
+    private Type type;
+
+    public int getId()
+    {
+        return id;
+    }
+
+    public void setId( int id )
+    {
+        this.id = id;
+    }
+
+    public String getMsg()
+    {
+        return msg;
+    }
+
+    public void setMsg( String msg )
+    {
+        this.msg = msg;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    public Type getType()
+    {
+        return type;
+    }
+
+    public void setType( Type type )
+    {
+        this.type = type;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/AcceleratorDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/AcceleratorDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/AcceleratorDAO.java
new file mode 100644
index 0000000..ecf529e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/AcceleratorDAO.java
@@ -0,0 +1,39 @@
+/*
+ *   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.dao;
+
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.UserRole;
+
+import java.util.List;
+
+
+public interface AcceleratorDAO
+{
+    public Session createSession( User user ) throws SecurityException;
+    public void deleteSession( Session session ) throws SecurityException;
+    public List<UserRole> sessionRoles( Session session ) throws SecurityException;
+    public boolean checkAccess( Session session, Permission perm ) throws SecurityException;
+    public void dropActiveRole( Session session, UserRole userRole ) throws SecurityException;
+    public void addActiveRole( Session session, UserRole userRole ) throws SecurityException;
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/AdminRoleDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/AdminRoleDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/AdminRoleDAO.java
new file mode 100644
index 0000000..b332924
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/AdminRoleDAO.java
@@ -0,0 +1,200 @@
+/*
+ *   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.dao;
+
+
+import java.util.List;
+
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.AdminRoleP;
+import org.apache.directory.fortress.core.rbac.Graphable;
+
+
+/**
+ * The AdminRoleDAO is called by {@link AdminRoleP} and processes data via its entity {@link AdminRole}.
+ * <p/>
+ * The Fortress AdminRoleDAO uses the following other Fortress structural and aux object classes:
+ * <h4>1. ftRls Structural objectclass is used to store the AdminRole information like name, and temporal constraints</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. ftPools Auxiliary object class store the ARBAC Perm and User OU assignments on AdminRole entity</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.3</code>
+ * <li> <code>NAME 'ftPools'</code>
+ * <li> <code>DESC 'Fortress Pools AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MAY ( ftOSU $ ftOSP ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>4. 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
+ */
+public interface AdminRoleDAO
+{
+    /**
+     * Create a new AdminRole entity using supplied data.  Required attribute is {@link AdminRole#name}.
+     * This data will be stored in the {@link GlobalIds#ADMIN_ROLE_ROOT} container.
+     *
+     * @param entity record contains AdminRole data.  Null attributes will be ignored.
+     * @return input record back to client.
+     * @throws org.apache.directory.fortress.core.CreateException in the event LDAP errors occur.
+     */
+    AdminRole create( AdminRole entity ) throws CreateException;
+
+
+    /**
+     * Update existing AdminRole entity using supplied data.  Required attribute is {@link AdminRole#name}.
+     * This data will be stored in the {@link GlobalIds#ADMIN_ROLE_ROOT} container.
+     *
+     * @param entity record contains AdminRole data.  Null attributes will be ignored.
+     * @return input record back to client.
+     * @throws UpdateException in the event LDAP errors occur.
+     */
+    AdminRole update( AdminRole entity ) throws UpdateException;
+
+
+    /**
+     *
+     * @param entity
+     * @throws UpdateException
+     */
+    void deleteParent( AdminRole entity ) throws UpdateException;
+
+
+    /**
+     * This method will add the supplied DN as a role occupant to the target record.
+     * This data will be stored in the {@link GlobalIds#ADMIN_ROLE_ROOT} container.
+     *
+     * @param entity record contains {@link AdminRole#name}.  Null attributes will be ignored.
+     * @param userDn contains the DN for userId who is being assigned.
+     * @return input record back to client.
+     * @throws UpdateException in the event LDAP errors occur.
+     */
+    AdminRole assign( AdminRole entity, String userDn ) throws UpdateException;
+
+
+    /**
+     * This method will remove the supplied DN as a role occupant to the target record.
+     * This data will be stored in the {@link GlobalIds#ADMIN_ROLE_ROOT} container.
+     *
+     * @param entity record contains {@link AdminRole#name}.  Null attributes will be ignored.
+     * @param userDn contains the DN for userId who is being deassigned.
+     * @return input record back to client.
+     * @throws UpdateException in the event LDAP errors occur.
+     */
+    AdminRole deassign( AdminRole entity, String userDn ) throws UpdateException;
+
+
+    /**
+     * This method will completely remove the AdminRole from the directory.  It will use {@link AdminRole#name} as key.
+     * This operation is performed on the {@link GlobalIds#ADMIN_ROLE_ROOT} container.
+     *
+     * @param role record contains {@link AdminRole#name}.
+     * @throws RemoveException in the event LDAP errors occur.
+     */
+    void remove( AdminRole role ) throws RemoveException;
+
+
+    /**
+     * This method will retrieve the AdminRole from {@link GlobalIds#ADMIN_ROLE_ROOT} container by name.
+     *
+     * @param adminRole maps to {@link AdminRole#name}.
+     * @return AdminRole back to client.
+     * @throws FinderException in the event LDAP errors occur.
+     */
+    AdminRole getRole( AdminRole adminRole ) throws FinderException;
+
+
+    /**
+     * @param adminRole
+     * @return
+     * @throws FinderException
+     *
+     */
+    List<AdminRole> findRoles( AdminRole adminRole ) throws FinderException;
+
+
+    /**
+     * @param adminRole
+     * @param limit
+     * @return
+     * @throws FinderException
+     *
+     */
+    List<String> findRoles( AdminRole adminRole, int limit ) throws FinderException;
+
+
+    /**
+     * @param userDn
+     * @return
+     * @throws FinderException
+     */
+    List<String> findAssignedRoles( String userDn, String contextId ) throws FinderException;
+
+
+    /**
+      *
+      * @param contextId
+      * @return
+      * @throws FinderException
+      */
+    List<Graphable> getAllDescendants( String contextId ) throws FinderException;
+}