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:20 UTC

[01/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.

Repository: directory-fortress-core
Updated Branches:
  refs/heads/master b3682894c -> 687ee1add


http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/openldap/fortress/AdminMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/AdminMgr.java b/src/main/java/org/openldap/fortress/AdminMgr.java
deleted file mode 100755
index ce99a30..0000000
--- a/src/main/java/org/openldap/fortress/AdminMgr.java
+++ /dev/null
@@ -1,1041 +0,0 @@
-/*
- *   Licensed to the Apache Software Foundation (ASF) under one
- *   or more contributor license agreements.  See the NOTICE file
- *   distributed with this work for additional information
- *   regarding copyright ownership.  The ASF licenses this file
- *   to you under the Apache License, Version 2.0 (the
- *   "License"); you may not use this file except in compliance
- *   with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing,
- *   software distributed under the License is distributed on an
- *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *   KIND, either express or implied.  See the License for the
- *   specific language governing permissions and limitations
- *   under the License.
- *
- */
-package org.openldap.fortress;
-
-import org.openldap.fortress.rbac.PermObj;
-import org.openldap.fortress.rbac.Permission;
-import org.openldap.fortress.rbac.Role;
-import org.openldap.fortress.rbac.SDSet;
-import org.openldap.fortress.rbac.User;
-import org.openldap.fortress.rbac.UserRole;
-
-/**
- * This class performs administrative functions to provision Fortress RBAC entities into the LDAP directory.  These APIs
- * map directly to similar named APIs specified by ANSI and NIST RBAC models.
- * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
- * The RBAC Functional specification describes administrative operations for the creation
- * and maintenance of RBAC element sets and relations; administrative review functions for
- * performing administrative queries; and system functions for creating and managing
- * RBAC attributes on user sessions and making access control decisions.
- * <p/>
- * <hr>
- * <h4>RBAC0 - Core</h4>
- * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
- * <p/>
- * <img src="./doc-files/RbacCore.png">
- * <hr>
- * <h4>RBAC1 - General Hierarchical Roles</h4>
- * Simplifies role engineering tasks using inheritance of one or more parent roles.
- * <p/>
- * <img src="./doc-files/RbacHier.png">
- * <hr>
- * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
- * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
- * <p/>
- * <img src="./doc-files/RbacSSD.png">
- * <hr>
- * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
- * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
- * <p/>
- * <img src="./doc-files/RbacDSD.png">
- * <hr>
- * <p/>
- * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.openldap.fortress.rbac.Session)}) are set.
- *
- * @author Shawn McKinney
- */
-public interface AdminMgr extends Manageable
-{
-    /**
-     * This command creates a new RBAC user. The command is valid only if the new user is
-     * not already a member of the USERS data set. The USER data set is updated. The new user
-     * does not own any session at the time of its creation.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
-     * <li>{@link User#password} - used to authenticate the User</li>
-     * <li>{@link User#ou} - contains the name of an already existing User OU node</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link User#pwPolicy} - contains the name of an already existing OpenLDAP password policy node</li>
-     * <li>{@link User#cn} - maps to INetOrgPerson common name attribute</li>
-     * <li>{@link User#sn} - maps to INetOrgPerson surname attribute</li>
-     * <li>{@link User#description} - maps to INetOrgPerson description attribute</li>
-     * <li>{@link User#title} - maps to INetOrgPerson title attribute</li>
-     * <li>{@link User#employeeType} - maps to INetOrgPerson employeeType attribute</li>
-     * <li>{@link User#phones} * - multi-occurring attribute maps to organizationalPerson telephoneNumber  attribute</li>
-     * <li>{@link User#mobiles} * - multi-occurring attribute maps to INetOrgPerson mobile attribute</li>
-     * <li>{@link User#emails} * - multi-occurring attribute maps to INetOrgPerson mail attribute</li>
-     * <li>{@link User#address} * - multi-occurring attribute maps to organizationalPerson postalAddress, st, l, postalCode, postOfficeBox attributes</li>
-     * <li>{@link User#beginTime} - HHMM - determines begin hour user may activate session</li>
-     * <li>{@link User#endTime} - HHMM - determines end hour user may activate session.</li>
-     * <li>{@link User#beginDate} - YYYYMMDD - determines date when user may sign on</li>
-     * <li>{@link User#endDate} - YYYYMMDD - indicates latest date user may sign on</li>
-     * <li>{@link User#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
-     * <li>{@link User#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
-     * <li>{@link User#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of user may sign on</li>
-     * <li>{@link User#timeout} - number in seconds of session inactivity time allowed</li>
-     * <li>{@link User#props} * - multi-occurring attribute contains property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
-     * <li>{@link User#roles} * - multi-occurring attribute contains the name of already existing role to assign to user</li>
-     * <li>{@link User#adminRoles} * - multi-occurring attribute contains the name of already existing adminRole to assign to user</li>
-     * </ul>
-     *
-     * @param user User entity must contain {@link User#userId} and {@link User#ou} (required) and optional {@link User#description},{@link User#roles} and many others.
-     * @return Returns entity containing user data that was added.
-     * @throws SecurityException thrown in the event of data validation or system error.
-     */
-    public User addUser(User user)
-        throws SecurityException;
-
-
-    /**
-     * This command deletes an existing user from the RBAC database. The command is valid
-     * if and only if the user to be deleted is a member of the USERS data set. The USERS and
-     * UA data sets and the assigned_users function are updated.
-     * Method performs a "soft" delete.  It performs the following:
-     * - sets the user status to "deleted"
-     * - deassigns all roles from the user
-     * - locks the user's password in LDAP
-     * - revokes all perms that have been granted to user entity.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
-     * </ul>
-     *
-     * @param user Contains the {@link User#userId} of the User targeted for deletion.
-     * @throws SecurityException thrown in the event of data validation or system error.
-     */
-    public void disableUser(User user)
-        throws SecurityException;
-
-
-    /**
-     * This command deletes an existing user from the RBAC database. The command is valid
-     * if and only if the user to be deleted is a member of the USERS data set. The USERS and
-     * UA data sets and the assigned_users function are updated.
-     * 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.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
-     * </ul>
-     *
-     * @param user Contains the {@link User#userId} of the User targeted for deletion.
-     * @throws SecurityException thrown in the event of data validation or system error.
-     */
-    public void deleteUser(User user)
-        throws SecurityException;
-
-
-    /**
-     * This method performs an update on User entity in directory.  Prior to making this call the entity must exist in
-     * directory.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link User#password} - used to authenticate the User</li>
-     * <li>{@link User#ou} - contains the name of an already existing User OU node</li>
-     * <li>{@link User#pwPolicy} - contains the name of an already existing OpenLDAP password policy node</li>
-     * <li>{@link User#cn} - maps to INetOrgPerson common name attribute</li>
-     * <li>{@link User#sn} - maps to INetOrgPerson surname attribute</li>
-     * <li>{@link User#description} - maps to INetOrgPerson description attribute</li>
-     * <li>{@link User#title} - maps to INetOrgPerson title attribute</li>
-     * <li>{@link User#employeeType} - maps to INetOrgPerson employeeType attribute</li>
-     * <li>{@link User#phones} * - multi-occurring attribute maps to organizationalPerson telephoneNumber  attribute</li>
-     * <li>{@link User#mobiles} * - multi-occurring attribute maps to INetOrgPerson mobile attribute</li>
-     * <li>{@link User#emails} * - multi-occurring attribute maps to INetOrgPerson mail attribute</li>
-     * <li>{@link User#address} * - multi-occurring attribute maps to organizationalPerson postalAddress, st, l, postalCode, postOfficeBox attributes</li>
-     * <li>{@link User#beginTime} - HHMM - determines begin hour user may activate session</li>
-     * <li>{@link User#endTime} - HHMM - determines end hour user may activate session.</li>
-     * <li>{@link User#beginDate} - YYYYMMDD - determines date when user may sign on</li>
-     * <li>{@link User#endDate} - YYYYMMDD - indicates latest date user may sign on</li>
-     * <li>{@link User#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
-     * <li>{@link User#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
-     * <li>{@link User#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of user may sign on</li>
-     * <li>{@link User#timeout} - number in seconds of session inactivity time allowed</li>
-     * <li>{@link User#props} * - multi-occurring attribute contains property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
-     * <li>{@link User#roles} * - multi-occurring attribute contains the name of already existing role to assign to user</li>
-     * <li>{@link User#adminRoles} * - multi-occurring attribute contains the name of already existing adminRole to assign to user</li>
-     * </ul>
-     *
-     * @param user must contain {@link User#userId} and optional entity data to update i.e. desc, ou, properties, all attributes that are not set will be ignored.
-     * @return Updated user entity data.
-     * @throws SecurityException thrown in the event of validation or system error.
-     */
-    public User updateUser(User user)
-        throws SecurityException;
-
-
-    /**
-     * Method will change user's password.  This method will evaluate user's password policies.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
-     * <li>{@link User#password} - contains the User's old password</li>
-     * <li>newPassword - contains the User's new password</li>
-     * </ul>
-     *
-     * @param user        contains {@link User#userId} and old user password {@link User#password}.
-     * @param newPassword contains new user password.
-     * @throws SecurityException will be thrown in the event of password policy violation or system error.
-     */
-    public void changePassword(User user, char[] newPassword)
-        throws SecurityException;
-
-
-    /**
-     * Method will lock user's password which will prevent the user from authenticating with directory.
-     * <p/>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
-     * </ul>
-     *
-     * @param user entity contains {@link User#userId} of User to be locked.
-     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
-     */
-    public void lockUserAccount(User user)
-        throws SecurityException;
-
-
-    /**
-     * Method will unlock user's password which will enable user to authenticate with directory.
-     * <p/>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
-     * </ul>
-     *
-     * @param user entity contains {@link User#userId} of User to be unlocked.
-     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
-     */
-    public void unlockUserAccount(User user)
-        throws SecurityException;
-
-
-    /**
-     * Method will reset user's password which will require user to change password before successful authentication with directory.
-     * This method will not evaluate password policies on the new user password as it must be changed before use.
-     * <p/>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
-     * <li>newPassword - contains the User's new password</li>
-     * </ul>
-     *
-     * @param user entity contains {@link User#userId} of User to be reset.
-     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
-     */
-    public void resetPassword(User user, char[] newPassword)
-        throws SecurityException;
-
-
-    /**
-     * Method will delete user's password policy designation.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
-     * <li>newPassword - contains the User's new password</li>
-     * </ul>
-     *
-     * @param user  contains {@link User#userId}.
-     * @throws SecurityException will be thrown in the event of password policy violation or system error.
-     */
-    public void deletePasswordPolicy(User user)
-        throws SecurityException;
-
-
-    /**
-     * This command creates a new role. The command is valid if and only if the new role is not
-     * already a member of the ROLES data set. The ROLES data set is updated.
-     * Initially, no user or permission is assigned to the new role.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link Role#name} - contains the name to use for the Role to be created.</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link Role#description} - maps to description attribute on organizationalRole object class</li>
-     * <li>{@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
-     * <li>{@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
-     * <li>{@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
-     * <li>{@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
-     * <li>{@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
-     * <li>{@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
-     * <li>{@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session</li>
-     * </ul>
-     *
-     * @param role must contains {@link Role#name} (required) and optional {@link Role#description}.
-     * @throws SecurityException thrown in the event of data validation or system error.
-     */
-    public Role addRole(Role role)
-        throws SecurityException;
-
-
-    /**
-     * This command deletes an existing role from the RBAC database. The command is valid
-     * if and only if the role to be deleted is a member of the ROLES data set.  This command will
-     * also deassign role from all users.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link Role#name} - contains the name to use for the Role to be deleted.</li>
-     * </ul>
-     * @param role Must contain {@link Role#name} for Role to delete.
-     * @throws SecurityException thrown in the event of data validation or system error.
-     */
-    public void deleteRole(Role role)
-        throws SecurityException;
-
-
-    /**
-     * Method will update a Role entity in the directory.  The role must exist in role container prior to this call.
-     *
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link Role#name} - contains the name to use for the Role to be updated.</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link Role#description} - maps to description attribute on organizationalRole object class</li>
-     * <li>{@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
-     * <li>{@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
-     * <li>{@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
-     * <li>{@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
-     * <li>{@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
-     * <li>{@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
-     * <li>{@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session</li>
-     * </ul>
-     * @param role Must contains {@link Role#name} and may contain new description or {@link org.openldap.fortress.util.time.Constraint}
-     * @return Role contains reference to entity operated on.
-     * @throws SecurityException in the event of validation or system error.
-     */
-    public Role updateRole(Role role)
-        throws org.openldap.fortress.SecurityException;
-
-
-    /**
-     * 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>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link UserRole#name} - contains the name for already existing Role to be assigned</li>
-     * <li>{@link UserRole#userId} - contains the userId for existing User</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link UserRole#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
-     * <li>{@link UserRole#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
-     * <li>{@link UserRole#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
-     * <li>{@link UserRole#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
-     * <li>{@link UserRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
-     * <li>{@link UserRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
-     * <li>{@link UserRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session</li>
-     * </ul>
-     *
-     * @param uRole must contain {@link UserRole#userId} and {@link UserRole#name} and optional {@code Constraints}.
-     * @throws SecurityException in the event of validation or system error.
-     */
-    public void assignUser(UserRole uRole)
-        throws org.openldap.fortress.SecurityException;
-
-
-    /**
-     * 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.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link UserRole#name} - contains the name for already existing Role to be deassigned</li>
-     * <li>{@link UserRole#userId} - contains the userId for existing User</li>
-     * </ul>
-     * @param uRole must contain {@link org.openldap.fortress.rbac.UserRole#userId} and {@link UserRole#name}.
-     * @throws SecurityException - in the event data error in user or role objects or system error.
-     */
-    public void deassignUser(UserRole uRole)
-        throws SecurityException;
-
-
-    /**
-     * This method will add permission operation to an existing permission object which resides under {@code ou=Permissions,ou=RBAC,dc=yourHostName,dc=com} container in directory information tree.
-     * The perm operation entity may have {@link org.openldap.fortress.rbac.Role} or {@link org.openldap.fortress.rbac.User} associations.  The target {@link Permission} must not exist prior to calling.
-     * A Fortress Permission instance exists in a hierarchical, one-many relationship between its parent and itself as stored in ldap tree: ({@link PermObj}*->{@link Permission}).
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission add</li>
-     * <li>{@link Permission#opName} - contains the name of new permission operation being added</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
-     * <li>{@link Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
-     * <li>{@link Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
-     * <li>{@link Permission#type} - any safe text</li>
-     * </ul>
-     *
-     * @param perm must contain the object, {@link org.openldap.fortress.rbac.Permission#objName}, and operation, {@link Permission#opName}, that identifies target along with optional other attributes..
-     * @return copy of Permission entity.
-     * @throws SecurityException - thrown in the event of perm object data or system error.
-     */
-    public Permission addPermission(Permission perm)
-        throws org.openldap.fortress.SecurityException;
-
-
-    /**
-     * This method will update permission operation pre-existing in target directory under {@code ou=Permissions,ou=RBAC,dc=yourHostName,dc=com} container in directory information tree.
-     * The perm operation entity may also contain {@link org.openldap.fortress.rbac.Role} or {@link org.openldap.fortress.rbac.User} associations to add or remove using this function.
-     * The perm operation must exist before making this call.  Only non-null attributes will be updated.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission update</li>
-     * <li>{@link Permission#opName} - contains the name of existing permission operation being updated</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
-     * <li>{@link Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
-     * <li>{@link Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
-     * <li>{@link Permission#type} - any safe text</li>
-     * </ul>
-     *
-     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target and any optional data to update.  Null or empty attributes will be ignored.
-     * @return copy of Permission entity.
-     * @throws org.openldap.fortress.SecurityException
-     *          - thrown in the event of perm object data or system error.
-     */
-    public Permission updatePermission(Permission perm)
-        throws org.openldap.fortress.SecurityException;
-
-
-    /**
-     * This method will remove permission operation entity from permission object. A Fortress permission is (object->operation).
-     * The perm operation must exist before making this call.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission delete</li>
-     * <li>{@link Permission#opName} - contains the name of existing permission operation being removed</li>
-     * </ul>
-     *
-     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
-     * @throws SecurityException - thrown in the event of perm object data or system error.
-     */
-    public void deletePermission(Permission perm)
-        throws SecurityException;
-
-
-    /**
-     * This method will add permission object to perms container in directory. The perm object must not exist before making this call.
-     * A {@link PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link PermObj}*->{@link Permission}).
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link PermObj#objName} - contains the name of new object being added</li>
-     * <li>{@link PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link PermObj#description} - any safe text</li>
-     * <li>{@link PermObj#type} - contains any safe text</li>
-     * <li>{@link PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
-     * </ul>
-     *
-     * @param pObj must contain the {@link PermObj#objName} and {@link PermObj#ou}.  The other attributes are optional.
-     * @return copy of PermObj entity.
-     * @throws SecurityException - thrown in the event of perm object data or system error.
-     */
-    public PermObj addPermObj(PermObj pObj)
-        throws SecurityException;
-
-
-    /**
-     * This method will update permission object in perms container in directory.  The perm object must exist before making this call.
-     * A {@link PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link PermObj}*->{@link Permission}).
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link PermObj#objName} - contains the name of existing object being updated</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
-     * <li>{@link PermObj#description} - any safe text</li>
-     * <li>{@link PermObj#type} - contains any safe text</li>
-     * <li>{@link PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
-     * </ul>
-     *
-     * @param pObj must contain the {@link PermObj#objName}. Only non-null attributes will be updated.
-     * @return copy of newly updated PermObj entity.
-     * @throws org.openldap.fortress.SecurityException
-     *          - thrown in the event of perm object data or system error.
-     */
-    public PermObj updatePermObj(PermObj pObj)
-        throws org.openldap.fortress.SecurityException;
-
-
-    /**
-     * This method will remove permission object to perms container in directory.  This method will also remove
-     * in associated permission objects that are attached to this object.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link PermObj#objName} - contains the name of existing object targeted for removal</li>
-     * </ul>
-     *
-     * @param pObj must contain the {@link PermObj#objName} of object targeted for removal.
-     * @throws SecurityException - thrown in the event of perm object data or system error.
-     */
-    public void deletePermObj(PermObj pObj)
-        throws SecurityException;
-
-
-    /**
-     * This command grants a role the permission to perform an operation on an object to a role.
-     * The command is implemented by granting permission by setting the access control list of
-     * the object involved.
-     * The command is valid if and only if the pair (operation, object) represents a permission,
-     * and the role is a member of the ROLES data set.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link Permission#objName} - contains the object name</li>
-     * <li>{@link Permission#opName} - contains the operation name</li>
-     * <li>{@link Role#name} - contains the role name</li>
-     * </ul>
-     *
-     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
-     * @param role must contains {@link Role#name}.
-     * @throws SecurityException Thrown in the event of data validation or system error.
-     */
-    public void grantPermission(Permission perm, Role role)
-        throws org.openldap.fortress.SecurityException;
-
-
-    /**
-     * This command revokes the permission to perform an operation on an object from the set
-     * of permissions assigned to a role. The command is implemented by setting the access control
-     * list of the object involved.
-     * The command is valid if and only if the pair (operation, object) represents a permission,
-     * the role is a member of the ROLES data set, and the permission is assigned to that role.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link Permission#objName} - contains the object name</li>
-     * <li>{@link Permission#opName} - contains the operation name</li>
-     * <li>{@link Role#name} - contains the role name</li>
-     * </ul>
-     *
-     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
-     * @param role must contains {@link Role#name}.
-     * @throws SecurityException Thrown in the event of data validation or system error.
-     */
-    public void revokePermission(Permission perm, Role role)
-        throws org.openldap.fortress.SecurityException;
-
-
-    /**
-     * This command grants a user the permission to perform an operation on an object to a role.
-     * The command is implemented by granting permission by setting the access control list of
-     * the object involved.
-     * The command is valid if and only if the pair (operation, object) represents a permission,
-     * and the user is a member of the USERS data set.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link Permission#objName} - contains the object name</li>
-     * <li>{@link Permission#opName} - contains the operation name</li>
-     * <li>{@link User#userId} - contains the userId</li>
-     * </ul>
-     *
-     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
-     * @param user must contain {@link User#userId} of target User entity.
-     * @throws SecurityException Thrown in the event of data validation or system error.
-     */
-    public void grantPermission(Permission perm, User user)
-        throws SecurityException;
-
-
-    /**
-     * This command revokes the permission to perform an operation on an object from the set
-     * of permissions assigned to a user. The command is implemented by setting the access control
-     * list of the object involved.
-     * The command is valid if and only if the pair (operation, object) represents a permission,
-     * the user is a member of the USERS data set, and the permission is assigned to that user.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link Permission#objName} - contains the object name</li>
-     * <li>{@link Permission#opName} - contains the operation name</li>
-     * <li>{@link User#userId} - contains the userId</li>
-     * </ul>
-     *
-     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
-     * @param user must contain {@link User#userId} of target User entity.
-     * @throws SecurityException Thrown in the event of data validation or system error.
-     */
-    public void revokePermission(Permission perm, User user)
-        throws org.openldap.fortress.SecurityException;
-
-    /**
-     * This command creates a new role childRole, and inserts it in the role hierarchy as an immediate descendant of
-     * the existing role parentRole.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li> The childRole is not a member of the ROLES data set.
-     * <li> The parentRole is a member of the ROLES data set.
-     * </ul>
-     * </p>
-     * <p> This method:
-     * <ul>
-     * <li> Adds new role.
-     * <li> Assigns role relationship between new childRole and pre-existing parentRole.
-     * </ul>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>parentRole - {@link Role#name} - contains the name of existing Role to be parent</li>
-     * <li>childRole - {@link Role#name} - contains the name of new Role to be child</li>
-     * </ul>
-     * <h4>optional parameters childRole</h4>
-     * <ul>
-     * <li>childRole - {@link Role#description} - maps to description attribute on organizationalRole object class for new child</li>
-     * <li>childRole - {@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session for new child</li>
-     * <li>childRole - {@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session for new child</li>
-     * <li>childRole - {@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session for new child</li>
-     * <li>childRole - {@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session for new child</li>
-     * <li>childRole - {@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new child</li>
-     * <li>childRole - {@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new child</li>
-     * <li>childRole - {@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session for new child</li>
-     * </ul>
-     *
-     * @param parentRole This entity must be present in ROLE data set.  Success will add role rel with childRole.
-     * @param childRole  This entity must not be present in ROLE data set.  Success will add the new role entity to ROLE data set.
-     * @throws org.openldap.fortress.SecurityException
-     *          thrown in the event of data validation or system error.
-     */
-    public void addDescendant(Role parentRole, Role childRole)
-        throws SecurityException;
-
-
-    /**
-     * This command creates a new role parentRole, and inserts it in the role hierarchy as an immediate ascendant of
-     * the existing role childRole.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li> The parentRole is not a member of the ROLES data set.
-     * <li> The childRole is a member of the ROLES data set.
-     * </ul>
-     * </p>
-     * <p> This method:
-     * <ul>
-     * <li> Adds new role.
-     * <li> Assigns role relationship between new parentRole and pre-existing childRole.
-     * </ul>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>childRole - {@link Role#name} - contains the name of existing child Role</li>
-     * <li>parentRole - {@link Role#name} - contains the name of new Role to be parent</li>
-     * </ul>
-     * <h4>optional parameters parentRole</h4>
-     * <ul>
-     * <li>parentRole - {@link Role#description} - maps to description attribute on organizationalRole object class for new parent</li>
-     * <li>parentRole - {@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session for new parent</li>
-     * <li>parentRole - {@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session for new parent</li>
-     * <li>parentRole - {@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session for new parent</li>
-     * <li>parentRole - {@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session for new parent</li>
-     * <li>parentRole - {@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new parent</li>
-     * <li>parentRole - {@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new parent</li>
-     * <li>parentRole - {@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session for new parent</li>
-     * </ul>
-     *
-     * @param parentRole completion of op assigns new child relationship with childRole.
-     * @param childRole  completion of op assigns new parent relationship with parentRole.
-     * @throws SecurityException thrown in the event of data validation or system error.
-     */
-    public void addAscendant(Role childRole, Role parentRole)
-        throws SecurityException;
-
-
-    /**
-     * This command establishes a new immediate inheritance relationship parentRole <<-- childRole between existing
-     * roles parentRole, childRole.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li> The parentRole and childRole are members of the ROLES data set.
-     * <li> The parentRole is not an immediate ascendant of childRole.
-     * <li> The childRole does not properly inherit parentRole (in order to avoid cycle creation).
-     * </ul>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>parentRole - {@link Role#name} - contains the name of existing Role to be parent</li>
-     * <li>childRole - {@link Role#name} - contains the name of existing Role to be child</li>
-     * </ul>
-     *
-     * @param parentRole completion of op deassigns child relationship with childRole.
-     * @param childRole  completion of op deassigns parent relationship with parentRole.
-     * @throws SecurityException thrown in the event of data validation or system error.
-     */
-    public void addInheritance(Role parentRole, Role childRole)
-        throws SecurityException;
-
-
-    /**
-     * This command deletes an existing immediate inheritance relationship parentRole <<-- childRole.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li> The roles parentRole and childRole are members of the ROLES data set.
-     * <li> The parentRole is an immediate ascendant of childRole.
-     * <li> The new inheritance relation is computed as the reflexive-transitive closure of the immediate inheritance
-     * relation resulted after deleting the relationship parentRole <<-- childRole.
-     * </ul>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>parentRole - {@link Role#name} - contains the name of existing Role to remove parent relationship</li>
-     * <li>childRole - {@link Role#name} - contains the name of existing Role to remove child relationship</li>
-     * </ul>
-     *
-     * @param parentRole completion of op removes child relationship with childRole.
-     * @param childRole  completion of op removes parent relationship with parentRole.
-     * @throws SecurityException thrown in the event of data validation or system error.
-     */
-    public void deleteInheritance(Role parentRole, Role childRole)
-        throws SecurityException;
-
-
-    /**
-     * This command creates a named SSD set of roles and sets the cardinality n of its subsets
-     * that cannot have common users.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li>The name of the SSD set is not already in use.
-     * <li> All the roles in the SSD set are members of the ROLES data set.
-     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the SSD role set.
-     * <li> The SSD constraint for the new role set is satisfied.
-     * </ul>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of new SSD role set to be added</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
-     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
-     * <li>{@link SDSet#description} - contains any safe text</li>
-     * </ul>
-     *
-     * @param ssdSet contains an instantiated reference to new SSD set containing, name, members, and cardinality (default 2)
-     * @return reference to newly created SSDSet object.
-     * @throws SecurityException in the event of data validation or system error.
-     */
-    public SDSet createSsdSet(SDSet ssdSet)
-        throws SecurityException;
-
-    /**
-     * This command updates existing SSD set of roles and sets the cardinality n of its subsets
-     * that cannot have common users.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li>The name of the SSD set already exists.
-     * <li> All the roles in the SSD set are members of the ROLES data set.
-     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the SSD role set.
-     * <li> The SSD constraint for the new role set is satisfied.
-     * </ul>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of existing SSD role set to be updated</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
-     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
-     * <li>{@link SDSet#description} - contains any safe text</li>
-     * </ul>
-     *
-     * @param ssdSet contains an instantiated reference to existing SSD set containing, name, members, and cardinality (default 2)
-     * @return reference to SSDSet object targeted for update.
-     * @throws SecurityException in the event of data validation or system error.
-     */
-    public SDSet updateSsdSet(SDSet ssdSet)
-        throws SecurityException;
-
-    /**
-     * This command adds a role to a named SSD set of roles. The cardinality associated with the role set remains unchanged.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li> The SSD role set exists.
-     * <li> The role to be added is a member of the ROLES data set but not of a member of the SSD role set.
-     * <li> The SSD constraint is satisfied after the addition of the role to the SSD role set.
-     * </ul>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
-     * <li>{@link Role#name} - contains the name of new {@link SDSet#members} to be added</li>
-     * </ul>
-     *
-     * @param ssdSet contains an instantiated reference to new SSD set containing, name
-     * @param role   contains instantiated Role object with role name field set.
-     * @return reference to updated SSDSet object.
-     * @throws org.openldap.fortress.SecurityException
-     *          in the event of data validation or system error.
-     */
-    public SDSet addSsdRoleMember(SDSet ssdSet, Role role)
-        throws SecurityException;
-
-    /**
-     * This command removes a role from a named SSD set of roles. The cardinality associated with the role set remains unchanged.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li> The SSD role set exists.
-     * <li> The role to be removed is a member of the SSD role set.
-     * <li> The cardinality associated with the SSD role set is less than the number of elements of the SSD role set.
-     * </ul>
-     * Note that the SSD constraint should be satisfied after the removal of the role from the SSD role set.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
-     * <li>{@link Role#name} - contains the name of existing {@link SDSet#members} to be removed</li>
-     * </ul>
-     *
-     * @param ssdSet contains an instantiated reference to new SSD set containing name.
-     * @param role   contains instantiated Role object with role name field set.
-     * @return reference to updated SSDSet object.
-     * @throws SecurityException in the event of data validation or system error.
-     */
-    public SDSet deleteSsdRoleMember(SDSet ssdSet, Role role)
-        throws SecurityException;
-
-    /**
-     * This command deletes a SSD role set completely. The command is valid if and only if the SSD role set exists.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of SSD role set to be removed</li>
-     * </ul>
-     *
-     * @param ssdSet contains an instantiated reference to SSD set targeted for removal.
-     * @return reference to deleted SSDSet object.
-     * @throws SecurityException in the event of data validation or system error.
-     */
-    public SDSet deleteSsdSet(SDSet ssdSet)
-        throws org.openldap.fortress.SecurityException;
-
-    /**
-     * This command sets the cardinality associated with a given SSD role set.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li> The SSD role set exists.
-     * <li> The new cardinality is a natural number greater than or equal to 2 and less than or equal to the number of elements of the SSD role set.
-     * <li> The SSD constraint is satisfied after setting the new cardinality.
-     * </ul>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
-     * <li>cardinality - contains new cardinality setting for SSD</li>
-     * </ul>
-     *
-     * @param ssdSet      contains an instantiated reference to new SSD set containing, name
-     * @param cardinality integer value contains new cardinality value for data set.
-     * @return reference to updated SSDSet object.
-     * @throws org.openldap.fortress.SecurityException
-     *          in the event of data validation or system error.
-     */
-    public SDSet setSsdSetCardinality(SDSet ssdSet, int cardinality)
-        throws org.openldap.fortress.SecurityException;
-
-
-    /**
-     * This command creates a named DSD set of roles and sets an associated cardinality n.
-     * The DSD constraint stipulates that the DSD role set cannot contain n or more roles
-     * simultaneously active in the same session.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li> The name of the DSD set is not already in use.
-     * <li> All the roles in the DSD set are members of the ROLES data set.
-     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the DSD role set.
-     * <li> The DSD constraint for the new role set is satisfied.
-     * </ul>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of new DSD role set to be added</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
-     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
-     * <li>{@link SDSet#description} - contains any safe text</li>
-     * </ul>
-     *
-     * @param dsdSet contains an instantiated reference to new DSD set containing, name, members, and cardinality (default 2)
-     * @return reference to newly created SSDSet object.
-     * @throws SecurityException in the event of data validation or system error.
-     */
-    public SDSet createDsdSet(SDSet dsdSet)
-        throws SecurityException;
-
-    /**
-     * This command updates existing DSD set of roles and sets the cardinality n of its subsets
-     * that cannot have common users.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li>The name of the DSD set already exists.
-     * <li> All the roles in the DSD set are members of the ROLES data set.
-     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the DSD role set.
-     * <li> The DSD constraint for the new role set is satisfied.
-     * </ul>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of existing DSD role set to be updated</li>
-     * </ul>
-     * <h4>optional parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
-     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
-     * <li>{@link SDSet#description} - contains any safe text</li>
-     * </ul>
-     *
-     * @param dsdSet contains an instantiated reference to existing DSD set containing, name, members, and cardinality (default 2)
-     * @return reference to DSDSet object targeted for update.
-     * @throws SecurityException in the event of data validation or system error.
-     */
-    public SDSet updateDsdSet(SDSet dsdSet)
-        throws SecurityException;
-
-    /**
-     * This command adds a role to a named DSD set of roles. The cardinality associated with
-     * the role set remains unchanged.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li> The DSD role set exists.
-     * <li> The role to be added is a member of the ROLES data set but not of a member of the DSD role set.
-     * <li> The DSD constraint is satisfied after the addition of the role to the SSD role set.
-     * </ul>
-     * </p>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of DSD role set to be modified</li>
-     * <li>{@link Role#name} - contains the name of new {@link SDSet#members} to be added</li>
-     * </ul>
-     * @param dsdSet contains an instantiated reference to new DSD set containing, name
-     * @param role   contains instantiated Role object with role name field set.
-     * @return reference to updated DSDSet object.
-     * @throws SecurityException in the event of data validation or system error.
-     */
-    public SDSet addDsdRoleMember(SDSet dsdSet, Role role)
-        throws SecurityException;
-
-    /**
-     * This command removes a role from a named DSD set of roles. The cardinality associated
-     * with the role set remains unchanged.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li> The DSD role set exists
-     * <li> The role to be removed is a member of the DSD role set.
-     * <li> The cardinality associated with the DSD role set is less than the number of elements of the DSD role set.
-     * </ul>
-     * Note that the DSD constraint should be satisfied after the removal of the role from the DSD role set.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of DSD role set to be modified</li>
-     * <li>{@link Role#name} - contains the name of existing {@link SDSet#members} to be removed</li>
-     * </ul>
-     *
-     * @param dsdSet contains an instantiated reference to new DSD set containing name.
-     * @param role   contains instantiated Role object with role name field set.
-     * @return reference to updated DSDSet object.
-     * @throws SecurityException in the event of data validation or system error.
-     */
-    public SDSet deleteDsdRoleMember(SDSet dsdSet, Role role)
-        throws SecurityException;
-
-    /**
-     * This command deletes a DSD role set completely. The command is valid if and only if the DSD role set exists.
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of DSD role set to be removed</li>
-     * </ul>
-     *
-     * @param dsdSet contains an instantiated reference to DSD set targeted for removal.
-     * @return reference to deleted DSDSet object.
-     * @throws SecurityException in the event of data validation or system error.
-     */
-    public SDSet deleteDsdSet(SDSet dsdSet)
-        throws SecurityException;
-
-    /**
-     * This command sets the cardinality associated with a given DSD role set.
-     * <p>
-     * The command is valid if and only if:
-     * <ul>
-     * <li> The SSD role set exists.
-     * <li> The new cardinality is a natural number greater than or equal to 2 and less than or equal to the number of elements of the SSD role set.
-     * <li> The SSD constraint is satisfied after setting the new cardinality.
-     * </ul>
-     * <h4>required parameters</h4>
-     * <ul>
-     * <li>{@link SDSet#name} - contains the name of DSD role set to be modified</li>
-     * <li>cardinality - contains new cardinality setting for SSD</li>
-     * </ul>
-     *
-     * @param dsdSet      contains an instantiated reference to new DSD set containing, name
-     * @param cardinality integer value contains new cardinality value for data set.
-     * @return reference to updated DSDSet object.
-     * @throws org.openldap.fortress.SecurityException
-     *          in the event of data validation or system error.
-     */
-    public SDSet setDsdSetCardinality(SDSet dsdSet, int cardinality)
-        throws org.openldap.fortress.SecurityException;
-}
\ No newline at end of file


[17/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/AdminRoleDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/AdminRoleDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/AdminRoleDAO.java
new file mode 100755
index 0000000..20a1648
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/AdminRoleDAO.java
@@ -0,0 +1,694 @@
+/*
+ *   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.apache;
+
+
+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.AdminRole;
+import org.apache.directory.fortress.core.rbac.AdminRoleP;
+import org.apache.directory.fortress.core.rbac.AdminRoleUtil;
+import org.apache.directory.fortress.core.rbac.Graphable;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.time.CUtil;
+
+
+/**
+ * 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 final class AdminRoleDAO extends ApacheDsDataProvider implements org.apache.directory.fortress.core.rbac.dao.AdminRoleDAO
+{
+    private static final String ROLE_OCCUPANT = "roleOccupant";
+    private static final String ROLE_OSP = "ftOSP";
+    private static final String ROLE_OSU = "ftOSU";
+    private static final String ROLE_RANGE = "ftRange";
+    private static final String POOLS_AUX_OBJECT_CLASS_NAME = "ftPools";
+    private static final String ADMIN_ROLE_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP,
+            GlobalIds.ROLE_OBJECT_CLASS_NM,
+            GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME,
+            POOLS_AUX_OBJECT_CLASS_NAME,
+            GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+    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,
+            ROLE_OSP,
+            ROLE_OSU,
+            ROLE_RANGE,
+            GlobalIds.PARENT_NODES
+    };
+
+
+    /**
+     * 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.
+     */
+    public final AdminRole create( AdminRole entity ) throws CreateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        try
+        {
+            Entry entry = new DefaultEntry( dn );
+
+            entry.add( GlobalIds.OBJECT_CLASS, ADMIN_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 ) );
+            loadAttrs( entity.getOsP(), entry, ROLE_OSP );
+            loadAttrs( entity.getOsU(), entry, ROLE_OSU );
+            String szRaw = entity.getRoleRangeRaw();
+
+            if ( VUtil.isNotNullOrEmpty( szRaw ) )
+            {
+                entry.add( ROLE_RANGE, szRaw );
+            }
+
+            // These multi-valued attributes are optional.  The utility function will return quietly if no items are 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.ARLE_ADD_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * 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.
+     */
+    public final AdminRole update( AdminRole entity ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        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, name ) );
+                }
+            }
+
+            if ( entity.isTemporalSet() )
+            {
+                String szRawData = CUtil.setConstraint( entity );
+                if ( VUtil.isNotNullOrEmpty( szRawData ) )
+                {
+                    mods.add( new DefaultModification(
+                        ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.CONSTRAINT, szRawData ) );
+                }
+            }
+
+            loadAttrs( entity.getOsU(), mods, ROLE_OSU );
+            loadAttrs( entity.getOsP(), mods, ROLE_OSP );
+            String szRaw = entity.getRoleRangeRaw();
+
+            if ( VUtil.isNotNullOrEmpty( szRaw ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, ROLE_RANGE, szRaw ) );
+            }
+
+            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.ARLE_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     *
+     * @param entity
+     * @throws UpdateException
+     */
+    public final void deleteParent( AdminRole entity ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        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.ARLE_REMOVE_PARENT_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * 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.
+     */
+    public final AdminRole assign( AdminRole entity, String userDn ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        try
+        {
+            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.ARLE_USER_ASSIGN_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * 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.
+     */
+    public final AdminRole deassign( AdminRole entity, String userDn ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+        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.ARLE_USER_DEASSIGN_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * 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.
+     */
+    public final void remove( AdminRole role ) throws RemoveException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( role );
+
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, dn, role );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove role name=" + role.getName() + " LdapException=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.ARLE_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * 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.
+     */
+    public final AdminRole getRole( AdminRole adminRole ) throws FinderException
+    {
+        AdminRole entity = null;
+        LdapConnection ld = null;
+        String dn = getDn( adminRole );
+
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, dn, ROLE_ATRS );
+            entity = unloadLdapEntry( findEntry, 0, adminRole.getContextId() );
+
+            if ( entity == null )
+            {
+                String warning = "getRole name [" + adminRole.getName() + "] no entry found dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.ARLE_NOT_FOUND, warning );
+            }
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getRole name [" + adminRole.getName() + "] Obj COULD NOT FIND ENTRY for dn [" + dn
+                + "]";
+            throw new FinderException( GlobalErrIds.ARLE_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getRole dn [" + dn + "] LEXCD=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param adminRole
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final List<AdminRole> findRoles( AdminRole adminRole ) throws FinderException
+    {
+        List<AdminRole> roleList = new ArrayList<>();
+        LdapConnection ld = null;
+        String roleRoot = getRootDn( adminRole.getContextId(), GlobalIds.ADMIN_ROLE_ROOT );
+        String filter;
+
+        try
+        {
+            String searchVal = encodeSafeText( adminRole.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++, adminRole.getContextId() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findRoles name [" + adminRole.getName() + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findRoles name [" + adminRole.getName() + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return roleList;
+    }
+
+
+    /**
+     * @param adminRole
+     * @param limit
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final List<String> findRoles( AdminRole adminRole, int limit ) throws FinderException
+    {
+        List<String> roleList = new ArrayList<>();
+        LdapConnection ld = null;
+        String roleRoot = getRootDn( adminRole.getContextId(), GlobalIds.ADMIN_ROLE_ROOT );
+        String filter;
+        String searchVal = null;
+
+        try
+        {
+            searchVal = encodeSafeText( adminRole.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 name [" + searchVal + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findRoles name [" + searchVal + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return roleList;
+    }
+
+
+    /**
+     * @param userDn
+     * @return
+     * @throws FinderException
+     */
+    public final List<String> findAssignedRoles( String userDn, String contextId ) throws FinderException
+    {
+        List<String> roleNameList = new ArrayList<>();
+        LdapConnection ld = null;
+        String roleRoot = getRootDn( contextId, GlobalIds.ADMIN_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.ARLE_OCCUPANT_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findAssignedRoles userDn [" + userDn + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_OCCUPANT_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return roleNameList;
+    }
+
+
+    /**
+      *
+      * @param contextId
+      * @return
+      * @throws FinderException
+      */
+    public 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.ADMIN_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.ARLE_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "getAllDescendants filter [" + filter + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_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
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     * @throws LdapException
+     */
+    private AdminRole unloadLdapEntry( Entry le, long sequence, String contextId )
+        throws LdapInvalidAttributeValueException
+    {
+        AdminRole entity = new ObjectFactory().createAdminRole();
+        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.setOsP( getAttributeSet( le, ROLE_OSP ) );
+        entity.setOsU( getAttributeSet( le, ROLE_OSU ) );
+        unloadTemporal( le, entity );
+        entity.setRoleRangeRaw( getAttribute( le, ROLE_RANGE ) );
+        //entity.setParents(AdminRoleUtil.getParents(entity.getName().toUpperCase(), contextId));
+        entity.setParents( getAttributeSet( le, GlobalIds.PARENT_NODES ) );
+        entity.setChildren( AdminRoleUtil.getChildren( entity.getName().toUpperCase(), contextId ) );
+        return entity;
+    }
+
+
+    private String getDn( AdminRole adminRole )
+    {
+        return GlobalIds.CN + "=" + adminRole.getName() + ","
+            + getRootDn( adminRole.getContextId(), GlobalIds.ADMIN_ROLE_ROOT );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/AuditDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/AuditDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/AuditDAO.java
new file mode 100755
index 0000000..a7f2cdb
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/AuditDAO.java
@@ -0,0 +1,784 @@
+/*
+ *   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.apache;
+
+
+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.Entry;
+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.message.SearchScope;
+import org.apache.directory.ldap.client.api.LdapConnection;
+
+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.cfg.Config;
+import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.rbac.AuthZ;
+import org.apache.directory.fortress.core.rbac.Bind;
+import org.apache.directory.fortress.core.rbac.Mod;
+import org.apache.directory.fortress.core.rbac.UserAudit;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * This class performs data access for OpenLDAP synch repl log data
+ * <p/>
+ * <h3>1. Binds</h3>
+ * <p/>
+ * The auditBind Structural object class is used to store authentication events that can later be queried via ldap API.<br />
+ * <code># The Bind class includes the reqVersion attribute which contains the LDAP</code>
+ * <code># protocol version specified in the Bind as well as the reqMethod attribute</code>
+ * <code># which contains the Bind Method used in the Bind. This will be the string</code>
+ * <code># SIMPLE for LDAP Simple Binds or SASL(mech) for SASL Binds. Note that unless</code>
+ * <code># configured as a global overlay, only Simple Binds using DNs that reside in</code>
+ * <code># the current database will be logged:</code>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass (  1.3.6.1.4.1.4203.666.11.5.2.6 NAME 'auditBind'</code>
+ * <li> <code>DESC 'Bind operation'</code>
+ * <li> <code>SUP auditObject STRUCTURAL</code>
+ * <li> <code>MUST ( reqVersion $ reqMethod ) )</code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <h3>2. Authorizations</h3>
+ * <code>For  the  Search class the reqScope attribute contains the scope of the</code><br />
+ * <code>original search request, using the values specified for  the  LDAP  URL</code><br />
+ * <code>format. I.e.  base, one, sub, or subord.  The reqDerefAliases attribute</code><br />
+ * <code>is one of never, finding, searching, or always,  denoting  how  aliases</code><br />
+ * <code>will  be  processed during the search.  The reqAttrsOnly attribute is a</code><br />
+ * <code>Boolean value showing TRUE if only attribute names were  requested,  or</code><br />
+ * <code>FALSE  if  attributes  and  their values were requested.  The reqFilter</code><br />
+ * <code>attribute carries the filter used in the search request.   The  reqAttr</code><br />
+ * <code>attribute  lists  the  requested attributes if specific attributes were</code><br />
+ * <code>requested.  The reqEntries attribute is the integer count of  how  many</code><br />
+ * <code>entries  were  returned  by  this search request.  The reqSizeLimit and</code><br />
+ * <code>reqTimeLimit attributes indicate what  limits  were  requested  on  the</code><br />
+ * <code>search operation.</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass  (  1.3.6.1.4.1.4203.666.11.5.2.11</code>
+ * <li> <code>NAME 'auditSearch'</code>
+ * <li> <code>DESC 'Search operation'</code>
+ * <li> <code>SUP auditReadObject STRUCTURAL</code>
+ * <li> <code>MUST ( reqScope $ reqDerefAliases $ reqAttrsOnly )</code>
+ * <li> <code>MAY ( reqFilter $ reqAttr $ reqEntries $ reqSizeLimit $</code>
+ * <li> <code>reqTimeLimit ) )</code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <p/>
+ * <p/>
+ * <h3>3. Modifications</h3>
+ * The auditModify Structural object class is used to store Fortress update and delete events that can later be queried via ldap API.<br />
+ * The deletions can be recorded in this manner and associated with Fortress context because deletions will perform a modification first
+ * if audit is enabled.
+ * <p/>
+ * <code>The Modify operation contains a description  of  modifications  in  the</code><br />
+ * <code>reqMod  attribute,  which  was  already  described  above  in  the  Add</code><br />
+ * <code>operation. It may optionally  contain  the  previous  contents  of  any</code><br />
+ * <code>modified  attributes  in the reqOld attribute, using the same format as</code><br />
+ * <code>described above for the Delete operation.  The reqOld attribute is only</code><br />
+ * <code>populated  if  the  entry  being modified matches the configured logold</code><br />
+ * <code>filter.</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass (  1.3.6.1.4.1.4203.666.11.5.2.9</code>
+ * <li> <code>NAME 'auditModify'</code>
+ * <li> <code>DESC 'Modify operation'</code>
+ * <li> <code>SUP auditWriteObject STRUCTURAL</code>
+ * <li> <code>MAY reqOld MUST reqMod )</code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <p/>
+ * Note this class used descriptions pulled from man pages on slapd access log.
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+public final class AuditDAO extends ApacheDsDataProvider implements org.apache.directory.fortress.core.rbac.dao.AuditDAO
+{
+    private static final String CREATETIMESTAMP = "createTimestamp";
+    private static final String CREATORSNAME = "creatorsName";
+    private static final String ENTRYCSN = "entryCSN";
+    private static final String ENTRYDN = "entryDN";
+    private static final String ENTRYUUID = "entryUUID";
+    private static final String HASSUBORDINATES = "hasSubordinates";
+    private static final String MODIFIERSNAME = "modifiersName";
+    private static final String MODIFYTIMESTAMP = "modifyTimestamp";
+    private static final String OBJECTCLASS = "objectClass";
+    private static final String REQUAUTHZID = "reqAuthzID";
+    private static final String REQCONTROLS = "reqControls";
+    private static final String REQDN = "reqDN";
+    private static final String REQEND = "reqEnd";
+    private static final String REQMETHOD = "reqMethod";
+    private static final String REQRESULT = "reqResult";
+    private static final String REQSESSION = "reqSession";
+    private static final String REQSTART = "reqStart";
+    private static final String REQTYPE = "reqType";
+    private static final String REQVERSION = "reqVersion";
+    private static final String REQMOD = "reqMod";
+    private static final String STRUCTURALOBJECTCLASS = "structuralObjectClass";
+    private static final String SUBSCHEMAENTRY = "subschemaSubentry";
+    private static final String REQATTR = "reqAttr";
+    private static final String REQATTRSONLY = "reqAttrsOnly";
+    private static final String REQDREFALIASES = "reqDerefAliases";
+    private static final String REQENTRIES = "reqEntries";
+    private static final String REQFILTER = "reqFilter";
+    private static final String REQSCOPE = "reqScope";
+    private static final String REQSIZELIMIT = "reqSizeLimit";
+    private static final String REQTIMELIMIT = "reqTimeLimit";
+    private static final String REQASSERTION = "reqAssertion";
+    private static final String ACCESS_BIND_CLASS_NM = "auditBind";
+    //private static final String ACCESS_AUTHZ_CLASS_NM = "auditSearch";
+    private static final String ACCESS_AUTHZ_CLASS_NM = "auditCompare";
+    private static final String ACCESS_MOD_CLASS_NM = "auditModify";
+    private static final String ACCESS_ADD_CLASS_NM = "auditAdd";
+    private static final String AUDIT_ROOT = "audit.root";
+
+    private static final String[] AUDIT_AUTHZ_ATRS =
+        {
+            CREATETIMESTAMP, CREATORSNAME, ENTRYCSN, ENTRYDN, ENTRYUUID, HASSUBORDINATES, MODIFIERSNAME,
+            MODIFYTIMESTAMP, OBJECTCLASS, REQATTR, REQATTRSONLY, REQUAUTHZID, REQCONTROLS, REQDN, REQDREFALIASES,
+            REQEND, REQENTRIES, REQFILTER, REQRESULT, REQSCOPE, REQSESSION, REQSIZELIMIT, REQSTART, REQTIMELIMIT,
+            REQTYPE, STRUCTURALOBJECTCLASS, SUBSCHEMAENTRY
+    };
+
+    private static final String[] AUDIT_BIND_ATRS =
+        {
+            CREATETIMESTAMP, CREATORSNAME, ENTRYCSN, ENTRYDN, ENTRYUUID, HASSUBORDINATES, MODIFIERSNAME,
+            MODIFYTIMESTAMP, OBJECTCLASS, REQUAUTHZID, REQCONTROLS, REQDN, REQEND, REQMETHOD, REQRESULT,
+            REQSESSION, REQSTART, REQTYPE, REQVERSION, STRUCTURALOBJECTCLASS, SUBSCHEMAENTRY
+    };
+
+    private static final String[] AUDIT_MOD_ATRS =
+        {
+            OBJECTCLASS, REQUAUTHZID, REQDN, REQEND, REQRESULT, REQSESSION, REQSTART, REQTYPE, REQMOD
+    };
+
+
+    /**
+     * This method returns failed authentications where the userid is not present in the directory.  This
+     * is possible because Fortress performs read on user before the bind.
+     * User:
+     * dn: reqStart=20101014235402.000000Z, cn=log
+     * reqStart: 20101014235402.000000Z
+     * reqEnd: 20101014235402.000001Z
+     * reqAuthzID: cn=Manager,dc=jts,dc=com
+     * reqDerefAliases: never
+     * reqSession: 84
+     * reqAttrsOnly: FALSE
+     * reqSizeLimit: -1
+     * objectClass: auditSearch
+     * reqResult: 32
+     * reqAttr: ftId
+     * reqAttr: uid
+     * reqAttr: userpassword
+     * reqAttr: description
+     * reqAttr: ou
+     * reqAttr: cn
+     * reqAttr: sn
+     * reqAttr: ftRoleCstr
+     * reqAttr: ftCstr
+     * reqAttr: ftRoleAsgn
+     * reqAttr: pwdReset
+     * reqAttr: pwdAccountLockedTime
+     * reqAttr: ftProps
+     * reqEntries: 0
+     * reqFilter: (|(objectClass=*)(?objectClass=ldapSubentry))
+     * reqType: search
+     * reqDN: uid=foo,ou=People,dc=jts,dc=com        /cal/cal2.jsp
+     * reqTimeLimit: -1
+     * reqScope: base
+     *
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<AuthZ> searchInvalidAuthNs( UserAudit audit ) throws FinderException
+    {
+        List<AuthZ> auditList = new ArrayList<>();
+        LdapConnection ld = null;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+        String userRoot = Config.getProperty( GlobalIds.USER_ROOT );
+
+        try
+        {
+            // use wildcard for user if not passed in:
+            //reqDN: uid=foo,ou=People,dc=jts,dc=com
+            //(&
+            //  (objectclass=auditSearch)
+            //      (reqDN=uid=*,ou=People,dc=jts,dc=com)
+            //      (reqAuthzID=cn=Manager,dc=jts,dc=com)
+            //      (reqEntries=0)
+            // )
+
+            String filter = GlobalIds.FILTER_PREFIX + ACCESS_AUTHZ_CLASS_NM + ")(";
+            String userId;
+
+            if ( VUtil.isNotNullOrEmpty( audit.getUserId() ) )
+            {
+                userId = audit.getUserId();
+                filter += REQDN + "=" + GlobalIds.UID + "=" + userId + "," + userRoot + ")(" +
+                    REQUAUTHZID + "=" + "cn=Manager," + Config.getProperty( GlobalIds.SUFFIX ) + ")";
+            }
+            else
+            {
+                // pull back all failed authN attempts for all users:
+                filter += REQATTR + "=" + GlobalIds.UID + ")(" +
+                    REQUAUTHZID + "=" + "cn=Manager," + Config.getProperty( GlobalIds.SUFFIX ) + ")";
+            }
+
+            if ( audit.isFailedOnly() )
+            {
+                filter += "(" + REQENTRIES + "=" + 0 + ")";
+            }
+
+            if ( audit.getBeginDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                filter += "(" + REQEND + ">=" + szTime + ")";
+            }
+
+            filter += ")";
+
+            //log.warn("filter=" + filter);
+            ld = getLogConnection();
+            SearchCursor searchResults = search( ld, auditRoot,
+                SearchScope.ONELEVEL, filter, AUDIT_AUTHZ_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                AuthZ authZ = getAuthzEntityFromLdapEntry( searchResults.getEntry(), sequence++ );
+                // todo: fix this workaround. This search will return failed role assign searches as well.  
+                // Work around is to remove the ou=People failed searches from user failed searches on authN.
+                if ( !AttrHelper.getAuthZId( authZ.getReqDN() ).equalsIgnoreCase( "People" ) )
+                    auditList.add( authZ );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "LdapException in AuditDAO.searchAuthZs id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_AUTHN_INVALID_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "LdapException in AuditDAO.searchAuthZs id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_AUTHN_INVALID_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+
+        return auditList;
+    }
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<AuthZ> searchAuthZs( UserAudit audit ) throws FinderException
+    {
+        List<AuthZ> auditList = new ArrayList<>();
+        LdapConnection ld = null;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+        String permRoot = getRootDn( audit.isAdmin(), audit.getContextId() );
+        String userRoot = getRootDn( audit.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String reqDn = PermDAO.getOpRdn( audit.getOpName(), audit.getObjId() ) + "," + GlobalIds.POBJ_NAME + "="
+                + audit.getObjName() + "," + permRoot;
+            String filter = GlobalIds.FILTER_PREFIX + ACCESS_AUTHZ_CLASS_NM + ")(" + REQDN + "=" +
+                reqDn + ")(" + REQUAUTHZID + "=" + GlobalIds.UID + "=" + audit.getUserId() + "," + userRoot + ")";
+
+            if ( audit.isFailedOnly() )
+            {
+                filter += "(!(" + REQRESULT + "=" + 6 + "))";
+            }
+
+            if ( audit.getBeginDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                filter += "(" + REQEND + ">=" + szTime + ")";
+            }
+
+            filter += ")";
+
+            //System.out.println("filter=" + filter);
+            ld = getLogConnection();
+            SearchCursor searchResults = search( ld, auditRoot,
+                SearchScope.ONELEVEL, filter, AUDIT_AUTHZ_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                auditList.add( getAuthzEntityFromLdapEntry( searchResults.getEntry(), sequence++ ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "LdapException in AuditDAO.searchAuthZs id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_AUTHZ_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "LdapException in AuditDAO.searchAuthZs id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_AUTHZ_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+
+        return auditList;
+    }
+
+
+    private String getRootDn( boolean isAdmin, String contextId )
+    {
+        String dn;
+
+        if ( isAdmin )
+        {
+            dn = getRootDn( contextId, GlobalIds.ADMIN_PERM_ROOT );
+        }
+        else
+        {
+            dn = getRootDn( contextId, GlobalIds.PERM_ROOT );
+        }
+
+        return dn;
+    }
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<AuthZ> getAllAuthZs( UserAudit audit ) throws FinderException
+    {
+        List<AuthZ> auditList = new ArrayList<>();
+        LdapConnection ld = null;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+        String userRoot = getRootDn( audit.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + ACCESS_AUTHZ_CLASS_NM + ")(";
+
+            if ( audit.getUserId() != null && audit.getUserId().length() > 0 )
+            {
+                filter += REQUAUTHZID + "=" + GlobalIds.UID + "=" + audit.getUserId() + "," + userRoot + ")";
+            }
+            else
+            {
+                // have to limit the query to only authorization entries.
+                // TODO: determine why the cn=Manager user is showing up in this search:
+                filter += REQUAUTHZID + "=*)(!(" + REQUAUTHZID + "=cn=Manager," + Config.getProperty( GlobalIds.SUFFIX )
+                    + "))";
+
+                // TODO: fix this so filter by only the Fortress AuthZ entries and not the others:
+                if ( audit.isFailedOnly() )
+                {
+                    filter += "(!(" + REQRESULT + "=" + 6 + "))";
+                }
+            }
+
+            if ( audit.getBeginDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                filter += "(" + REQEND + ">=" + szTime + ")";
+            }
+
+            filter += ")";
+
+            //log.warn("filter=" + filter);
+            ld = getLogConnection();
+            SearchCursor searchResults = search( ld, auditRoot,
+                SearchScope.ONELEVEL, filter, AUDIT_AUTHZ_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                auditList.add( getAuthzEntityFromLdapEntry( searchResults.getEntry(), sequence++ ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "LdapException in AuditDAO.getAllAuthZs id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_AUTHZ_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "LdapException in AuditDAO.getAllAuthZs id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_AUTHZ_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+
+        return auditList;
+    }
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Bind> searchBinds( UserAudit audit ) throws FinderException
+    {
+        List<Bind> auditList = new ArrayList<>();
+        LdapConnection ld = null;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+        String userRoot = getRootDn( audit.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String filter;
+
+            if ( audit.getUserId() != null && audit.getUserId().length() > 0 )
+            {
+                filter = GlobalIds.FILTER_PREFIX + ACCESS_BIND_CLASS_NM + ")(" +
+                    REQDN + "=" + GlobalIds.UID + "=" + audit.getUserId() + "," + userRoot + ")";
+
+                if ( audit.isFailedOnly() )
+                {
+                    filter += "(" + REQRESULT + ">=" + 1 + ")";
+                }
+
+                if ( audit.getBeginDate() != null )
+                {
+                    String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                    filter += "(" + REQEND + ">=" + szTime + ")";
+                }
+
+                filter += ")";
+            }
+            else
+            {
+                filter = GlobalIds.FILTER_PREFIX + ACCESS_BIND_CLASS_NM + ")";
+
+                if ( audit.isFailedOnly() )
+                {
+                    filter += "(" + REQRESULT + ">=" + 1 + ")";
+                }
+
+                if ( audit.getBeginDate() != null )
+                {
+                    String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                    filter += "(" + REQEND + ">=" + szTime + ")";
+                }
+
+                filter += ")";
+            }
+
+            //log.warn("filter=" + filter);
+            ld = getLogConnection();
+            SearchCursor searchResults = search( ld, auditRoot,
+                SearchScope.ONELEVEL, filter, AUDIT_BIND_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                auditList.add( getBindEntityFromLdapEntry( searchResults.getEntry(), sequence++ ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "LdapException in AuditDAO.searchBinds id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_BIND_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "LdapException in AuditDAO.searchBinds id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_BIND_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+
+        return auditList;
+    }
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Mod> searchUserMods( UserAudit audit ) throws FinderException
+    {
+        List<Mod> modList = new ArrayList<>();
+        LdapConnection ld = null;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+
+        String userRoot = getRootDn( audit.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + ACCESS_MOD_CLASS_NM + ")(" +
+                REQDN + "=" + GlobalIds.UID + "=" + audit.getUserId() + "," + userRoot + ")";
+
+            if ( audit.getBeginDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                filter += "(" + REQEND + ">=" + szTime + ")";
+            }
+
+            filter += ")";
+            //log.warn("filter=" + filter);
+            ld = getLogConnection();
+            SearchCursor searchResults = search( ld, auditRoot,
+                SearchScope.ONELEVEL, filter, AUDIT_MOD_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                modList.add( getModEntityFromLdapEntry( searchResults.getEntry(), sequence++ ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "searchUserMods caught LdapException id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_MOD_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "searchUserMods caught LdapException id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_MOD_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+
+        return modList;
+    }
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws FinderException
+     */
+    public final List<Mod> searchAdminMods( UserAudit audit ) throws FinderException
+    {
+        List<Mod> modList = new ArrayList<>();
+        LdapConnection ld = null;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+
+        try
+        {
+            String filter = "(&(|(objectclass=" + ACCESS_MOD_CLASS_NM + ")";
+            filter += "(objectclass=" + ACCESS_ADD_CLASS_NM + "))";
+
+            if ( VUtil.isNotNullOrEmpty( audit.getDn() ) )
+            {
+                filter += "(" + REQDN + "=" + audit.getDn() + ")";
+            }
+
+            if ( VUtil.isNotNullOrEmpty( audit.getObjName() ) )
+            {
+                filter += "(|(" + REQMOD + "=" + GlobalIds.FT_MODIFIER_CODE + ":= " + audit.getObjName() + ".";
+
+                if ( VUtil.isNotNullOrEmpty( audit.getOpName() ) )
+                {
+                    filter += audit.getOpName();
+                }
+
+                filter += "*)";
+                filter += "(" + REQMOD + "=" + GlobalIds.FT_MODIFIER_CODE + ":+ " + audit.getObjName() + ".";
+
+                if ( VUtil.isNotNullOrEmpty( audit.getOpName() ) )
+                {
+                    filter += audit.getOpName();
+                }
+
+                filter += "*))";
+            }
+
+            if ( VUtil.isNotNullOrEmpty( audit.getInternalUserId() ) )
+            {
+                filter += "(|(" + REQMOD + "=" + GlobalIds.FT_MODIFIER + ":= " + audit.getInternalUserId() + ")";
+                filter += "(" + REQMOD + "=" + GlobalIds.FT_MODIFIER + ":+ " + audit.getInternalUserId() + "))";
+            }
+
+            if ( audit.getBeginDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                filter += "(" + REQEND + ">=" + szTime + ")";
+            }
+
+            if ( audit.getEndDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getEndDate() );
+                filter += "(" + REQEND + "<=" + szTime + ")";
+            }
+
+            filter += ")";
+            //log.warn("filter=" + filter);
+            ld = getLogConnection();
+            SearchCursor searchResults = search( ld, auditRoot,
+                SearchScope.ONELEVEL, filter, AUDIT_MOD_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                modList.add( getModEntityFromLdapEntry( searchResults.getEntry(), sequence++ ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "searchAdminMods caught LdapException id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_MOD_ADMIN_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "searchAdminMods caught LdapException id=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_MOD_ADMIN_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+
+        return modList;
+    }
+
+
+    /**
+     * @param le
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     * @throws LdapException
+     */
+    private Bind getBindEntityFromLdapEntry( Entry le, long sequence ) throws LdapInvalidAttributeValueException
+    {
+
+        Bind auditBind = new ObjectFactory().createBind();
+        auditBind.setSequenceId( sequence );
+        auditBind.setCreateTimestamp( getAttribute( le, CREATETIMESTAMP ) );
+        auditBind.setCreatorsName( getAttribute( le, CREATORSNAME ) );
+        auditBind.setEntryCSN( getAttribute( le, ENTRYCSN ) );
+        auditBind.setEntryDN( getAttribute( le, ENTRYDN ) );
+        auditBind.setEntryUUID( getAttribute( le, ENTRYUUID ) );
+        auditBind.setHasSubordinates( getAttribute( le, HASSUBORDINATES ) );
+        auditBind.setModifiersName( getAttribute( le, MODIFIERSNAME ) );
+        auditBind.setModifyTimestamp( getAttribute( le, MODIFYTIMESTAMP ) );
+        auditBind.setObjectClass( getAttribute( le, OBJECTCLASS ) );
+        auditBind.setReqAuthzID( getAttribute( le, REQUAUTHZID ) );
+        auditBind.setReqControls( getAttribute( le, REQCONTROLS ) );
+        auditBind.setReqDN( getAttribute( le, REQDN ) );
+        auditBind.setReqEnd( getAttribute( le, REQEND ) );
+        auditBind.setReqMethod( getAttribute( le, REQMETHOD ) );
+        auditBind.setReqResult( getAttribute( le, REQRESULT ) );
+        auditBind.setReqSession( getAttribute( le, REQSESSION ) );
+        auditBind.setReqStart( getAttribute( le, REQSTART ) );
+        auditBind.setReqType( getAttribute( le, REQTYPE ) );
+        auditBind.setReqVersion( getAttribute( le, REQVERSION ) );
+        auditBind.setStructuralObjectClass( getAttribute( le, STRUCTURALOBJECTCLASS ) );
+
+        return auditBind;
+    }
+
+
+    /**
+     * @param le
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     * @throws LdapException
+     */
+    private AuthZ getAuthzEntityFromLdapEntry( Entry le, long sequence ) throws LdapInvalidAttributeValueException
+    {
+
+        // these attrs also on audit bind OC:
+        AuthZ authZ = new ObjectFactory().createAuthZ();
+        authZ.setSequenceId( sequence );
+        authZ.setCreateTimestamp( getAttribute( le, CREATETIMESTAMP ) );
+        authZ.setCreatorsName( getAttribute( le, CREATORSNAME ) );
+        authZ.setEntryCSN( getAttribute( le, ENTRYCSN ) );
+        authZ.setEntryDN( getAttribute( le, ENTRYDN ) );
+        authZ.setEntryUUID( getAttribute( le, ENTRYUUID ) );
+        authZ.setHasSubordinates( getAttribute( le, HASSUBORDINATES ) );
+        authZ.setModifiersName( getAttribute( le, MODIFIERSNAME ) );
+        authZ.setModifyTimestamp( getAttribute( le, MODIFYTIMESTAMP ) );
+        authZ.setObjectClass( getAttribute( le, OBJECTCLASS ) );
+        authZ.setReqAuthzID( getAttribute( le, REQUAUTHZID ) );
+        authZ.setReqControls( getAttribute( le, REQCONTROLS ) );
+        authZ.setReqDN( getAttribute( le, REQDN ) );
+        authZ.setReqEnd( getAttribute( le, REQEND ) );
+        authZ.setReqResult( getAttribute( le, REQRESULT ) );
+        authZ.setReqSession( getAttribute( le, REQSESSION ) );
+        authZ.setReqStart( getAttribute( le, REQSTART ) );
+        authZ.setReqType( getAttribute( le, REQTYPE ) );
+        authZ.setStructuralObjectClass( getAttribute( le, STRUCTURALOBJECTCLASS ) );
+
+        // these attrs only on audit search OC:
+        authZ.setReqAttr( getAttribute( le, REQATTR ) );
+        authZ.setReqAttrsOnly( getAttribute( le, REQATTRSONLY ) );
+        authZ.setReqDerefAliases( getAttribute( le, REQDREFALIASES ) );
+        authZ.setReqEntries( getAttribute( le, REQENTRIES ) );
+        authZ.setReqFilter( getAttribute( le, REQFILTER ) );
+        authZ.setReqScope( getAttribute( le, REQSCOPE ) );
+        authZ.setReqSizeLimit( getAttribute( le, REQSIZELIMIT ) );
+        authZ.setReqTimeLimit( getAttribute( le, REQTIMELIMIT ) );
+
+        return authZ;
+    }
+
+
+    private Mod getModEntityFromLdapEntry( Entry le, long sequence ) throws LdapInvalidAttributeValueException
+    {
+        Mod mod = new ObjectFactory().createMod();
+        mod.setSequenceId( sequence );
+        mod.setObjectClass( getAttribute( le, OBJECTCLASS ) );
+        mod.setReqAuthzID( getAttribute( le, REQUAUTHZID ) );
+        mod.setReqDN( getAttribute( le, REQDN ) );
+        mod.setReqEnd( getAttribute( le, REQEND ) );
+        mod.setReqResult( getAttribute( le, REQRESULT ) );
+        mod.setReqSession( getAttribute( le, REQSESSION ) );
+        mod.setReqStart( getAttribute( le, REQSTART ) );
+        mod.setReqType( getAttribute( le, REQTYPE ) );
+        mod.setReqMod( getAttributes( le, REQMOD ) );
+
+        return mod;
+    }
+}
\ 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/apache/OrgUnitDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/OrgUnitDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/OrgUnitDAO.java
new file mode 100755
index 0000000..2641be5
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/OrgUnitDAO.java
@@ -0,0 +1,706 @@
+/*
+ *   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.apache;
+
+
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.OrgUnit;
+import org.apache.directory.fortress.core.rbac.PsoUtil;
+import org.apache.directory.fortress.core.rbac.UsoUtil;
+
+
+/**
+ * This class provides dataaccess to the OrgUnit datasets in LDAP.
+ * <p/>
+ * The OrgUnitDAO maintains the following structural and aux object classes:
+ * <h4>1. organizationalUnit Structural Object Class is used to store basic attributes like ou and description</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 2.5.6.5 NAME 'organizationalUnit'</code>
+ * <li> <code>DESC 'RFC2256: an organizational unit'</code>
+ * <li> <code>SUP top STRUCTURAL</code>
+ * <li> <code>MUST ou</code>
+ * <li> <code>MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $</code>
+ * <li> <code>x121Address $ registeredAddress $ destinationIndicator $</code>
+ * <li> <code>preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $</code>
+ * <li> <code>telephoneNumber $ internationaliSDNNumber $</code>
+ * <li> <code>facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $</code>
+ * <li> <code>postalAddress $ physicalDeliveryOfficeName $ st $ l $ description ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>2. ftOrgUnit Structural objectclass is used to store the OrgUnit internal id</h4>
+ * <ul>                                                              org.apache.directory.fortress.arbac.
+ * <li>  ------------------------------------------
+ * <li> <code> objectclass	( 1.3.6.1.4.1.38088.2.6</code>
+ * <li> <code>NAME 'ftOrgUnit'</code>
+ * <li> <code>DESC 'Fortress OrgUnit Class'</code>
+ * <li> <code>SUP organizationalunit</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST ( ftId ) )</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
+ * @created September 18, 2010
+ */
+public final class OrgUnitDAO extends ApacheDsDataProvider implements org.apache.directory.fortress.core.rbac.dao.OrgUnitDAO
+{
+    private static final String CLS_NM = OrgUnitDAO.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final String ORGUNIT_OBJECT_CLASS_NM = "ftOrgUnit";
+
+    private static final String ORGUNIT_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP, ORGUNIT_OBJECT_CLASS_NM, GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+    private static final String[] ORGUNIT_ATRS =
+        {
+            GlobalIds.FT_IID, GlobalIds.OU, GlobalIds.DESC, GlobalIds.PARENT_NODES
+    };
+
+    private static final String[] ORGUNIT_ATR =
+        {
+            GlobalIds.OU
+    };
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    public final OrgUnit create( OrgUnit entity ) throws CreateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        try
+        {
+            Entry entry = new DefaultEntry( dn );
+            entry.add( GlobalIds.OBJECT_CLASS, ORGUNIT_OBJ_CLASS );
+            entity.setId();
+            entry.add( GlobalIds.FT_IID, entity.getId() );
+
+            if ( entity.getDescription() != null && entity.getDescription().length() > 0 )
+            {
+                entry.add( GlobalIds.DESC, entity.getDescription() );
+            }
+
+            // organizational name requires OU attribute:
+            entry.add( GlobalIds.OU, entity.getName() );
+
+            // These multi-valued attributes are optional.  The utility function will return quietly if no items are loaded into collection:
+            loadAttrs( entity.getParents(), entry, GlobalIds.PARENT_NODES );
+
+            ld = getAdminConnection();
+            add( ld, entry, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "create orgUnit name [" + entity.getName() + "] type [" + entity.getType()
+                + "] root [" + dn + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_ADD_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_ADD_FAILED_USER;
+
+            }
+
+            throw new CreateException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    public final OrgUnit update( OrgUnit entity ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            if ( entity.getDescription() != null && entity.getDescription().length() > 0 )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.DESC, entity.getDescription() ) );
+            }
+
+            loadAttrs( entity.getParents(), mods, GlobalIds.PARENT_NODES );
+
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods, entity );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "update orgUnit name [" + entity.getName() + "] type [" + entity.getType()
+                + "] root [" + dn + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_UPDATE_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_UPDATE_FAILED_USER;
+            }
+
+            throw new UpdateException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    public final void deleteParent( OrgUnit entity ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        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 orgUnit name [" + entity.getName() + "] type [" + entity.getType()
+                + "] root [" + dn + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_REMOVE_PARENT_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_REMOVE_PARENT_FAILED_USER;
+            }
+
+            throw new UpdateException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.RemoveException
+     *
+     */
+    public final OrgUnit remove( OrgUnit entity ) throws RemoveException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, dn, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove orgUnit name [" + entity.getName() + "] type [" + entity.getType()
+                + "] root [" + dn + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_DELETE_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_DELETE_FAILED_USER;
+            }
+
+            throw new RemoveException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final OrgUnit findByKey( OrgUnit entity ) throws FinderException
+    {
+        OrgUnit oe = null;
+        LdapConnection ld = null;
+        String dn = getDn( entity );
+
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, dn, ORGUNIT_ATRS );
+
+            if ( findEntry == null )
+            {
+                String warning = "findByKey orgUnit name [" + entity.getName() + "] type ["
+                    + entity.getType() + "] COULD NOT FIND ENTRY for dn [" + dn + "]";
+                int errCode;
+
+                if ( entity.getType() == OrgUnit.Type.PERM )
+                {
+                    errCode = GlobalErrIds.ORG_NOT_FOUND_PERM;
+                }
+                else
+                {
+                    errCode = GlobalErrIds.ORG_NOT_FOUND_USER;
+                }
+
+                throw new FinderException( errCode, warning );
+            }
+
+            oe = getEntityFromLdapEntry( findEntry, 0, entity.getContextId() );
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "findByKey orgUnit name [" + entity.getName() + "] type ["
+                + entity.getType() + "] COULD NOT FIND ENTRY for dn [" + dn + "]";
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_NOT_FOUND_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_NOT_FOUND_USER;
+            }
+            throw new FinderException( errCode, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "findByKey orgUnitName [" + entity.getName() + "] type [" + entity.getType()
+                + "] dn [" + dn + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_READ_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_READ_FAILED_USER;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return oe;
+    }
+
+
+    /**
+     * @param orgUnit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<OrgUnit> findOrgs( OrgUnit orgUnit ) throws FinderException
+    {
+        List<OrgUnit> orgUnitList = new ArrayList<>();
+        LdapConnection ld = null;
+        String orgUnitRoot = getOrgRoot( orgUnit );
+
+        try
+        {
+            String searchVal = encodeSafeText( orgUnit.getName(), GlobalIds.ROLE_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + ORGUNIT_OBJECT_CLASS_NM + ")("
+                + GlobalIds.OU + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, orgUnitRoot,
+                SearchScope.ONELEVEL, filter, ORGUNIT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                orgUnitList
+                    .add( getEntityFromLdapEntry( searchResults.getEntry(), sequence++, orgUnit.getContextId() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findOrgs search val [" + orgUnit.getName() + "] type [" + orgUnit.getType()
+                + "] root [" + orgUnitRoot + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( orgUnit.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_SEARCH_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_SEARCH_FAILED_USER;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findOrgs search val [" + orgUnit.getName() + "] type [" + orgUnit.getType()
+                + "] root [" + orgUnitRoot + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( orgUnit.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_SEARCH_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_SEARCH_FAILED_USER;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return orgUnitList;
+    }
+
+
+    /**
+     *
+     * @param orgUnit
+     * @return
+     * @throws FinderException
+     */
+    public final Set<String> getOrgs( OrgUnit orgUnit ) throws FinderException
+    {
+        Set<String> ouSet = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        LdapConnection ld = null;
+        String orgUnitRoot = getOrgRoot( orgUnit );
+
+        try
+        {
+            String filter = "(objectclass=" + ORGUNIT_OBJECT_CLASS_NM + ")";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, orgUnitRoot,
+                SearchScope.ONELEVEL, filter, ORGUNIT_ATR, false, GlobalIds.BATCH_SIZE );
+
+            while ( searchResults.next() )
+            {
+                ouSet.add( getAttribute( searchResults.getEntry(), GlobalIds.OU ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "getOrgs type [" + orgUnit.getType() + "] root [" + orgUnitRoot
+                + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( orgUnit.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_GET_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_GET_FAILED_USER;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "getOrgs type [" + orgUnit.getType() + "] root [" + orgUnitRoot
+                + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( orgUnit.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_GET_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_GET_FAILED_USER;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return ouSet;
+    }
+
+
+    /**
+      *
+      * @param orgUnit
+      * @return
+      * @throws FinderException
+      */
+    public final List<Graphable> getAllDescendants( OrgUnit orgUnit ) throws FinderException
+    {
+        String orgUnitRoot = getOrgRoot( orgUnit );
+        String[] DESC_ATRS =
+            { GlobalIds.OU, GlobalIds.PARENT_NODES };
+        List<Graphable> descendants = new ArrayList<>();
+        LdapConnection ld = null;
+        String filter = null;
+
+        try
+        {
+            filter = GlobalIds.FILTER_PREFIX + ORGUNIT_OBJECT_CLASS_NM + ")("
+                + GlobalIds.PARENT_NODES + "=*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, orgUnitRoot,
+                SearchScope.ONELEVEL, filter, DESC_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                descendants.add( unloadDescendants( searchResults.getEntry(), sequence++, orgUnit.getContextId() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "getAllDescendants filter [" + filter + "] caught LdapException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "getAllDescendants filter [" + filter + "] caught LdapException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return descendants;
+    }
+
+
+    /**
+     * @param orgUnit
+     * @return
+     */
+    private String getDn( OrgUnit orgUnit )
+    {
+        String dn = null;
+
+        switch ( orgUnit.type )
+        {
+            case USER:
+                dn = GlobalIds.OU + "=" + orgUnit.getName() + ","
+                    + getRootDn( orgUnit.getContextId(), GlobalIds.OSU_ROOT );
+                break;
+
+            case PERM:
+                dn = GlobalIds.OU + "=" + orgUnit.getName() + ","
+                    + getRootDn( orgUnit.getContextId(), GlobalIds.PSU_ROOT );
+                break;
+
+            default:
+                String warning = "getDn invalid type";
+                LOG.warn( warning );
+                break;
+        }
+
+        return dn;
+    }
+
+
+    /**
+     *
+     * @param orgUnit
+     * @return
+     */
+    private String getOrgRoot( OrgUnit orgUnit )
+    {
+        String dn = null;
+
+        switch ( orgUnit.type )
+        {
+            case USER:
+                dn = getRootDn( orgUnit.getContextId(), GlobalIds.OSU_ROOT );
+                break;
+
+            case PERM:
+                dn = getRootDn( orgUnit.getContextId(), GlobalIds.PSU_ROOT );
+                break;
+
+            default:
+                String warning = "getOrgRootDn invalid type";
+                LOG.warn( warning );
+                break;
+        }
+
+        return dn;
+    }
+
+
+    /**
+    *
+    * @param le
+    * @param sequence
+    * @param contextId
+    * @return
+     * @throws LdapInvalidAttributeValueException 
+    * @throws LdapException
+    */
+    private Graphable unloadDescendants( Entry le, long sequence, String contextId )
+        throws LdapInvalidAttributeValueException
+    {
+        OrgUnit entity = new ObjectFactory().createOrgUnit();
+        entity.setSequenceId( sequence );
+        entity.setName( getAttribute( le, GlobalIds.OU ) );
+        entity.setParents( getAttributeSet( le, GlobalIds.PARENT_NODES ) );
+
+        return entity;
+    }
+
+
+    /**
+     *
+     * @param le
+     * @param sequence
+     * @param contextId
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     * @throws LdapException
+     */
+    private OrgUnit getEntityFromLdapEntry( Entry le, long sequence, String contextId )
+        throws LdapInvalidAttributeValueException
+    {
+        OrgUnit entity = new ObjectFactory().createOrgUnit();
+        entity.setSequenceId( sequence );
+        entity.setId( getAttribute( le, GlobalIds.FT_IID ) );
+        entity.setName( getAttribute( le, GlobalIds.OU ) );
+        entity.setDescription( getAttribute( le, GlobalIds.DESC ) );
+        String dn = le.getDn().getName();
+
+        if ( dn.contains( getRootDn( contextId, GlobalIds.PSU_ROOT ) ) )
+        {
+            entity.setType( OrgUnit.Type.PERM );
+            //entity.setParents(PsoUtil.getParents(entity.getName().toUpperCase(), contextId));
+            entity.setChildren( PsoUtil.getChildren( entity.getName().toUpperCase(), contextId ) );
+        }
+        else if ( dn.contains( getRootDn( contextId, GlobalIds.OSU_ROOT ) ) )
+        {
+            entity.setType( OrgUnit.Type.USER );
+            //entity.setParents(UsoUtil.getParents(entity.getName().toUpperCase(), contextId));
+            entity.setChildren( UsoUtil.getChildren( entity.getName().toUpperCase(), contextId ) );
+        }
+
+        entity.setParents( getAttributeSet( le, GlobalIds.PARENT_NODES ) );
+
+        return entity;
+    }
+}
\ No newline at end of file


[06/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rest/DelAdminMgrRestImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/DelAdminMgrRestImpl.java b/src/main/java/org/apache/directory/fortress/core/rest/DelAdminMgrRestImpl.java
new file mode 100644
index 0000000..a8b5ec9
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/DelAdminMgrRestImpl.java
@@ -0,0 +1,1291 @@
+/*
+ *   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.rest;
+
+import org.apache.directory.fortress.core.DelAdminMgr;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.AdminRoleRelationship;
+import org.apache.directory.fortress.core.rbac.Manageable;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.OrgUnitRelationship;
+import org.apache.directory.fortress.core.rbac.PermGrant;
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * This class implements the ARBAC02 DelAdminMgr interface for performing policy administration of Fortress ARBAC entities
+ * using HTTP access to En Masse REST server.
+ * These APIs map directly to similar named APIs specified by ARBAC02 functions.  The ARBAC Functional specification describes delegated administrative
+ * operations for the creation and maintenance of ARBAC element sets and relations.  Delegated administrative review functions for performing administrative queries
+ * and system functions for creating and managing ARBAC attributes on user sessions and making delegated administrative access control decisions.
+ * This class is NOT thread safe.
+ * <h3>Administrative Role Based Access Control (ARBAC)</h3>
+ * <img src="../doc-files/ARbac.png">
+ * <p/>
+ * Fortress fully supports the Oh/Sandhu/Zhang ARBAC02 model for delegated administration.  ARBAC provides large enterprises the capability to delegate administrative authority to users that reside outside of the security admin group.
+ * Decentralizing administration helps because it provides security provisioning capability to work groups without sacrificing regulations for accountability or traceability.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public final class DelAdminMgrRestImpl extends Manageable implements DelAdminMgr
+{
+    private static final String CLS_NM = DelAdminMgrRestImpl.class.getName();
+
+    /**
+     * This command creates a new admin role. The command is valid if and only if the new admin role is not
+     * already a member of the ADMIN ROLES data set. The ADMIN ROLES data set is updated.
+     * Initially, no user or permission is assigned to the new role.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of the new AdminRole being targeted for addition to LDAP</li>
+     * </ul>
+     * <p/>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#description} - contains any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#osPs} * - multi-occurring attribute used to set associations to existing PERMS OrgUnits</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#osUs} * - multi-occurring attribute used to set associations to existing USERS OrgUnits</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginRange} - contains the name of an existing RBAC Role that represents the lowest role in hierarchy that administrator (whoever has this AdminRole activated) controls</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endRange} - contains the name of an existing RBAC Role that represents that highest role in hierarchy that administrator may control</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginInclusive} - if 'true' the RBAC Role specified in beginRange is also controlled by the posessor of this AdminRole</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endInclusive} - if 'true' the RBAC Role specified in endRange is also controlled by the administratrator</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginTime} - HHMM - determines begin hour adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endTime} - HHMM - determines end hour adminRole may be activated into user's ARBAC session.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginDate} - YYYYMMDD - determines date when adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endDate} - YYYYMMDD - indicates latest date adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's ARBAC session</li>
+     * </ul>
+     *
+     * @param role Contains role name and description.
+     * @return Override contains reference to entity added.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public AdminRole addRole(AdminRole role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ARLE_NULL, CLS_NM + ".addRole");
+        AdminRole retRole;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retRole = (AdminRole) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRole;
+    }
+
+    /**
+     * This command deletes an existing admin role from the ARBAC database. The command is valid
+     * if and only if the role to be deleted is a member of the ADMIN ROLES data set.  This command will
+     * also deassign role from all users.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of the new AdminRole being targeted for removal</li>
+     * </ul>
+     * <p/>
+     *
+     * @param role Contains role name.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteRole(AdminRole role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ARLE_NULL, CLS_NM + ".deleteRole");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * Method will update an AdminRole entity in the directory.  The role must exist in directory prior to this call.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains the name of the new AdminRole being targeted for updating</li>
+     * </ul>
+     * <p/>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#description} - contains any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#osPs} * - multi-occurring attribute used to set associations to existing PERMS OrgUnits</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#osUs} * - multi-occurring attribute used to set associations to existing USERS OrgUnits</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginRange} - contains the name of an existing RBAC Role that represents the lowest role in hierarchy that administrator (whoever has this AdminRole activated) controls</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endRange} - contains the name of an existing RBAC Role that represents that highest role in hierarchy that administrator may control</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginInclusive} - if 'true' the RBAC Role specified in beginRange is also controlled by the posessor of this AdminRole</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endInclusive} - if 'true' the RBAC Role specified in endRange is also controlled by the administratrator</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginTime} - HHMM - determines begin hour adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endTime} - HHMM - determines end hour adminRole may be activated into user's ARBAC session.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginDate} - YYYYMMDD - determines date when adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endDate} - YYYYMMDD - indicates latest date adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's ARBAC session</li>
+     * </ul>
+     *
+     * @param role Contains role name and new description.
+     * @return Override contains reference to entity updated.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Description of the Exception
+     */
+    @Override
+    public AdminRole updateRole(AdminRole role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ARLE_NULL, CLS_NM + ".updateRole");
+        AdminRole retRole;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retRole = (AdminRole) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRole;
+    }
+
+
+    /**
+     * 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>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#name} - contains the name for already existing AdminRole to be assigned</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#beginTime} - HHMM - determines begin hour AdminRole may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#endTime} - HHMM - determines end hour AdminRole may be activated into user's RBAC session.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#beginDate} - YYYYMMDD - determines date when AdminRole may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#endDate} - YYYYMMDD - indicates latest date AdminRole may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's ARBAC session</li>
+     * </ul>
+     *
+     * @param uAdminRole entity contains {@link org.apache.directory.fortress.core.rbac.User#userId} and {@link AdminRole#name} and optional {@code Constraints}.
+     * @throws SecurityException in the event data error in user or role objects or system error.
+     */
+    @Override
+    public void assignUser(UserAdminRole uAdminRole)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(uAdminRole, GlobalErrIds.ARLE_NULL, CLS_NM + ".assignUser");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(uAdminRole);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_ASGN);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+
+    /**
+     * 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.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#name} - contains the name for already existing AdminRole to be deassigned</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     *
+     * @param uAdminRole entity contains {@link org.apache.directory.fortress.core.rbac.User#userId} and {@link AdminRole#name}.
+     * @throws SecurityException - in the event data error in user or role objects or system error.
+     */
+    @Override
+    public void deassignUser(UserAdminRole uAdminRole)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(uAdminRole, GlobalErrIds.ARLE_NULL, CLS_NM + ".deassignUser");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(uAdminRole);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_DEASGN);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+
+    /**
+     * Commands adds a new OrgUnit entity to OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new USERS or PERMS OrgUnit to be added</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit contains reference to entity added.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public OrgUnit add(OrgUnit entity)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(entity, GlobalErrIds.ORG_NULL, CLS_NM + ".addOU");
+        OrgUnit retOrg;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(entity);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ORG_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retOrg = (OrgUnit) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retOrg;
+    }
+
+    /**
+     * Commands updates existing OrgUnit entity to OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new USERS or PERMS OrgUnit to be updated</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link OrgUnit#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit contains reference to entity updated.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public OrgUnit update(OrgUnit entity)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(entity, GlobalErrIds.ORG_NULL, CLS_NM + ".updateOU");
+        OrgUnit retOrg;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(entity);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ORG_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retOrg = (OrgUnit) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retOrg;
+    }
+
+    /**
+     * Commands deletes existing OrgUnit entity to OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new USERS or PERMS OrgUnit to be removed</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit contains reference to entity removed.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public OrgUnit delete(OrgUnit entity)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(entity, GlobalErrIds.ORG_NULL, CLS_NM + ".deleteOU");
+        OrgUnit retOrg;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(entity);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ORG_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retOrg = (OrgUnit) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retOrg;
+    }
+
+
+    /**
+     * This command creates a new orgunit child, and inserts it in the orgunit hierarchy as an immediate descendant of
+     * the existing orgunit parent.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The child orgunit is not a member of the ORGUNITS data set.
+     * <li> The parent orgunit is a member of the ORGUNITS data set.
+     * </ul>
+     * </p>
+     * <p> This method:
+     * <ul>
+     * <li> Adds new orgunit.
+     * <li> Assigns orgunit relationship between new child and pre-existing parent.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new OrgUnit to be child</li>
+     * </ul>
+     * <h4>optional parameters child</h4>
+     * <ul>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#description} - maps to description attribute on organizationalUnit object class for new child</li>
+     * </ul>
+     *
+     * @param parent This entity must be present in ORGUNIT data set.  Success will add rel with child.
+     * @param child  This entity must not be present in ORGUNIT data set.  Success will add the new entity to ORGUNIT data set.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addDescendant(OrgUnit parent, OrgUnit child)
+        throws SecurityException
+    {
+        String methodName = "addDescendantOU";
+        VUtil.assertNotNull(parent, GlobalErrIds.ORG_PARENT_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(parent.getType(), GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(child, GlobalErrIds.ORG_CHILD_NULL, CLS_NM + "." + methodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        OrgUnitRelationship relationship = new OrgUnitRelationship();
+        relationship.setParent(parent);
+        relationship.setChild(child);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ORG_DESC);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+
+    /**
+     * This command creates a new orgunit parent, and inserts it in the orgunit hierarchy as an immediate ascendant of
+     * the existing child orgunit.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The parent is not a member of the ORGUNITS data set.
+     * <li> The child is a member of the ORGUNITS data set.
+     * </ul>
+     * </p>
+     * <p> This method:
+     * <ul>
+     * <li> Adds new orgunit.
+     * <li> Assigns orgunit relationship between new parent and pre-existing child.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be parent</li>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>child - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new OrgUnit to be child</li>
+     * </ul>
+     * <h4>optional parameters child</h4>
+     * <ul>
+     * <li>child - {@link org.apache.directory.fortress.core.rbac.OrgUnit#description} - maps to description attribute on organizationalUnit object class for new child</li>
+     * </ul>
+     *
+     * @param parent completion of op assigns new child relationship with child orgunit.
+     * @param child  completion of op assigns new parent relationship with parent orgunit.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addAscendant(OrgUnit child, OrgUnit parent)
+        throws SecurityException
+    {
+        String methodName = "addAscendantOU";
+        VUtil.assertNotNull(parent, GlobalErrIds.ORG_PARENT_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(parent.getType(), GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        OrgUnitRelationship relationship = new OrgUnitRelationship();
+        relationship.setParent(parent);
+        relationship.setChild(child);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ORG_ASC);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command establishes a new immediate inheritance relationship with parent orgunit <<-- child orgunit
+     * <p/>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The parent and child are members of the ORGUNITS data set.
+     * <li> The parent is not an immediate ascendant of child.
+     * <li> The child does not properly inherit parent (in order to avoid cycle creation).
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be parent</li>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>child - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be child</li>
+     * </ul>
+     *
+     * @param parent completion of op deassigns child relationship with child orgunit.
+     * @param child  completion of op deassigns parent relationship with parent orgunit.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addInheritance(OrgUnit parent, OrgUnit child)
+        throws SecurityException
+    {
+        String methodName = "addInheritanceOU";
+        VUtil.assertNotNull(parent, GlobalErrIds.ORG_PARENT_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(parent.getType(), GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(child, GlobalErrIds.ORG_CHILD_NULL, CLS_NM + "." + methodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        OrgUnitRelationship relationship = new OrgUnitRelationship();
+        relationship.setParent(parent);
+        relationship.setChild(child);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ORG_ADDINHERIT);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command deletes an existing immediate inheritance relationship parent <<-- child.
+     * <p/>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The orgunits parent and child are members of the ORGUNITS data set.
+     * <li> The parent is an immediate ascendant of child.
+     * <li> The new inheritance relation is computed as the reflexive-transitive closure of the immediate inheritance
+     * relation resulted after deleting the relationship parent <<-- child.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to remove as parent</li>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>child - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to remove as child</li>
+     * </ul>
+     *
+     * @param parent completion of op removes child relationship with childRole.
+     * @param child  completion of op removes parent relationship with parentRole.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteInheritance(OrgUnit parent, OrgUnit child)
+        throws SecurityException
+    {
+        String methodName = "deleteInheritanceOU";
+        VUtil.assertNotNull(parent, GlobalErrIds.ORG_PARENT_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(parent.getType(), GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(child, GlobalErrIds.ORG_CHILD_NULL, CLS_NM + "." + methodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        OrgUnitRelationship relationship = new OrgUnitRelationship();
+        relationship.setParent(parent);
+        relationship.setChild(child);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ORG_DELINHERIT);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+
+    /**
+     * This command creates a new role childRole, and inserts it in the role hierarchy as an immediate descendant of
+     * the existing role parentRole. The command is valid if and only if childRole is not a member of the ADMINROLES data set,
+     * and parentRole is a member of the ADMINROLES data set.
+     * <p/>
+     * This method:
+     * 1 - Adds new role.
+     * 2 - Assigns role relationship between new childRole and pre-existing parentRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing Role to be parent</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of new Role to be child</li>
+     * </ul>
+     * <h4>optional parameters childRole</h4>
+     * <ul>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#description} - maps to description attribute on organizationalRole object class for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginTime} - HHMM - determines begin hour role may be activated into user's session for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endTime} - HHMM - determines end hour role may be activated into user's session for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginDate} - YYYYMMDD - determines date when role may be activated into user's session for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endDate} - YYYYMMDD - indicates latest date role may be activated into user's session for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's session for new child</li>
+     * </ul>
+     *
+     * @param parentRole This entity must be present in ADMINROLES data set.  Success will add role rel with childRole.
+     * @param childRole  This entity must not be present in ADMINROLES data set.  Success will add the new role entity to ADMINROLES data set.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addDescendant(AdminRole parentRole, AdminRole childRole)
+        throws SecurityException
+    {
+        String methodName = "addDescendantRole";
+        VUtil.assertNotNull(parentRole, GlobalErrIds.ARLE_PARENT_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(childRole, GlobalErrIds.ARLE_CHILD_NULL, CLS_NM + "." + methodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        AdminRoleRelationship relationship = new AdminRoleRelationship();
+        relationship.setParent(parentRole);
+        relationship.setChild(childRole);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_DESC);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command creates a new role parentRole, and inserts it in the role hierarchy as an immediate ascendant of
+     * the existing role childRole. The command is valid if and only if parentRole is not a member of the ROLES data set,
+     * and childRole is a member of the ROLES data set.
+     * This method:
+     * 1 - Adds new role.
+     * 2 - Assigns role relationship between new parentRole and pre-existing childRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing Role to be child</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of new Role to be added as parent</li>
+     * </ul>
+     * <h4>optional parameters parentRole</h4>
+     * <ul>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#description} - maps to description attribute on organizationalRole object class for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginTime} - HHMM - determines begin hour role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endTime} - HHMM - determines end hour role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginDate} - YYYYMMDD - determines date when role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endDate} - YYYYMMDD - indicates latest date role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's session for new parent</li>
+     * </ul>
+     *
+     * @param parentRole completion of op assigns new child relationship with childRole.
+     * @param childRole  completion of op assigns new parent relationship with parentRole.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addAscendant(AdminRole childRole, AdminRole parentRole)
+        throws SecurityException
+    {
+        String methodName = "addAscendantRole";
+        VUtil.assertNotNull(parentRole, GlobalErrIds.ARLE_PARENT_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(childRole, GlobalErrIds.ARLE_CHILD_NULL, CLS_NM + "." + methodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        AdminRoleRelationship relationship = new AdminRoleRelationship();
+        relationship.setParent(parentRole);
+        relationship.setChild(childRole);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_ASC);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command establishes a new immediate inheritance relationship parentRole <<-- childRole between existing
+     * roles parentRole, childRole. The command is valid if and only if parentRole and childRole are members of the ROLES data
+     * set, parentRole is not an immediate ascendant of childRole, and childRole does not properly inherit parentRole (in order to
+     * avoid cycle creation).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing AdminRole to be parent</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing AdminRole to be child</li>
+     * </ul>
+     *
+     * @param parentRole completion of op deassigns child relationship with childRole.
+     * @param childRole  completion of op deassigns parent relationship with parentRole.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addInheritance(AdminRole parentRole, AdminRole childRole)
+        throws SecurityException
+    {
+        String methodName = "addInheritanceRole";
+        VUtil.assertNotNull(parentRole, GlobalErrIds.ARLE_PARENT_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(childRole, GlobalErrIds.ARLE_CHILD_NULL, CLS_NM + "." + methodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        AdminRoleRelationship relationship = new AdminRoleRelationship();
+        relationship.setParent(parentRole);
+        relationship.setChild(childRole);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_ADDINHERIT);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command deletes an existing immediate inheritance relationship parentRole <<-- childRole. The command is
+     * valid if and only if the roles parentRole and childRole are members of the ROLES data set, and parentRole is an
+     * immediate ascendant of childRole. The new inheritance relation is computed as the reflexive-transitive
+     * closure of the immediate inheritance relation resulted after deleting the relationship parentRole <<-- childRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing AdminRole to remove as parent</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing AdminRole to remove as child</li>
+     * </ul>
+     *
+     * @param parentRole completion of op removes child relationship with childRole.
+     * @param childRole  completion of op removes parent relationship with parentRole.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteInheritance(AdminRole parentRole, AdminRole childRole)
+        throws SecurityException
+    {
+        String methodName = "deleteInheritanceRole";
+        VUtil.assertNotNull(parentRole, GlobalErrIds.ARLE_PARENT_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(childRole, GlobalErrIds.ARLE_CHILD_NULL, CLS_NM + "." + methodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        AdminRoleRelationship relationship = new AdminRoleRelationship();
+        relationship.setParent(parentRole);
+        relationship.setChild(childRole);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_DELINHERIT);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This method will add an administrative permission operation to an existing permission object which resides under {@code ou=AdminPerms,ou=ARBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may have {@link org.apache.directory.fortress.core.rbac.AdminRole} or {@link org.apache.directory.fortress.core.rbac.User} associations.  The target {@link org.apache.directory.fortress.core.rbac.Permission} must not exist prior to calling.
+     * A Fortress Permission instance exists in a hierarchical, one-many relationship between its parent and itself as stored in ldap tree: ({@link org.apache.directory.fortress.core.rbac.PermObj}*->{@link org.apache.directory.fortress.core.rbac.Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the name of existing object being targeted for the permission add</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the name of new permission operation being added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target along with optional other attributes..
+     * @return copy of Permission entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public Permission addPermission(Permission perm)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".addPermission");
+        Permission retPerm;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        perm.setAdmin(true);
+        request.setEntity(perm);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPerm = (Permission) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPerm;
+    }
+
+    /**
+     * This method will update administrative permission operation pre-existing in target directory under {@code ou=AdminPerms,ou=ARBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may also contain {@link org.apache.directory.fortress.core.rbac.AdminRole} or {@link org.apache.directory.fortress.core.rbac.User} associations to add or remove using this function.
+     * The perm operation must exist before making this call.  Only non-null attributes will be updated.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the name of existing object being targeted for the permission update</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the name of existing permission operation being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target and any optional data to update.  Null or empty attributes will be ignored.
+     * @return copy of permOp entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public Permission updatePermission(Permission perm)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".updatePermission");
+        Permission retPerm;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        perm.setAdmin(true);
+        request.setEntity(perm);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPerm = (Permission) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPerm;
+    }
+
+    /**
+     * This method will remove administrative permission operation entity from permission object. A Fortress permission is (object->operation).
+     * The perm operation must exist before making this call.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the name of existing object being targeted for the permission delete</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the name of existing permission operation being removed</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public void deletePermission(Permission perm)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".deletePermission");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        perm.setAdmin(true);
+        request.setEntity(perm);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This method will add administrative permission object to admin perms container in directory. The perm object must not exist before making this call.
+     * A {@link org.apache.directory.fortress.core.rbac.PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link org.apache.directory.fortress.core.rbac.PermObj}*->{@link org.apache.directory.fortress.core.rbac.Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#objName} - contains the name of new object being added</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#description} - any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#type} - contains any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link org.apache.directory.fortress.core.rbac.PermObj#objName} and {@link org.apache.directory.fortress.core.rbac.PermObj#ou}.  The other attributes are optional.
+     * @return copy of permObj entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public PermObj addPermObj(PermObj pObj)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(pObj, GlobalErrIds.PERM_OBJECT_NULL, CLS_NM + ".addPermObj");
+        PermObj retObj;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        pObj.setAdmin(true);
+        request.setEntity(pObj);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.OBJ_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retObj = (PermObj) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retObj;
+    }
+
+    /**
+     * This method will update administrative permission object in perms container in directory.  The perm object must exist before making this call.
+     * A {@link org.apache.directory.fortress.core.rbac.PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link org.apache.directory.fortress.core.rbac.PermObj}*->{@link org.apache.directory.fortress.core.rbac.Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of existing object being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * <li>{@link PermObj#description} - any safe text</li>
+     * <li>{@link PermObj#type} - contains any safe text</li>
+     * <li>{@link PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link PermObj#objName}. Only non-null attributes will be updated.
+     * @return copy of newly updated permObj entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public PermObj updatePermObj(PermObj pObj)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(pObj, GlobalErrIds.PERM_OBJECT_NULL, CLS_NM + ".updatePermObj");
+        PermObj retObj;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        pObj.setAdmin(true);
+        request.setEntity(pObj);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.OBJ_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retObj = (PermObj) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retObj;
+    }
+
+    /**
+     * This method will remove administrative permission object from perms container in directory.  This method will also remove
+     * in associated permission objects that are attached to this object.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#objName} - contains the name of existing object targeted for removal</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link org.apache.directory.fortress.core.rbac.PermObj#objName} of object targeted for removal.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public void deletePermObj(PermObj pObj)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(pObj, GlobalErrIds.PERM_OBJECT_NULL, CLS_NM + ".deletePermObj");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        pObj.setAdmin(true);
+        request.setEntity(pObj);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.OBJ_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command grants an AdminRole the administrative permission to perform an operation on an object to a role.
+     * The command is implemented by granting administrative permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * and the adminRole is a member of the ADMIN_ROLES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the object name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the operation name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the adminRole name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target.
+     * @param role must contains {@link org.apache.directory.fortress.core.rbac.AdminRole#name}.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void grantPermission(Permission perm, AdminRole role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".grantPermission");
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".grantPermission");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        PermGrant permGrant = new PermGrant();
+        permGrant.setAdmin(true);
+        permGrant.setObjName(perm.getObjName());
+        permGrant.setObjId(perm.getObjId());
+        permGrant.setOpName(perm.getOpName());
+        permGrant.setRoleNm(role.getName());
+        request.setEntity(permGrant);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_GRANT);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command revokes the administrative permission to perform an operation on an object from the set
+     * of permissions assigned to an AdminRole. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * the role is a member of the ADMIN_ROLES data set, and the permission is assigned to that AdminRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the object name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the operation name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the adminRole name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target.
+     * @param role must contains {@link org.apache.directory.fortress.core.rbac.AdminRole#name}.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void revokePermission(Permission perm, AdminRole role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".revokePermission");
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".revokePermission");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        PermGrant permGrant = new PermGrant();
+        permGrant.setAdmin(true);
+        permGrant.setObjName(perm.getObjName());
+        permGrant.setObjId(perm.getObjId());
+        permGrant.setOpName(perm.getOpName());
+        permGrant.setRoleNm(role.getName());
+        request.setEntity(permGrant);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_REVOKE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command grants a user the administrative permission to perform an operation on an object to a user.
+     * The command is implemented by granting administrative permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents an administrative permission,
+     * and the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the object name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the operation name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target.
+     * @param user must contain {@link org.apache.directory.fortress.core.rbac.User#userId} of target User entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void grantPermission(Permission perm, User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".grantPermissionUser");
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".grantPermissionUser");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        PermGrant permGrant = new PermGrant();
+        permGrant.setAdmin(true);
+        permGrant.setObjName(perm.getObjName());
+        permGrant.setObjId(perm.getObjId());
+        permGrant.setOpName(perm.getOpName());
+        permGrant.setUserId(user.getUserId());
+        request.setEntity(permGrant);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_GRANT);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command revokes the administrative permission to perform an operation on an object from the set
+     * of permissions assigned to a user. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents an administrative permission,
+     * the user is a member of the USERS data set, and the permission is assigned to that user.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the object name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the operation name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target.
+     * @param user must contain {@link org.apache.directory.fortress.core.rbac.User#userId} of target User entity.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void revokePermission(Permission perm, User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".revokePermission");
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".revokePermission");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        PermGrant permGrant = new PermGrant();
+        permGrant.setAdmin(true);
+        permGrant.setObjName(perm.getObjName());
+        permGrant.setObjId(perm.getObjId());
+        permGrant.setOpName(perm.getOpName());
+        permGrant.setUserId(user.getUserId());
+        request.setEntity(permGrant);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_REVOKE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rest/DelReviewMgrRestImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/DelReviewMgrRestImpl.java b/src/main/java/org/apache/directory/fortress/core/rest/DelReviewMgrRestImpl.java
new file mode 100644
index 0000000..c852ca2
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/DelReviewMgrRestImpl.java
@@ -0,0 +1,306 @@
+/*
+ *   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.rest;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.DelReviewMgr;
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.Manageable;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class implements the ARBAC02 DelReviewMgr interface for performing policy interrogation of provisioned Fortress ARBAC entities
+ * using HTTP access to En Masse REST server.
+ * These APIs map directly to similar named APIs specified by ARBAC02 functions.  The ARBAC Functional specification describes delegated administrative
+ * operations for the creation and maintenance of ARBAC element sets and relations.  Delegated administrative review functions for performing administrative queries
+ * and system functions for creating and managing ARBAC attributes on user sessions and making delegated administrative access control decisions.
+ * <h3>Administrative Role Based Access Control (ARBAC)</h3>
+ * <img src="../doc-files/ARbac.png">
+ * <p/>
+ * Fortress fully supports the Oh/Sandhu/Zhang ARBAC02 model for delegated administration.  ARBAC provides large enterprises the capability to delegate administrative authority to users that reside outside of the security admin group.
+ * Decentralizing administration helps because it provides security provisioning capability to work groups without sacrificing regulations for accountability or traceability.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ * <p/>
+ * This class is NOT thread safe iff "adminSession" instance variable is set
+ */
+public class DelReviewMgrRestImpl extends Manageable implements DelReviewMgr
+{
+    private static final String CLS_NM = DelReviewMgrRestImpl.class.getName();
+
+    /**
+     * Method reads Admin Role entity from the admin role container in directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains the name of the new AdminRole being targeted for read</li>
+     * </ul>
+     *
+     * @param role contains role name to be read.
+     * @return AdminRole entity that corresponds with role name.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          will be thrown if role not found or system error occurs.
+     */
+    @Override
+    public AdminRole readRole(AdminRole role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ARLE_NULL, CLS_NM + ".readRole");
+        AdminRole retRole;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_READ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retRole = (AdminRole) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRole;
+    }
+
+
+    /**
+     * Method will return a list of type Admin Role.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains all or some chars in the name of AdminRole(s) targeted for search</li>
+     * </ul>
+     *
+     * @param searchVal contains the all or some of the chars corresponding to admin role entities stored in directory.
+     * @return List of type AdminRole containing role entities that match the search criteria.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of system error.
+     */
+    @Override
+    public List<AdminRole> findRoles(String searchVal)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(searchVal, GlobalErrIds.ARLE_NM_NULL, CLS_NM + ".findRoles");
+        List<AdminRole> retRoles;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setValue(searchVal);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_SEARCH);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retRoles = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRoles;
+    }
+
+    /**
+     * This function returns the set of admin roles assigned to a given user. The function is valid if and
+     * only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains userId matching user entity stored in the directory.
+     * @return List of type UserAdminRole containing the user admin role data.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          If user not found or system error occurs.
+     */
+    @Override
+    public List<UserAdminRole> assignedRoles(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".assignedRoles");
+        List<UserAdminRole> retUserRoles;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ARLE_ASGNED);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUserRoles = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUserRoles;
+    }
+
+
+    /**
+     * This method returns the data set of all users who are assigned the given admin role.  This searches the User data set for
+     * AdminRole relationship.  This method does NOT search for hierarchical Admin Roles relationships.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains the name of AdminRole targeted for search</li>
+     * </ul>
+     *
+     * @param role contains the role name used to search the User data set.
+     * @return List of type User containing the users assigned data.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          If system error occurs.
+     */
+    @Override
+    public List<User> assignedUsers(AdminRole role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ARLE_NULL, CLS_NM + ".assignedUsers");
+        List<User> retUsers;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_ASGNED_ADMIN);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUsers = response.getEntities();
+            // do not return a null list to the caller:
+            if (retUsers == null)
+            {
+                retUsers = new ArrayList<>();
+            }
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUsers;
+    }
+
+
+    /**
+     * Commands reads existing OrgUnit entity from OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name associated with the OrgUnit object targeted for search.</li>
+     * <li>{@link OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit entity that corresponds with ou name and type.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public OrgUnit read(OrgUnit entity)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(entity, GlobalErrIds.ORG_NULL, CLS_NM + ".readOrgUnit");
+        OrgUnit retOrg;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(entity);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ORG_READ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retOrg = (OrgUnit) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retOrg;
+    }
+
+
+    /**
+     * Commands searches existing OrgUnit entities from OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type parameter on API.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>searchVal - contains some or all of the chars associated with the OrgUnit objects targeted for search.</li>
+     * </ul>
+     *
+     * @param type      either PERM or USER
+     * @param searchVal contains the leading chars that map to {@link OrgUnit#name} on existing OrgUnit(s) targeted for search.
+     * @return List of type OrgUnit containing the OrgUnit data.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *
+     */
+    @Override
+    public List<OrgUnit> search(OrgUnit.Type type, String searchVal)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(type, GlobalErrIds.ORG_TYPE_NULL, CLS_NM + ".search");
+        List<OrgUnit> retOrgs;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        OrgUnit inOrg = new OrgUnit(searchVal, type);
+        request.setEntity(inOrg);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ORG_SEARCH);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retOrgs = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retOrgs;
+    }
+}
\ 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/rest/FortRequest.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/FortRequest.java b/src/main/java/org/apache/directory/fortress/core/rest/FortRequest.java
new file mode 100644
index 0000000..49d3c57
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/FortRequest.java
@@ -0,0 +1,105 @@
+/*
+ *   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.rest;
+
+import org.apache.directory.fortress.core.rbac.FortEntity;
+import org.apache.directory.fortress.core.rbac.Session;
+
+import javax.xml.bind.annotation.*;
+
+/**
+ * This class is used to pass request data to En Masse server.
+ * </p>
+ * This class is not thread safe.
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "FortRequest")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "fortRequest", propOrder =
+{
+    "entity",
+    "value",
+    "limit",
+    "contextId",
+    "session"
+})
+public class FortRequest
+{
+    @XmlElement(nillable = true)
+    private FortEntity entity;
+    @XmlElement(nillable = true)
+    private Session session;
+    private String value;
+    @XmlElement(nillable = true)
+    private Integer limit;
+    private String contextId;
+
+    public FortEntity getEntity()
+    {
+        return entity;
+    }
+
+    public void setEntity(FortEntity entity)
+    {
+        this.entity = entity;
+    }
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+
+    public Session getSession()
+    {
+        return session;
+    }
+
+    public void setSession(Session session)
+    {
+        this.session = session;
+    }
+
+    public Integer getLimit()
+    {
+        return limit;
+    }
+
+    public void setLimit(Integer limit)
+    {
+        this.limit = limit;
+    }
+
+    public String getContextId()
+    {
+        return contextId;
+    }
+
+    public void setContextId(String contextId)
+    {
+        this.contextId = contextId;
+    }
+}
+


[12/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/PermDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/PermDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/PermDAO.java
new file mode 100755
index 0000000..afdc79a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/PermDAO.java
@@ -0,0 +1,1405 @@
+/*
+ *   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.unboundid;
+
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+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.UnboundIdDataProvider;
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.AdminRoleUtil;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.RoleUtil;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttribute;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModification;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModificationSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPSearchResults;
+
+
+/**
+ * Permission data access class for LDAP.
+ * <p/>
+ * This DAO class maintains the PermObj and Permission entities.
+ * <h3>The Fortress PermObj Entity Class is a composite of 3 LDAP Schema object classes</h2>
+ * <h4>PermObj Base - ftObject STRUCTURAL Object Class is used to store object name, id and type variables on target entity.</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass	( 1.3.6.1.4.1.38088.2.2</code>
+ * <li> <code>NAME 'ftObject'</code>
+ * <li> <code>DESC 'Fortress Permission Object Class'</code>
+ * <li> <code>SUP organizationalunit</code>                                              GlobalIds
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST (</code>
+ * <li> <code>ftId $ ftObjNm ) </code>
+ * <li> <code>MAY ( ftType ) )  </code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>PermObj - 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>PermObj - 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>
+ * <h3>The Fortress Permission Entity Class is composite of 3 LDAP Schema object classes</h3>
+ * The Permission entity extends a single OpenLDAP standard structural object class, 'organizationalRole' with
+ * one extension structural class, ftOperation,  and two auxiliary object classes, ftProperties, ftMods.
+ * The following 4 LDAP object classes will be mapped into this entity:
+ * <h4>Permission Base - 'ftOperation' STRUCTURAL Object Class is assigned roles and/or users which grants permissions which can be later checked</h4>
+ * using either 'checkAccess' or 'sessionPermissions APIs both methods that reside in the 'AccessMgrImpl' class.
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass	( 1.3.6.1.4.1.38088.2.3</code>
+ * <li> <code>NAME 'ftOperation'</code>
+ * <li> <code>DESC 'Fortress Permission Operation Object Class'</code>
+ * <li> <code>SUP organizationalrole</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST ( ftId $ ftPermName $</code>
+ * <li> <code>ftObjNm $ ftOpNm )</code>
+ * <li> <code>MAY ( ftRoles $ ftUsers $</code>
+ * <li> <code> ftObjId $ ftType) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>Permission Aux - ftProperties AUXILIARY Object Class is used to store optional client or otherwise custom 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>Permission Aux - 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>
+ * This class is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public final class PermDAO extends UnboundIdDataProvider implements org.apache.directory.fortress.core.rbac.dao.PermDAO
+{
+    /*
+          *  *************************************************************************
+          *  **  OpenAccessMgr PERMISSION STATICS
+          *  ************************************************************************
+          */
+    private static final String TYPE = "ftType";
+    private static final String PERM_OBJ_OBJECT_CLASS_NAME = "ftObject";
+    private static final String PERM_OP_OBJECT_CLASS_NAME = "ftOperation";
+
+    private static final String PERM_OBJ_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP,
+            "organizationalunit",
+            PERM_OBJ_OBJECT_CLASS_NAME,
+            GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME,
+            GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+
+    private static final String PERM_OP_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP,
+            "organizationalrole",
+            PERM_OP_OBJECT_CLASS_NAME,
+            GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME,
+            GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+
+    private static final String PERM_NAME = "ftPermName";
+    private static final String POBJ_ID = "ftObjId";
+    private static final String ROLES = "ftRoles";
+    private static final String USERS = "ftUsers";
+    private static final String[] PERMISSION_OP_ATRS =
+        {
+            GlobalIds.FT_IID, PERM_NAME, GlobalIds.POBJ_NAME, GlobalIds.POP_NAME, GlobalIds.DESC, GlobalIds.OU,
+            POBJ_ID, TYPE, ROLES, USERS, GlobalIds.PROPS
+    };
+
+    private static final String[] PERMISION_OBJ_ATRS =
+        {
+            GlobalIds.FT_IID, GlobalIds.POBJ_NAME, GlobalIds.DESC, GlobalIds.OU, TYPE,
+            GlobalIds.PROPS
+    };
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    public final PermObj createObject( PermObj entity )
+        throws CreateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity, entity.getContextId() );
+        try
+        {
+            LDAPAttributeSet attrs = new LDAPAttributeSet();
+            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS, PERM_OBJ_OBJ_CLASS ) );
+            attrs.add( createAttribute( GlobalIds.POBJ_NAME, entity.getObjName() ) );
+
+            // this will generatre a new random, unique id on this entity:
+            entity.setInternalId();
+            // create the rDN:
+            attrs.add( createAttribute( GlobalIds.FT_IID, entity.getInternalId() ) );
+            // ou is required:
+            attrs.add( createAttribute( GlobalIds.OU, entity.getOu() ) );
+
+            // description is optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                attrs.add( createAttribute( GlobalIds.DESC, entity.getDescription() ) );
+            }
+            // type is optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getType() ) )
+            {
+                attrs.add( createAttribute( TYPE, entity.getType() ) );
+            }
+            // props are optional as well:
+            //if the props is null don't try to load these attributes
+            if ( VUtil.isNotNullOrEmpty( entity.getProperties() ) )
+            {
+                loadProperties( entity.getProperties(), attrs, GlobalIds.PROPS );
+            }
+
+            // create the new entry:
+            LDAPEntry myEntry = new LDAPEntry( dn, attrs );
+            entity.setDn( dn );
+
+            // now add the new entry to directory:
+            ld = getAdminConnection();
+            add( ld, myEntry, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "createObject perm obj [" + entity.getObjName() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new CreateException( GlobalErrIds.PERM_ADD_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    public final PermObj updateObj( PermObj entity )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity, entity.getContextId() );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            if ( VUtil.isNotNullOrEmpty( entity.getOu() ) )
+            {
+                LDAPAttribute ou = new LDAPAttribute( GlobalIds.OU, entity.getOu() );
+                mods.add( LDAPModification.REPLACE, ou );
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                LDAPAttribute desc = new LDAPAttribute( GlobalIds.DESC,
+                    entity.getDescription() );
+                mods.add( LDAPModification.REPLACE, desc );
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getType() ) )
+            {
+                LDAPAttribute type = new LDAPAttribute( TYPE,
+                    entity.getType() );
+                mods.add( LDAPModification.REPLACE, type );
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getProperties() ) )
+            {
+                loadProperties( entity.getProperties(), mods, GlobalIds.PROPS, true );
+            }
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods, entity );
+                entity.setDn( dn );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "updateObj objName [" + entity.getObjName() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.PERM_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.RemoveException
+     *
+     */
+    public final void deleteObj( PermObj entity )
+        throws RemoveException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity, entity.getContextId() );
+        try
+        {
+            ld = getAdminConnection();
+            deleteRecursive( ld, dn, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "deleteObj objName [" + entity.getObjName() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.PERM_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    public final Permission createOperation( Permission entity )
+        throws CreateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity, entity.getContextId() );
+        try
+        {
+            LDAPAttributeSet attrs = new LDAPAttributeSet();
+            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS, PERM_OP_OBJ_CLASS ) );
+            attrs.add( createAttribute( GlobalIds.POP_NAME, entity.getOpName() ) );
+            attrs.add( createAttribute( GlobalIds.POBJ_NAME, entity.getObjName() ) );
+            entity.setAbstractName( entity.getObjName() + "." + entity.getOpName() );
+
+            // this will generatre a new random, unique id on this entity:
+            entity.setInternalId();
+            // create the internal id:
+            attrs.add( createAttribute( GlobalIds.FT_IID, entity.getInternalId() ) );
+            // the abstract name is the human readable identifier:
+            attrs.add( createAttribute( PERM_NAME, entity.getAbstractName() ) );
+            // organizational name requires CN attribute:
+            attrs.add( createAttribute( GlobalIds.CN, entity.getAbstractName() ) );
+
+            // objectid is optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getObjId() ) )
+            {
+                attrs.add( createAttribute( POBJ_ID, entity.getObjId() ) );
+            }
+            // description is optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                attrs.add( createAttribute( GlobalIds.DESC, entity.getDescription() ) );
+            }
+            // type is optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getType() ) )
+            {
+                attrs.add( createAttribute( TYPE, entity.getType() ) );
+            }
+            // These are multi-valued attributes, use the util function to load:
+            // These items are optional as well.  The utility function will return quietly if no items are loaded into collection:
+            loadAttrs( entity.getRoles(), attrs, ROLES );
+            loadAttrs( entity.getUsers(), attrs, USERS );
+
+            // props are optional as well:
+            //if the props is null don't try to load these attributes
+            if ( VUtil.isNotNullOrEmpty( entity.getProperties() ) )
+            {
+                loadProperties( entity.getProperties(), attrs, GlobalIds.PROPS );
+            }
+            // create the new entry:
+            LDAPEntry myEntry = new LDAPEntry( dn, attrs );
+            // now add the new entry to directory:
+            ld = getAdminConnection();
+            add( ld, myEntry, entity );
+            entity.setDn( dn );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "createOperation objName [" + entity.getObjName() + "] opName ["
+                + entity.getOpName() + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new CreateException( GlobalErrIds.PERM_ADD_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    public final Permission updateOperation( Permission entity )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity, entity.getContextId() );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                LDAPAttribute desc = new LDAPAttribute( GlobalIds.DESC,
+                    entity.getDescription() );
+                mods.add( LDAPModification.REPLACE, desc );
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getAbstractName() ) )
+            {
+                // the abstract name is the human readable identifier:
+                LDAPAttribute abstractName = new LDAPAttribute( PERM_NAME,
+                    entity.getAbstractName() );
+                mods.add( LDAPModification.REPLACE, abstractName );
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getType() ) )
+            {
+                LDAPAttribute type = new LDAPAttribute( TYPE,
+                    entity.getType() );
+                mods.add( LDAPModification.REPLACE, type );
+            }
+
+            // These are multi-valued attributes, use the util function to load:
+            loadAttrs( entity.getRoles(), mods, ROLES );
+            loadAttrs( entity.getUsers(), mods, USERS );
+            loadProperties( entity.getProperties(), mods, GlobalIds.PROPS, true );
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods, entity );
+                entity.setDn( dn );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "updateOperation objName [" + entity.getObjName() + "] opName ["
+                + entity.getOpName() + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.PERM_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.RemoveException
+     *
+     */
+    public final void deleteOperation( Permission entity )
+        throws RemoveException
+    {
+        LDAPConnection ld = null;
+        String dn = getOpRdn( entity.getOpName(), entity.getObjId() ) + "," + GlobalIds.POBJ_NAME + "="
+            + entity.getObjName() + "," + getRootDn( entity.isAdmin(), entity.getContextId() );
+        try
+        {
+            ld = getAdminConnection();
+            deleteRecursive( ld, dn, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "deleteOperation objName [" + entity.getObjName() + "] opName ["
+                + entity.getOpName() + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.PERM_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param pOp
+     * @param role
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final void grant( Permission pOp, Role role )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( pOp, pOp.getContextId() );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute attr = new LDAPAttribute( ROLES, role.getName() );
+            mods.add( LDAPModification.ADD, attr );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, pOp );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.ATTRIBUTE_OR_VALUE_EXISTS )
+            {
+                String warning = "grant perm object [" + pOp.getObjName() + "] operation ["
+                    + pOp.getOpName() + "] role [" + role.getName() + "] assignment already exists, Fortress rc="
+                    + GlobalErrIds.PERM_ROLE_EXIST;
+                throw new UpdateException( GlobalErrIds.PERM_ROLE_EXIST, warning );
+            }
+            else if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "grant perm object [" + pOp.getObjName() + "] operation ["
+                    + pOp.getOpName() + "] role [" + role.getName() + "] perm not found, Fortress rc="
+                    + GlobalErrIds.PERM_OP_NOT_FOUND;
+                throw new UpdateException( GlobalErrIds.PERM_OP_NOT_FOUND, warning );
+            }
+            else
+            {
+                String error = "grant perm object [" + pOp.getObjName() + "] operation ["
+                    + pOp.getOpName() + "] name [" + role.getName() + "]  caught LDAPException="
+                    + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                throw new UpdateException( GlobalErrIds.PERM_GRANT_FAILED, error, e );
+            }
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param pOp
+     * @param role
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final void revoke( Permission pOp, Role role )
+        throws UpdateException, FinderException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( pOp, pOp.getContextId() );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute attr = new LDAPAttribute( ROLES, role.getName() );
+            mods.add( LDAPModification.DELETE, attr );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, pOp );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_ATTRIBUTE )
+            {
+                String warning = "revoke perm object [" + pOp.getObjName() + "] operation ["
+                    + pOp.getOpName() + "] name [" + role.getName() + "] assignment does not exist.";
+                throw new FinderException( GlobalErrIds.PERM_ROLE_NOT_EXIST, warning );
+            }
+            else
+            {
+                String error = "revoke perm object [" + pOp.getObjName() + "] operation ["
+                    + pOp.getOpName() + "] name [" + role.getName() + "] caught LDAPException=" + e.getLDAPResultCode()
+                    + " msg=" + e.getMessage();
+                throw new UpdateException( GlobalErrIds.PERM_REVOKE_FAILED, error, e );
+            }
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param pOp
+     * @param user
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final void grant( Permission pOp, User user )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( pOp, pOp.getContextId() );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute attr = new LDAPAttribute( USERS, user.getUserId() );
+            mods.add( LDAPModification.ADD, attr );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, pOp );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.ATTRIBUTE_OR_VALUE_EXISTS )
+            {
+                String warning = "grant perm object [" + pOp.getObjName() + "] operation ["
+                    + pOp.getOpName() + "] userId [" + user.getUserId() + "] assignment already exists, Fortress rc="
+                    + GlobalErrIds.PERM_USER_EXIST;
+                throw new UpdateException( GlobalErrIds.PERM_USER_EXIST, warning );
+            }
+            else if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "grant perm object [" + pOp.getObjName() + "] operation ["
+                    + pOp.getOpName() + "] userId [" + user.getUserId() + "] perm not found, Fortress rc="
+                    + GlobalErrIds.PERM_OP_NOT_FOUND;
+                throw new UpdateException( GlobalErrIds.PERM_OP_NOT_FOUND, warning );
+            }
+            else
+            {
+                String error = "grant perm object [" + pOp.getObjName() + "] operation ["
+                    + pOp.getOpName() + "] userId [" + user.getUserId() + "] caught LDAPException="
+                    + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                throw new UpdateException( GlobalErrIds.PERM_GRANT_USER_FAILED, error, e );
+            }
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param pOp
+     * @param user
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final void revoke( Permission pOp, User user )
+        throws UpdateException, FinderException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( pOp, pOp.getContextId() );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute attr = new LDAPAttribute( USERS, user.getUserId() );
+            mods.add( LDAPModification.DELETE, attr );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, pOp );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_ATTRIBUTE )
+            {
+                String warning = "revoke perm object [" + pOp.getObjName() + "] operation ["
+                    + pOp.getOpName() + "] userId [" + user.getUserId() + "] assignment does not exist.";
+                throw new FinderException( GlobalErrIds.PERM_USER_NOT_EXIST, warning );
+            }
+            else
+            {
+                String error = "revoke perm object [" + pOp.getObjName() + "] operation ["
+                    + pOp.getOpName() + "] userId [" + user.getUserId() + "] caught LDAPException="
+                    + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                throw new UpdateException( GlobalErrIds.PERM_REVOKE_FAILED, error, e );
+            }
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param permission
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final Permission getPerm( Permission permission )
+        throws FinderException
+    {
+        Permission entity = null;
+        LDAPConnection ld = null;
+        String dn = getOpRdn( permission.getOpName(), permission.getObjId() ) + "," + GlobalIds.POBJ_NAME + "="
+            + permission.getObjName() + "," + getRootDn( permission.isAdmin(), permission.getContextId() );
+        try
+        {
+            ld = getAdminConnection();
+            LDAPEntry findEntry = read( ld, dn, PERMISSION_OP_ATRS );
+            entity = unloadPopLdapEntry( findEntry, 0, permission.isAdmin() );
+            if ( entity == null )
+            {
+                String warning = "getPerm no entry found dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.PERM_OP_NOT_FOUND, warning );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "getPerm Op COULD NOT FIND ENTRY for dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.PERM_OP_NOT_FOUND, warning );
+            }
+
+            String error = "getUser [" + dn + "] caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_READ_OP_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param permObj
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final PermObj getPerm( PermObj permObj )
+        throws FinderException
+    {
+        PermObj entity = null;
+        LDAPConnection ld = null;
+        String dn = GlobalIds.POBJ_NAME + "=" + permObj.getObjName() + ","
+            + getRootDn( permObj.isAdmin(), permObj.getContextId() );
+        try
+        {
+            ld = getAdminConnection();
+            LDAPEntry findEntry = read( ld, dn, PERMISION_OBJ_ATRS );
+            entity = unloadPobjLdapEntry( findEntry, 0, permObj.isAdmin() );
+            if ( entity == null )
+            {
+                String warning = "getPerm Obj no entry found dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.PERM_OBJ_NOT_FOUND, warning );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "getPerm Obj COULD NOT FIND ENTRY for dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.PERM_OBJ_NOT_FOUND, warning );
+            }
+            String error = "getPerm Obj dn [" + dn + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_READ_OBJ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * This method performs fortress authorization using data passed in (session) and stored on ldap server (permission).  It has been recently changed to use ldap compare operations in order to trigger slapd access log updates in directory.
+     * It performs ldap operations:  read and (optionally) compare.  The first is to pull back the permission to see if user has access or not.  The second is to trigger audit
+     * record storage on ldap server but can be disabled.
+     *
+     * @param session contains {@link Session#getUserId()}, for rbac check {@link org.apache.directory.fortress.core.rbac.Session#getRoles()}, for arbac check: {@link org.apache.directory.fortress.core.rbac.Session#getAdminRoles()}.
+     * @param inPerm  must contain required attributes {@link Permission#objName} and {@link Permission#opName}.  {@link Permission#objId} is optional.
+     * @return boolean containing result of check.
+     * @throws org.apache.directory.fortress.core.FinderException
+     *          In the event system error occurs looking up data on ldap server.
+     */
+    public final boolean checkPermission( Session session, Permission inPerm )
+        throws FinderException
+    {
+        boolean isAuthZd = false;
+        LDAPConnection ld = null;
+        String dn = getOpRdn( inPerm.getOpName(), inPerm.getObjId() ) + "," + GlobalIds.POBJ_NAME + "="
+            + inPerm.getObjName() + "," + getRootDn( inPerm.isAdmin(), inPerm.getContextId() );
+        try
+        {
+            // Use unauthenticated connection because we want to assert the end user identity onto ldap hop:
+            ld = getAdminConnection();
+            // LDAP Operation #1: Read the targeted permission from ldap server
+            LDAPEntry entry = read( ld, dn, PERMISSION_OP_ATRS );
+            if(entry == null)
+            {
+                // if permission not found, cannot continue.
+                String error = "checkPermission DOES NOT EXIST : obj name [" + inPerm.getObjName() + "], obj id [" + inPerm.getObjId() + "], op name [" + inPerm.getOpName() + "], idAdmin [" + inPerm.isAdmin() + "]";
+                throw new FinderException( GlobalErrIds.PERM_NOT_EXIST, error );
+            }
+
+            // load the permission entity with data retrieved from the permission node:
+            Permission outPerm = unloadPopLdapEntry( entry, 0, inPerm.isAdmin() );
+            // The admin flag will be set to 'true' if this is an administrative permission:
+            outPerm.setAdmin( inPerm.isAdmin() );
+            // Pass the tenant id along:
+            outPerm.setContextId( inPerm.getContextId() );
+            // The objective of these next steps is to evaluate the outcome of authorization attempt and trigger a write to slapd access logger containing the result.
+            // The objectClass triggered by slapd access log write for upcoming ldap op is 'auditCompare'.
+            // Set this attribute either with actual operation name that will succeed compare (for authZ success) or bogus value which will fail compare (for authZ failure):
+            String attributeValue;
+            // This method determines if the user is authorized for this permission:
+            isAuthZd = isAuthorized( session, outPerm );
+            // This is done to leave an audit trail in ldap server log:
+            if ( isAuthZd )
+            {
+                // Yes, set the operation name onto this attribute for storage into audit trail:
+                attributeValue = outPerm.getOpName();
+            }
+            else
+            {
+                // No, set a simple error message onto this attribute for storage into audit trail:
+                attributeValue = GlobalIds.AUTH_Z_FAILED;
+            }
+            // There is a switch in fortress config to disable audit ops like this one.
+            // But if used the compare method will use OpenLDAP's Proxy Authorization Control to assert identity of end user onto connection.
+            // LDAP Operation #2: Compare.
+            addAuthZAudit( ld, dn, session.getUser().getDn(), attributeValue );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() != LDAPException.NO_RESULTS_RETURNED
+                && e.getLDAPResultCode() != LDAPException.NO_SUCH_OBJECT )
+            {
+                String error = "checkPermission caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                    + e.getMessage();
+                throw new FinderException( GlobalErrIds.PERM_READ_OP_FAILED, error, e );
+            }
+            // There is a switch in fortress config to disable the audit ops.
+            addAuthZAudit( ld, dn, session.getUser().getDn(), "AuthZ Invalid" );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return isAuthZd;
+    }
+
+
+    /**
+     * Perform LDAP compare operation here to associate audit record with user authorization event.
+     *
+     * @param ld this method expects the ldap connection to be good
+     * @param permDn contains distinguished name of the permission object.
+     * @param userDn contains the distinguished name of the user object.
+     * @param attributeValue string value will be associated with the 'audit' record stored in ldap.
+     * @throws FinderException in the event ldap system exception occurs.
+     */
+    private void addAuthZAudit( LDAPConnection ld, String permDn, String userDn, String attributeValue )
+        throws FinderException
+    {
+        // Audit can be turned off here with fortress config param: 'enable.audit=false'
+        if ( GlobalIds.IS_AUDIT && GlobalIds.IS_OPENLDAP )
+        {
+            try
+            {
+                // The compare method uses OpenLDAP's Proxy Authorization Control to assert identity of end user onto connection:
+                // LDAP Operation #2: Compare:
+                compareNode( ld, permDn, userDn, createAttribute( GlobalIds.POP_NAME, attributeValue ) );
+            }
+            catch ( UnsupportedEncodingException ee )
+            {
+                String error = "addAuthZAudit caught UnsupportedEncodingException=" + ee.getMessage();
+                throw new FinderException( GlobalErrIds.PERM_COMPARE_OP_FAILED, error, ee );
+            }
+            catch ( LDAPException e )
+            {
+                if ( e.getLDAPResultCode() != LDAPException.NO_RESULTS_RETURNED
+                    && e.getLDAPResultCode() != LDAPException.NO_SUCH_OBJECT )
+                {
+                    String error = "addAuthZAudit caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                        + e.getMessage();
+                    throw new FinderException( GlobalErrIds.PERM_COMPARE_OP_FAILED, error, e );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * This function will first compare the userId from the session object with the list of users attached to permission object.
+     * If match does not occur there, determine if there is a match between the authorized roles of user with roles attached to permission object.
+     * For this use {@link org.apache.directory.fortress.core.rbac.Permission#isAdmin()} to determine if admin permissions or normal permissions have been passed in by caller.
+     *
+     * @param session contains the {@link org.apache.directory.fortress.core.rbac.Session#getUserId()},{@link Session#getRoles()} or {@link org.apache.directory.fortress.core.rbac.Session#getAdminRoles()}.
+     * @param permission contains {@link org.apache.directory.fortress.core.rbac.Permission#getUsers()} and {@link Permission#getRoles()}.
+     * @return binary result.
+     */
+    private boolean isAuthorized( Session session, Permission permission )
+    {
+        boolean result = false;
+        Set<String> userIds = permission.getUsers();
+        if ( VUtil.isNotNullOrEmpty( userIds ) && userIds.contains( session.getUserId() ) )
+        {
+            // user is assigned directly to this permission, no need to look further.
+            return true;
+        }
+        Set<String> roles = permission.getRoles();
+        if ( VUtil.isNotNullOrEmpty( roles ) )
+        {
+            if ( permission.isAdmin() )
+            {
+                // ARBAC Permission check include's User's inherited admin roles:
+                Set<String> activatedRoles = AdminRoleUtil.getInheritedRoles( session.getAdminRoles(),
+                    permission.getContextId() );
+                for ( String role : roles )
+                {
+                    // This is case insensitive op determines if user has matching admin role to the admin permission::
+                    if ( activatedRoles.contains( role ) )
+                    {
+                        result = true;
+                        break;
+                    }
+                }
+            }
+            else
+            {
+                // RBAC Permission check include's User's inherited roles:
+                Set<String> activatedRoles = RoleUtil.getInheritedRoles( session.getRoles(), permission.getContextId() );
+                for ( String role : roles )
+                {
+                    // This is case insensitive op determines if user has matching role:
+                    if ( activatedRoles.contains( role ) )
+                    {
+                        result = true;
+                        break;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * @param le
+     * @param sequence
+     * @return
+     * @throws LDAPException
+     */
+    private Permission unloadPopLdapEntry( LDAPEntry le, long sequence, boolean isAdmin )
+    {
+        Permission entity = new ObjectFactory().createPermission();
+        entity.setDn( le.getDN() );
+        entity.setSequenceId( sequence );
+        entity.setAbstractName( getAttribute( le, PERM_NAME ) );
+        entity.setObjName( getAttribute( le, GlobalIds.POBJ_NAME ) );
+        entity.setObjId( getAttribute( le, POBJ_ID ) );
+        entity.setOpName( getAttribute( le, GlobalIds.POP_NAME ) );
+        entity.setDescription( getAttribute( le, GlobalIds.DESC ) );
+        entity.setInternalId( getAttribute( le, GlobalIds.FT_IID ) );
+        entity.setRoles( getAttributeSet( le, ROLES ) );
+        entity.setUsers( getAttributeSet( le, USERS ) );
+        entity.setType( getAttribute( le, TYPE ) );
+        entity.addProperties( AttrHelper.getProperties( getAttributes( le, GlobalIds.PROPS ) ) );
+        entity.setAdmin( isAdmin );
+        return entity;
+    }
+
+
+    /**
+     * @param le
+     * @param sequence
+     * @return
+     * @throws LDAPException
+     */
+    private PermObj unloadPobjLdapEntry( LDAPEntry le, long sequence, boolean isAdmin )
+    {
+        PermObj entity = new ObjectFactory().createPermObj();
+        entity.setSequenceId( sequence );
+        entity.setObjName( getAttribute( le, GlobalIds.POBJ_NAME ) );
+        entity.setOu( getAttribute( le, GlobalIds.OU ) );
+        entity.setDn( le.getDN() );
+        entity.setInternalId( getAttribute( le, GlobalIds.FT_IID ) );
+        entity.setType( getAttribute( le, TYPE ) );
+        entity.setDescription( getAttribute( le, GlobalIds.DESC ) );
+        entity.addProperties( AttrHelper.getProperties( getAttributes( le, GlobalIds.PROPS ) ) );
+        entity.setAdmin( isAdmin );
+        return entity;
+    }
+
+
+    /**
+     * @param permission
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Permission> findPermissions( Permission permission )
+        throws FinderException
+    {
+        List<Permission> permList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String permRoot = getRootDn( permission.isAdmin(), permission.getContextId() );
+        try
+        {
+            String permObjVal = encodeSafeText( permission.getObjName(), GlobalIds.PERM_LEN );
+            String permOpVal = encodeSafeText( permission.getOpName(), GlobalIds.PERM_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OP_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.POBJ_NAME + "=" + permObjVal + "*)("
+                + GlobalIds.POP_NAME + "=" + permOpVal + "*))";
+
+            ld = getAdminConnection();
+            searchResults = search( ld, permRoot,
+                LDAPConnection.SCOPE_SUB, filter, PERMISSION_OP_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                permList.add( unloadPopLdapEntry( searchResults.next(), sequence++, permission.isAdmin() ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findPermissions caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return permList;
+    }
+
+
+    /**
+     * @param permObj
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<PermObj> findPermissions( PermObj permObj )
+        throws FinderException
+    {
+        List<PermObj> permList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String permRoot = getRootDn( permObj.isAdmin(), permObj.getContextId() );
+        try
+        {
+            String permObjVal = encodeSafeText( permObj.getObjName(), GlobalIds.PERM_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OBJ_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.POBJ_NAME + "=" + permObjVal + "*))";
+            ld = getAdminConnection();
+            searchResults = search( ld, permRoot,
+                LDAPConnection.SCOPE_SUB, filter, PERMISION_OBJ_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                permList.add( unloadPobjLdapEntry( searchResults.next(), sequence++, permObj.isAdmin() ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findPermissions caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return permList;
+    }
+
+
+    /**
+     * @param ou
+     * @return
+     * @throws FinderException
+     */
+    public final List<PermObj> findPermissions( OrgUnit ou, boolean limitSize )
+        throws FinderException
+    {
+        List<PermObj> permList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String permRoot = getRootDn( ou.getContextId(), GlobalIds.PERM_ROOT );
+        try
+        {
+            String ouVal = encodeSafeText( ou.getName(), GlobalIds.OU_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OBJ_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.OU + "=" + ouVal + "*))";
+            int maxLimit;
+            if ( limitSize )
+            {
+                maxLimit = 10;
+            }
+            else
+            {
+                maxLimit = 0;
+            }
+            ld = getAdminConnection();
+            searchResults = search( ld, permRoot,
+                LDAPConnection.SCOPE_SUB, filter, PERMISION_OBJ_ATRS, false, GlobalIds.BATCH_SIZE, maxLimit );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                permList.add( unloadPobjLdapEntry( searchResults.next(), sequence++, false ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findPermissions caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return permList;
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Permission> findPermissions( Role role )
+        throws FinderException
+    {
+        List<Permission> permList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String permRoot;
+        boolean isAdmin = false;
+        if ( role.getClass().equals( AdminRole.class ) )
+        {
+            permRoot = getRootDn( role.getContextId(), GlobalIds.ADMIN_PERM_ROOT );
+            isAdmin = true;
+        }
+        else
+        {
+            permRoot = getRootDn( role.getContextId(), GlobalIds.PERM_ROOT );
+        }
+        try
+        {
+            String roleVal = encodeSafeText( role.getName(), GlobalIds.ROLE_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OP_OBJECT_CLASS_NAME + ")(";
+            Set<String> roles;
+            if ( role.getClass().equals( AdminRole.class ) )
+            {
+                roles = AdminRoleUtil.getAscendants( role.getName(), role.getContextId() );
+            }
+            else
+            {
+                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();
+            searchResults = search( ld, permRoot,
+                LDAPConnection.SCOPE_SUB, filter, PERMISSION_OP_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                permList.add( unloadPopLdapEntry( searchResults.next(), sequence++, isAdmin ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findPermissions caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_ROLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return permList;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Permission> findPermissions( User user )
+        throws FinderException
+    {
+        List<Permission> permList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String permRoot = getRootDn( user.getContextId(), GlobalIds.PERM_ROOT );
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OP_OBJECT_CLASS_NAME + ")(|";
+            Set<String> roles = RoleUtil.getInheritedRoles( user.getRoles(), user.getContextId() );
+            if ( VUtil.isNotNullOrEmpty( roles ) )
+            {
+                for ( String uRole : roles )
+                {
+                    filter += "(" + ROLES + "=" + uRole + ")";
+                }
+            }
+            filter += "(" + USERS + "=" + user.getUserId() + ")))";
+            ld = getAdminConnection();
+            searchResults = search( ld, permRoot,
+                LDAPConnection.SCOPE_SUB, filter, PERMISSION_OP_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                permList.add( unloadPopLdapEntry( searchResults.next(), sequence++, false ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findPermissions user [" + user.getUserId()
+                + "] caught LDAPException in PermDAO.findPermissions=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_USER_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return permList;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Permission> findUserPermissions( User user )
+        throws FinderException
+    {
+        List<Permission> permList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String permRoot = getRootDn( user.getContextId(), GlobalIds.PERM_ROOT );
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OP_OBJECT_CLASS_NAME + ")";
+            filter += "(" + USERS + "=" + user.getUserId() + "))";
+            ld = getAdminConnection();
+            searchResults = search( ld, permRoot,
+                LDAPConnection.SCOPE_SUB, filter, PERMISSION_OP_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                permList.add( unloadPopLdapEntry( searchResults.next(), sequence++, false ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findUserPermissions user [" + user.getUserId()
+                + "] caught LDAPException in PermDAO.findPermissions=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_USER_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return permList;
+    }
+
+
+    /**
+     * @param session
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Permission> findPermissions( Session session, boolean isAdmin )
+        throws FinderException
+    {
+        List<Permission> permList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String permRoot = getRootDn( isAdmin, session.getContextId() );
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OP_OBJECT_CLASS_NAME + ")(|";
+            filter += "(" + USERS + "=" + session.getUserId() + ")";
+            //Set<String> roles = RoleUtil.getInheritedRoles( session.getRoles(), session.getContextId() );
+            Set<String> roles;
+            if(isAdmin)
+            {
+                roles = AdminRoleUtil.getInheritedRoles( session.getAdminRoles(), session.getContextId() );
+            }
+            else
+            {
+                roles = RoleUtil.getInheritedRoles( session.getRoles(), session.getContextId() );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( roles ) )
+            {
+                for ( String uRole : roles )
+                {
+                    filter += "(" + ROLES + "=" + uRole + ")";
+                }
+            }
+            filter += "))";
+            ld = getAdminConnection();
+            searchResults = search( ld, permRoot,
+                LDAPConnection.SCOPE_SUB, filter, PERMISSION_OP_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                permList.add( unloadPopLdapEntry( searchResults.next(), sequence++, isAdmin ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findPermissions user [" + session.getUserId()
+                + "] caught LDAPException in PermDAO.findPermissions=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SESS_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return permList;
+    }
+
+
+    /**
+     * @param opName
+     * @param objId
+     * @return
+     */
+    static String getOpRdn( String opName, String objId )
+    {
+        String rDn;
+        if ( objId != null && objId.length() > 0 )
+            rDn = GlobalIds.POP_NAME + "=" + opName + "+" + POBJ_ID + "=" + objId;
+        else
+            rDn = GlobalIds.POP_NAME + "=" + opName;
+        return rDn;
+    }
+
+
+    private String getDn( Permission pOp, String contextId )
+    {
+        return getOpRdn( pOp.getOpName(), pOp.getObjId() ) + "," + GlobalIds.POBJ_NAME + "=" + pOp.getObjName()
+            + "," + getRootDn( pOp.isAdmin(), contextId );
+    }
+
+
+    private String getDn( PermObj pObj, String contextId )
+    {
+        return GlobalIds.POBJ_NAME + "=" + pObj.getObjName() + "," + getRootDn( pObj.isAdmin(), contextId );
+    }
+
+
+    private String getRootDn( boolean isAdmin, String contextId )
+    {
+        String dn;
+        if ( isAdmin )
+        {
+            dn = getRootDn( contextId, GlobalIds.ADMIN_PERM_ROOT );
+        }
+        else
+        {
+            dn = getRootDn( contextId, GlobalIds.PERM_ROOT );
+        }
+        return dn;
+    }
+}
\ 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/unboundid/PolicyDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/PolicyDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/PolicyDAO.java
new file mode 100755
index 0000000..33bda6d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/PolicyDAO.java
@@ -0,0 +1,623 @@
+/*
+ *   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.unboundid;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+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.UnboundIdDataProvider;
+import org.apache.directory.fortress.core.rbac.PwPolicy;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttribute;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModification;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModificationSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPSearchResults;
+
+
+/**
+ * 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
+ */
+public final class PolicyDAO extends UnboundIdDataProvider implements org.apache.directory.fortress.core.rbac.dao.PolicyDAO
+{
+    /*
+      *  *************************************************************************
+      *  **  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
+     *
+     */
+    public final PwPolicy create( PwPolicy entity )
+        throws CreateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            LDAPAttributeSet attrs = new LDAPAttributeSet();
+            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS, OAM_PWPOLICY_OBJ_CLASS ) );
+            attrs.add( createAttribute( GlobalIds.CN, entity.getName() ) );
+            attrs.add( createAttribute( OLPW_ATTRIBUTE, OLPW_POLICY_EXTENSION ) );
+            if ( entity.getMinAge() != null )
+            {
+                attrs.add( createAttribute( OLPW_MIN_AGE, entity.getMinAge().toString() ) );
+            }
+            if ( entity.getMaxAge() != null )
+            {
+                attrs.add( createAttribute( OLPW_MAX_AGE, entity.getMaxAge().toString() ) );
+            }
+            if ( entity.getInHistory() != null )
+            {
+                attrs.add( createAttribute( OLPW_IN_HISTORY, entity.getInHistory().toString() ) );
+            }
+            if ( entity.getCheckQuality() != null )
+            {
+                attrs.add( createAttribute( OLPW_CHECK_QUALITY, entity.getCheckQuality().toString() ) );
+            }
+            if ( entity.getMinLength() != null )
+            {
+                attrs.add( createAttribute( OLPW_MIN_LENGTH, entity.getMinLength().toString() ) );
+            }
+            if ( entity.getExpireWarning() != null )
+            {
+                attrs.add( createAttribute( OLPW_EXPIRE_WARNING, entity.getExpireWarning().toString() ) );
+            }
+            if ( entity.getGraceLoginLimit() != null )
+            {
+                attrs.add( createAttribute( OLPW_GRACE_LOGIN_LIMIT, entity.getGraceLoginLimit().toString() ) );
+            }
+            if ( entity.getLockout() != null )
+            {
+                /**
+                 * For some reason OpenLDAP requires the pwdLockout boolean value to be upper case:
+                 */
+                attrs.add( createAttribute( OLPW_LOCKOUT, entity.getLockout().toString().toUpperCase() ) );
+            }
+            if ( entity.getLockoutDuration() != null )
+            {
+                attrs.add( createAttribute( OLPW_LOCKOUT_DURATION, entity.getLockoutDuration().toString() ) );
+            }
+            if ( entity.getMaxFailure() != null )
+            {
+                attrs.add( createAttribute( OLPW_MAX_FAILURE, entity.getMaxFailure().toString() ) );
+            }
+            if ( entity.getFailureCountInterval() != null )
+            {
+                attrs.add( createAttribute( OLPW_FAILURE_COUNT_INTERVAL, entity.getFailureCountInterval().toString() ) );
+            }
+            if ( entity.getMustChange() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                attrs.add( createAttribute( OLPW_MUST_CHANGE, entity.getMustChange().toString().toUpperCase() ) );
+            }
+            if ( entity.getAllowUserChange() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                attrs.add( createAttribute( OLPW_ALLOW_USER_CHANGE, entity.getAllowUserChange().toString()
+                    .toUpperCase() ) );
+            }
+            if ( entity.getSafeModify() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                attrs.add( createAttribute( OLPW_SAFE_MODIFY, entity.getSafeModify().toString().toUpperCase() ) );
+            }
+
+            LDAPEntry myEntry = new LDAPEntry( dn, attrs );
+            ld = getAdminConnection();
+            add( ld, myEntry, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "create name [" + entity.getName() + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + 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
+     *
+     */
+    public final void update( PwPolicy entity )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            if ( entity.getMinAge() != null )
+            {
+                LDAPAttribute minAge = new LDAPAttribute( OLPW_MIN_AGE, entity.getMinAge().toString() );
+                mods.add( LDAPModification.REPLACE, minAge );
+            }
+            if ( entity.getMaxAge() != null )
+            {
+                LDAPAttribute maxAge = new LDAPAttribute( OLPW_MAX_AGE, entity.getMaxAge().toString() );
+                mods.add( LDAPModification.REPLACE, maxAge );
+            }
+            if ( entity.getInHistory() != null )
+            {
+                LDAPAttribute inHistory = new LDAPAttribute( OLPW_IN_HISTORY, entity.getInHistory().toString() );
+                mods.add( LDAPModification.REPLACE, inHistory );
+            }
+            if ( entity.getCheckQuality() != null )
+            {
+                LDAPAttribute checkQuality = new LDAPAttribute( OLPW_CHECK_QUALITY, entity.getCheckQuality().toString() );
+                mods.add( LDAPModification.REPLACE, checkQuality );
+            }
+            if ( entity.getMinLength() != null )
+            {
+                LDAPAttribute minLength = new LDAPAttribute( OLPW_MIN_LENGTH, entity.getMinLength().toString() );
+                mods.add( LDAPModification.REPLACE, minLength );
+            }
+            if ( entity.getExpireWarning() != null )
+            {
+                LDAPAttribute expireWarning = new LDAPAttribute( OLPW_EXPIRE_WARNING, entity.getExpireWarning()
+                    .toString() );
+                mods.add( LDAPModification.REPLACE, expireWarning );
+            }
+            if ( entity.getGraceLoginLimit() != null )
+            {
+                LDAPAttribute graceLoginLimit = new LDAPAttribute( OLPW_GRACE_LOGIN_LIMIT, entity.getGraceLoginLimit()
+                    .toString() );
+                mods.add( LDAPModification.REPLACE, graceLoginLimit );
+            }
+            if ( entity.getLockout() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                LDAPAttribute lockout = new LDAPAttribute( OLPW_LOCKOUT, entity.getLockout().toString().toUpperCase() );
+                mods.add( LDAPModification.REPLACE, lockout );
+            }
+            if ( entity.getLockoutDuration() != null )
+            {
+                LDAPAttribute lockoutDuration = new LDAPAttribute( OLPW_LOCKOUT_DURATION, entity.getLockoutDuration()
+                    .toString() );
+                mods.add( LDAPModification.REPLACE, lockoutDuration );
+            }
+            if ( entity.getMaxFailure() != null )
+            {
+                LDAPAttribute maxFailure = new LDAPAttribute( OLPW_MAX_FAILURE, entity.getMaxFailure().toString() );
+                mods.add( LDAPModification.REPLACE, maxFailure );
+            }
+            if ( entity.getFailureCountInterval() != null )
+            {
+                LDAPAttribute failureCountInterval = new LDAPAttribute( OLPW_FAILURE_COUNT_INTERVAL, entity
+                    .getFailureCountInterval().toString() );
+                mods.add( LDAPModification.REPLACE, failureCountInterval );
+            }
+            if ( entity.getMustChange() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                LDAPAttribute mustChange = new LDAPAttribute( OLPW_MUST_CHANGE, entity.getMustChange().toString()
+                    .toUpperCase() );
+                mods.add( LDAPModification.REPLACE, mustChange );
+            }
+            if ( entity.getAllowUserChange() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                LDAPAttribute allowUserChange = new LDAPAttribute( OLPW_ALLOW_USER_CHANGE, entity.getAllowUserChange()
+                    .toString().toUpperCase() );
+                mods.add( LDAPModification.REPLACE, allowUserChange );
+            }
+            if ( entity.getSafeModify() != null )
+            {
+                /**
+                 * OpenLDAP requires the boolean values to be upper case:
+                 */
+                LDAPAttribute safeModify = new LDAPAttribute( OLPW_SAFE_MODIFY, entity.getSafeModify().toString()
+                    .toUpperCase() );
+                mods.add( LDAPModification.REPLACE, safeModify );
+            }
+            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.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.PSWD_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.RemoveException
+     */
+    public 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.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.PSWD_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param policy
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final PwPolicy getPolicy( PwPolicy policy )
+        throws FinderException
+    {
+        PwPolicy entity = null;
+        LDAPConnection ld = null;
+        String dn = getDn( policy );
+        try
+        {
+            ld = getAdminConnection();
+            LDAPEntry findEntry = read( ld, dn, PASSWORD_POLICY_ATRS );
+            entity = unloadLdapEntry( findEntry, 0 );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+                {
+                    String warning = "getPolicy Obj COULD NOT FIND ENTRY for dn [" + dn + "]";
+                    throw new FinderException( GlobalErrIds.PSWD_NOT_FOUND, warning );
+                }
+            }
+            else
+            {
+                String error = "getPolicy name [" + policy.getName() + "] caught LDAPException="
+                    + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                throw new FinderException( GlobalErrIds.PSWD_READ_FAILED, error, e );
+            }
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     *
+     * @param le
+     * @param sequence
+     * @return
+     * @throws LDAPException
+     */
+    private PwPolicy unloadLdapEntry( LDAPEntry le, long sequence )
+    {
+        PwPolicy entity = new ObjectFactory().createPswdPolicy();
+        entity.setSequenceId( sequence );
+        entity.setName( getRdn( le.getDN() ) );
+        //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
+     *
+     */
+    public final List<PwPolicy> findPolicy( PwPolicy policy )
+        throws FinderException
+    {
+        List<PwPolicy> policyArrayList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        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();
+            searchResults = search( ld, policyRoot,
+                LDAPConnection.SCOPE_ONE, filter, PASSWORD_POLICY_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                policyArrayList.add( unloadLdapEntry( searchResults.next(), sequence++ ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findPolicy name [" + searchVal + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PSWD_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return policyArrayList;
+    }
+
+
+    /**
+     * @return
+     * @throws FinderException
+     */
+    public final Set<String> getPolicies( String contextId )
+        throws FinderException
+    {
+        Set<String> policySet = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String policyRoot = getPolicyRoot( contextId );
+        try
+        {
+            String filter = "(objectclass=" + OLPW_POLICY_CLASS + ")";
+            ld = getAdminConnection();
+            searchResults = search( ld, policyRoot,
+                LDAPConnection.SCOPE_ONE, filter, PASSWORD_POLICY_NAME_ATR, false, GlobalIds.BATCH_SIZE );
+            while ( searchResults.hasMoreElements() )
+            {
+                policySet.add( getAttribute( searchResults.next(), GlobalIds.CN ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "getPolicies caught LDAPException=" + e.getLDAPResultCode() + " msg=" + 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 );
+    }
+}


[27/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/DelAdminMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/DelAdminMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/rbac/DelAdminMgrImpl.java
new file mode 100755
index 0000000..ea6291c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/DelAdminMgrImpl.java
@@ -0,0 +1,1171 @@
+/*
+ *   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 org.apache.directory.fortress.core.AdminMgr;
+import org.apache.directory.fortress.core.AdminMgrFactory;
+import org.apache.directory.fortress.core.DelAdminMgr;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.util.time.CUtil;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class implements the ARBAC02 DelAdminMgr interface for performing policy administration of Fortress ARBAC entities
+ * that reside in LDAP directory.
+ * These APIs map directly to similar named APIs specified by ARBAC02 functions.  The ARBAC Functional specification describes delegated administrative
+ * operations for the creation and maintenance of ARBAC element sets and relations.  Delegated administrative review functions for performing administrative queries
+ * and system functions for creating and managing ARBAC attributes on user sessions and making delegated administrative access control decisions.
+ * This class is NOT thread safe.
+ * <h3>Administrative Role Based Access Control (ARBAC)</h3>
+ * <img src="../doc-files/ARbac.png">
+ * <p/>
+ * Fortress fully supports the Oh/Sandhu/Zhang ARBAC02 model for delegated administration.  ARBAC provides large enterprises the capability to delegate administrative authority to users that reside outside of the security admin group.
+ * Decentralizing administration helps because it provides security provisioning capability to work groups without sacrificing regulations for accountability or traceability.
+ * <p/>
+ * This class is NOT thread safe if parent instance variables ({@link #contextId} or {@link #adminSess}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public final class DelAdminMgrImpl extends Manageable implements DelAdminMgr
+{
+    private static final String CLS_NM = DelAdminMgrImpl.class.getName();
+    private static final OrgUnitP ouP = new OrgUnitP();
+    private static final AdminRoleP admRP = new AdminRoleP();
+    private static final PermP permP = new PermP();
+    private static final UserP userP = new UserP();
+
+    // package private constructor ensures outside classes cannot use:
+    DelAdminMgrImpl()
+    {}
+
+    /**
+     * This command creates a new admin role. The command is valid if and only if the new admin role is not
+     * already a member of the ADMIN ROLES data set. The ADMIN ROLES data set is updated.
+     * Initially, no user or permission is assigned to the new role.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of the new AdminRole being targeted for addition to LDAP</li>
+     * </ul>
+     * <p/>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#description} - contains any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#osPs} * - multi-occurring attribute used to set associations to existing PERMS OrgUnits</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#osUs} * - multi-occurring attribute used to set associations to existing USERS OrgUnits</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginRange} - contains the name of an existing RBAC Role that represents the lowest role in hierarchy that administrator (whoever has this AdminRole activated) controls</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endRange} - contains the name of an existing RBAC Role that represents that highest role in hierarchy that administrator may control</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginInclusive} - if 'true' the RBAC Role specified in beginRange is also controlled by the posessor of this AdminRole</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endInclusive} - if 'true' the RBAC Role specified in endRange is also controlled by the administratrator</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginTime} - HHMM - determines begin hour adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endTime} - HHMM - determines end hour adminRole may be activated into user's ARBAC session.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginDate} - YYYYMMDD - determines date when adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endDate} - YYYYMMDD - indicates latest date adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's ARBAC session</li>
+     * </ul>
+     *
+     * @param role Contains role name and description.
+     * @return AdminRole contains reference to entity operated on.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public AdminRole addRole(AdminRole role)
+        throws SecurityException
+    {
+        String methodName = "addRole";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ARLE_NULL);
+        setEntitySession(CLS_NM, methodName, role);
+        return admRP.add(role);
+    }
+
+    /**
+     * This command deletes an existing admin role from the ARBAC database. The command is valid
+     * if and only if the role to be deleted is a member of the ADMIN ROLES data set.  This command will
+     * also deassign role from all users.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains the name of the new AdminRole being targeted for removal</li>
+     * </ul>
+     * <p/>
+     *
+     * @param role Contains role name.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteRole(AdminRole role)
+        throws SecurityException
+    {
+        String methodName = "deleteRole";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ARLE_NULL);
+        setEntitySession(CLS_NM, methodName, role);
+        int numChildren = AdminRoleUtil.numChildren( role.getName(), role.getContextId() );
+        if (numChildren > 0)
+        {
+            String error =  methodName + " role [" + role.getName() + "] must remove [" + numChildren + "] descendants before deletion";
+            throw new SecurityException(GlobalErrIds.HIER_DEL_FAILED_HAS_CHILD, error, null);
+        }
+        // search for all users assigned this role and deassign:
+        List<User> users = userP.getAssignedUsers(role);
+        if (users != null)
+        {
+            for (User ue : users)
+            {
+                User user = new User(ue.getUserId());
+                UserAdminRole uAdminRole = new UserAdminRole(ue.getUserId(), role.getName());
+                uAdminRole.setContextId(contextId);
+                setAdminData(CLS_NM, methodName, user);
+                deassignUser(uAdminRole);
+            }
+        }
+        permP.remove(role);
+        // remove all parent relationships from the role graph:
+        Set<String> parents = AdminRoleUtil.getParents(role.getName(), this.contextId);
+        if(parents != null)
+        {
+            for(String parent : parents)
+            {
+                AdminRoleUtil.updateHier(this.contextId, new Relationship(role.getName().toUpperCase(), parent.toUpperCase()), Hier.Op.REM);
+            }
+        }
+        admRP.delete(role);
+    }
+
+    /**
+     * Method will update an AdminRole entity in the directory.  The role must exist in directory prior to this call.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains the name of the new AdminRole being targeted for updating</li>
+     * </ul>
+     * <p/>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#description} - contains any safe text</li>
+     * <li>{@link AdminRole#osPs} * - multi-occurring attribute used to set associations to existing PERMS OrgUnits</li>
+     * <li>{@link AdminRole#osUs} * - multi-occurring attribute used to set associations to existing USERS OrgUnits</li>
+     * <li>{@link AdminRole#beginRange} - contains the name of an existing RBAC Role that represents the lowest role in hierarchy that administrator (whoever has this AdminRole activated) controls</li>
+     * <li>{@link AdminRole#endRange} - contains the name of an existing RBAC Role that represents that highest role in hierarchy that administrator may control</li>
+     * <li>{@link AdminRole#beginInclusive} - if 'true' the RBAC Role specified in beginRange is also controlled by the posessor of this AdminRole</li>
+     * <li>{@link AdminRole#endInclusive} - if 'true' the RBAC Role specified in endRange is also controlled by the administratrator</li>
+     * <li>{@link AdminRole#beginTime} - HHMM - determines begin hour adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link AdminRole#endTime} - HHMM - determines end hour adminRole may be activated into user's ARBAC session.</li>
+     * <li>{@link AdminRole#beginDate} - YYYYMMDD - determines date when adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link AdminRole#endDate} - YYYYMMDD - indicates latest date adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's ARBAC session</li>
+     * </ul>
+     *
+     * @param role Contains role name and new description.
+     * @return AdminRole contains reference to entity operated on.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Description of the Exception
+     */
+    @Override
+    public AdminRole updateRole(AdminRole role)
+        throws SecurityException
+    {
+        String methodName = "updateRole";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ARLE_NULL);
+        setEntitySession(CLS_NM, methodName, role);
+        AdminRole re = admRP.update(role);
+        // search for all users assigned this role and update:
+        List<User> users = userP.getAssignedUsers(role);
+        if(VUtil.isNotNullOrEmpty(users))
+        {
+            final AdminMgr aMgr = AdminMgrFactory.createInstance(this.contextId);
+            for (User ue : users)
+            {
+                User upUe = new User(ue.getUserId());
+                setAdminData(CLS_NM, methodName, upUe);
+                List<UserAdminRole> uaRoles = ue.getAdminRoles();
+                UserAdminRole chgRole = new UserAdminRole();
+                chgRole.setName(role.getName());
+                chgRole.setUserId(ue.getUserId());
+                chgRole.setOsP(role.getOsP());
+                chgRole.setOsU(role.getOsU());
+                uaRoles.remove(chgRole);
+                CUtil.copy(re, chgRole);
+                uaRoles.add(chgRole);
+                upUe.setUserId(ue.getUserId());
+                upUe.setAdminRole(chgRole);
+                aMgr.updateUser(upUe);
+            }
+        }
+        return re;
+    }
+
+
+    /**
+     * 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>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#name} - contains the name for already existing AdminRole to be assigned</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#beginTime} - HHMM - determines begin hour AdminRole may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#endTime} - HHMM - determines end hour AdminRole may be activated into user's RBAC session.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#beginDate} - YYYYMMDD - determines date when AdminRole may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#endDate} - YYYYMMDD - indicates latest date AdminRole may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's ARBAC session</li>
+     * </ul>
+     *
+     * @param uAdminRole entity contains {@link org.apache.directory.fortress.core.rbac.User#userId} and {@link org.apache.directory.fortress.core.rbac.AdminRole#name} and optional {@code org.apache.directory.fortress.core.rbac.Constraints}.
+     * @throws SecurityException in the event data error in user or role objects or system error.
+     */
+    @Override
+    public void assignUser(UserAdminRole uAdminRole)
+        throws SecurityException
+    {
+        String methodName = "assignUser";
+        assertContext(CLS_NM, methodName, uAdminRole, GlobalErrIds.ARLE_NULL);
+        setEntitySession(CLS_NM, methodName, uAdminRole);
+
+        AdminRole adminRole = new AdminRole(uAdminRole.getName());
+        adminRole.setContextId(uAdminRole.getContextId());
+        // retrieve the admin role info:
+        AdminRole validRole = admRP.read(adminRole);
+
+        // if the UserAdminRole entity doesn't have temporal constraints set already, copy from the AdminRole declaration:
+        // if the input role entity attribute doesn't have temporal constraints set, copy from the role declaration:
+        CUtil.validateOrCopy(validRole, uAdminRole);
+
+        // copy the ARBAC AdminRole attributes to UserAdminRole:
+        AttrHelper.copyAdminAttrs(validRole, uAdminRole);
+        String dn = userP.assign(uAdminRole);
+        // copy the admin session info to AdminRole:
+        setAdminData(CLS_NM, methodName, validRole);
+        // Assign user dn attribute to the adminRole, this will add a single, standard attribute value, called "roleOccupant", directly onto the adminRole node:
+        admRP.assign(validRole, dn);
+    }
+
+
+    /**
+     * 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.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#name} - contains the name for already existing AdminRole to be deassigned</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     *
+     * @param uAdminRole entity contains {@link org.apache.directory.fortress.core.rbac.User#userId} and {@link org.apache.directory.fortress.core.rbac.AdminRole#name}.
+     * @throws SecurityException - in the event data error in user or role objects or system error.
+     */
+    @Override
+    public void deassignUser(UserAdminRole uAdminRole)
+        throws SecurityException
+    {
+        String methodName = "deassignUser";
+        assertContext(CLS_NM, methodName, uAdminRole, GlobalErrIds.ARLE_NULL);
+        setEntitySession(CLS_NM, methodName, uAdminRole);
+        String dn = userP.deassign(uAdminRole);
+        AdminRole adminRole = new AdminRole(uAdminRole.getName());
+        // copy the ARBAC attributes to AdminRole:
+        setAdminData(CLS_NM, methodName, adminRole);
+        // Deassign user dn attribute to the adminRole, this will remove a single, standard attribute value, called "roleOccupant", directly onto the adminRole node:
+        admRP.deassign(adminRole, dn);
+    }
+
+
+    /**
+     * Commands adds a new OrgUnit entity to OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new USERS or PERMS OrgUnit to be added</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit contains reference to entity added.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public OrgUnit add(OrgUnit entity)
+        throws SecurityException
+    {
+        String methodName = "addOU";
+        assertContext(CLS_NM, methodName, entity, GlobalErrIds.ORG_NULL);
+        setEntitySession(CLS_NM, methodName, entity);
+        VUtil.assertNotNull(entity.getType(), GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        return ouP.add(entity);
+    }
+
+    /**
+     * Commands updates existing OrgUnit entity to OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new USERS or PERMS OrgUnit to be updated</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit contains reference to entity operated on.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public OrgUnit update(OrgUnit entity)
+        throws SecurityException
+    {
+        String methodName = "updateOU";
+        assertContext(CLS_NM, methodName, entity, GlobalErrIds.ORG_NULL);
+        setEntitySession(CLS_NM, methodName, entity);
+        VUtil.assertNotNull(entity.getType(), GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        return ouP.update(entity);
+    }
+
+    /**
+     * Commands deletes existing OrgUnit entity to OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new USERS or PERMS OrgUnit to be removed</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit contains reference to entity operated on.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public OrgUnit delete(OrgUnit entity)
+        throws SecurityException
+    {
+        String methodName = "deleteOU";
+        assertContext(CLS_NM, methodName, entity, GlobalErrIds.ORG_NULL);
+        setEntitySession(CLS_NM, methodName, entity);
+        VUtil.assertNotNull(entity.getType(), GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        int numChildren;
+        if (entity.getType() == OrgUnit.Type.USER)
+        {
+            numChildren = UsoUtil.numChildren( entity.getName(), entity.getContextId() );
+        }
+        else
+        {
+            numChildren = PsoUtil.numChildren( entity.getName(), entity.getContextId() );
+        }
+        if (numChildren > 0)
+        {
+            String error =  methodName + " orgunit [" + entity.getName() + "] must remove [" + numChildren + "] descendants before deletion";
+            throw new SecurityException(GlobalErrIds.HIER_DEL_FAILED_HAS_CHILD, error, null);
+        }
+        if (entity.getType() == OrgUnit.Type.USER)
+        {
+            // Ensure the org unit is not assigned to any users, but set the sizeLimit to "true" to limit result set size.
+            List<User> assignedUsers = userP.search(entity, true);
+            if (VUtil.isNotNullOrEmpty(assignedUsers))
+            {
+                String error =  methodName + " orgunit [" + entity.getName() + "] must unassign [" + assignedUsers.size() + "] users before deletion";
+                throw new SecurityException(GlobalErrIds.ORG_DEL_FAILED_USER, error, null);
+            }
+        }
+        else
+        {
+            // Ensure the org unit is not assigned to any permission objects but set the sizeLimit to "true" to limit result set size..
+            // pass a "false" which places no restrictions on how many records server returns.
+            List<PermObj> assignedPerms = permP.search(entity, false);
+            if (VUtil.isNotNullOrEmpty(assignedPerms))
+            {
+                String error =  methodName + " orgunit [" + entity.getName() + "] must unassign [" + assignedPerms.size() + "] perm objs before deletion";
+                throw new SecurityException(GlobalErrIds.ORG_DEL_FAILED_PERM, error, null);
+            }
+        }
+        // remove all parent relationships from this org graph:
+        Set<String> parents;
+        if (entity.getType() == OrgUnit.Type.USER)
+        {
+            parents = UsoUtil.getParents(entity.getName(), this.contextId);
+        }
+        else
+        {
+            parents = PsoUtil.getParents(entity.getName(), this.contextId);
+        }
+        if(parents != null)
+        {
+            for(String parent : parents)
+            {
+                if (entity.getType() == OrgUnit.Type.USER)
+                {
+                    UsoUtil.updateHier(this.contextId, new Relationship(entity.getName().toUpperCase(), parent.toUpperCase()), Hier.Op.REM);
+                }
+                else
+                {
+                    PsoUtil.updateHier(this.contextId, new Relationship(entity.getName().toUpperCase(), parent.toUpperCase()), Hier.Op.REM);
+                }
+            }
+        }
+        // everything checked out good - remove the org unit from the OrgUnit data set:
+        return ouP.delete(entity);
+    }
+
+
+    /**
+     * This command creates a new orgunit child, and inserts it in the orgunit hierarchy as an immediate descendant of
+     * the existing orgunit parent.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The child orgunit is not a member of the ORGUNITS data set.
+     * <li> The parent orgunit is a member of the ORGUNITS data set.
+     * </ul>
+     * </p>
+     * <p> This method:
+     * <ul>
+     * <li> Adds new orgunit.
+     * <li> Assigns orgunit relationship between new child and pre-existing parent.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new OrgUnit to be child</li>
+     * </ul>
+     * <h4>optional parameters child</h4>
+     * <ul>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#description} - maps to description attribute on organizationalUnit object class for new child</li>
+     * </ul>
+     *
+     * @param parent This entity must be present in ORGUNIT data set.  Success will add rel with child.
+     * @param child  This entity must not be present in ORGUNIT data set.  Success will add the new entity to ORGUNIT data set.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addDescendant(OrgUnit parent, OrgUnit child)
+        throws SecurityException
+    {
+        String methodName = "addDescendantOU";
+        assertContext(CLS_NM, methodName, parent, GlobalErrIds.ORG_PARENT_NULL);
+        VUtil.assertNotNull(parent.getType(), GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        assertContext(CLS_NM, methodName, child, GlobalErrIds.ORG_CHILD_NULL);
+        setEntitySession(CLS_NM, methodName, child);
+
+        // ensure the parent OrgUnit exists:
+        ouP.read(parent);
+        if (parent.getType() == OrgUnit.Type.USER)
+        {
+            UsoUtil.validateRelationship(child, parent, false);
+        }
+        else
+        {
+            PsoUtil.validateRelationship(child, parent, false);
+        }
+        child.setParent(parent.getName());
+        ouP.add(child);
+        if (parent.getType() == OrgUnit.Type.USER)
+        {
+            UsoUtil.updateHier(this.contextId, new Relationship(child.getName().toUpperCase(), parent.getName().toUpperCase()), Hier.Op.ADD);
+        }
+        else
+        {
+            PsoUtil.updateHier(this.contextId, new Relationship(child.getName().toUpperCase(), parent.getName().toUpperCase()), Hier.Op.ADD);
+        }
+    }
+
+    /**
+     * This command creates a new orgunit parent, and inserts it in the orgunit hierarchy as an immediate ascendant of
+     * the existing child orgunit.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The parent is not a member of the ORGUNITS data set.
+     * <li> The child is a member of the ORGUNITS data set.
+     * </ul>
+     * </p>
+     * <p> This method:
+     * <ul>
+     * <li> Adds new orgunit.
+     * <li> Assigns orgunit relationship between new parent and pre-existing child.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be parent</li>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>child - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new OrgUnit to be child</li>
+     * </ul>
+     * <h4>optional parameters child</h4>
+     * <ul>
+     * <li>child - {@link org.apache.directory.fortress.core.rbac.OrgUnit#description} - maps to description attribute on organizationalUnit object class for new child</li>
+     * </ul>
+     *
+     * @param parent completion of op assigns new child relationship with child orgunit.
+     * @param child  completion of op assigns new parent relationship with parent orgunit.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addAscendant(OrgUnit child, OrgUnit parent)
+        throws SecurityException
+    {
+        String methodName = "addAscendantOU";
+        assertContext(CLS_NM, methodName, parent, GlobalErrIds.ORG_PARENT_NULL);
+        VUtil.assertNotNull(parent.getType(), GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        setEntitySession(CLS_NM, methodName, parent);
+        assertContext(CLS_NM, methodName, child, GlobalErrIds.ORG_CHILD_NULL);
+
+        // ensure the child OrgUnit exists:
+        OrgUnit newChild = ouP.read(child);
+        if (parent.getType() == OrgUnit.Type.USER)
+        {
+            UsoUtil.validateRelationship(child, parent, false);
+        }
+        else
+        {
+            PsoUtil.validateRelationship(child, parent, false);
+        }
+        ouP.add(parent);
+        newChild.setParent(parent.getName());
+        newChild.setContextId(this.contextId);
+        ouP.update(newChild);
+        if (parent.getType() == OrgUnit.Type.USER)
+        {
+            UsoUtil.updateHier(this.contextId, new Relationship(child.getName().toUpperCase(), parent.getName().toUpperCase()), Hier.Op.ADD);
+        }
+        else
+        {
+            PsoUtil.updateHier(this.contextId, new Relationship(child.getName().toUpperCase(), parent.getName().toUpperCase()), Hier.Op.ADD);
+        }
+    }
+
+    /**
+     * This command establishes a new immediate inheritance relationship with parent orgunit <<-- child orgunit
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The parent and child are members of the ORGUNITS data set.
+     * <li> The parent is not an immediate ascendant of child.
+     * <li> The child does not properly inherit parent (in order to avoid cycle creation).
+     * </ul>
+     * </p>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be parent</li>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>child - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be child</li>
+     * </ul>
+     *
+     * @param parent completion of op deassigns child relationship with child orgunit.
+     * @param child  completion of op deassigns parent relationship with parent orgunit.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addInheritance(OrgUnit parent, OrgUnit child)
+        throws SecurityException
+    {
+        String methodName = "addInheritanceOU";
+        assertContext(CLS_NM, methodName, parent, GlobalErrIds.ORG_PARENT_NULL);
+        VUtil.assertNotNull(parent.getType(), GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        assertContext(CLS_NM, methodName, child, GlobalErrIds.ORG_CHILD_NULL);
+        setEntitySession(CLS_NM, methodName, parent);
+        if (parent.getType() == OrgUnit.Type.USER)
+        {
+            UsoUtil.validateRelationship(child, parent, false);
+        }
+        else
+        {
+            PsoUtil.validateRelationship(child, parent, false);
+        }
+        // validate that both orgs are present:
+        ouP.read(parent);
+        OrgUnit cOrg = ouP.read(child);
+        cOrg.setParent(parent.getName());
+        cOrg.setContextId(this.contextId);
+        setAdminData(CLS_NM, methodName, cOrg);
+        ouP.update(cOrg);
+
+        // we're still good, now set the hierarchical relationship:
+        if (parent.getType() == OrgUnit.Type.USER)
+        {
+            UsoUtil.updateHier(this.contextId, new Relationship(child.getName().toUpperCase(), parent.getName().toUpperCase()), Hier.Op.ADD);
+        }
+        else
+        {
+            PsoUtil.updateHier(this.contextId, new Relationship(child.getName().toUpperCase(), parent.getName().toUpperCase()), Hier.Op.ADD);
+        }
+    }
+
+    /**
+     * This command deletes an existing immediate inheritance relationship parent <<-- child.
+     * <p/>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The orgunits parent and child are members of the ORGUNITS data set.
+     * <li> The parent is an immediate ascendant of child.
+     * <li> The new inheritance relation is computed as the reflexive-transitive closure of the immediate inheritance
+     * relation resulted after deleting the relationship parent <<-- child.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to remove as parent</li>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>child - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to remove as child</li>
+     * </ul>
+     *
+     * @param parent completion of op removes child relationship with childRole.
+     * @param child  completion of op removes parent relationship with parentRole.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteInheritance(OrgUnit parent, OrgUnit child)
+        throws SecurityException
+    {
+        String methodName = "deleteInheritanceOU";
+        assertContext(CLS_NM, methodName, parent, GlobalErrIds.ORG_PARENT_NULL);
+        VUtil.assertNotNull(parent.getType(), GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        assertContext(CLS_NM, methodName, child, GlobalErrIds.ORG_CHILD_NULL);
+        setEntitySession(CLS_NM, methodName, parent);
+        if (parent.getType() == OrgUnit.Type.USER)
+        {
+            UsoUtil.validateRelationship(child, parent, true);
+        }
+        else
+        {
+            PsoUtil.validateRelationship(child, parent, true);
+        }
+        if (parent.getType() == OrgUnit.Type.USER)
+        {
+            UsoUtil.updateHier(this.contextId, new Relationship(child.getName().toUpperCase(), parent.getName().toUpperCase()), Hier.Op.REM);
+        }
+        else
+        {
+            PsoUtil.updateHier(this.contextId, new Relationship(child.getName().toUpperCase(), parent.getName().toUpperCase()), Hier.Op.REM);
+        }
+        OrgUnit cOrg = ouP.read(child);
+        cOrg.setContextId(this.contextId);
+        cOrg.delParent(parent.getName());
+        setAdminData(CLS_NM, methodName, cOrg);
+        // are there any parents left?
+        if(!VUtil.isNotNullOrEmpty(cOrg.getParents()))
+        {
+            // The updates only update non-empty multi-occurring attributes
+            // so if last parent assigned, so must remove the attribute completely:
+            ouP.deleteParent(cOrg);
+        }
+        else
+        {
+            ouP.update(cOrg);
+        }
+    }
+
+
+    /**
+     * This command creates a new role childRole, and inserts it in the role hierarchy as an immediate descendant of
+     * the existing role parentRole. The command is valid if and only if childRole is not a member of the ADMINROLES data set,
+     * and parentRole is a member of the ADMINROLES data set.
+     * <p/>
+     * This method:
+     * 1 - Adds new role.
+     * 2 - Assigns role relationship between new childRole and pre-existing parentRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link AdminRole#name} - contains the name of existing Role to be parent</li>
+     * <li>childRole - {@link AdminRole#name} - contains the name of new Role to be child</li>
+     * </ul>
+     * <h4>optional parameters childRole</h4>
+     * <ul>
+     * <li>childRole - {@link AdminRole#description} - maps to description attribute on organizationalRole object class for new child</li>
+     * <li>childRole - {@link AdminRole#beginTime} - HHMM - determines begin hour role may be activated into user's session for new child</li>
+     * <li>childRole - {@link AdminRole#endTime} - HHMM - determines end hour role may be activated into user's session for new child</li>
+     * <li>childRole - {@link AdminRole#beginDate} - YYYYMMDD - determines date when role may be activated into user's session for new child</li>
+     * <li>childRole - {@link AdminRole#endDate} - YYYYMMDD - indicates latest date role may be activated into user's session for new child</li>
+     * <li>childRole - {@link AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new child</li>
+     * <li>childRole - {@link AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new child</li>
+     * <li>childRole - {@link AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's session for new child</li>
+     * </ul>
+     *
+     * @param parentRole This entity must be present in ADMINROLES data set.  Success will add role rel with childRole.
+     * @param childRole  This entity must not be present in ADMINROLES data set.  Success will add the new role entity to ADMINROLES data set.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addDescendant(AdminRole parentRole, AdminRole childRole)
+        throws SecurityException
+    {
+        String methodName = "addDescendantRole";
+        assertContext(CLS_NM, methodName, parentRole, GlobalErrIds.ARLE_PARENT_NULL);
+        assertContext(CLS_NM, methodName, childRole, GlobalErrIds.ARLE_CHILD_NULL);
+        setEntitySession(CLS_NM, methodName, childRole);
+        // ensure the parent AdminRole exists:
+        admRP.read(parentRole);
+        AdminRoleUtil.validateRelationship(childRole, parentRole, false);
+        childRole.setParent(parentRole.getName());
+        admRP.add(childRole);
+        AdminRoleUtil.updateHier(this.contextId, new Relationship(childRole.getName().toUpperCase(), parentRole.getName().toUpperCase()), Hier.Op.ADD);
+    }
+
+
+    /**
+     * This command creates a new role parentRole, and inserts it in the role hierarchy as an immediate ascendant of
+     * the existing role childRole. The command is valid if and only if parentRole is not a member of the ROLES data set,
+     * and childRole is a member of the ROLES data set.
+     * This method:
+     * 1 - Adds new role.
+     * 2 - Assigns role relationship between new parentRole and pre-existing childRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>childRole - {@link AdminRole#name} - contains the name of existing Role to be child</li>
+     * <li>parentRole - {@link AdminRole#name} - contains the name of new Role to be added as parent</li>
+     * </ul>
+     * <h4>optional parameters parentRole</h4>
+     * <ul>
+     * <li>parentRole - {@link AdminRole#description} - maps to description attribute on organizationalRole object class for new parent</li>
+     * <li>parentRole - {@link AdminRole#beginTime} - HHMM - determines begin hour role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link AdminRole#endTime} - HHMM - determines end hour role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link AdminRole#beginDate} - YYYYMMDD - determines date when role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link AdminRole#endDate} - YYYYMMDD - indicates latest date role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new parent</li>
+     * <li>parentRole - {@link AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new parent</li>
+     * <li>parentRole - {@link AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's session for new parent</li>
+     * </ul>
+     *
+     * @param parentRole completion of op assigns new child relationship with childRole.
+     * @param childRole  completion of op assigns new parent relationship with parentRole.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addAscendant(AdminRole childRole, AdminRole parentRole)
+        throws SecurityException
+    {
+        String methodName = "addAscendantRole";
+        assertContext(CLS_NM, methodName, parentRole, GlobalErrIds.ARLE_PARENT_NULL);
+        setEntitySession(CLS_NM, methodName, parentRole);
+        assertContext(CLS_NM, methodName, childRole, GlobalErrIds.ARLE_CHILD_NULL);
+        // ensure the child AdminRole exists:
+        AdminRole newChild = admRP.read(childRole);
+        AdminRoleUtil.validateRelationship(childRole, parentRole, false);
+        admRP.add(parentRole);
+
+        // Use cRole2 to update ONLY the parents attribute on the child role and nothing else:
+        AdminRole cRole2 = new AdminRole(childRole.getName());
+        cRole2.setParents(newChild.getParents());
+        cRole2.setParent(parentRole.getName());
+        cRole2.setContextId(this.contextId);
+        setAdminData(CLS_NM, methodName, cRole2);
+        admRP.update(cRole2);
+        AdminRoleUtil.updateHier(this.contextId, new Relationship(childRole.getName().toUpperCase(), parentRole.getName().toUpperCase()), Hier.Op.ADD);
+    }
+
+
+    /**
+     * This command establishes a new immediate inheritance relationship parentRole <<-- childRole between existing
+     * roles parentRole, childRole. The command is valid if and only if parentRole and childRole are members of the ROLES data
+     * set, parentRole is not an immediate ascendant of childRole, and childRole does not properly inherit parentRole (in order to
+     * avoid cycle creation).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link AdminRole#name} - contains the name of existing AdminRole to be parent</li>
+     * <li>childRole - {@link AdminRole#name} - contains the name of existing AdminRole to be child</li>
+     * </ul>
+     *
+     * @param parentRole completion of op deassigns child relationship with childRole.
+     * @param childRole  completion of op deassigns parent relationship with parentRole.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addInheritance(AdminRole parentRole, AdminRole childRole)
+        throws SecurityException
+    {
+        String methodName = "addInheritanceRole";
+        assertContext(CLS_NM, methodName, parentRole, GlobalErrIds.ARLE_PARENT_NULL);
+        assertContext(CLS_NM, methodName, childRole, GlobalErrIds.ARLE_CHILD_NULL);
+        setEntitySession(CLS_NM, methodName, parentRole);
+        // make sure the parent role is already there:
+        admRP.read(parentRole);
+        AdminRoleUtil.validateRelationship(childRole, parentRole, false);
+        // make sure the child role is already there:
+        AdminRole cRole = new AdminRole(childRole.getName());
+        cRole.setContextId(this.contextId);
+        cRole = admRP.read(cRole);
+        // Use cRole2 to update ONLY the parents attribute on the child role and nothing else:
+        AdminRole cRole2 = new AdminRole(childRole.getName());
+        cRole2.setParents(cRole.getParents());
+        cRole2.setParent(parentRole.getName());
+        cRole2.setContextId(this.contextId);
+        setAdminData(CLS_NM, methodName, cRole2);
+        AdminRoleUtil.updateHier(this.contextId, new Relationship(childRole.getName().toUpperCase(), parentRole.getName().toUpperCase()), Hier.Op.ADD);
+        admRP.update(cRole2);
+    }
+
+
+    /**
+     * This command deletes an existing immediate inheritance relationship parentRole <<-- childRole. The command is
+     * valid if and only if the roles parentRole and childRole are members of the ROLES data set, and parentRole is an
+     * immediate ascendant of childRole. The new inheritance relation is computed as the reflexive-transitive
+     * closure of the immediate inheritance relation resulted after deleting the relationship parentRole <<-- childRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link AdminRole#name} - contains the name of existing AdminRole to remove as parent</li>
+     * <li>childRole - {@link AdminRole#name} - contains the name of existing AdminRole to remove as child</li>
+     * </ul>
+     *
+     * @param parentRole completion of op removes child relationship with childRole.
+     * @param childRole  completion of op removes parent relationship with parentRole.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteInheritance(AdminRole parentRole, AdminRole childRole)
+        throws SecurityException
+    {
+        String methodName = "deleteInheritanceRole";
+        assertContext(CLS_NM, methodName, parentRole, GlobalErrIds.ARLE_PARENT_NULL);
+        assertContext(CLS_NM, methodName, childRole, GlobalErrIds.ARLE_CHILD_NULL);
+        setEntitySession(CLS_NM, methodName, parentRole);
+        AdminRoleUtil.validateRelationship(childRole, parentRole, true);
+        AdminRoleUtil.updateHier(this.contextId, new Relationship(childRole.getName().toUpperCase(), parentRole.getName().toUpperCase()), Hier.Op.REM);
+        // need to remove the parent from the child role:
+        AdminRole cRole = new AdminRole(childRole.getName());
+        cRole.setContextId(this.contextId);
+        cRole = admRP.read(cRole);
+        // Use cRole2 to update ONLY the parents attribute on the child role and nothing else:
+        AdminRole cRole2 = new AdminRole(childRole.getName());
+        cRole2.setParents(cRole.getParents());
+        cRole2.delParent(parentRole.getName());
+        cRole2.setContextId(this.contextId);
+        setAdminData(CLS_NM, methodName, cRole2);
+        // are there any parents left?
+        if(!VUtil.isNotNullOrEmpty(cRole2.getParents()))
+        {
+            // The updates only update non-empty multi-occurring attributes
+            // so if last parent assigned, so must remove the attribute completely:
+            admRP.deleteParent(cRole2);
+        }
+        else
+        {
+            admRP.update(cRole2);
+        }
+    }
+
+    /**
+     * This method will add an administrative permission operation to an existing permission object which resides under {@code ou=AdminPerms,ou=ARBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may have {@link AdminRole} or {@link org.apache.directory.fortress.core.rbac.User} associations.  The target {@link org.apache.directory.fortress.core.rbac.Permission} must not exist prior to calling.
+     * A Fortress Permission instance exists in a hierarchical, one-many relationship between its parent and itself as stored in ldap tree: ({@link PermObj}*->{@link org.apache.directory.fortress.core.rbac.Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the name of existing object being targeted for the permission add</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the name of new permission operation being added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target along with optional other attributes..
+     * @return copy of Permission entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public Permission addPermission(Permission perm)
+        throws SecurityException
+    {
+        final AdminMgr adminMgr = AdminMgrFactory.createInstance(this.contextId);
+        perm.setAdmin(true);
+        return adminMgr.addPermission(perm);
+    }
+
+    /**
+     * This method will update administrative permission operation pre-existing in target directory under {@code ou=AdminPerms,ou=ARBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may also contain {@link AdminRole} or {@link org.apache.directory.fortress.core.rbac.User} associations to add or remove using this function.
+     * The perm operation must exist before making this call.  Only non-null attributes will be updated.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission update</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
+     * <li>{@link Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
+     * <li>{@link Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target and any optional data to update.  Null or empty attributes will be ignored.
+     * @return copy of Permission entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public Permission updatePermission(Permission perm)
+        throws SecurityException
+    {
+        final AdminMgr adminMgr = AdminMgrFactory.createInstance(this.contextId);
+        perm.setAdmin(true);
+        return adminMgr.updatePermission(perm);
+    }
+
+    /**
+     * This method will remove administrative permission operation entity from permission object. A Fortress permission is (object->operation).
+     * The perm operation must exist before making this call.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission delete</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation being removed</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public void deletePermission(Permission perm)
+        throws SecurityException
+    {
+        final AdminMgr adminMgr = AdminMgrFactory.createInstance(this.contextId);
+        perm.setAdmin(true);
+        adminMgr.deletePermission(perm);
+    }
+
+    /**
+     * This method will add administrative permission object to admin perms container in directory. The perm object must not exist before making this call.
+     * A {@link PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link PermObj}*->{@link Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of new object being added</li>
+     * <li>{@link PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#description} - any safe text</li>
+     * <li>{@link PermObj#type} - contains any safe text</li>
+     * <li>{@link PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link PermObj#objName} and {@link PermObj#ou}.  The other attributes are optional.
+     * @return copy of PermObj entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public PermObj addPermObj(PermObj pObj)
+        throws SecurityException
+    {
+        final AdminMgr adminMgr = AdminMgrFactory.createInstance(this.contextId);
+        pObj.setAdmin(true);
+        return adminMgr.addPermObj(pObj);
+    }
+
+    /**
+     * This method will update administrative permission object in perms container in directory.  The perm object must exist before making this call.
+     * A {@link PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link PermObj}*->{@link Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of existing object being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * <li>{@link PermObj#description} - any safe text</li>
+     * <li>{@link PermObj#type} - contains any safe text</li>
+     * <li>{@link PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link PermObj#objName}. Only non-null attributes will be updated.
+     * @return copy of newly updated PermObj entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public PermObj updatePermObj(PermObj pObj)
+        throws SecurityException
+    {
+        final AdminMgr adminMgr = AdminMgrFactory.createInstance(this.contextId);
+        pObj.setAdmin(true);
+        return adminMgr.updatePermObj(pObj);
+    }
+
+    /**
+     * This method will remove administrative permission object from perms container in directory.  This method will also remove
+     * in associated permission objects that are attached to this object.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of existing object targeted for removal</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link PermObj#objName} of object targeted for removal.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public void deletePermObj(PermObj pObj)
+        throws SecurityException
+    {
+        final AdminMgr adminMgr = AdminMgrFactory.createInstance(this.contextId);
+        pObj.setAdmin(true);
+        adminMgr.deletePermObj(pObj);
+    }
+
+    /**
+     * This command grants an AdminRole the administrative permission to perform an operation on an object to a role.
+     * The command is implemented by granting administrative permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * and the adminRole is a member of the ADMIN_ROLES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link AdminRole#name} - contains the adminRole name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param role must contains {@link AdminRole#name}.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void grantPermission(Permission perm, AdminRole role)
+        throws SecurityException
+    {
+        final AdminMgr adminMgr = AdminMgrFactory.createInstance(this.contextId);
+        perm.setAdmin(true);
+        adminMgr.grantPermission(perm, role);
+    }
+
+    /**
+     * This command revokes the administrative permission to perform an operation on an object from the set
+     * of permissions assigned to an AdminRole. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * the role is a member of the ADMIN_ROLES data set, and the permission is assigned to that AdminRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link AdminRole#name} - contains the adminRole name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param role must contains {@link AdminRole#name}.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void revokePermission(Permission perm, AdminRole role)
+        throws SecurityException
+    {
+        final AdminMgr adminMgr = AdminMgrFactory.createInstance(this.contextId);
+        perm.setAdmin(true);
+        adminMgr.revokePermission(perm, role);
+    }
+
+    /**
+     * This command grants a user the administrative permission to perform an operation on an object to a user.
+     * The command is implemented by granting administrative permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents an administrative permission,
+     * and the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param user must contain {@link User#userId} of target User entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void grantPermission(Permission perm, User user)
+        throws SecurityException
+    {
+        final AdminMgr adminMgr = AdminMgrFactory.createInstance(this.contextId);
+        perm.setAdmin(true);
+        adminMgr.grantPermission(perm, user);
+    }
+
+    /**
+     * This command revokes the administrative permission to perform an operation on an object from the set
+     * of permissions assigned to a user. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents an administrative permission,
+     * the user is a member of the USERS data set, and the permission is assigned to that user.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param user must contain {@link User#userId} of target User entity.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void revokePermission(Permission perm, User user)
+        throws SecurityException
+    {
+        final AdminMgr adminMgr = AdminMgrFactory.createInstance(this.contextId);
+        perm.setAdmin(true);
+        adminMgr.revokePermission(perm, user);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/DelReviewMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/DelReviewMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/rbac/DelReviewMgrImpl.java
new file mode 100755
index 0000000..c4caa02
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/DelReviewMgrImpl.java
@@ -0,0 +1,207 @@
+/*
+ *   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 org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.DelReviewMgr;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.List;
+
+/**
+ * This class implements the ARBAC02 DelReviewMgr interface for performing policy interrogation of provisioned Fortress ARBAC entities
+ * that reside in LDAP directory.
+ * These APIs map directly to similar named APIs specified by ARBAC02 functions.  The ARBAC Functional specification describes delegated administrative
+ * operations for the creation and maintenance of ARBAC element sets and relations.  Delegated administrative review functions for performing administrative queries
+ * and system functions for creating and managing ARBAC attributes on user sessions and making delegated administrative access control decisions.
+ * <h3>Administrative Role Based Access Control (ARBAC)</h3>
+ * <img src="../doc-files/ARbac.png">
+ * <p/>
+ * Fortress fully supports the Oh/Sandhu/Zhang ARBAC02 model for delegated administration.  ARBAC provides large enterprises the capability to delegate administrative authority to users that reside outside of the security admin group.
+ * Decentralizing administration helps because it provides security provisioning capability to work groups without sacrificing regulations for accountability or traceability.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ * <p/>
+ * This class is NOT thread safe if parent instance variables ({@link #contextId} or {@link #adminSess}) are set.
+ */
+public class DelReviewMgrImpl extends Manageable implements DelReviewMgr
+{
+    private static final String CLS_NM = DelReviewMgrImpl.class.getName();
+    private static final UserP userP = new UserP();
+    private static final OrgUnitP ouP = new OrgUnitP();
+    private static final AdminRoleP admRP = new AdminRoleP();
+
+    // package private constructor ensures outside classes cannot use:
+    DelReviewMgrImpl()
+    {}
+
+    /**
+     * Method reads Admin Role entity from the admin role container in directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of the AdminRole being targeted for read</li>
+     * </ul>
+     *
+     * @param role contains role name to be read.
+     * @return AdminRole entity that corresponds with role name.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          will be thrown if role not found or system error occurs.
+     */
+    @Override
+    public AdminRole readRole(AdminRole role)
+        throws SecurityException
+    {
+        String methodName = "readRole";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ARLE_NULL);
+        checkAccess(CLS_NM, methodName);
+        return admRP.read(role);
+    }
+
+
+    /**
+     * Method will return a list of type Admin Role.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains all or some chars in the name of AdminRole(s) targeted for search</li>
+     * </ul>
+     *
+     * @param searchVal contains the all or some of the chars corresponding to admin role entities stored in directory.
+     * @return List of type AdminRole containing role entities that match the search criteria.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of system error.
+     */
+    @Override
+    public List<AdminRole> findRoles(String searchVal)
+        throws SecurityException
+    {
+        String methodName = "findRoles";
+        VUtil.assertNotNull(searchVal, GlobalErrIds.ARLE_NM_NULL, CLS_NM + "." + methodName);
+        checkAccess(CLS_NM, methodName);
+        AdminRole adminRole = new AdminRole(searchVal);
+        adminRole.setContextId(this.contextId);
+        return admRP.search(adminRole);
+    }
+
+    /**
+     * This function returns the set of admin roles assigned to a given user. The function is valid if and
+     * only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains userId matching user entity stored in the directory.
+     * @return List of type UserAdminRole containing the user admin role data.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          If user not found or system error occurs.
+     */
+    @Override
+    public List<UserAdminRole> assignedRoles(User user)
+        throws SecurityException
+    {
+        String methodName = "assignedRoles";
+        assertContext(CLS_NM, methodName, user, GlobalErrIds.USER_NULL);
+        checkAccess(CLS_NM, methodName);
+        User ue = userP.read(user, true);
+        return ue.getAdminRoles();
+    }
+
+
+    /**
+     * This method returns the data set of all users who are assigned the given admin role.  This searches the User data set for
+     * AdminRole relationship.  This method does NOT search for hierarchical Admin Roles relationships.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains the name of AdminRole targeted for search</li>
+     * </ul>
+     *
+     * @param role contains the role name used to search the User data set.
+     * @return List of type User containing the users assigned data.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          If system error occurs.
+     */
+    @Override
+    public List<User> assignedUsers(AdminRole role)
+        throws SecurityException
+    {
+        String methodName = "assignedUsers";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ARLE_NULL);
+        checkAccess(CLS_NM, methodName);
+        return userP.getAssignedUsers(role);
+    }
+
+
+    /**
+     * Commands reads existing OrgUnit entity from OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name associated with the OrgUnit object targeted for search.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit entity that corresponds with ou name and type.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public OrgUnit read(OrgUnit entity)
+        throws SecurityException
+    {
+        String methodName = "readOU";
+        assertContext(CLS_NM, methodName, entity, GlobalErrIds.ORG_NULL);
+        checkAccess(CLS_NM, methodName);
+        return ouP.read(entity);
+    }
+
+
+    /**
+     * Commands searches existing OrgUnit entities from OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type parameter on API.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link OrgUnit#type} - contains the type of OU:  {@link OrgUnit.Type#USER} or {@link OrgUnit.Type#PERM}</li>
+     * <li>searchVal - contains some or all of the chars associated with the OrgUnit objects targeted for search.</li>
+     * </ul>
+     *
+     * @param type      either PERM or USER
+     * @param searchVal contains the leading chars that map to {@link OrgUnit#name} on existing OrgUnit(s) targeted for search.
+     * @return List of type OrgUnit containing the OrgUnit data.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *
+     */
+    @Override
+    public List<OrgUnit> search(OrgUnit.Type type, String searchVal)
+        throws SecurityException
+    {
+        String methodName = "searchOU";
+        //VUtil.assertNotNullOrEmpty(searchVal, GlobalErrIds.ORG_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNull(type, GlobalErrIds.ORG_TYPE_NULL, CLS_NM + "." + methodName);
+        checkAccess(CLS_NM, methodName);
+        OrgUnit orgUnit = new OrgUnit(searchVal);
+        orgUnit.setType(type);
+        orgUnit.setContextId(this.contextId);
+        return ouP.search(orgUnit);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/FortEntity.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/FortEntity.java b/src/main/java/org/apache/directory/fortress/core/rbac/FortEntity.java
new file mode 100755
index 0000000..e1610cd
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/FortEntity.java
@@ -0,0 +1,236 @@
+/*
+ *   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.UUID;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * This abstract class is extended by other Fortress entities.  It is used to store contextual data that can be used for
+ * administrative RBAC checking in addition to associating an audit context with every LDAP operation.
+ * <p>
+ * <h4>Audit Context Schema</h4>
+ * The FortEntity Class is used to tag all Fortress LDAP records with variables contained within this auxiliary object class:
+ * <p/>
+ * ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Audit Modification Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.4
+ *  NAME 'ftMods'
+ *  DESC 'Fortress Modifiers AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftModifier $
+ *      ftModCode $
+ *      ftModId
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * This class is not thread safe.
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortEntity")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "fortEntity", propOrder =
+    {
+        "modId",
+        "modCode",
+        "sequenceId"
+})
+@XmlSeeAlso(
+    {
+        Role.class,
+        SDSet.class,
+        OrgUnit.class,
+        UserRole.class,
+        User.class,
+        Permission.class,
+        PermObj.class,
+        PwPolicy.class,
+        RoleRelationship.class,
+        PermGrant.class,
+        Session.class,
+        AdminRoleRelationship.class,
+        OrgUnitRelationship.class,
+        RolePerm.class,
+        UserAudit.class,
+        AuthZ.class,
+        Bind.class,
+        Mod.class,
+        Props.class
+})
+public abstract class FortEntity
+{
+protected String modCode;
+protected String modId;
+@XmlTransient
+protected Session adminSession;
+protected long sequenceId;
+@XmlTransient
+protected String contextId;
+
+
+/**
+ * Default constructor will call the setter to load a new internal ID into entity.
+ */
+public FortEntity()
+{
+    setInternalId();
+}
+
+
+/**
+ * Use this constructor to load administrative RBAC session into this entity.
+ *
+ * @param adminSession contains ARBAC Session object.
+ */
+public FortEntity( Session adminSession )
+{
+    setInternalId();
+    this.adminSession = adminSession;
+}
+
+
+/**
+ * This attribute is required but is set automatically by Fortress DAO class before object is persisted to ldap.
+ * This generated internal id is associated with PermObj.  This method is used by DAO class and
+ * is not available to outside classes.   The generated attribute maps to 'ftId' in 'ftObject' object class.
+ */
+private void setInternalId()
+{
+    UUID uuid = UUID.randomUUID();
+    this.modId = uuid.toString();
+}
+
+
+/**
+ * Return the ARBAC Session object that was loaded into this entity.
+ *
+ * @return ARBAC Session object.
+ */
+public Session getAdminSession()
+{
+    return adminSession;
+}
+
+
+/**
+ * Load an ARBAC Session object into this entity.  Once loaded, all Fortress Manager's will perform administrative
+ * permission checks against the User who is contained within the Session.
+ *
+ * @param adminSession
+ */
+public void setAdminSession( Session adminSession )
+{
+    this.adminSession = adminSession;
+}
+
+
+/**
+ * Contains the Fortress modification code to be associated with an audit record.  This is the ObjectName.methodName
+ * for the Manager API that was called.
+ *
+ * @return String contains the modification code maps to 'ftModCode' attribute in 'FortEntity' object class.
+ */
+public String getModCode()
+{
+    return modCode;
+}
+
+
+/**
+ * Set the Fortress modification code to be associated with an audit record.  Contains the Fortress modification code
+ * which is ObjectName.methodName for the Manager API that was called.
+ *
+ * @param modCode contains the modification code maps to 'ftModCode' attribute in 'FortEntity' object class.
+ */
+public void setModCode( String modCode )
+{
+    this.modCode = modCode;
+}
+
+
+/**
+ * Get the unique ID that is to be associated with a particular audit record in directory.
+ *
+ * @return attribute that maps to 'ftModId' attribute in 'FortEntity' object class.
+ */
+public String getModId()
+{
+    return modId;
+}
+
+
+/**
+ * Return the contextId for this record.  The contextId is used for multi-tenancy to isolate data sets within a particular sub-tree within DIT
+ *
+ * @return value maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ */
+public String getContextId()
+{
+    return contextId;
+}
+
+
+/**
+ * Set the contextId associated with this record.  The contextId is used for multi-tenancy to isolate data sets within a particular sub-tree within DIT.
+ * Package private to prevent outside classes from setting.
+ *
+ * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+ */
+public void setContextId( String contextId )
+{
+    this.contextId = contextId;
+}
+
+
+/**
+ * Sequence id is used internal to Fortress.
+ *
+ * @return long value contains sequence id.
+ */
+public long getSequenceId()
+{
+    return sequenceId;
+}
+
+
+/**
+ * Sequence id is used internal to Fortress
+ *
+ * @param sequenceId contains sequence to use.
+ */
+public void setSequenceId( long sequenceId )
+{
+    this.sequenceId = sequenceId;
+}
+}
\ 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/GlobalPwMsgIds.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/GlobalPwMsgIds.java b/src/main/java/org/apache/directory/fortress/core/rbac/GlobalPwMsgIds.java
new file mode 100755
index 0000000..cb590dd
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/GlobalPwMsgIds.java
@@ -0,0 +1,197 @@
+/*
+ *   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;
+
+/**
+ * This class contains constants that contain status for Fortress password policy checking.
+ *
+ * @author Shawn McKinney
+ */
+public class GlobalPwMsgIds
+    implements java.io.Serializable
+{
+    /**
+     * The processor could not process the password message.
+     */
+    public final static int INVALID_PASSWORD_MESSAGE = -10;
+
+    /**
+     * Password policies check out good.
+     */
+    public final static int GOOD = 0;
+
+    /**
+     * No warnings are associated with password.
+     */
+    public final static int PP_NOWARNING = 0;
+
+    /**
+     * The user has no password policies in effect.
+     */
+    public final static int NOT_PW_POLICY_ENABLED = 8;
+
+    /**
+     * The OPENLDAP password policies are not enforced.
+     */
+    public final static int NOT_OLPW_POLICY_ENABLED = 9;
+
+    /**
+     * The password policy control was not found in the message.
+     */
+    public final static int NO_CONTROLS_FOUND = 10;
+
+    /**
+     * The password is expiring.
+     */
+    public final static int PASSWORD_EXPIRATION_WARNING = 11;
+
+    /**
+     * Password in grace.
+     */
+    public final static int PASSWORD_GRACE_WARNING = 12;
+
+    /**
+     * The password has expired.
+     */
+    public final static int PASSWORD_HAS_EXPIRED = 100;
+
+    /**
+     * The User account is locked on the server.
+     */
+    public final static int ACCOUNT_LOCKED = 101;
+
+    /**
+     * The change after reset flag is set indicating the user must change their password.
+     */
+    public final static int CHANGE_AFTER_RESET = 102;
+
+    /**
+     * The User is not allowed to modify their password.
+     */
+    public final static int NO_MODIFICATIONS = 103;
+
+    /**
+     * The User did not supply their old password when trying to change.
+     */
+    public final static int MUST_SUPPLY_OLD = 104;
+
+    /**
+     * The password is not of sufficient quality.
+     */
+    public final static int INSUFFICIENT_QUALITY = 105;
+
+    /**
+     * The new password is too short.
+     */
+    public final static int PASSWORD_TOO_SHORT = 106;
+
+    /**
+     * The new password is too young to be changed.  This is typically used to prevent users from cycling thru
+     * password on forced password change to reuse their previous password (to circumvent history constraints).
+     */
+    public final static int PASSWORD_TOO_YOUNG = 107;
+
+    /**
+     * The new password was found in history.
+     */
+    public final static int HISTORY_VIOLATION = 108;
+
+    /**
+     * The User account is locked.
+     */
+    public final static int ACCOUNT_LOCKED_CONSTRAINTS = 109;
+
+    /**
+     * These message will correspond with the errors above and will be loaded into the pw message entity and returned to
+     * caller.
+     */
+    private final static String[] pwMsgs = {
+        "password will expire",
+        "password in grace limit",
+        "password is expired",
+        "user account is locked",
+        "password requires change after reset",
+        "password modification is not allowed",
+        "old password is required",
+        "insufficient password quality is found",
+        "password is too short",
+        "password is too young",
+        "password is in history",
+        "account is locked due to user constraints"
+    };
+
+    /**
+     * array contains the password policy violations.
+     */
+    private final static int[] pwIds = {
+        PASSWORD_EXPIRATION_WARNING,
+        PASSWORD_GRACE_WARNING,
+        PASSWORD_HAS_EXPIRED,
+        ACCOUNT_LOCKED,
+        CHANGE_AFTER_RESET,
+        NO_MODIFICATIONS,
+        MUST_SUPPLY_OLD,
+        INSUFFICIENT_QUALITY,
+        PASSWORD_TOO_SHORT,
+        PASSWORD_TOO_YOUNG,
+        HISTORY_VIOLATION,
+        ACCOUNT_LOCKED_CONSTRAINTS
+    };
+
+
+    /**
+     * Return a message that corresponds with error code for User's password.
+     *
+     * @param iId contains index offset of message.
+     * @return string containing the error message.
+     */
+    public static String getMessage(int iId)
+    {
+        for (int i = 0; i < pwIds.length; i++)
+        {
+            if (iId == pwIds[i])
+            {
+                return pwMsgs[i];
+            }
+        }
+        return "";
+    }
+
+
+    /**
+     * Given a particular message value return the integer offset that corresponds to the index position
+     * within the message array.
+     *
+     * @param strMsg
+     * @return int
+     */
+    private static int getMessageCode(String strMsg)
+    {
+        for (int i = 0; i < pwMsgs.length; i++)
+        {
+            if (pwMsgs[i].equals(strMsg))
+            {
+                return pwIds[i];
+            }
+        }
+        return -1;
+    }
+}
+


[18/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/AuditDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/AuditDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/AuditDAO.java
new file mode 100644
index 0000000..2b4ab29
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/AuditDAO.java
@@ -0,0 +1,193 @@
+/*
+ *   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.FinderException;
+import org.apache.directory.fortress.core.rbac.AuthZ;
+import org.apache.directory.fortress.core.rbac.Bind;
+import org.apache.directory.fortress.core.rbac.Mod;
+import org.apache.directory.fortress.core.rbac.UserAudit;
+
+
+/**
+ * This class performs data access for OpenLDAP synch repl log data
+ * <p/>
+ * <h3>1. Binds</h3>
+ * <p/>
+ * The auditBind Structural object class is used to store authentication events that can later be queried via ldap API.<br />
+ * <code># The Bind class includes the reqVersion attribute which contains the LDAP</code>
+ * <code># protocol version specified in the Bind as well as the reqMethod attribute</code>
+ * <code># which contains the Bind Method used in the Bind. This will be the string</code>
+ * <code># SIMPLE for LDAP Simple Binds or SASL(mech) for SASL Binds. Note that unless</code>
+ * <code># configured as a global overlay, only Simple Binds using DNs that reside in</code>
+ * <code># the current database will be logged:</code>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass (  1.3.6.1.4.1.4203.666.11.5.2.6 NAME 'auditBind'</code>
+ * <li> <code>DESC 'Bind operation'</code>
+ * <li> <code>SUP auditObject STRUCTURAL</code>
+ * <li> <code>MUST ( reqVersion $ reqMethod ) )</code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <h3>2. Authorizations</h3>
+ * <code>For  the  Search class the reqScope attribute contains the scope of the</code><br />
+ * <code>original search request, using the values specified for  the  LDAP  URL</code><br />
+ * <code>format. I.e.  base, one, sub, or subord.  The reqDerefAliases attribute</code><br />
+ * <code>is one of never, finding, searching, or always,  denoting  how  aliases</code><br />
+ * <code>will  be  processed during the search.  The reqAttrsOnly attribute is a</code><br />
+ * <code>Boolean value showing TRUE if only attribute names were  requested,  or</code><br />
+ * <code>FALSE  if  attributes  and  their values were requested.  The reqFilter</code><br />
+ * <code>attribute carries the filter used in the search request.   The  reqAttr</code><br />
+ * <code>attribute  lists  the  requested attributes if specific attributes were</code><br />
+ * <code>requested.  The reqEntries attribute is the integer count of  how  many</code><br />
+ * <code>entries  were  returned  by  this search request.  The reqSizeLimit and</code><br />
+ * <code>reqTimeLimit attributes indicate what  limits  were  requested  on  the</code><br />
+ * <code>search operation.</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass  (  1.3.6.1.4.1.4203.666.11.5.2.11</code>
+ * <li> <code>NAME 'auditSearch'</code>
+ * <li> <code>DESC 'Search operation'</code>
+ * <li> <code>SUP auditReadObject STRUCTURAL</code>
+ * <li> <code>MUST ( reqScope $ reqDerefAliases $ reqAttrsOnly )</code>
+ * <li> <code>MAY ( reqFilter $ reqAttr $ reqEntries $ reqSizeLimit $</code>
+ * <li> <code>reqTimeLimit ) )</code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <p/>
+ * <p/>
+ * <h3>3. Modifications</h3>
+ * The auditModify Structural object class is used to store Fortress update and delete events that can later be queried via ldap API.<br />
+ * The deletions can be recorded in this manner and associated with Fortress context because deletions will perform a modification first
+ * if audit is enabled.
+ * <p/>
+ * <code>The Modify operation contains a description  of  modifications  in  the</code><br />
+ * <code>reqMod  attribute,  which  was  already  described  above  in  the  Add</code><br />
+ * <code>operation. It may optionally  contain  the  previous  contents  of  any</code><br />
+ * <code>modified  attributes  in the reqOld attribute, using the same format as</code><br />
+ * <code>described above for the Delete operation.  The reqOld attribute is only</code><br />
+ * <code>populated  if  the  entry  being modified matches the configured logold</code><br />
+ * <code>filter.</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass (  1.3.6.1.4.1.4203.666.11.5.2.9</code>
+ * <li> <code>NAME 'auditModify'</code>
+ * <li> <code>DESC 'Modify operation'</code>
+ * <li> <code>SUP auditWriteObject STRUCTURAL</code>
+ * <li> <code>MAY reqOld MUST reqMod )</code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <p/>
+ * Note this class used descriptions pulled from man pages on slapd access log.
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+public interface AuditDAO
+{
+    /**
+     * This method returns failed authentications where the userid is not present in the directory.  This
+     * is possible because Fortress performs read on user before the bind.
+     * User:
+     * dn: reqStart=20101014235402.000000Z, cn=log
+     * reqStart: 20101014235402.000000Z
+     * reqEnd: 20101014235402.000001Z
+     * reqAuthzID: cn=Manager,dc=jts,dc=com
+     * reqDerefAliases: never
+     * reqSession: 84
+     * reqAttrsOnly: FALSE
+     * reqSizeLimit: -1
+     * objectClass: auditSearch
+     * reqResult: 32
+     * reqAttr: ftId
+     * reqAttr: uid
+     * reqAttr: userpassword
+     * reqAttr: description
+     * reqAttr: ou
+     * reqAttr: cn
+     * reqAttr: sn
+     * reqAttr: ftRoleCstr
+     * reqAttr: ftCstr
+     * reqAttr: ftRoleAsgn
+     * reqAttr: pwdReset
+     * reqAttr: pwdAccountLockedTime
+     * reqAttr: ftProps
+     * reqEntries: 0
+     * reqFilter: (|(objectClass=*)(?objectClass=ldapSubentry))
+     * reqType: search
+     * reqDN: uid=foo,ou=People,dc=jts,dc=com        /cal/cal2.jsp
+     * reqTimeLimit: -1
+     * reqScope: base
+     *
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<AuthZ> searchInvalidAuthNs( UserAudit audit ) throws FinderException;
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<AuthZ> searchAuthZs( UserAudit audit ) throws FinderException;
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<AuthZ> getAllAuthZs( UserAudit audit ) throws FinderException;
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<Bind> searchBinds( UserAudit audit ) throws FinderException;
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<Mod> searchUserMods( UserAudit audit ) throws FinderException;
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws FinderException
+     */
+    List<Mod> searchAdminMods( UserAudit audit ) throws FinderException;
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/DAOType.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/DAOType.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/DAOType.java
new file mode 100644
index 0000000..cb98431
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/DAOType.java
@@ -0,0 +1,27 @@
+/*
+ *   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;
+
+
+public enum DAOType
+{
+    APACHE_LDAP_API,
+    UNBOUNDID_API;
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/DaoFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/DaoFactory.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/DaoFactory.java
new file mode 100644
index 0000000..7f9f535
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/DaoFactory.java
@@ -0,0 +1,272 @@
+/*
+ *   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.GlobalIds;
+import org.apache.directory.fortress.core.cfg.Config;
+
+
+/**
+ * A factory that creates DAO for either the UnboundID or the Apache Ldap API lib
+ * @author elecharny
+ */
+public class DaoFactory
+{
+
+    /**
+     * Create an instance of a AdminRoleDAO which depends of the used Backend
+     * 
+     * @return The created instance
+     */
+    public static AdminRoleDAO createAdminRoleDAO()
+    {
+        String daoConnector = Config.getProperty( GlobalIds.DAO_CONNECTOR );
+
+        DAOType daoType = DAOType.UNBOUNDID_API;
+
+        if ( ( daoConnector != null ) && ( daoConnector.equalsIgnoreCase( GlobalIds.APACHE_LDAP_API ) ) )
+        {
+            daoType = DAOType.APACHE_LDAP_API;
+        }
+
+        switch ( daoType )
+        {
+            case UNBOUNDID_API:
+                return new org.apache.directory.fortress.core.rbac.dao.unboundid.AdminRoleDAO();
+
+            case APACHE_LDAP_API:
+                return new org.apache.directory.fortress.core.rbac.dao.apache.AdminRoleDAO();
+
+            default:
+                return null;
+        }
+    }
+
+
+    /**
+     * Create an instance of a AuditDAO which depends of the used Backend
+     * 
+     * @return The created instance
+     */
+    public static AuditDAO createAuditDAO()
+    {
+        String daoConnector = Config.getProperty( GlobalIds.DAO_CONNECTOR );
+
+        DAOType daoType = DAOType.UNBOUNDID_API;
+
+        if ( ( daoConnector != null ) && ( daoConnector.equalsIgnoreCase( GlobalIds.APACHE_LDAP_API ) ) )
+        {
+            daoType = DAOType.APACHE_LDAP_API;
+        }
+
+        switch ( daoType )
+        {
+            case UNBOUNDID_API:
+                return new org.apache.directory.fortress.core.rbac.dao.unboundid.AuditDAO();
+
+            case APACHE_LDAP_API:
+                return new org.apache.directory.fortress.core.rbac.dao.apache.AuditDAO();
+
+            default:
+                return null;
+        }
+    }
+
+
+    /**
+     * Create an instance of a OrgUnitDAO which depends of the used Backend
+     * 
+     * @return The created instance
+     */
+    public static OrgUnitDAO createOrgUnitDAO()
+    {
+        String daoConnector = Config.getProperty( GlobalIds.DAO_CONNECTOR );
+
+        DAOType daoType = DAOType.UNBOUNDID_API;
+
+        if ( ( daoConnector != null ) && ( daoConnector.equalsIgnoreCase( GlobalIds.APACHE_LDAP_API ) ) )
+        {
+            daoType = DAOType.APACHE_LDAP_API;
+        }
+
+        switch ( daoType )
+        {
+            case UNBOUNDID_API:
+                return new org.apache.directory.fortress.core.rbac.dao.unboundid.OrgUnitDAO();
+
+            case APACHE_LDAP_API:
+                return new org.apache.directory.fortress.core.rbac.dao.apache.OrgUnitDAO();
+
+            default:
+                return null;
+        }
+    }
+
+
+    /**
+     * Create an instance of a PermDAO which depends of the used Backend
+     * 
+     * @return The created instance
+     */
+    public static PermDAO createPermDAO()
+    {
+        String daoConnector = Config.getProperty( GlobalIds.DAO_CONNECTOR );
+
+        DAOType daoType = DAOType.UNBOUNDID_API;
+
+        if ( ( daoConnector != null ) && ( daoConnector.equalsIgnoreCase( GlobalIds.APACHE_LDAP_API ) ) )
+        {
+            daoType = DAOType.APACHE_LDAP_API;
+        }
+
+        switch ( daoType )
+        {
+            case UNBOUNDID_API:
+                return new org.apache.directory.fortress.core.rbac.dao.unboundid.PermDAO();
+
+            case APACHE_LDAP_API:
+                return new org.apache.directory.fortress.core.rbac.dao.apache.PermDAO();
+
+            default:
+                return null;
+        }
+    }
+
+
+    /**
+     * Create an instance of a PolicyDAO which depends of the used Backend
+     * 
+     * @return The created instance
+     */
+    public static PolicyDAO createPolicyDAO()
+    {
+        String daoConnector = Config.getProperty( GlobalIds.DAO_CONNECTOR );
+
+        DAOType daoType = DAOType.UNBOUNDID_API;
+
+        if ( ( daoConnector != null ) && ( daoConnector.equalsIgnoreCase( GlobalIds.APACHE_LDAP_API ) ) )
+        {
+            daoType = DAOType.APACHE_LDAP_API;
+        }
+
+        switch ( daoType )
+        {
+            case UNBOUNDID_API:
+                return new org.apache.directory.fortress.core.rbac.dao.unboundid.PolicyDAO();
+
+            case APACHE_LDAP_API:
+                return new org.apache.directory.fortress.core.rbac.dao.apache.PolicyDAO();
+
+            default:
+                return null;
+        }
+    }
+
+
+    /**
+     * Create an instance of a RoleDAO which depends of the used Backend
+     * 
+     * @return The created instance
+     */
+    public static RoleDAO createRoleDAO()
+    {
+        String daoConnector = Config.getProperty( GlobalIds.DAO_CONNECTOR );
+
+        DAOType daoType = DAOType.UNBOUNDID_API;
+
+        if ( ( daoConnector != null ) && ( daoConnector.equalsIgnoreCase( GlobalIds.APACHE_LDAP_API ) ) )
+        {
+            daoType = DAOType.APACHE_LDAP_API;
+        }
+
+        switch ( daoType )
+        {
+            case UNBOUNDID_API:
+                return new org.apache.directory.fortress.core.rbac.dao.unboundid.RoleDAO();
+
+            case APACHE_LDAP_API:
+                return new org.apache.directory.fortress.core.rbac.dao.apache.RoleDAO();
+
+            default:
+                return null;
+        }
+    }
+
+
+    /**
+     * Create an instance of a SdDAO which depends of the used Backend
+     * 
+     * @return The created instance
+     */
+    public static SdDAO createSdDAO()
+    {
+        String daoConnector = Config.getProperty( GlobalIds.DAO_CONNECTOR );
+
+        DAOType daoType = DAOType.UNBOUNDID_API;
+
+        if ( ( daoConnector != null ) && ( daoConnector.equalsIgnoreCase( GlobalIds.APACHE_LDAP_API ) ) )
+        {
+            daoType = DAOType.APACHE_LDAP_API;
+        }
+
+        switch ( daoType )
+        {
+            case UNBOUNDID_API:
+                return new org.apache.directory.fortress.core.rbac.dao.unboundid.SdDAO();
+
+            case APACHE_LDAP_API:
+                return new org.apache.directory.fortress.core.rbac.dao.apache.SdDAO();
+
+            default:
+                return null;
+        }
+    }
+
+
+    /**
+     * Create an instance of a UserDAO which depends of the used Backend
+     * 
+     * @return The created instance
+     */
+    public static UserDAO createUserDAO()
+    {
+        String daoConnector = Config.getProperty( GlobalIds.DAO_CONNECTOR );
+
+        DAOType daoType = DAOType.UNBOUNDID_API;
+
+        if ( ( daoConnector != null ) && ( daoConnector.equalsIgnoreCase( GlobalIds.APACHE_LDAP_API ) ) )
+        {
+            daoType = DAOType.APACHE_LDAP_API;
+        }
+
+        switch ( daoType )
+        {
+            case UNBOUNDID_API:
+                return new org.apache.directory.fortress.core.rbac.dao.unboundid.UserDAO();
+
+            case APACHE_LDAP_API:
+                return new org.apache.directory.fortress.core.rbac.dao.apache.UserDAO();
+
+            default:
+                return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/OrgUnitDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/OrgUnitDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/OrgUnitDAO.java
new file mode 100644
index 0000000..d7dba4d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/OrgUnitDAO.java
@@ -0,0 +1,152 @@
+/*
+ *   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 java.util.Set;
+
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.rbac.Graphable;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+
+
+/**
+ * This class provides dataaccess to the OrgUnit datasets in LDAP.
+ * <p/>
+ * The OrgUnitDAO maintains the following structural and aux object classes:
+ * <h4>1. organizationalUnit Structural Object Class is used to store basic attributes like ou and description</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 2.5.6.5 NAME 'organizationalUnit'</code>
+ * <li> <code>DESC 'RFC2256: an organizational unit'</code>
+ * <li> <code>SUP top STRUCTURAL</code>
+ * <li> <code>MUST ou</code>
+ * <li> <code>MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $</code>
+ * <li> <code>x121Address $ registeredAddress $ destinationIndicator $</code>
+ * <li> <code>preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $</code>
+ * <li> <code>telephoneNumber $ internationaliSDNNumber $</code>
+ * <li> <code>facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $</code>
+ * <li> <code>postalAddress $ physicalDeliveryOfficeName $ st $ l $ description ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>2. ftOrgUnit Structural objectclass is used to store the OrgUnit internal id</h4>
+ * <ul>                                                              org.apache.directory.fortress.arbac.
+ * <li>  ------------------------------------------
+ * <li> <code> objectclass  ( 1.3.6.1.4.1.38088.2.6</code>
+ * <li> <code>NAME 'ftOrgUnit'</code>
+ * <li> <code>DESC 'Fortress OrgUnit Class'</code>
+ * <li> <code>SUP organizationalunit</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST ( ftId ) )</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 Emmanuel Lecharny
+ */
+public interface OrgUnitDAO
+{
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    OrgUnit create( OrgUnit entity ) throws CreateException;
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    OrgUnit update( OrgUnit entity ) throws UpdateException;
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    void deleteParent( OrgUnit entity ) throws UpdateException;
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.RemoveException
+     *
+     */
+    OrgUnit remove( OrgUnit entity ) throws RemoveException;
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws FinderException
+     *
+     */
+    OrgUnit findByKey( OrgUnit entity ) throws FinderException;
+
+
+    /**
+     * @param orgUnit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<OrgUnit> findOrgs( OrgUnit orgUnit ) throws FinderException;
+
+
+    /**
+     *
+     * @param orgUnit
+     * @return
+     * @throws FinderException
+     */
+    Set<String> getOrgs( OrgUnit orgUnit ) throws FinderException;
+
+
+    /**
+      *
+      * @param orgUnit
+      * @return
+      * @throws FinderException
+      */
+    List<Graphable> getAllDescendants( OrgUnit orgUnit ) throws FinderException;
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/PermDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/PermDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/PermDAO.java
new file mode 100644
index 0000000..d526e8c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/PermDAO.java
@@ -0,0 +1,317 @@
+/*
+ *   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.RemoveException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rbac.User;
+
+
+/**
+ * Permission data access class for LDAP.
+ * <p/>
+ * This DAO class maintains the PermObj and Permission entities.
+ * <h3>The Fortress PermObj Entity Class is a composite of 3 LDAP Schema object classes</h2>
+ * <h4>PermObj Base - ftObject STRUCTURAL Object Class is used to store object name, id and type variables on target entity.</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass   ( 1.3.6.1.4.1.38088.2.2</code>
+ * <li> <code>NAME 'ftObject'</code>
+ * <li> <code>DESC 'Fortress Permission Object Class'</code>
+ * <li> <code>SUP organizationalunit</code>                                              GlobalIds
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST (</code>
+ * <li> <code>ftId $ ftObjNm ) </code>
+ * <li> <code>MAY ( ftType ) )  </code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>PermObj - 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>PermObj - 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>
+ * <h3>The Fortress Permission Entity Class is composite of 3 LDAP Schema object classes</h3>
+ * The Permission entity extends a single OpenLDAP standard structural object class, 'organizationalRole' with
+ * one extension structural class, ftOperation,  and two auxiliary object classes, ftProperties, ftMods.
+ * The following 4 LDAP object classes will be mapped into this entity:
+ * <h4>Permission Base - 'ftOperation' STRUCTURAL Object Class is assigned roles and/or users which grants permissions which can be later checked</h4>
+ * using either 'checkAccess' or 'sessionPermissions APIs both methods that reside in the 'AccessMgrImpl' class.
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass   ( 1.3.6.1.4.1.38088.2.3</code>
+ * <li> <code>NAME 'ftOperation'</code>
+ * <li> <code>DESC 'Fortress Permission Operation Object Class'</code>
+ * <li> <code>SUP organizationalrole</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST ( ftId $ ftPermName $</code>
+ * <li> <code>ftObjNm $ ftOpNm )</code>
+ * <li> <code>MAY ( ftRoles $ ftUsers $</code>
+ * <li> <code> ftObjId $ ftType) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>Permission Aux - ftProperties AUXILIARY Object Class is used to store optional client or otherwise custom 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>Permission Aux - 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>
+ * This class is thread safe.
+ * <p/>
+ *
+ * @author Emmanuel Lecharny
+ */
+public interface PermDAO
+{
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    PermObj createObject( PermObj entity ) throws CreateException;
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    PermObj updateObj( PermObj entity ) throws UpdateException;
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.RemoveException
+     *
+     */
+    void deleteObj( PermObj entity ) throws RemoveException;
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    Permission createOperation( Permission entity ) throws CreateException;
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    Permission updateOperation( Permission entity ) throws UpdateException;
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.RemoveException
+     *
+     */
+    void deleteOperation( Permission entity ) throws RemoveException;
+
+
+    /**
+     * @param pOp
+     * @param role
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    void grant( Permission pOp, Role role ) throws UpdateException;
+
+
+    /**
+     * @param pOp
+     * @param role
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    void revoke( Permission pOp, Role role ) throws UpdateException, FinderException;
+
+
+    /**
+     * @param pOp
+     * @param user
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    void grant( Permission pOp, User user ) throws UpdateException;
+
+
+    /**
+     * @param pOp
+     * @param user
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    void revoke( Permission pOp, User user ) throws UpdateException, FinderException;
+
+
+    /**
+     * @param permission
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    Permission getPerm( Permission permission ) throws FinderException;
+
+
+    /**
+     * @param permObj
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    PermObj getPerm( PermObj permObj ) throws FinderException;
+
+
+    /**
+     * This method performs fortress authorization using data passed in (session) and stored on ldap server (permission).  It has been recently changed to use ldap compare operations in order to trigger slapd access log updates in directory.
+     * It performs ldap operations:  read and (optionally) compare.  The first is to pull back the permission to see if user has access or not.  The second is to trigger audit
+     * record storage on ldap server but can be disabled.
+     *
+     * @param session contains {@link Session#getUserId()}, for rbac check {@link org.apache.directory.fortress.core.rbac.Session#getRoles()}, for arbac check: {@link org.apache.directory.fortress.core.rbac.Session#getAdminRoles()}.
+     * @param inPerm  must contain required attributes {@link Permission#objName} and {@link Permission#opName}.  {@link Permission#objectId} is optional.
+     * @return boolean containing result of check.
+     * @throws org.apache.directory.fortress.core.FinderException
+     *          In the event system error occurs looking up data on ldap server.
+     */
+    boolean checkPermission( Session session, Permission inPerm ) throws FinderException;
+
+
+    /**
+     * @param permission
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<Permission> findPermissions( Permission permission ) throws FinderException;
+
+
+    /**
+     * @param permObj
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<PermObj> findPermissions( PermObj permObj ) throws FinderException;
+
+
+    /**
+     * @param ou
+     * @return
+     * @throws FinderException
+     */
+    List<PermObj> findPermissions( OrgUnit ou, boolean limitSize ) throws FinderException;
+
+
+    /**
+     * @param role
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<Permission> findPermissions( Role role ) throws FinderException;
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<Permission> findPermissions( User user ) throws FinderException;
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<Permission> findUserPermissions( User user ) throws FinderException;
+
+
+    /**
+     * @param session
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<Permission> findPermissions( Session session, boolean isAdmin ) throws FinderException;
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/PolicyDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/PolicyDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/PolicyDAO.java
new file mode 100644
index 0000000..666406b
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/PolicyDAO.java
@@ -0,0 +1,127 @@
+/*
+ *   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 java.util.Set;
+
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.rbac.PwPolicy;
+
+
+/**
+ * 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
+ */
+public interface PolicyDAO
+{
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    PwPolicy create( PwPolicy entity ) throws CreateException;
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    void update( PwPolicy entity ) throws UpdateException;
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.RemoveException
+     */
+    void remove( PwPolicy entity ) throws RemoveException;
+
+
+    /**
+     * @param policy
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    PwPolicy getPolicy( PwPolicy policy ) throws FinderException;
+
+
+    /**
+     * @param policy
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<PwPolicy> findPolicy( PwPolicy policy ) throws FinderException;
+
+
+    /**
+     * @return
+     * @throws FinderException
+     */
+    Set<String> getPolicies( String contextId ) throws FinderException;
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/RoleDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/RoleDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/RoleDAO.java
new file mode 100644
index 0000000..2cd573d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/RoleDAO.java
@@ -0,0 +1,177 @@
+/*
+ *   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.RemoveException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.rbac.Graphable;
+import org.apache.directory.fortress.core.rbac.Role;
+
+
+/**
+ * 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 Emmanuel Lecharny
+ */
+public interface RoleDAO
+{
+    /**
+     * @param entity
+     * @return
+     * @throws CreateException
+     */
+    Role create( Role entity ) throws CreateException;
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    Role update( Role entity ) throws UpdateException;
+
+
+    /**
+     *
+     * @param entity
+     * @throws UpdateException
+     */
+    void deleteParent( Role entity ) throws UpdateException;
+
+
+    /**
+     * @param entity
+     * @param userDn
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    Role assign( Role entity, String userDn ) throws UpdateException;
+
+
+    /**
+     * @param entity
+     * @param userDn
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    Role deassign( Role entity, String userDn ) throws UpdateException;
+
+
+    /**
+     * @param role
+     * @throws RemoveException
+     */
+    void remove( Role role ) throws RemoveException;
+
+
+    /**
+     * @param role
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    Role getRole( Role role ) throws FinderException;
+
+
+    /**
+     * @param role
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<Role> findRoles( Role role ) throws FinderException;
+
+
+    /**
+     * @param role
+     * @param limit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<String> findRoles( Role role, int limit ) throws FinderException;
+
+
+    /**
+     *
+     * @param userDn
+     * @param contextId
+     * @return
+     * @throws FinderException
+     */
+    List<String> findAssignedRoles( String userDn, String contextId ) throws FinderException;
+
+
+    /**
+     *
+     * @param contextId
+     * @return
+     * @throws FinderException
+     */
+    List<Graphable> getAllDescendants( String contextId ) throws FinderException;
+}
\ 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/SdDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/SdDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/SdDAO.java
new file mode 100644
index 0000000..53eb10f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/SdDAO.java
@@ -0,0 +1,154 @@
+/*
+ *   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 java.util.Set;
+
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.SDSet;
+
+
+/**
+ * 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
+ */
+public interface SdDAO
+{
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     */
+    SDSet create( SDSet entity ) throws CreateException;
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     */
+    SDSet update( SDSet entity ) throws UpdateException;
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.RemoveException
+     */
+    SDSet remove( SDSet entity ) throws RemoveException;
+
+
+    /**
+     * @param sdSet
+     * @return
+     * @throws FinderException
+     */
+    SDSet getSD( SDSet sdSet ) throws FinderException;
+
+
+    /**
+     * 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
+     */
+    List<SDSet> search( SDSet sdset ) throws FinderException;
+
+
+    /**
+     * @param role
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     */
+    List<SDSet> search( Role role, SDSet.SDType type ) throws FinderException;
+
+
+    /**
+     * @param roles
+     * @param sdSet
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     */
+    Set<SDSet> search( Set<String> roles, SDSet sdSet ) throws FinderException;
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/UserDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/UserDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/UserDAO.java
new file mode 100644
index 0000000..abf4960
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/UserDAO.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 java.util.Set;
+
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+import org.apache.directory.fortress.core.rbac.UserRole;
+
+
+/**
+ * Data access class for LDAP User entity.
+ * <p/>
+ * <p/>
+ * The Fortress User LDAP schema follows:
+ * <p/>
+ * <h4>1. InetOrgPerson Structural Object Class </h4>
+ * <code># The inetOrgPerson represents people who are associated with an</code><br />
+ * <code># organization in some way.  It is a structural class and is derived</code><br />
+ * <code># from the organizationalPerson which is defined in X.521 [X521].</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 2.16.840.1.113730.3.2.2</code>
+ * <li> <code>NAME 'inetOrgPerson'</code>
+ * <li> <code>DESC 'RFC2798: Internet Organizational Person'</code>
+ * <li> <code>SUP organizationalPerson</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MAY ( audio $ businessCategory $ carLicense $ departmentNumber $</code>
+ * <li> <code>displayName $ employeeNumber $ employeeType $ givenName $</code>
+ * <li> <code>homePhone $ homePostalAddress $ initials $ jpegPhoto $</code>
+ * <li> <code>labeledURI $ mail $ manager $ mobile $ o $ pager $ photo $</code>
+ * <li> <code>roomNumber $ secretary $ uid $ userCertificate $</code>
+ * <li> <code>x500uniqueIdentifier $ preferredLanguage $</code>
+ * <li> <code>userSMIMECertificate $ userPKCS12 ) )</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>
+ * <p/>
+ * <h4>3. ftUserAttrs is used to store user RBAC and Admin role assignment and other security attributes on User entity</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.1</code>
+ * <li> <code>NAME 'ftUserAttrs'</code>
+ * <li> <code>DESC 'Fortress User Attribute AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MUST ( ftId )</code>
+ * <li> <code>MAY ( ftRC $ ftRA $ ftARC $ ftARA $ ftCstr</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 Emmanuel Lecharny
+ */
+public interface UserDAO
+{
+    List<User> findUsers( OrgUnit ou, boolean limitSize ) throws FinderException;
+
+
+    List<User> findUsers( User user ) throws FinderException;
+
+
+    List<String> findUsers( User user, int limit ) throws FinderException;
+
+
+    String assign( UserRole uRole ) throws UpdateException, FinderException;
+
+
+    /**
+     * @param uRole
+     * @return
+     * @throws UpdateException
+     *
+     * @throws FinderException
+     *
+     */
+    String assign( UserAdminRole uRole ) throws UpdateException, FinderException;
+
+
+    boolean changePassword( User entity, char[] newPassword ) throws SecurityException;
+
+
+    Session checkPassword( User user ) throws FinderException;
+
+
+    List<User> getAuthorizedUsers( Role role ) throws FinderException;
+
+
+    User update( User entity ) throws UpdateException;
+
+
+    void lock( User user ) throws UpdateException;
+
+
+    void unlock( User user ) throws UpdateException;
+
+
+    User create( User entity ) throws CreateException;
+
+
+    /**
+     * @param uRole
+     * @return
+     * @throws UpdateException
+     *
+     * @throws FinderException
+     *
+     */
+    String deassign( UserAdminRole uRole ) throws UpdateException, FinderException;
+
+
+    String deassign( UserRole uRole ) throws UpdateException, FinderException;
+
+
+    void resetUserPassword( User user ) throws UpdateException;
+
+
+    User updateProps( User entity, boolean replace ) throws UpdateException;
+
+
+    String remove( User user ) throws RemoveException;
+
+
+    String deletePwPolicy( User user ) throws UpdateException;
+
+
+    /**
+     * @param role
+     * @return
+     * @throws FinderException
+     */
+    List<User> getAssignedUsers( AdminRole role ) throws FinderException;
+
+
+    List<User> getAssignedUsers( Role role ) throws FinderException;
+
+
+    List<String> getRoles( User user ) throws FinderException;
+
+
+    User getUser( User user, boolean isRoles ) throws FinderException;
+
+
+    Set<String> getAssignedUsers( Set<String> roles, String contextId ) throws FinderException;
+
+
+    List<String> getAuthorizedUsers( Role role, int limit ) throws FinderException;
+}
\ 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/apache/AcceleratorDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/AcceleratorDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/AcceleratorDAO.java
new file mode 100644
index 0000000..efaf510
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/AcceleratorDAO.java
@@ -0,0 +1,379 @@
+/*
+ *   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.apache;
+
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.openldap.accelerator.api.addRole.RbacAddRoleRequest;
+import org.openldap.accelerator.api.addRole.RbacAddRoleRequestImpl;
+import org.openldap.accelerator.api.addRole.RbacAddRoleResponse;
+import org.openldap.accelerator.api.checkAccess.RbacCheckAccessRequest;
+import org.openldap.accelerator.api.checkAccess.RbacCheckAccessRequestImpl;
+import org.openldap.accelerator.api.checkAccess.RbacCheckAccessResponse;
+import org.openldap.accelerator.api.createSession.RbacCreateSessionRequest;
+import org.openldap.accelerator.api.createSession.RbacCreateSessionRequestImpl;
+import org.openldap.accelerator.api.createSession.RbacCreateSessionResponse;
+import org.openldap.accelerator.api.deleteSession.RbacDeleteSessionRequest;
+import org.openldap.accelerator.api.deleteSession.RbacDeleteSessionRequestImpl;
+import org.openldap.accelerator.api.deleteSession.RbacDeleteSessionResponse;
+import org.openldap.accelerator.api.dropRole.RbacDropRoleRequest;
+import org.openldap.accelerator.api.dropRole.RbacDropRoleRequestImpl;
+import org.openldap.accelerator.api.dropRole.RbacDropRoleResponse;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+
+import org.openldap.accelerator.api.sessionRoles.RbacSessionRolesRequest;
+import org.openldap.accelerator.api.sessionRoles.RbacSessionRolesRequestImpl;
+import org.openldap.accelerator.api.sessionRoles.RbacSessionRolesResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.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 org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Data access class for invoking RBAC Accelerator server-side operations.  This class utilizes the openldap accelerator component for LDAPv3 extended operations.
+ * This class follows the pattern of {@link org.apache.directory.fortress.core.AccessMgr} except policy decisions are session state are made/stored on server-side and not client-side.
+ * Its methods are not intended to be invoked by outside clients that should instead use {@link org.apache.directory.fortress.core.rbac.AccelMgrImpl}.
+ *
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+public final class AcceleratorDAO extends ApacheDsDataProvider implements org.apache.directory.fortress.core.rbac.dao.AcceleratorDAO
+
+{
+    private static final Logger LOG = LoggerFactory.getLogger( AcceleratorDAO.class.getName() );
+
+    /**
+     * Authenticate user and return sessionId inside {@link Session#sessionId}.
+     * This function follows the pattern from: {@link org.apache.directory.fortress.core.AccessMgr#createSession(org.apache.directory.fortress.core.rbac.User, boolean)}
+     * Success will result in rbac session state, i.e. {@link org.apache.directory.fortress.core.rbac.Session}, to be stored on server-side.
+     * Result may be stored inside RBAC server-side audit record and retrieved with {@link org.apache.directory.fortress.core.AuditMgr#searchBinds(org.apache.directory.fortress.core.rbac.UserAudit)}
+     *
+     * It uses the {@link RbacCreateSessionRequest} and {@link RbacCreateSessionResponse} accelerator APIs.
+     *
+     * todo: this method does not yet, but will soon, return password policy decisions.
+     *
+     * @param user
+     * @return session contains a valid sessionId captured from accelerator createSession method.
+     *
+     * @throws SecurityException rethrows {@code LdapException} with {@code GlobalErrIds.ACEL_CREATE_SESSION_ERR}.
+     *
+     */
+    @Override
+    public final Session createSession( User user ) throws SecurityException
+    {
+        Session session = null;
+        LdapConnection ld = null;
+        try
+        {
+            ld = getAdminConnection();
+            ld.setTimeOut( 0 );
+            // Create a new RBAC session
+            RbacCreateSessionRequest rbacCreateSessionRequest = new RbacCreateSessionRequestImpl();
+            //rbacCreateSessionRequest.setTenantId( "jts" );
+            rbacCreateSessionRequest.setTenantId( user.getContextId() );
+            rbacCreateSessionRequest.setUserIdentity( user.getUserId() );
+            rbacCreateSessionRequest.setPassword( new String(user.getPassword()) );
+            if( VUtil.isNotNullOrEmpty( user.getRoles() ))
+            {
+                for ( UserRole userRole : user.getRoles())
+                {
+                    rbacCreateSessionRequest.addRole( userRole.getName() );
+                }
+            }
+            // Send the request
+            RbacCreateSessionResponse rbacCreateSessionResponse = ( RbacCreateSessionResponse ) ld.extended(
+                rbacCreateSessionRequest );
+            LOG.debug( "createSession userId: " + user.getUserId() + ", sessionId: " +  rbacCreateSessionResponse.getSessionId() + ", resultCode: " +   rbacCreateSessionResponse.getLdapResult().getResultCode().getResultCode());
+            session = new Session( user, rbacCreateSessionResponse.getSessionId() );
+            if(rbacCreateSessionResponse.getLdapResult().getResultCode().getResultCode() == 0)
+            {
+                session.setAuthenticated(true);
+            }
+            else
+            {
+                session.setAuthenticated(false);
+                String info = "createSession UserId [" + user.getUserId() + "] failed: " + rbacCreateSessionResponse.getLdapResult() + " , resultCode: " + rbacCreateSessionResponse.getLdapResult().getResultCode().getResultCode();
+                throw new SecurityException( GlobalErrIds.USER_PW_INVLD, info );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "createSession userId [" + user.getUserId() + "] caught LDAPException=" + " msg=" + e
+                .getMessage();
+            throw new SecurityException( GlobalErrIds.ACEL_CREATE_SESSION_ERR, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return session;
+    }
+
+
+    /**
+     * Perform user rbac authorization.  This function returns a Boolean value meaning whether the subject of a given session is
+     * allowed or not to perform a given operation on a given object. The function is valid if and
+     * only if the session is a valid Fortress session, the object is a member of the OBJS data set,
+     * and the operation is a member of the OPS data set. The session's subject has the permission
+     * to perform the operation on that object if and only if that permission is assigned to (at least)
+     * one of the session's active roles. This implementation will verify the roles or userId correspond
+     * to the subject's active roles are registered in the object's access control list.
+     * It uses the {@link RbacCheckAccessRequest} and {@link RbacCheckAccessResponse} accelerator APIs.
+     *
+     * @param session This object must be instantiated by calling {@link #createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param perm  must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, of permission User is trying to access.
+     * @return True if user has access, false otherwise.
+     * @throws SecurityException rethrows {@code LdapException} with {@code GlobalErrIds.ACEL_CHECK_ACCESS_ERR}.
+     */
+    @Override
+    public boolean checkAccess( Session session, Permission perm )
+        throws SecurityException
+    {
+        boolean result = false;
+        LdapConnection ld = null;
+        try
+        {
+            ld = getAdminConnection();
+            RbacCheckAccessRequest rbacCheckAccessRequest = new RbacCheckAccessRequestImpl();
+            rbacCheckAccessRequest.setSessionId( session.getSessionId() );
+            rbacCheckAccessRequest.setObject( perm.getObjName() );
+            // objectId is optional
+            if(VUtil.isNotNullOrEmpty( perm.getObjId()))
+            {
+                rbacCheckAccessRequest.setObjectId( perm.getObjId() );
+            }
+            rbacCheckAccessRequest.setOperation( perm.getOpName() );
+            // Send the request
+            RbacCheckAccessResponse rbacCheckAccessResponse = ( RbacCheckAccessResponse ) ld.extended(
+                rbacCheckAccessRequest );
+            LOG.debug( "checkAccess result: {}", rbacCheckAccessResponse.getLdapResult().getResultCode().getResultCode());
+            if(rbacCheckAccessResponse.getLdapResult().getResultCode().getResultCode() == 0)
+            {
+                result = true;
+            }
+            else
+            {
+                result = false;
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "checkAccess perm obj [" + perm.getObjName() + "], operation [" + perm.getOpName() + "] caught LDAPException=" + " msg=" + e
+                .getMessage();
+            throw new SecurityException( GlobalErrIds.ACEL_CHECK_ACCESS_ERR, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return result;
+    }
+
+
+    /**
+     * Deactivate user role from rbac session
+     * This function follows the pattern from: {@link org.apache.directory.fortress.core.AccessMgr#dropActiveRole(org.apache.directory.fortress.core.rbac.Session, org.apache.directory.fortress.core.rbac.UserRole)}.
+     * Success will result in rbac session state to be modified inside server-side cache.
+     * It uses the {@link RbacDropRoleRequest} and {@link RbacDropRoleResponse} accelerator APIs.
+     *
+     * @param session contains a valid sessionId captured from accelerator createSession method.
+     * @param userRole both the {@link UserRole#userId} and {@link UserRole#name} fields must be set before invoking.
+     * @throws SecurityException rethrows {@code LdapException} with {@code GlobalErrIds.ACEL_DROP_ROLE_ERR}.
+     */
+    public void dropActiveRole( Session session, UserRole userRole ) throws SecurityException
+    {
+        LdapConnection ld = null;
+        try
+        {
+            ld = getAdminConnection();
+            RbacDropRoleRequest dropRoleRequest = new RbacDropRoleRequestImpl();
+            dropRoleRequest.setSessionId( session.getSessionId() );
+            dropRoleRequest.setRole( userRole.getName() );
+            dropRoleRequest.setUserIdentity( userRole.getUserId() );
+            // Send the request
+            RbacDropRoleResponse rbacDropRoleResponse = ( RbacDropRoleResponse ) ld.extended(
+                dropRoleRequest );
+            LOG.debug( "dropActiveRole result: {}", rbacDropRoleResponse.getLdapResult().getResultCode().getResultCode());
+            if(rbacDropRoleResponse.getLdapResult().getResultCode().getResultCode() != 0)
+            {
+                String info = "dropActiveRole Role [" + userRole.getName() + "] User ["
+                    + session.getUserId() + "], not previously activated.";
+                throw new SecurityException( GlobalErrIds.URLE_NOT_ACTIVE, info );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "dropActiveRole role name [" + userRole.getName() + "] caught LDAPException=" + " msg=" + e
+                .getMessage();
+            throw new SecurityException( GlobalErrIds.ACEL_DROP_ROLE_ERR, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+    /**
+     * Activate user role into rbac session
+     * This function follows the pattern from: {@link org.apache.directory.fortress.core.AccessMgr#addActiveRole(org.apache.directory.fortress.core.rbac.Session, org.apache.directory.fortress.core.rbac.UserRole)}.
+     * Success will result in rbac session state to be modified inside server-side cache.
+     * It uses the {@link RbacAddRoleRequest} and {@link RbacAddRoleResponse} accelerator APIs.
+     *
+     * @param session contains a valid sessionId captured from accelerator createSession method.
+     * @param userRole both the {@link UserRole#userId} and {@link UserRole#name} fields must be set before invoking.
+     * @throws SecurityException rethrows {@code LdapException} with {@code GlobalErrIds.ACEL_ADD_ROLE_ERR}.
+     */
+    public void addActiveRole( Session session, UserRole userRole ) throws SecurityException
+    {
+        LdapConnection ld = null;
+        try
+        {
+            ld = getAdminConnection();
+            RbacAddRoleRequest addRoleRequest = new RbacAddRoleRequestImpl();
+            addRoleRequest.setSessionId( session.getSessionId() );
+            addRoleRequest.setRole( userRole.getName() );
+            addRoleRequest.setUserIdentity( userRole.getUserId() );
+            // Send the request
+            RbacAddRoleResponse rbacAddRoleResponse = ( RbacAddRoleResponse ) ld.extended(
+                addRoleRequest );
+            LOG.debug( "addActiveRole result: {}", rbacAddRoleResponse.getLdapResult().getResultCode().getResultCode());
+            if(rbacAddRoleResponse.getLdapResult().getResultCode().getResultCode() != 0)
+            {
+                String info;
+                int rc;
+                if(rbacAddRoleResponse.getLdapResult().getResultCode().getResultCode() == 20)
+                {
+                    info = "addActiveRole Role [" + userRole.getName() + "] User ["
+                        + session.getUserId() + "], already activated.";
+                    rc = GlobalErrIds.URLE_ALREADY_ACTIVE;
+                }
+                else
+                {
+                    info = "addActiveRole Role [" + userRole.getName() + "] User ["
+                        + session.getUserId() + "], not authorized for user.";
+                    rc = GlobalErrIds.URLE_ACTIVATE_FAILED;
+                }
+                throw new SecurityException( rc, info );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "addActiveRole role name [" + userRole.getName() + "] caught LDAPException=" + " msg=" + e
+                .getMessage();
+            throw new SecurityException( GlobalErrIds.ACEL_ADD_ROLE_ERR, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+    /**
+     * Delete the stored session on rbac accelerator server.
+     * It uses the {@link RbacDeleteSessionRequest} and {@link RbacDeleteSessionResponse} accelerator APIs.
+     *
+     * @param session contains a valid sessionId captured from accelerator createSession method.
+     * @throws SecurityException rethrows {@code LdapException} with {@code GlobalErrIds.ACEL_DELETE_SESSION_ERR}.
+     */
+    public void deleteSession( Session session ) throws SecurityException
+    {
+        LdapConnection ld = null;
+        try
+        {
+            ld = getAdminConnection();
+            RbacDeleteSessionRequest deleteSessionRequest = new RbacDeleteSessionRequestImpl();
+            deleteSessionRequest.setSessionId( session.getSessionId() );
+            deleteSessionRequest.setUserIdentity( session.getUserId() );
+            // Send the request
+            RbacDeleteSessionResponse deleteSessionResponse = ( RbacDeleteSessionResponse ) ld.extended(
+                deleteSessionRequest );
+            LOG.debug( "deleteSession result: {}", deleteSessionResponse.getLdapResult().getResultCode().getResultCode());
+        }
+        catch ( LdapException e )
+        {
+            String error = "deleteSession caught LDAPException=" + " msg=" + e
+                .getMessage();
+            throw new SecurityException( GlobalErrIds.ACEL_DELETE_SESSION_ERR, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * SessionRoles returns a list of UserRole's activated for user on rbac server.
+     * It uses the {@link RbacSessionRolesRequest} and {@link RbacSessionRolesResponse} accelerator APIs.
+     *
+     * todo: This method does not yet, but will soon populate temporal constraints associated with entities returned.
+     *
+     * @param session contains a valid sessionId captured from accelerator createSession method.
+     * @return List of type UserRole.  May be null if user has no roles activated in session stored - server side.
+     * @throws SecurityException rethrows {@code LdapException} with {@code GlobalErrIds.ACEL_SESSION_ROLES_ERR}.
+     */
+    public List<UserRole> sessionRoles( Session session ) throws SecurityException
+    {
+        LdapConnection ld = null;
+        List<UserRole> userRoleList = null;
+        try
+        {
+            ld = getAdminConnection();
+            RbacSessionRolesRequest sessionRolesRequest = new RbacSessionRolesRequestImpl();
+            sessionRolesRequest.setSessionId( session.getSessionId() );
+            sessionRolesRequest.setUserIdentity( session.getUserId() );
+            // Send the request
+            RbacSessionRolesResponse sessionRolesResponse = ( RbacSessionRolesResponse ) ld.extended(
+                sessionRolesRequest );
+            LOG.debug( "sessionRoles result: {}", sessionRolesResponse.getLdapResult().getResultCode().getResultCode());
+            if(VUtil.isNotNullOrEmpty( sessionRolesResponse.getRoles() ) )
+            {
+                userRoleList = new ArrayList<>(  );
+                for( String roleNm : sessionRolesResponse.getRoles() )
+                {
+                    userRoleList.add( new UserRole( session.getUserId(), roleNm ) );
+                    // todo: add temporal constraints here
+                }
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "sessionRoles caught LDAPException=" + " msg=" + e
+                .getMessage();
+            throw new SecurityException( GlobalErrIds.ACEL_SESSION_ROLES_ERR, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return userRoleList;
+    }
+}


[48/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/AdminMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/AdminMgr.java b/src/main/java/org/apache/directory/fortress/core/AdminMgr.java
new file mode 100755
index 0000000..bcd4624
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/AdminMgr.java
@@ -0,0 +1,1041 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.SDSet;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.UserRole;
+
+/**
+ * This class performs administrative functions to provision Fortress RBAC entities into the LDAP directory.  These APIs
+ * map directly to similar named APIs specified by ANSI and NIST RBAC models.
+ * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
+ * The RBAC Functional specification describes administrative operations for the creation
+ * and maintenance of RBAC element sets and relations; administrative review functions for
+ * performing administrative queries; and system functions for creating and managing
+ * RBAC attributes on user sessions and making access control decisions.
+ * <p/>
+ * <hr>
+ * <h4>RBAC0 - Core</h4>
+ * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
+ * <p/>
+ * <img src="./doc-files/RbacCore.png">
+ * <hr>
+ * <h4>RBAC1 - General Hierarchical Roles</h4>
+ * Simplifies role engineering tasks using inheritance of one or more parent roles.
+ * <p/>
+ * <img src="./doc-files/RbacHier.png">
+ * <hr>
+ * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+ * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
+ * <p/>
+ * <img src="./doc-files/RbacSSD.png">
+ * <hr>
+ * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+ * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+ * <p/>
+ * <img src="./doc-files/RbacDSD.png">
+ * <hr>
+ * <p/>
+ * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.apache.directory.fortress.core.rbac.Session)}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public interface AdminMgr extends Manageable
+{
+    /**
+     * This command creates a new RBAC user. The command is valid only if the new user is
+     * not already a member of the USERS data set. The USER data set is updated. The new user
+     * does not own any session at the time of its creation.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * <li>{@link User#password} - used to authenticate the User</li>
+     * <li>{@link User#ou} - contains the name of an already existing User OU node</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link User#pwPolicy} - contains the name of an already existing OpenLDAP password policy node</li>
+     * <li>{@link User#cn} - maps to INetOrgPerson common name attribute</li>
+     * <li>{@link User#sn} - maps to INetOrgPerson surname attribute</li>
+     * <li>{@link User#description} - maps to INetOrgPerson description attribute</li>
+     * <li>{@link User#title} - maps to INetOrgPerson title attribute</li>
+     * <li>{@link User#employeeType} - maps to INetOrgPerson employeeType attribute</li>
+     * <li>{@link User#phones} * - multi-occurring attribute maps to organizationalPerson telephoneNumber  attribute</li>
+     * <li>{@link User#mobiles} * - multi-occurring attribute maps to INetOrgPerson mobile attribute</li>
+     * <li>{@link User#emails} * - multi-occurring attribute maps to INetOrgPerson mail attribute</li>
+     * <li>{@link User#address} * - multi-occurring attribute maps to organizationalPerson postalAddress, st, l, postalCode, postOfficeBox attributes</li>
+     * <li>{@link User#beginTime} - HHMM - determines begin hour user may activate session</li>
+     * <li>{@link User#endTime} - HHMM - determines end hour user may activate session.</li>
+     * <li>{@link User#beginDate} - YYYYMMDD - determines date when user may sign on</li>
+     * <li>{@link User#endDate} - YYYYMMDD - indicates latest date user may sign on</li>
+     * <li>{@link User#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link User#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link User#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of user may sign on</li>
+     * <li>{@link User#timeout} - number in seconds of session inactivity time allowed</li>
+     * <li>{@link User#props} * - multi-occurring attribute contains property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link User#roles} * - multi-occurring attribute contains the name of already existing role to assign to user</li>
+     * <li>{@link User#adminRoles} * - multi-occurring attribute contains the name of already existing adminRole to assign to user</li>
+     * </ul>
+     *
+     * @param user User entity must contain {@link User#userId} and {@link User#ou} (required) and optional {@link User#description},{@link User#roles} and many others.
+     * @return Returns entity containing user data that was added.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    public User addUser(User user)
+        throws SecurityException;
+
+
+    /**
+     * This command deletes an existing user from the RBAC database. The command is valid
+     * if and only if the user to be deleted is a member of the USERS data set. The USERS and
+     * UA data sets and the assigned_users function are updated.
+     * Method performs a "soft" delete.  It performs the following:
+     * - sets the user status to "deleted"
+     * - deassigns all roles from the user
+     * - locks the user's password in LDAP
+     * - revokes all perms that have been granted to user entity.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user Contains the {@link User#userId} of the User targeted for deletion.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    public void disableUser(User user)
+        throws SecurityException;
+
+
+    /**
+     * This command deletes an existing user from the RBAC database. The command is valid
+     * if and only if the user to be deleted is a member of the USERS data set. The USERS and
+     * UA data sets and the assigned_users function are updated.
+     * 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.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user Contains the {@link User#userId} of the User targeted for deletion.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    public void deleteUser(User user)
+        throws SecurityException;
+
+
+    /**
+     * This method performs an update on User entity in directory.  Prior to making this call the entity must exist in
+     * directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link User#password} - used to authenticate the User</li>
+     * <li>{@link User#ou} - contains the name of an already existing User OU node</li>
+     * <li>{@link User#pwPolicy} - contains the name of an already existing OpenLDAP password policy node</li>
+     * <li>{@link User#cn} - maps to INetOrgPerson common name attribute</li>
+     * <li>{@link User#sn} - maps to INetOrgPerson surname attribute</li>
+     * <li>{@link User#description} - maps to INetOrgPerson description attribute</li>
+     * <li>{@link User#title} - maps to INetOrgPerson title attribute</li>
+     * <li>{@link User#employeeType} - maps to INetOrgPerson employeeType attribute</li>
+     * <li>{@link User#phones} * - multi-occurring attribute maps to organizationalPerson telephoneNumber  attribute</li>
+     * <li>{@link User#mobiles} * - multi-occurring attribute maps to INetOrgPerson mobile attribute</li>
+     * <li>{@link User#emails} * - multi-occurring attribute maps to INetOrgPerson mail attribute</li>
+     * <li>{@link User#address} * - multi-occurring attribute maps to organizationalPerson postalAddress, st, l, postalCode, postOfficeBox attributes</li>
+     * <li>{@link User#beginTime} - HHMM - determines begin hour user may activate session</li>
+     * <li>{@link User#endTime} - HHMM - determines end hour user may activate session.</li>
+     * <li>{@link User#beginDate} - YYYYMMDD - determines date when user may sign on</li>
+     * <li>{@link User#endDate} - YYYYMMDD - indicates latest date user may sign on</li>
+     * <li>{@link User#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link User#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link User#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of user may sign on</li>
+     * <li>{@link User#timeout} - number in seconds of session inactivity time allowed</li>
+     * <li>{@link User#props} * - multi-occurring attribute contains property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link User#roles} * - multi-occurring attribute contains the name of already existing role to assign to user</li>
+     * <li>{@link User#adminRoles} * - multi-occurring attribute contains the name of already existing adminRole to assign to user</li>
+     * </ul>
+     *
+     * @param user must contain {@link User#userId} and optional entity data to update i.e. desc, ou, properties, all attributes that are not set will be ignored.
+     * @return Updated user entity data.
+     * @throws SecurityException thrown in the event of validation or system error.
+     */
+    public User updateUser(User user)
+        throws SecurityException;
+
+
+    /**
+     * Method will change user's password.  This method will evaluate user's password policies.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * <li>{@link User#password} - contains the User's old password</li>
+     * <li>newPassword - contains the User's new password</li>
+     * </ul>
+     *
+     * @param user        contains {@link User#userId} and old user password {@link User#password}.
+     * @param newPassword contains new user password.
+     * @throws SecurityException will be thrown in the event of password policy violation or system error.
+     */
+    public void changePassword(User user, char[] newPassword)
+        throws SecurityException;
+
+
+    /**
+     * Method will lock user's password which will prevent the user from authenticating with directory.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user entity contains {@link User#userId} of User to be locked.
+     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
+     */
+    public void lockUserAccount(User user)
+        throws SecurityException;
+
+
+    /**
+     * Method will unlock user's password which will enable user to authenticate with directory.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user entity contains {@link User#userId} of User to be unlocked.
+     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
+     */
+    public void unlockUserAccount(User user)
+        throws SecurityException;
+
+
+    /**
+     * Method will reset user's password which will require user to change password before successful authentication with directory.
+     * This method will not evaluate password policies on the new user password as it must be changed before use.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * <li>newPassword - contains the User's new password</li>
+     * </ul>
+     *
+     * @param user entity contains {@link User#userId} of User to be reset.
+     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
+     */
+    public void resetPassword(User user, char[] newPassword)
+        throws SecurityException;
+
+
+    /**
+     * Method will delete user's password policy designation.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * <li>newPassword - contains the User's new password</li>
+     * </ul>
+     *
+     * @param user  contains {@link User#userId}.
+     * @throws SecurityException will be thrown in the event of password policy violation or system error.
+     */
+    public void deletePasswordPolicy(User user)
+        throws SecurityException;
+
+
+    /**
+     * This command creates a new role. The command is valid if and only if the new role is not
+     * already a member of the ROLES data set. The ROLES data set is updated.
+     * Initially, no user or permission is assigned to the new role.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role to be created.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Role#description} - maps to description attribute on organizationalRole object class</li>
+     * <li>{@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+     * <li>{@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+     * <li>{@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+     * <li>{@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+     * <li>{@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session</li>
+     * </ul>
+     *
+     * @param role must contains {@link Role#name} (required) and optional {@link Role#description}.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    public Role addRole(Role role)
+        throws SecurityException;
+
+
+    /**
+     * This command deletes an existing role from the RBAC database. The command is valid
+     * if and only if the role to be deleted is a member of the ROLES data set.  This command will
+     * also deassign role from all users.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role to be deleted.</li>
+     * </ul>
+     * @param role Must contain {@link Role#name} for Role to delete.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    public void deleteRole(Role role)
+        throws SecurityException;
+
+
+    /**
+     * Method will update a Role entity in the directory.  The role must exist in role container prior to this call.
+     *
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role to be updated.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Role#description} - maps to description attribute on organizationalRole object class</li>
+     * <li>{@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+     * <li>{@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+     * <li>{@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+     * <li>{@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+     * <li>{@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session</li>
+     * </ul>
+     * @param role Must contains {@link Role#name} and may contain new description or {@link org.apache.directory.fortress.core.util.time.Constraint}
+     * @return Role contains reference to entity operated on.
+     * @throws SecurityException in the event of validation or system error.
+     */
+    public Role updateRole(Role role)
+        throws SecurityException;
+
+
+    /**
+     * 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>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserRole#name} - contains the name for already existing Role to be assigned</li>
+     * <li>{@link UserRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserRole#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+     * <li>{@link UserRole#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+     * <li>{@link UserRole#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+     * <li>{@link UserRole#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+     * <li>{@link UserRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link UserRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link UserRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session</li>
+     * </ul>
+     *
+     * @param uRole must contain {@link UserRole#userId} and {@link UserRole#name} and optional {@code Constraints}.
+     * @throws SecurityException in the event of validation or system error.
+     */
+    public void assignUser(UserRole uRole)
+        throws SecurityException;
+
+
+    /**
+     * 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.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserRole#name} - contains the name for already existing Role to be deassigned</li>
+     * <li>{@link UserRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     * @param uRole must contain {@link org.apache.directory.fortress.core.rbac.UserRole#userId} and {@link UserRole#name}.
+     * @throws SecurityException - in the event data error in user or role objects or system error.
+     */
+    public void deassignUser(UserRole uRole)
+        throws SecurityException;
+
+
+    /**
+     * This method will add permission operation to an existing permission object which resides under {@code ou=Permissions,ou=RBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may have {@link org.apache.directory.fortress.core.rbac.Role} or {@link org.apache.directory.fortress.core.rbac.User} associations.  The target {@link Permission} must not exist prior to calling.
+     * A Fortress Permission instance exists in a hierarchical, one-many relationship between its parent and itself as stored in ldap tree: ({@link PermObj}*->{@link Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission add</li>
+     * <li>{@link Permission#opName} - contains the name of new permission operation being added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
+     * <li>{@link Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
+     * <li>{@link Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link Permission#opName}, that identifies target along with optional other attributes..
+     * @return copy of Permission entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    public Permission addPermission(Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * This method will update permission operation pre-existing in target directory under {@code ou=Permissions,ou=RBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may also contain {@link org.apache.directory.fortress.core.rbac.Role} or {@link org.apache.directory.fortress.core.rbac.User} associations to add or remove using this function.
+     * The perm operation must exist before making this call.  Only non-null attributes will be updated.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission update</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
+     * <li>{@link Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
+     * <li>{@link Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target and any optional data to update.  Null or empty attributes will be ignored.
+     * @return copy of Permission entity.
+     * @throws SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    public Permission updatePermission(Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * This method will remove permission operation entity from permission object. A Fortress permission is (object->operation).
+     * The perm operation must exist before making this call.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission delete</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation being removed</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    public void deletePermission(Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * This method will add permission object to perms container in directory. The perm object must not exist before making this call.
+     * A {@link PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link PermObj}*->{@link Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of new object being added</li>
+     * <li>{@link PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#description} - any safe text</li>
+     * <li>{@link PermObj#type} - contains any safe text</li>
+     * <li>{@link PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link PermObj#objName} and {@link PermObj#ou}.  The other attributes are optional.
+     * @return copy of PermObj entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    public PermObj addPermObj(PermObj pObj)
+        throws SecurityException;
+
+
+    /**
+     * This method will update permission object in perms container in directory.  The perm object must exist before making this call.
+     * A {@link PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link PermObj}*->{@link Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of existing object being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * <li>{@link PermObj#description} - any safe text</li>
+     * <li>{@link PermObj#type} - contains any safe text</li>
+     * <li>{@link PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link PermObj#objName}. Only non-null attributes will be updated.
+     * @return copy of newly updated PermObj entity.
+     * @throws SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    public PermObj updatePermObj(PermObj pObj)
+        throws SecurityException;
+
+
+    /**
+     * This method will remove permission object to perms container in directory.  This method will also remove
+     * in associated permission objects that are attached to this object.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of existing object targeted for removal</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link PermObj#objName} of object targeted for removal.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    public void deletePermObj(PermObj pObj)
+        throws SecurityException;
+
+
+    /**
+     * This command grants a role the permission to perform an operation on an object to a role.
+     * The command is implemented by granting permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * and the role is a member of the ROLES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link Role#name} - contains the role name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param role must contains {@link Role#name}.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    public void grantPermission(Permission perm, Role role)
+        throws SecurityException;
+
+
+    /**
+     * This command revokes the permission to perform an operation on an object from the set
+     * of permissions assigned to a role. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * the role is a member of the ROLES data set, and the permission is assigned to that role.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link Role#name} - contains the role name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param role must contains {@link Role#name}.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    public void revokePermission(Permission perm, Role role)
+        throws SecurityException;
+
+
+    /**
+     * This command grants a user the permission to perform an operation on an object to a role.
+     * The command is implemented by granting permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * and the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param user must contain {@link User#userId} of target User entity.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    public void grantPermission(Permission perm, User user)
+        throws SecurityException;
+
+
+    /**
+     * This command revokes the permission to perform an operation on an object from the set
+     * of permissions assigned to a user. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * the user is a member of the USERS data set, and the permission is assigned to that user.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param user must contain {@link User#userId} of target User entity.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    public void revokePermission(Permission perm, User user)
+        throws SecurityException;
+
+    /**
+     * This command creates a new role childRole, and inserts it in the role hierarchy as an immediate descendant of
+     * the existing role parentRole.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The childRole is not a member of the ROLES data set.
+     * <li> The parentRole is a member of the ROLES data set.
+     * </ul>
+     * </p>
+     * <p> This method:
+     * <ul>
+     * <li> Adds new role.
+     * <li> Assigns role relationship between new childRole and pre-existing parentRole.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#name} - contains the name of existing Role to be parent</li>
+     * <li>childRole - {@link Role#name} - contains the name of new Role to be child</li>
+     * </ul>
+     * <h4>optional parameters childRole</h4>
+     * <ul>
+     * <li>childRole - {@link Role#description} - maps to description attribute on organizationalRole object class for new child</li>
+     * <li>childRole - {@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session for new child</li>
+     * <li>childRole - {@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session for new child</li>
+     * <li>childRole - {@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session for new child</li>
+     * <li>childRole - {@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session for new child</li>
+     * <li>childRole - {@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new child</li>
+     * <li>childRole - {@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new child</li>
+     * <li>childRole - {@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session for new child</li>
+     * </ul>
+     *
+     * @param parentRole This entity must be present in ROLE data set.  Success will add role rel with childRole.
+     * @param childRole  This entity must not be present in ROLE data set.  Success will add the new role entity to ROLE data set.
+     * @throws SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    public void addDescendant(Role parentRole, Role childRole)
+        throws SecurityException;
+
+
+    /**
+     * This command creates a new role parentRole, and inserts it in the role hierarchy as an immediate ascendant of
+     * the existing role childRole.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The parentRole is not a member of the ROLES data set.
+     * <li> The childRole is a member of the ROLES data set.
+     * </ul>
+     * </p>
+     * <p> This method:
+     * <ul>
+     * <li> Adds new role.
+     * <li> Assigns role relationship between new parentRole and pre-existing childRole.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>childRole - {@link Role#name} - contains the name of existing child Role</li>
+     * <li>parentRole - {@link Role#name} - contains the name of new Role to be parent</li>
+     * </ul>
+     * <h4>optional parameters parentRole</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#description} - maps to description attribute on organizationalRole object class for new parent</li>
+     * <li>parentRole - {@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session for new parent</li>
+     * <li>parentRole - {@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session for new parent</li>
+     * <li>parentRole - {@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session for new parent</li>
+     * <li>parentRole - {@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session for new parent</li>
+     * <li>parentRole - {@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new parent</li>
+     * <li>parentRole - {@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new parent</li>
+     * <li>parentRole - {@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session for new parent</li>
+     * </ul>
+     *
+     * @param parentRole completion of op assigns new child relationship with childRole.
+     * @param childRole  completion of op assigns new parent relationship with parentRole.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    public void addAscendant(Role childRole, Role parentRole)
+        throws SecurityException;
+
+
+    /**
+     * This command establishes a new immediate inheritance relationship parentRole <<-- childRole between existing
+     * roles parentRole, childRole.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The parentRole and childRole are members of the ROLES data set.
+     * <li> The parentRole is not an immediate ascendant of childRole.
+     * <li> The childRole does not properly inherit parentRole (in order to avoid cycle creation).
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#name} - contains the name of existing Role to be parent</li>
+     * <li>childRole - {@link Role#name} - contains the name of existing Role to be child</li>
+     * </ul>
+     *
+     * @param parentRole completion of op deassigns child relationship with childRole.
+     * @param childRole  completion of op deassigns parent relationship with parentRole.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    public void addInheritance(Role parentRole, Role childRole)
+        throws SecurityException;
+
+
+    /**
+     * This command deletes an existing immediate inheritance relationship parentRole <<-- childRole.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The roles parentRole and childRole are members of the ROLES data set.
+     * <li> The parentRole is an immediate ascendant of childRole.
+     * <li> The new inheritance relation is computed as the reflexive-transitive closure of the immediate inheritance
+     * relation resulted after deleting the relationship parentRole <<-- childRole.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#name} - contains the name of existing Role to remove parent relationship</li>
+     * <li>childRole - {@link Role#name} - contains the name of existing Role to remove child relationship</li>
+     * </ul>
+     *
+     * @param parentRole completion of op removes child relationship with childRole.
+     * @param childRole  completion of op removes parent relationship with parentRole.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    public void deleteInheritance(Role parentRole, Role childRole)
+        throws SecurityException;
+
+
+    /**
+     * This command creates a named SSD set of roles and sets the cardinality n of its subsets
+     * that cannot have common users.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li>The name of the SSD set is not already in use.
+     * <li> All the roles in the SSD set are members of the ROLES data set.
+     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the SSD role set.
+     * <li> The SSD constraint for the new role set is satisfied.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of new SSD role set to be added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
+     * <li>{@link SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to new SSD set containing, name, members, and cardinality (default 2)
+     * @return reference to newly created SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet createSsdSet(SDSet ssdSet)
+        throws SecurityException;
+
+    /**
+     * This command updates existing SSD set of roles and sets the cardinality n of its subsets
+     * that cannot have common users.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li>The name of the SSD set already exists.
+     * <li> All the roles in the SSD set are members of the ROLES data set.
+     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the SSD role set.
+     * <li> The SSD constraint for the new role set is satisfied.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing SSD role set to be updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
+     * <li>{@link SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to existing SSD set containing, name, members, and cardinality (default 2)
+     * @return reference to SSDSet object targeted for update.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet updateSsdSet(SDSet ssdSet)
+        throws SecurityException;
+
+    /**
+     * This command adds a role to a named SSD set of roles. The cardinality associated with the role set remains unchanged.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The SSD role set exists.
+     * <li> The role to be added is a member of the ROLES data set but not of a member of the SSD role set.
+     * <li> The SSD constraint is satisfied after the addition of the role to the SSD role set.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
+     * <li>{@link Role#name} - contains the name of new {@link SDSet#members} to be added</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to new SSD set containing, name
+     * @param role   contains instantiated Role object with role name field set.
+     * @return reference to updated SSDSet object.
+     * @throws SecurityException
+     *          in the event of data validation or system error.
+     */
+    public SDSet addSsdRoleMember(SDSet ssdSet, Role role)
+        throws SecurityException;
+
+    /**
+     * This command removes a role from a named SSD set of roles. The cardinality associated with the role set remains unchanged.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The SSD role set exists.
+     * <li> The role to be removed is a member of the SSD role set.
+     * <li> The cardinality associated with the SSD role set is less than the number of elements of the SSD role set.
+     * </ul>
+     * Note that the SSD constraint should be satisfied after the removal of the role from the SSD role set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
+     * <li>{@link Role#name} - contains the name of existing {@link SDSet#members} to be removed</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to new SSD set containing name.
+     * @param role   contains instantiated Role object with role name field set.
+     * @return reference to updated SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet deleteSsdRoleMember(SDSet ssdSet, Role role)
+        throws SecurityException;
+
+    /**
+     * This command deletes a SSD role set completely. The command is valid if and only if the SSD role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of SSD role set to be removed</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to SSD set targeted for removal.
+     * @return reference to deleted SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet deleteSsdSet(SDSet ssdSet)
+        throws SecurityException;
+
+    /**
+     * This command sets the cardinality associated with a given SSD role set.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The SSD role set exists.
+     * <li> The new cardinality is a natural number greater than or equal to 2 and less than or equal to the number of elements of the SSD role set.
+     * <li> The SSD constraint is satisfied after setting the new cardinality.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
+     * <li>cardinality - contains new cardinality setting for SSD</li>
+     * </ul>
+     *
+     * @param ssdSet      contains an instantiated reference to new SSD set containing, name
+     * @param cardinality integer value contains new cardinality value for data set.
+     * @return reference to updated SSDSet object.
+     * @throws SecurityException
+     *          in the event of data validation or system error.
+     */
+    public SDSet setSsdSetCardinality(SDSet ssdSet, int cardinality)
+        throws SecurityException;
+
+
+    /**
+     * This command creates a named DSD set of roles and sets an associated cardinality n.
+     * The DSD constraint stipulates that the DSD role set cannot contain n or more roles
+     * simultaneously active in the same session.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The name of the DSD set is not already in use.
+     * <li> All the roles in the DSD set are members of the ROLES data set.
+     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the DSD role set.
+     * <li> The DSD constraint for the new role set is satisfied.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of new DSD role set to be added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
+     * <li>{@link SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to new DSD set containing, name, members, and cardinality (default 2)
+     * @return reference to newly created SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet createDsdSet(SDSet dsdSet)
+        throws SecurityException;
+
+    /**
+     * This command updates existing DSD set of roles and sets the cardinality n of its subsets
+     * that cannot have common users.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li>The name of the DSD set already exists.
+     * <li> All the roles in the DSD set are members of the ROLES data set.
+     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the DSD role set.
+     * <li> The DSD constraint for the new role set is satisfied.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing DSD role set to be updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
+     * <li>{@link SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to existing DSD set containing, name, members, and cardinality (default 2)
+     * @return reference to DSDSet object targeted for update.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet updateDsdSet(SDSet dsdSet)
+        throws SecurityException;
+
+    /**
+     * This command adds a role to a named DSD set of roles. The cardinality associated with
+     * the role set remains unchanged.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The DSD role set exists.
+     * <li> The role to be added is a member of the ROLES data set but not of a member of the DSD role set.
+     * <li> The DSD constraint is satisfied after the addition of the role to the SSD role set.
+     * </ul>
+     * </p>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of DSD role set to be modified</li>
+     * <li>{@link Role#name} - contains the name of new {@link SDSet#members} to be added</li>
+     * </ul>
+     * @param dsdSet contains an instantiated reference to new DSD set containing, name
+     * @param role   contains instantiated Role object with role name field set.
+     * @return reference to updated DSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet addDsdRoleMember(SDSet dsdSet, Role role)
+        throws SecurityException;
+
+    /**
+     * This command removes a role from a named DSD set of roles. The cardinality associated
+     * with the role set remains unchanged.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The DSD role set exists
+     * <li> The role to be removed is a member of the DSD role set.
+     * <li> The cardinality associated with the DSD role set is less than the number of elements of the DSD role set.
+     * </ul>
+     * Note that the DSD constraint should be satisfied after the removal of the role from the DSD role set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of DSD role set to be modified</li>
+     * <li>{@link Role#name} - contains the name of existing {@link SDSet#members} to be removed</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to new DSD set containing name.
+     * @param role   contains instantiated Role object with role name field set.
+     * @return reference to updated DSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet deleteDsdRoleMember(SDSet dsdSet, Role role)
+        throws SecurityException;
+
+    /**
+     * This command deletes a DSD role set completely. The command is valid if and only if the DSD role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of DSD role set to be removed</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to DSD set targeted for removal.
+     * @return reference to deleted DSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet deleteDsdSet(SDSet dsdSet)
+        throws SecurityException;
+
+    /**
+     * This command sets the cardinality associated with a given DSD role set.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The SSD role set exists.
+     * <li> The new cardinality is a natural number greater than or equal to 2 and less than or equal to the number of elements of the SSD role set.
+     * <li> The SSD constraint is satisfied after setting the new cardinality.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of DSD role set to be modified</li>
+     * <li>cardinality - contains new cardinality setting for SSD</li>
+     * </ul>
+     *
+     * @param dsdSet      contains an instantiated reference to new DSD set containing, name
+     * @param cardinality integer value contains new cardinality value for data set.
+     * @return reference to updated DSDSet object.
+     * @throws SecurityException
+     *          in the event of data validation or system error.
+     */
+    public SDSet setDsdSetCardinality(SDSet dsdSet, int cardinality)
+        throws SecurityException;
+}
\ 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/AdminMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/AdminMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/AdminMgrFactory.java
new file mode 100755
index 0000000..e6cd9dc
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/AdminMgrFactory.java
@@ -0,0 +1,114 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.AdminMgrImpl;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rest.AdminMgrRestImpl;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Creates an instance of the AdminMgr object.
+ * The factory allows deployments of Fortress override the default AdminMgrImpl component with another.
+ * <p/>
+ * The default class is specified as {@link AdminMgrImpl} but can be overridden by
+ * adding the {@link GlobalIds#ADMIN_IMPLEMENTATION} config property.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class AdminMgrFactory
+{
+    private static String adminClassName = Config.getProperty(GlobalIds.ADMIN_IMPLEMENTATION);
+    private static final String CLS_NM = AdminMgrFactory.class.getName();
+
+    /**
+     * Create and return a reference to {@link AdminMgr} object using HOME context.
+     *
+     * @return instance of {@link AdminMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AdminMgr createInstance()
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME );
+    }
+
+    /**
+     * Create and return a reference to {@link AdminMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return instance of {@link AdminMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AdminMgr createInstance(String contextId)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance");
+        if (!VUtil.isNotNullOrEmpty(adminClassName))
+        {
+            if(GlobalIds.IS_REST)
+            {
+                adminClassName = AdminMgrRestImpl.class.getName();
+            }
+            else
+            {
+                adminClassName = AdminMgrImpl.class.getName();
+            }
+        }
+
+        AdminMgr adminMgr = (AdminMgr) ClassUtil.createInstance(adminClassName);
+        adminMgr.setContextId(contextId);
+        return adminMgr;
+    }
+
+    /**
+     * Create and return a reference to {@link AdminMgr} object using HOME context.
+     *
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link AdminMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AdminMgr createInstance(Session adminSess)
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME, adminSess );
+    }
+
+    /**
+     * Create and return a reference to {@link AdminMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link AdminMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AdminMgr createInstance(String contextId, Session adminSess)
+        throws SecurityException
+    {
+        AdminMgr adminMgr = createInstance(contextId);
+        adminMgr.setAdmin(adminSess);
+        return adminMgr;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/AuditMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/AuditMgr.java b/src/main/java/org/apache/directory/fortress/core/AuditMgr.java
new file mode 100755
index 0000000..24538bb
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/AuditMgr.java
@@ -0,0 +1,199 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.rbac.AuthZ;
+import org.apache.directory.fortress.core.rbac.Mod;
+import org.apache.directory.fortress.core.rbac.UserAudit;
+import org.apache.directory.fortress.core.rbac.Bind;
+
+import java.util.List;
+
+/**
+ * This interface prescribes methods used to search <a href="http://www.openldap.org/">OpenLDAP</a>'s slapd access log.  The access log events are
+ * persisted in <a href="http://www.oracle.com/technetwork/database/berkeleydb/overview/index.html">BDB</a> and available for inquiry via common LDAP protocols.
+ * Audit entries stored on behalf of Fortress operations correspond to runtime authentication {@link org.apache.directory.fortress.core.rbac.Bind}, authorization {@link org.apache.directory.fortress.core.rbac.AuthZ} and modification {@link org.apache.directory.fortress.core.rbac.Mod}
+ * events as they occur automatically on the server when audit is enabled.
+ * <h4>Audit Interrogator</h4>
+ * Provides an OpenLDAP access log retrieval mechanism that enables security event monitoring.
+ * <ol>
+ * <li>Authentication events:
+ * <li>Session enablement events
+ * <li>Authorization events
+ * <li>Entity mods and deletes
+ * </li>
+ * </ol>
+ * <img src="./doc-files/Audit.png">
+ * <p/>
+ * All events include Fortress context, see {@link org.apache.directory.fortress.core.rbac.FortEntity}.
+ * <p/>
+ * <h4>
+ * The following APIs generate events subsequently stored in this access log:
+ * </h4>
+ * <ul>
+ * <li> {@link AccessMgr}
+ * <li> {@link AdminMgr}
+ * <li> {@link AdminMgr}
+ * <li> {@link DelAdminMgr}
+ * <li> {@link org.apache.directory.fortress.cfg.ConfigMgr}
+ * <li> {@link PwPolicyMgr}
+ * </ul>
+ * <h4>
+ * The following reports are supported using search input: {@link org.apache.directory.fortress.core.rbac.UserAudit}
+ * </h4>
+ * <ul>
+ * <li>User Authentications:     <code>List<{@link org.apache.directory.fortress.core.rbac.Bind}>  {@link AuditMgr#searchBinds(org.apache.directory.fortress.core.rbac.UserAudit)}</code>
+ * <li>Invalid User AuthN:       <code>List<{@link org.apache.directory.fortress.core.rbac.Bind}>  {@link AuditMgr#searchInvalidUsers(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>User Authorizations 1:    <code>List<{@link org.apache.directory.fortress.core.rbac.AuthZ}> {@link AuditMgr#getUserAuthZs(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>User Authorizations 2:    <code>List<{@link org.apache.directory.fortress.core.rbac.AuthZ}> {@link AuditMgr#searchAuthZs(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>User Session Activations: <code>List<{@link org.apache.directory.fortress.core.rbac.Mod}>   {@link AuditMgr#searchUserSessions(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>Entity Modifications:     <code>List<{@link org.apache.directory.fortress.core.rbac.Mod}>   {@link AuditMgr#searchAdminMods(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * </ul>
+ * <p/>
+ * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.apache.directory.fortress.core.rbac.Session)}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public interface AuditMgr extends Manageable
+{
+    /**
+     * This method returns a list of authorization events for a particular user {@link org.apache.directory.fortress.core.rbac.UserAudit#userId}
+     * and given timestamp field {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.<BR>
+     * Method also can discriminate between all events or failed only by setting {@link org.apache.directory.fortress.core.rbac.UserAudit#failedOnly}.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAudit#userId} - contains the target userId</li>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one authorization event.
+     * @throws SecurityException if a runtime system error occurs.
+     */
+    public List<AuthZ> getUserAuthZs(UserAudit uAudit)
+        throws SecurityException;
+
+    /**
+     * This method returns a list of authorization events for a particular user {@link org.apache.directory.fortress.core.rbac.UserAudit#userId},
+     * object {@link org.apache.directory.fortress.core.rbac.UserAudit#objName}, and given timestamp field {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.<BR>
+     * Method also can discriminate between all events or failed only by setting flag {@link UserAudit#failedOnly}..
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId<</li>
+     * <li>{@link UserAudit#objName} - contains the object (authorization resource) name</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one authorization event.
+     * @throws SecurityException
+     *          if a runtime system error occurs.
+     */
+    public List<AuthZ> searchAuthZs(UserAudit uAudit)
+        throws SecurityException;
+
+    /**
+     * This method returns a list of authentication audit events for a particular user {@link org.apache.directory.fortress.core.rbac.UserAudit#userId},
+     * and given timestamp field {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.<BR>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAudit#userId} - contains the target userId<</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type Bind.  Each Bind object contains one bind event.
+     * @throws SecurityException
+     *          if a runtime system error occurs.
+     */
+    public List<Bind> searchBinds(UserAudit uAudit)
+        throws SecurityException;
+
+    /**
+     * This method returns a list of sessions created for a given user {@link UserAudit#userId},
+     * and timestamp {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.<BR>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId<</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type Mod.  Each Mod object in list corresponds to one update or delete event on directory.
+     * @throws SecurityException if a runtime system error occurs.
+     */
+    public List<Mod> searchUserSessions(UserAudit uAudit)
+        throws SecurityException;
+
+    /**
+     * This method returns a list of admin operations events for a particular entity {@link org.apache.directory.fortress.core.rbac.UserAudit#dn},
+     * object {@link UserAudit#objName} and timestamp {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.  If the internal
+     * userId {@link org.apache.directory.fortress.core.rbac.UserAudit#internalUserId} is set it will limit search by that field.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#dn} - contains the LDAP distinguished name for the updated object.  For example if caller
+     * wants to find out what changes were made to John Doe's user object this would be 'uid=jdoe,ou=People,dc=example,dc=com'</li>
+     * <li>{@link UserAudit#objName} - contains the object (authorization resource) name corresponding to the event.  For example if caller
+     * wants to return events where User object was modified, this would be 'updateUser'</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAudit#internalUserId} - maps to the internalUserId of user who changed the record in LDAP.  This maps to {@link org.apache.directory.fortress.core.rbac.User#internalId}.</li>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#endDate} - contains the date in which to end search</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type Mod.  Each Mod object in list corresponds to one update or delete event on directory.
+     * @throws SecurityException
+     *          if a runtime system error occurs.
+     */
+    public List<Mod> searchAdminMods(UserAudit uAudit)
+        throws SecurityException;
+
+    /**
+     * This method returns a list of failed authentication attempts on behalf of an invalid identity {@link org.apache.directory.fortress.core.rbac.UserAudit#userId},
+     * and given timestamp {@link UserAudit#beginDate}.  If the {@link org.apache.directory.fortress.core.rbac.UserAudit#failedOnly} is true it will
+     * return only authentication attempts made with invalid userId.  This event represents either User incorrectly entering userId during signon or
+     * possible fraudulent logon attempt by hostile agent.
+     * </p>
+     * This event is generated when Fortress looks up User record prior to LDAP bind operation.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId</li>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one failed authentication event.
+     * @throws SecurityException
+     *          if a runtime system error occurs.
+     */
+    public List<AuthZ> searchInvalidUsers(UserAudit uAudit)
+        throws SecurityException;
+
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/AuditMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/AuditMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/AuditMgrFactory.java
new file mode 100755
index 0000000..8a28dd0
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/AuditMgrFactory.java
@@ -0,0 +1,111 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.AuditMgrImpl;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rest.AuditMgrRestImpl;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Creates an instance of the AuditMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link AuditMgrImpl} but can be overridden by
+ * adding the {@link GlobalIds#AUDIT_IMPLEMENTATION} config property.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class AuditMgrFactory
+{
+    private static String auditClassName = Config.getProperty(GlobalIds.AUDIT_IMPLEMENTATION);
+    private static final String CLS_NM = AuditMgrFactory.class.getName();
+
+    /**
+     * Create and return a reference to {@link AuditMgr} object using HOME context.
+     *
+     * @return instance of {@link AuditMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AuditMgr createInstance()
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME );
+    }
+
+    /**
+     * Create and return a reference to {@link AuditMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return instance of {@link AuditMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AuditMgr createInstance(String contextId)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance");
+        if (!VUtil.isNotNullOrEmpty(auditClassName))
+        {
+            if(GlobalIds.IS_REST)
+            {
+                auditClassName = AuditMgrRestImpl.class.getName();
+            }
+            else
+            {
+                auditClassName = AuditMgrImpl.class.getName();
+            }
+        }
+
+        AuditMgr auditMgr = (AuditMgr) ClassUtil.createInstance(auditClassName);
+        auditMgr.setContextId(contextId);
+        return auditMgr;
+    }
+
+    /**
+     * Create and return a reference to {@link AuditMgr} object using HOME context.
+     *
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link AuditMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AuditMgr createInstance(Session adminSess)
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME, adminSess );
+    }
+
+    /**
+     * Create and return a reference to {@link AuditMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link AuditMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AuditMgr createInstance(String contextId, Session adminSess)
+        throws SecurityException
+    {
+        AuditMgr auditMgr = createInstance(contextId);
+        auditMgr.setAdmin(adminSess);
+        return auditMgr;
+    }
+}
\ 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/AuthorizationException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/AuthorizationException.java b/src/main/java/org/apache/directory/fortress/core/AuthorizationException.java
new file mode 100755
index 0000000..7641bc5
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/AuthorizationException.java
@@ -0,0 +1,42 @@
+/*
+ *   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;
+
+
+/**
+ * This exception extends {@link SecurityException} and is thrown when administrative permission check fails.
+ * See the {@link GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+public class AuthorizationException extends SecurityException
+{
+    /**
+     * Create an exception with an error code that maps to {@link GlobalErrIds} and message text.
+     *
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     */
+    public AuthorizationException(int errorId, String msg)
+    {
+        super(errorId, msg);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/BaseException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/BaseException.java b/src/main/java/org/apache/directory/fortress/core/BaseException.java
new file mode 100755
index 0000000..69d99af
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/BaseException.java
@@ -0,0 +1,68 @@
+/*
+ *   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;
+
+/**
+ * Base exception class for checked exceptions thrown.  This class wraps {@code java.lang.Exception}.  The BaseException
+ * class adds int attribute which stores the necessary error code as required by all checked exceptions in this system.
+ * The BaseException class has been extended by {@link SecurityException} which is then declared thrown on most Fortress public APIs.
+ * See the {@link GlobalErrIds} javadoc for list of error ids that will be set.
+ *
+ * @author Shawn McKinney
+ */
+public abstract class BaseException extends Exception implements StandardException
+{
+	private final int errorId;
+
+    /**
+     * Create exception containing error code and message.
+     *
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     */
+	BaseException(int errorId, String msg)
+	{
+		super(msg);
+		this.errorId = errorId;
+	}
+
+    /**
+     * Create exception containing error code, message and previous exception.
+     *
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     * @param previousException contains reference to related exception which usually is system related, i.e. ldap.
+     */
+	BaseException(int errorId, String msg, Throwable previousException)
+	{
+		super(msg, previousException);
+		this.errorId = errorId;
+	}
+
+    /**
+     * Return the error id that is defined by this class {@link GlobalErrIds}.
+     *
+     * @return error id which is defined here {@link GlobalErrIds}.  Valid values for Fortress error codes fall between 0 and 100_000.
+     */
+	public int getErrorId()
+	{
+		return errorId;
+	}
+}
\ 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/BaseRuntimeException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/BaseRuntimeException.java b/src/main/java/org/apache/directory/fortress/core/BaseRuntimeException.java
new file mode 100755
index 0000000..106f7c7
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/BaseRuntimeException.java
@@ -0,0 +1,83 @@
+/*
+ *   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;
+
+/**
+ *  Base runtime exception class for Fortress runtime exceptions.
+ * See the {@link GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+public abstract class BaseRuntimeException extends RuntimeException
+{
+
+	private final int errorId;
+	private final String[] msgParams;
+
+    /**
+     *
+     * @param errorId int contains the error id which is defined here {@link GlobalErrIds}.
+     * @param msgParam contains message pertaining to exception.
+     * @param previousException contains reference to related exception which usually is system related, i.e. ldap.
+     */
+	protected BaseRuntimeException(int errorId, String msgParam, Throwable previousException)
+	{
+		super(msgParam + ", errCode=" + errorId, previousException);
+		this.errorId = errorId;
+		this.msgParams = new String[1];
+		this.msgParams[0] = msgParam;
+	}
+
+    /**
+     *
+     * @param errorId int contains the error id which is defined here {@link GlobalErrIds}.
+     * @param msgParam contains message pertaining to exception.
+     */
+	protected BaseRuntimeException(int errorId, String msgParam)
+	{
+		super(msgParam + ", errCode=" + errorId);
+		this.errorId = errorId;
+		this.msgParams = new String[1];
+		this.msgParams[0] = msgParam;
+	}
+
+    /**
+     * Return the message for current exception.
+     *
+     * @return string contains the error message.
+     */
+	public String getMsg()
+	{
+        String msg = null;
+		if (this.msgParams != null)
+            msg = this.msgParams[0];
+		return msg;
+	}
+
+    /**
+     * Return the error id that is defined by this class {@link GlobalErrIds}.
+     *
+     * @return error id which is defined here {@link GlobalErrIds}.
+     */
+	public int getErrorId()
+	{
+		return errorId;
+	}
+}


[50/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/ldap/setup/DelegatedAdminManagerLoad.xml
----------------------------------------------------------------------
diff --git a/ldap/setup/DelegatedAdminManagerLoad.xml b/ldap/setup/DelegatedAdminManagerLoad.xml
index 5b308f6..d265c8c 100644
--- a/ldap/setup/DelegatedAdminManagerLoad.xml
+++ b/ldap/setup/DelegatedAdminManagerLoad.xml
@@ -18,7 +18,7 @@
    under the License.
 -->
 <project basedir="." default="all" name="Fortress Sample Data">
-    <taskdef classname="org.openldap.fortress.ant.FortressAntTask" name="FortressAdmin" >
+    <taskdef classname="org.apache.directory.fortress.core.ant.FortressAntTask" name="FortressAdmin" >
         <classpath path="${java.class.path}"/>
     </taskdef>
 
@@ -36,255 +36,255 @@
             </addadminrole>
 
             <addpermgrant>
-                <permgrant objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="searchBinds" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="searchAuthZs" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="getUserAuthZs" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="searchUserSessions" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="searchAdminMods" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="searchInvalidUsers" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="searchBinds" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="searchAuthZs" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="getUserAuthZs" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="searchUserSessions" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="searchAdminMods" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="searchInvalidUsers" roleNm="FortressSuperAdmin" admin="true"/>
 
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="readPermission" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="readPermObj" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="findPermissions" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="findPermObjs" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="readRole" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="findRoles" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="readUser" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="findUsers" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="assignedUsers" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="assignedRoles" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="authorizedUsers" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="authorizedRoles" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="rolePermissions" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="userPermissions" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="permissionRoles" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="authorizedPermissionRoles" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="permissionUsers" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="authorizedPermissionUsers" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="ssdRoleSets" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="ssdRoleSet" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="ssdRoleSetRoles" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="ssdRoleSetCardinality" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="dsdRoleSets" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="ssdSets" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="dsdRoleSet" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="dsdRoleSetRoles" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="dsdRoleSetCardinality" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="dsdSets" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="readPermission" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="readPermObj" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="findPermissions" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="findPermObjs" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="readRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="findRoles" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="readUser" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="findUsers" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="assignedUsers" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="assignedRoles" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="authorizedUsers" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="authorizedRoles" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="rolePermissions" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="userPermissions" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="permissionRoles" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="authorizedPermissionRoles" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="permissionUsers" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="authorizedPermissionUsers" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="ssdRoleSets" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="ssdRoleSet" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="ssdRoleSetRoles" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="ssdRoleSetCardinality" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="dsdRoleSets" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="ssdSets" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="dsdRoleSet" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="dsdRoleSetRoles" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="dsdRoleSetCardinality" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="dsdSets" roleNm="FortressSuperAdmin" admin="true"/>
 
-                <permgrant objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="readRole" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="findRoles" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="assignedRoles" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="assignedUsers" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="readOU" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="searchOU" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="readRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="findRoles" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="assignedRoles" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="assignedUsers" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="readOU" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="searchOU" roleNm="FortressSuperAdmin" admin="true"/>
 
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addUser" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="disableUser" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteUser" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updateUser" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="changePassword" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="lockUserAccount" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="unlockUserAccount" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="resetPassword" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addRole" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteRole" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updateRole" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="assignUser" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deassignUser" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addPermission" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addPermObj" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deletePermission" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deletePermObj" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updatePermission" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updatePermObj" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="grantPermission" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="revokePermission" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="grantPermissionUser" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="revokePermissionUser" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addDescendant" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addAscendant" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addInheritance" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteInheritance" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="createSsdSet" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updateSsdSet" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addSsdRoleMember" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteSsdRoleMember" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteSsdSet" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="setSsdSetCardinality" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="createDsdSet" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updateDsdSet" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addDsdRoleMember" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteDsdRoleMember" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteDsdSet" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="setDsdSetCardinality" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addUser" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="disableUser" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteUser" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updateUser" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="changePassword" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="lockUserAccount" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="unlockUserAccount" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="resetPassword" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updateRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="assignUser" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deassignUser" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addPermission" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addPermObj" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deletePermission" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deletePermObj" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updatePermission" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updatePermObj" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="grantPermission" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="revokePermission" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="grantPermissionUser" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="revokePermissionUser" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addDescendant" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addAscendant" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addInheritance" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteInheritance" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="createSsdSet" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updateSsdSet" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addSsdRoleMember" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteSsdRoleMember" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteSsdSet" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="setSsdSetCardinality" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="createDsdSet" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updateDsdSet" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addDsdRoleMember" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteDsdRoleMember" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteDsdSet" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="setDsdSetCardinality" roleNm="FortressSuperAdmin" admin="true"/>
 
-                <permgrant objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="add" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="update" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="delete" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="updateUserPolicy" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="deletePasswordPolicy" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="search" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="add" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="update" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="delete" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="updateUserPolicy" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="deletePasswordPolicy" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="search" roleNm="FortressSuperAdmin" admin="true"/>
 
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addRole" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="deleteRole" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="updateRole" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="assignUser" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="deassignUser" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addOU" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="updateOU" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="deleteOU" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addDescendantOU" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addAscendantOU" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addInheritanceOU" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="deleteInheritanceOU" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addDescendantRole" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addAscendantRole" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addInheritanceRole" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="deleteInheritanceRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="deleteRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="updateRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="assignUser" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="deassignUser" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addOU" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="updateOU" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="deleteOU" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addDescendantOU" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addAscendantOU" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addInheritanceOU" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="deleteInheritanceOU" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addDescendantRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addAscendantRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addInheritanceRole" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="deleteInheritanceRole" roleNm="FortressSuperAdmin" admin="true"/>
 
-                <permgrant objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="add" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="update" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="delete" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="addProperty" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="deleteProperty" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="assign" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="deassign" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="read" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="find" roleNm="FortressSuperAdmin" admin="true"/>
-                <permgrant objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="findWithUsers" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="add" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="update" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="delete" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="addProperty" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="deleteProperty" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="assign" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="deassign" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="read" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="find" roleNm="FortressSuperAdmin" admin="true"/>
+                <permgrant objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="findWithUsers" roleNm="FortressSuperAdmin" admin="true"/>
 
             </addpermgrant>
 
             <addpermobj>
-                <permobj objName="org.openldap.fortress.rbac.DelAdminMgrImpl" description="ARBAC02 admin policies" ou="default" type="ARBAC" admin="true"/>
-                <permobj objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" description="Password policies" ou="default" type="ARBAC" admin="true"/>
-                <permobj objName="org.openldap.fortress.rbac.AdminMgrImpl" description="RBAC admin policies" ou="default" type="ARBAC" admin="true"/>
-                <permobj objName="org.openldap.fortress.rbac.DelReviewMgrImpl" description="ARBAC review policies" ou="default" type="ARBAC" admin="true"/>
-                <permobj objName="org.openldap.fortress.rbac.ReviewMgrImpl" description="RBAC review policies" ou="default" type="ARBAC" admin="true"/>
-                <permobj objName="org.openldap.fortress.rbac.AuditMgrImpl" description="RBAC audit review" ou="default" type="ARBAC" admin="true"/>
-                <permobj objName="org.openldap.fortress.ldap.group.GroupMgrImpl" description="LDAP Group admin policies" ou="default" type="ARBAC" admin="true"/>
+                <permobj objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" description="ARBAC02 admin policies" ou="default" type="ARBAC" admin="true"/>
+                <permobj objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" description="Password policies" ou="default" type="ARBAC" admin="true"/>
+                <permobj objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" description="RBAC admin policies" ou="default" type="ARBAC" admin="true"/>
+                <permobj objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" description="ARBAC review policies" ou="default" type="ARBAC" admin="true"/>
+                <permobj objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" description="RBAC review policies" ou="default" type="ARBAC" admin="true"/>
+                <permobj objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" description="RBAC audit review" ou="default" type="ARBAC" admin="true"/>
+                <permobj objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" description="LDAP Group admin policies" ou="default" type="ARBAC" admin="true"/>
             </addpermobj>
 
             <addpermop>
 
-                <permop objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="searchBinds" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="searchAuthZs" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="getUserAuthZs" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="searchUserSessions" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="searchAdminMods" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AuditMgrImpl" opName="searchInvalidUsers" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="searchBinds" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="searchAuthZs" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="getUserAuthZs" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="searchUserSessions" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="searchAdminMods" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AuditMgrImpl" opName="searchInvalidUsers" admin="true"/>
 
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="readPermission" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="readPermObj" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="findPermissions" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="findPermObjs" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="readRole" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="findRoles" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="readUser" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="findUsers" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="assignedUsers" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="assignedRoles" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="authorizedUsers" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="authorizedRoles" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="rolePermissions" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="userPermissions" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="permissionRoles" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="authorizedPermissionRoles" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="permissionUsers" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="authorizedPermissionUsers" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="ssdRoleSets" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="ssdRoleSet" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="ssdRoleSetRoles" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="ssdRoleSetCardinality" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="dsdRoleSets" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="ssdSets" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="dsdRoleSet" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="dsdRoleSetRoles" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="dsdRoleSetCardinality" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.ReviewMgrImpl" opName="dsdSets" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="readPermission" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="readPermObj" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="findPermissions" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="findPermObjs" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="readRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="findRoles" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="readUser" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="findUsers" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="assignedUsers" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="assignedRoles" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="authorizedUsers" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="authorizedRoles" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="rolePermissions" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="userPermissions" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="permissionRoles" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="authorizedPermissionRoles" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="permissionUsers" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="authorizedPermissionUsers" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="ssdRoleSets" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="ssdRoleSet" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="ssdRoleSetRoles" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="ssdRoleSetCardinality" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="dsdRoleSets" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="ssdSets" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="dsdRoleSet" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="dsdRoleSetRoles" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="dsdRoleSetCardinality" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.ReviewMgrImpl" opName="dsdSets" admin="true"/>
 
-                <permop objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="readRole" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="findRoles" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="assignedRoles" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="assignedUsers" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="readOU" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelReviewMgrImpl" opName="searchOU" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="readRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="findRoles" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="assignedRoles" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="assignedUsers" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="readOU" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelReviewMgrImpl" opName="searchOU" admin="true"/>
 
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addUser" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="disableUser" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteUser" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updateUser" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="changePassword" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="lockUserAccount" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="unlockUserAccount" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="resetPassword" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addRole" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteRole" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updateRole" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="assignUser" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deassignUser" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addPermission" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addPermObj" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deletePermission" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deletePermObj" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updatePermission" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updatePermObj" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="grantPermission" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="revokePermission" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="grantPermissionUser" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="revokePermissionUser" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addDescendant" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addAscendant" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addInheritance" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteInheritance" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="createSsdSet" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updateSsdSet" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addSsdRoleMember" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteSsdRoleMember" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteSsdSet" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="setSsdSetCardinality" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="createDsdSet" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="updateDsdSet" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="addDsdRoleMember" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteDsdRoleMember" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="deleteDsdSet" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.AdminMgrImpl" opName="setDsdSetCardinality" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addUser" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="disableUser" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteUser" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updateUser" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="changePassword" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="lockUserAccount" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="unlockUserAccount" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="resetPassword" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updateRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="assignUser" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deassignUser" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addPermission" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addPermObj" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deletePermission" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deletePermObj" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updatePermission" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updatePermObj" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="grantPermission" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="revokePermission" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="grantPermissionUser" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="revokePermissionUser" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addDescendant" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addAscendant" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addInheritance" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteInheritance" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="createSsdSet" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updateSsdSet" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addSsdRoleMember" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteSsdRoleMember" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteSsdSet" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="setSsdSetCardinality" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="createDsdSet" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="updateDsdSet" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="addDsdRoleMember" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteDsdRoleMember" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="deleteDsdSet" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AdminMgrImpl" opName="setDsdSetCardinality" admin="true"/>
 
-                <permop objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="add" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="update" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="delete" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="updateUserPolicy" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="deletePasswordPolicy" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.PwPolicyMgrImpl" opName="search" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="add" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="update" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="delete" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="updateUserPolicy" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="deletePasswordPolicy" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl" opName="search" admin="true"/>
 
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addRole" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="deleteRole" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="updateRole" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="assignUser" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="deassignUser" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addOU" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="updateOU" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="deleteOU" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addDescendantOU" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addAscendantOU" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addInheritanceOU" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="deleteInheritanceOU" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addDescendantRole" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addAscendantRole" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="addInheritanceRole" admin="true"/>
-                <permop objName="org.openldap.fortress.rbac.DelAdminMgrImpl" opName="deleteInheritanceRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="deleteRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="updateRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="assignUser" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="deassignUser" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addOU" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="updateOU" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="deleteOU" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addDescendantOU" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addAscendantOU" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addInheritanceOU" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="deleteInheritanceOU" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addDescendantRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addAscendantRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="addInheritanceRole" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.DelAdminMgrImpl" opName="deleteInheritanceRole" admin="true"/>
 
-                <permop objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="add" admin="true"/>
-                <permop objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="update" admin="true"/>
-                <permop objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="delete" admin="true"/>
-                <permop objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="addProperty" admin="true"/>
-                <permop objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="deleteProperty" admin="true"/>
-                <permop objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="read" admin="true"/>
-                <permop objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="find" admin="true"/>
-                <permop objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="findWithUsers" admin="true"/>
-                <permop objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="assign" admin="true"/>
-                <permop objName="org.openldap.fortress.ldap.group.GroupMgrImpl" opName="deassign" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="add" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="update" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="delete" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="addProperty" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="deleteProperty" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="read" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="find" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="findWithUsers" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="assign" admin="true"/>
+                <permop objName="org.apache.directory.fortress.core.ldap.group.GroupMgrImpl" opName="deassign" admin="true"/>
             </addpermop>
 
          </FortressAdmin>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/ldap/setup/FortressDemoUsers.xml
----------------------------------------------------------------------
diff --git a/ldap/setup/FortressDemoUsers.xml b/ldap/setup/FortressDemoUsers.xml
index dde1d30..67f4da1 100755
--- a/ldap/setup/FortressDemoUsers.xml
+++ b/ldap/setup/FortressDemoUsers.xml
@@ -18,7 +18,7 @@
    under the License.
 -->
 <project basedir="." default="all" name="Fortress Sample Data">
-    <taskdef classname="org.openldap.fortress.ant.FortressAntTask" name="FortressAdmin" >
+    <taskdef classname="org.apache.directory.fortress.core.ant.FortressAntTask" name="FortressAdmin" >
         <classpath path="${java.class.path}"/>
     </taskdef>
 
@@ -221,7 +221,7 @@
 
 <!--
                 <permobj admin="true"
-                         objName="org.openldap.fortress.audit.AuditMgrImpl"
+                         objName="org.apache.directory.fortress.audit.AuditMgrImpl"
                          description="AuditMgr Object"
                          ou="demoapps1" type="Ant"/>
 -->
@@ -243,12 +243,12 @@
                 <permop opName="6pm" objName="/cal/cal2.jsp" type="Ant"/>
 
 <!--
-                <permop admin="true" opName="searchBinds" objName="org.openldap.fortress.audit.AuditMgrImpl" type="Ant"/>
-                <permop admin="true" opName="searchAuthZs" objName="org.openldap.fortress.audit.AuditMgrImpl" type="Ant"/>
-                <permop admin="true" opName="getUserAuthZs" objName="org.openldap.fortress.audit.AuditMgrImpl" type="Ant"/>
-                <permop admin="true" opName="searchUserSessions" objName="org.openldap.fortress.audit.AuditMgrImpl" type="Ant"/>
-                <permop admin="true" opName="searchAdminMods" objName="org.openldap.fortress.audit.AuditMgrImpl" type="Ant"/>
-                <permop admin="true" opName="searchInvalidUsers" objName="org.openldap.fortress.audit.AuditMgrImpl" type="Ant"/>
+                <permop admin="true" opName="searchBinds" objName="org.apache.directory.fortress.audit.AuditMgrImpl" type="Ant"/>
+                <permop admin="true" opName="searchAuthZs" objName="org.apache.directory.fortress.audit.AuditMgrImpl" type="Ant"/>
+                <permop admin="true" opName="getUserAuthZs" objName="org.apache.directory.fortress.audit.AuditMgrImpl" type="Ant"/>
+                <permop admin="true" opName="searchUserSessions" objName="org.apache.directory.fortress.audit.AuditMgrImpl" type="Ant"/>
+                <permop admin="true" opName="searchAdminMods" objName="org.apache.directory.fortress.audit.AuditMgrImpl" type="Ant"/>
+                <permop admin="true" opName="searchInvalidUsers" objName="org.apache.directory.fortress.audit.AuditMgrImpl" type="Ant"/>
 -->
             </addpermop>
 
@@ -262,12 +262,12 @@
                 <permgrant objName="/cal/cal2.jsp" opName="6pm" roleNm="role1"/>
 
 <!--
-                <permgrant admin="true" objName="org.openldap.fortress.audit.AuditMgrImpl" opName="searchBinds" roleNm="DemoAdminUsers"/>
-                <permgrant admin="true" objName="org.openldap.fortress.audit.AuditMgrImpl" opName="searchAuthZs" roleNm="DemoAdminUsers"/>
-                <permgrant admin="true" objName="org.openldap.fortress.audit.AuditMgrImpl" opName="getUserAuthZs" roleNm="DemoAdminUsers"/>
-                <permgrant admin="true" objName="org.openldap.fortress.audit.AuditMgrImpl" opName="searchUserSessions" roleNm="DemoAdminUsers"/>
-                <permgrant admin="true" objName="org.openldap.fortress.audit.AuditMgrImpl" opName="searchAdminMods" roleNm="DemoAdminUsers"/>
-                <permgrant admin="true" objName="org.openldap.fortress.audit.AuditMgrImpl" opName="searchInvalidUsers" roleNm="DemoAdminUsers"/>
+                <permgrant admin="true" objName="org.apache.directory.fortress.audit.AuditMgrImpl" opName="searchBinds" roleNm="DemoAdminUsers"/>
+                <permgrant admin="true" objName="org.apache.directory.fortress.audit.AuditMgrImpl" opName="searchAuthZs" roleNm="DemoAdminUsers"/>
+                <permgrant admin="true" objName="org.apache.directory.fortress.audit.AuditMgrImpl" opName="getUserAuthZs" roleNm="DemoAdminUsers"/>
+                <permgrant admin="true" objName="org.apache.directory.fortress.audit.AuditMgrImpl" opName="searchUserSessions" roleNm="DemoAdminUsers"/>
+                <permgrant admin="true" objName="org.apache.directory.fortress.audit.AuditMgrImpl" opName="searchAdminMods" roleNm="DemoAdminUsers"/>
+                <permgrant admin="true" objName="org.apache.directory.fortress.audit.AuditMgrImpl" opName="searchInvalidUsers" roleNm="DemoAdminUsers"/>
 -->
             </addpermgrant>
 

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/ldap/setup/HierarchicalAdminRoleExample.xml
----------------------------------------------------------------------
diff --git a/ldap/setup/HierarchicalAdminRoleExample.xml b/ldap/setup/HierarchicalAdminRoleExample.xml
index 384c818..25989ce 100755
--- a/ldap/setup/HierarchicalAdminRoleExample.xml
+++ b/ldap/setup/HierarchicalAdminRoleExample.xml
@@ -36,7 +36,7 @@
     <property name="ehcache-core.jar" value="${lib.dir}/ehcache-core-2.6.5.jar"/>
     <property name="slf4j-api.jar" value="${lib.dir}/slf4j-api-1.7.5.jar"/>
     <property name="slf4j-log4j.jar" value="${lib.dir}/slf4j-log4j12-1.7.5.jar"/>
-    <taskdef classname="org.openldap.fortress.ant.FortressAntTask" name="FortressAdmin" >
+    <taskdef classname="org.apache.directory.fortress.core.ant.FortressAntTask" name="FortressAdmin" >
     	<classpath path="${config}:${Fortress.jar}:${log4j.jar}:${ldapjdk.jar}:${jgrapht.jar}:${jasypt.jar}:${commons-configuration.jar}:${commons-lang.jar}:${commons-collections.jar}:${commons-logging.jar}:${ehcache-core.jar}:${slf4j-api.jar}:${slf4j-log4j.jar}"/>
     </taskdef>
 

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/ldap/setup/HierarchicalRoleExample.xml
----------------------------------------------------------------------
diff --git a/ldap/setup/HierarchicalRoleExample.xml b/ldap/setup/HierarchicalRoleExample.xml
index e4c3eeb..55022f4 100755
--- a/ldap/setup/HierarchicalRoleExample.xml
+++ b/ldap/setup/HierarchicalRoleExample.xml
@@ -35,7 +35,7 @@
     <property name="ehcache-core.jar" value="${lib.dir}/ehcache-core-2.6.5.jar"/>
     <property name="slf4j-api.jar" value="${lib.dir}/slf4j-api-1.7.5.jar"/>
     <property name="slf4j-log4j.jar" value="${lib.dir}/slf4j-log4j12-1.7.5.jar"/>
-    <taskdef classname="org.openldap.fortress.ant.FortressAntTask" name="FortressAdmin" >
+    <taskdef classname="org.apache.directory.fortress.core.ant.FortressAntTask" name="FortressAdmin" >
     	<classpath path="${config}:${Fortress.jar}:${log4j.jar}:${ldapjdk.jar}:${jgrapht.jar}:${jasypt.jar}:${commons-configuration.jar}:${commons-lang.jar}:${commons-collections.jar}:${commons-logging.jar}:${ehcache-core.jar}:${slf4j-api.jar}:${slf4j-log4j.jar}"/>
     </taskdef>
 

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/ldap/setup/LdapGroupSetup.xml
----------------------------------------------------------------------
diff --git a/ldap/setup/LdapGroupSetup.xml b/ldap/setup/LdapGroupSetup.xml
index 936c174..5665569 100644
--- a/ldap/setup/LdapGroupSetup.xml
+++ b/ldap/setup/LdapGroupSetup.xml
@@ -18,7 +18,7 @@
    under the License.
 -->
 <project basedir="." default="all" name="Fortress LDAP Group Test 002 Data">
-    <taskdef classname="org.openldap.fortress.ant.FortressAntTask" name="FortressAdmin" >
+    <taskdef classname="org.apache.directory.fortress.core.ant.FortressAntTask" name="FortressAdmin" >
         <classpath path="${java.class.path}"/>
     </taskdef>
 

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/ldap/setup/LoadTestUsers.xml
----------------------------------------------------------------------
diff --git a/ldap/setup/LoadTestUsers.xml b/ldap/setup/LoadTestUsers.xml
index 8ff6729..757588b 100644
--- a/ldap/setup/LoadTestUsers.xml
+++ b/ldap/setup/LoadTestUsers.xml
@@ -18,7 +18,7 @@
    under the License.
 -->
 <project basedir="." default="all" name="Fortress Sample Data">
-    <taskdef classname="org.openldap.fortress.ant.FortressAntTask" name="FortressAdmin" >
+    <taskdef classname="org.apache.directory.fortress.core.ant.FortressAntTask" name="FortressAdmin" >
         <classpath path="${java.class.path}"/>
     </taskdef>
 

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/ldap/setup/OrgUnitExample.xml
----------------------------------------------------------------------
diff --git a/ldap/setup/OrgUnitExample.xml b/ldap/setup/OrgUnitExample.xml
index 11223e2..09d94c1 100755
--- a/ldap/setup/OrgUnitExample.xml
+++ b/ldap/setup/OrgUnitExample.xml
@@ -36,7 +36,7 @@
     <property name="ehcache-core.jar" value="${lib.dir}/ehcache-core-2.6.5.jar"/>
     <property name="slf4j-api.jar" value="${lib.dir}/slf4j-api-1.7.5.jar"/>
     <property name="slf4j-log4j.jar" value="${lib.dir}/slf4j-log4j12-1.7.5.jar"/>
-    <taskdef classname="org.openldap.fortress.ant.FortressAntTask" name="FortressAdmin" >
+    <taskdef classname="org.apache.directory.fortress.core.ant.FortressAntTask" name="FortressAdmin" >
     	<classpath path="${config}:${Fortress.jar}:${log4j.jar}:${ldapjdk.jar}:${jgrapht.jar}:${jasypt.jar}:${commons-configuration.jar}:${commons-lang.jar}:${commons-collections.jar}:${commons-logging.jar}:${ehcache-core.jar}:${slf4j-api.jar}:${slf4j-log4j.jar}"/>
     </taskdef>
 

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/ldap/setup/RbacAcceleratorTestUsers.xml
----------------------------------------------------------------------
diff --git a/ldap/setup/RbacAcceleratorTestUsers.xml b/ldap/setup/RbacAcceleratorTestUsers.xml
index 7c329f2..061b9f2 100644
--- a/ldap/setup/RbacAcceleratorTestUsers.xml
+++ b/ldap/setup/RbacAcceleratorTestUsers.xml
@@ -18,7 +18,7 @@
    under the License.
 -->
 <project basedir="." default="all" name="Fortress Sample Data">
-    <taskdef classname="org.openldap.fortress.ant.FortressAntTask" name="FortressAdmin" >
+    <taskdef classname="org.apache.directory.fortress.core.ant.FortressAntTask" name="FortressAdmin" >
         <classpath path="${java.class.path}"/>
     </taskdef>
 

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/ldap/setup/demo-fortressproject-users.xml
----------------------------------------------------------------------
diff --git a/ldap/setup/demo-fortressproject-users.xml b/ldap/setup/demo-fortressproject-users.xml
index 6fdbc93..48e21dc 100644
--- a/ldap/setup/demo-fortressproject-users.xml
+++ b/ldap/setup/demo-fortressproject-users.xml
@@ -19,7 +19,7 @@
 -->
 <project basedir="." default="all" name="Fortress Sample Data">
 
-    <taskdef classname="org.openldap.fortress.ant.FortressAntTask" name="FortressAdmin" >
+    <taskdef classname="org.apache.directory.fortress.core.ant.FortressAntTask" name="FortressAdmin" >
         <classpath path="${java.class.path}"/>
     </taskdef>
 
@@ -99,14 +99,14 @@
                 <permobj objName="com.mycompany.Page1"/>
                 <permobj objName="com.mycompany.Page2"/>
                 <permobj objName="com.mycompany.Page3"/>
-                <permobj objName="org.openldap.fortress.rbac.AccessMgrImpl"/>
+                <permobj objName="org.apache.directory.fortress.core.rbac.AccessMgrImpl"/>
             </delpermobj>
 
             <addpermobj>
                 <permobj objName="com.mycompany.Page1" description="Wicket Test Page 1" ou="WicketPerms" type="Page"/>
                 <permobj objName="com.mycompany.Page2" description="Wicket Test Page 2" ou="WicketPerms" type="Page"/>
                 <permobj objName="com.mycompany.Page3" description="Wicket Test Page 3" ou="WicketPerms" type="Page"/>
-                <permobj objName="org.openldap.fortress.rbac.AccessMgrImpl" description="Used to perform role activation functions" ou="WicketPerms" type="Page"/>
+                <permobj objName="org.apache.directory.fortress.core.rbac.AccessMgrImpl" description="Used to perform role activation functions" ou="WicketPerms" type="Page"/>
                 <permobj objName="ROLE_TEST1" description="Used to perform ROLE_TEST1 role activation functions" ou="WicketPerms" type="Page"/>
                 <permobj objName="ROLE_TEST2" description="Used to perform ROLE_TEST2 role activation functions" ou="WicketPerms" type="Page"/>
                 <permobj objName="ROLE_TEST3" description="Used to perform ROLE_TEST3 role activation functions" ou="WicketPerms" type="Page"/>
@@ -122,8 +122,8 @@
                 <permop objName="com.mycompany.Page3" opName="Button1"/>
                 <permop objName="com.mycompany.Page3" opName="Button2"/>
                 <permop objName="com.mycompany.Page3" opName="Button3"/>
-                <permop objName="org.openldap.fortress.rbac.AccessMgrImpl" opName="addActiveRole"/>
-                <permop objName="org.openldap.fortress.rbac.AccessMgrImpl" opName="dropActiveRole"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AccessMgrImpl" opName="addActiveRole"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AccessMgrImpl" opName="dropActiveRole"/>
                 <permop objName="ROLE_TEST1" opName="dropActiveRole"/>
                 <permop objName="ROLE_TEST1" opName="dropActiveRole" type="Button"/>
                 <permop objName="ROLE_TEST2" opName="addActiveRole" type="Button"/>
@@ -142,8 +142,8 @@
                 <permop objName="com.mycompany.Page3" opName="Button1" type="Button"/>
                 <permop objName="com.mycompany.Page3" opName="Button2" type="Button"/>
                 <permop objName="com.mycompany.Page3" opName="Button3" type="Button"/>
-                <permop objName="org.openldap.fortress.rbac.AccessMgrImpl" opName="addActiveRole" type="Button"/>
-                <permop objName="org.openldap.fortress.rbac.AccessMgrImpl" opName="dropActiveRole" type="Button"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AccessMgrImpl" opName="addActiveRole" type="Button"/>
+                <permop objName="org.apache.directory.fortress.core.rbac.AccessMgrImpl" opName="dropActiveRole" type="Button"/>
                 <permop objName="ROLE_TEST1" opName="addActiveRole" type="Button"/>
                 <permop objName="ROLE_TEST1" opName="dropActiveRole" type="Button"/>
                 <permop objName="ROLE_TEST2" opName="addActiveRole" type="Button"/>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/ldap/setup/refreshLDAPData-src.xml
----------------------------------------------------------------------
diff --git a/ldap/setup/refreshLDAPData-src.xml b/ldap/setup/refreshLDAPData-src.xml
index 39120f6..90c7941 100755
--- a/ldap/setup/refreshLDAPData-src.xml
+++ b/ldap/setup/refreshLDAPData-src.xml
@@ -18,7 +18,7 @@
    under the License.
 -->
 <project basedir="." default="all" name="Fortress Properties">
-    <taskdef classname="org.openldap.fortress.ant.FortressAntTask" name="FortressAdmin" >
+    <taskdef classname="org.apache.directory.fortress.core.ant.FortressAntTask" name="FortressAdmin" >
         <classpath path="${java.class.path}"/>
     </taskdef>
 
@@ -74,16 +74,16 @@
                 <config props="adminrole.root:@ADMINROLES_DN@"/>
                 <config props="adminperm.root:@ADMINPERMS_DN@"/>
                 <config props="example.root:ou=Examples,@SUFFIX@"/>
-                <!--config props="accessmgr.implementation:org.openldap.fortress.rbac.AccessMgrImpl"/-->
-                <!--config props="auditmgr.implementation:org.openldap.fortress.audit.AuditMgrImpl"/-->
+                <!--config props="accessmgr.implementation:org.apache.directory.fortress.core.rbac.AccessMgrImpl"/-->
+                <!--config props="auditmgr.implementation:org.apache.directory.fortress.audit.AuditMgrImpl"/-->
                 <config props="audit.root:@AUDITS_DN@"/>
                 <config props="superadmin.role:FortressSuperAdmin"/>
-                <config props="temporal.validator.0:org.openldap.fortress.util.time.Date"/>
-                <config props="temporal.validator.1:org.openldap.fortress.util.time.LockDate"/>
-                <config props="temporal.validator.2:org.openldap.fortress.util.time.Timeout"/>
-                <config props="temporal.validator.3:org.openldap.fortress.util.time.ClockTime"/>
-                <config props="temporal.validator.4:org.openldap.fortress.util.time.Day"/>
-                <config props="temporal.validator.dsd:org.openldap.fortress.rbac.DSDChecker"/>
+                <config props="temporal.validator.0:org.apache.directory.fortress.core.util.time.Date"/>
+                <config props="temporal.validator.1:org.apache.directory.fortress.core.util.time.LockDate"/>
+                <config props="temporal.validator.2:org.apache.directory.fortress.core.util.time.Timeout"/>
+                <config props="temporal.validator.3:org.apache.directory.fortress.core.util.time.ClockTime"/>
+                <config props="temporal.validator.4:org.apache.directory.fortress.core.util.time.Day"/>
+                <config props="temporal.validator.dsd:org.apache.directory.fortress.core.rbac.DSDChecker"/>
                 <config props="user.objectclass:inetOrgPerson"/>
                 <config props="group.objectclass:@GROUP_OBJECT_CLASS@"/>
                 <config props="group.protocol:@GROUP_PROTOCOL@"/>
@@ -143,14 +143,14 @@
                 <config props="adminperm.root:ou=AdminPerms,ou=ARBAC,@SUFFIX@"/>
                 <config props="audit.root:cn=log"/>
                 <config props="superadmin.role:oamSuperAdmin"/>
-                <config props="temporal.validator.0:org.openldap.fortress.util.time.Date"/>
-                <config props="temporal.validator.1:org.openldap.fortress.util.time.LockDate"/>
-                <config props="temporal.validator.2:org.openldap.fortress.util.time.Timeout"/>
-                <config props="temporal.validator.3:org.openldap.fortress.util.time.ClockTime"/>
-                <config props="temporal.validator.4:org.openldap.fortress.util.time.Day"/>
-                <config props="temporal.validator.dsd:org.openldap.fortress.rbac.DSDChecker"/>
-                <config props="accessmgr.implementation:org.openldap.fortress.rbac.AccessMgrImpl"/>
-                <config props="auditmgr.implementation:org.openldap.fortress.rbac.AuditMgrImpl"/>
+                <config props="temporal.validator.0:org.apache.directory.fortress.core.util.time.Date"/>
+                <config props="temporal.validator.1:org.apache.directory.fortress.core.util.time.LockDate"/>
+                <config props="temporal.validator.2:org.apache.directory.fortress.core.util.time.Timeout"/>
+                <config props="temporal.validator.3:org.apache.directory.fortress.core.util.time.ClockTime"/>
+                <config props="temporal.validator.4:org.apache.directory.fortress.core.util.time.Day"/>
+                <config props="temporal.validator.dsd:org.apache.directory.fortress.core.rbac.DSDChecker"/>
+                <config props="accessmgr.implementation:org.apache.directory.fortress.core.rbac.AccessMgrImpl"/>
+                <config props="auditmgr.implementation:org.apache.directory.fortress.core.rbac.AuditMgrImpl"/>
                 <config props="user.objectclass:inetOrgPerson"/>
                 <config props="group.objectclass:@GROUP_OBJECT_CLASS@"/>
                 <config props="group.protocol:@GROUP_PROTOCOL@"/>


[26/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/Graphable.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Graphable.java b/src/main/java/org/apache/directory/fortress/core/rbac/Graphable.java
new file mode 100644
index 0000000..ad2909f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Graphable.java
@@ -0,0 +1,90 @@
+/*
+ *   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;
+
+/**
+ * The Fortress Graphable interface prescribes attributes that are used to maintain implementor within a simple directed graph.
+ * {@link org.apache.directory.fortress.core.rbac.Role}, {@link org.apache.directory.fortress.core.rbac.AdminRole}, {@link org.apache.directory.fortress.core.rbac.OrgUnit} entities.
+ * <p/>
+ * <img src="../doc-files/HierRoleAscendants.png">
+ * <p/>
+ * <p/>
+ * <img src="../doc-files/HierRoleDescendants.png">
+ * <p/>
+ * <p/>
+ * <img src="../doc-files/HierRoleSimple.png">
+ * <p/>
+ * <h4>Manageable Schema</h4>
+ * The entity maps to Fortress LDAP attributetype ( 1.3.6.1.4.1.1.38088.1.28
+ * NAME 'ftParents'
+ * DESC 'Fortress Parent Nodes'
+ * EQUALITY caseIgnoreMatch
+ * SUBSTR caseIgnoreSubstringsMatch
+ * SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public interface Graphable
+{
+    /**
+     * 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();
+
+    /**
+     * 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);
+
+    /**
+     * Set the occupant attribute with the contents of the User dn.
+     *
+     * @param parent maps to 'ftParents' attribute on 'ftRls' object class.
+     */
+    public void setParent(String parent);
+
+    /**
+     * Set the occupant attribute with the contents of the User dn.
+     *
+     * @param parent maps to 'ftParents' attribute on 'ftRls' object class.
+     */
+    public void delParent(String parent);
+
+    /**
+     * Get the name required attribute of the node.
+     *
+     * @return attribute maps to attribute  on 'organizationalUnit' object class.
+     */
+    public String getName();
+
+    /**
+     * Sets the required name attribute on the node.
+     *
+     */
+    public void setName(String name);
+}
\ 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/Hier.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Hier.java b/src/main/java/org/apache/directory/fortress/core/rbac/Hier.java
new file mode 100755
index 0000000..9e0db40
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Hier.java
@@ -0,0 +1,321 @@
+/*
+ *   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;
+
+/**
+ * All entities (User, Role, Permission, Policy, SDSet, etc...) are used to carry data between Fortress's
+ * layers starting with the (1) Manager layer down thru middle (2) Process layer and it's processing rules into
+ * (3) DAO layer where persistence with the OpenLDAP server occurs.  The clients must instantiate an Fortress entity before use
+ * and must provide enough information to uniquely identity target record for reads.
+ * <p/>
+ * <h4>Hierarchical Relationship Schema</h4>
+ * <p/>
+ * The Fortress ftHier Entity Class is used internal to Fortress and usually does not require manipulation by external program.  The
+ * entity is a composite of 3 different LDAP Schema object classes:
+ * <p/>
+ * 1. organizationalRole Structural Object Class is used to store basic attributes like cn and description.
+ * <pre>
+ * ------------------------------------------
+ * objectclass ( 2.5.6.8 NAME 'organizationalRole'
+ *  DESC 'RFC2256: an organizational role'
+ *  SUP top STRUCTURAL
+ *  MUST cn
+ *  MAY (
+ *      x121Address $ registeredAddress $ destinationIndicator $
+ *      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
+ *      telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
+ *      seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $
+ *      postOfficeBox $ postalCode $ postalAddress $
+ *      physicalDeliveryOfficeName $ ou $ st $ l $ description
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 2. ftHier AUXILIARY Object Class is used to store parent to child relationships on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Hierarchies Structural Object Class
+ * objectclass	( 1.3.6.1.4.1.38088.2.7
+ * NAME 'ftHier'
+ * DESC 'Fortress Hierarchy Structural Object Class'
+ * SUP organizationalrole
+ * STRUCTURAL
+ * MUST (
+ *      cn
+ *  )
+ * MAY (
+ *      ftRels $
+ *      description
+ *  )
+ * )
+ * <p/>
+ * 3. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Audit Modification Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.4
+ *  NAME 'ftMods'
+ *  DESC 'Fortress Modifiers AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftModifier $
+ *      ftModCode $
+ *      ftModId
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class Hier extends FortEntity
+    implements java.io.Serializable
+{
+    public Op op;
+    public Type type;
+    private List<Relationship> relationships;
+
+    /**
+     * default constructor is used by internal components.
+     */
+    public Hier()
+    {
+    }
+
+    /**
+     * construct hierarchy given a list of parent-child relationships.
+     *
+     * @param relationships maps to 'ftRels' attribute on 'ftHier' object class.
+     */
+    public Hier(List<Relationship> relationships)
+    {
+        this.relationships = relationships;
+    }
+
+    /**
+     * Construct entity given a hierarchy type - ROLE, AROLE, USER, PERM.
+     *
+     * @param type determines where the target node resides.  For example the 'ROLE' type will specify the RBAC Role container as target.
+     */
+    public Hier(Type type)
+    {
+        this.type = type;
+    }
+
+    /**
+     * Construct entity given a parent, child and a hierarchy type.
+     *
+     * @param type   determines where the target node resides.  For example the 'ROLE' type will specify the RBAC Role container as target.
+     * @param child  maps to the 'ftRels' attribute in 'ftHier' object class.
+     * @param parent maps to the 'ftRels' attribute in 'ftHier' object class.
+     */
+    public Hier(Type type, String child, String parent)
+    {
+        this.type = type;
+        setRelationship(child, parent);
+    }
+
+    /**
+     * Construct entity given a parent and child.
+     *
+     * @param child  maps to the 'ftRels' attribute in 'ftHier' object class.
+     * @param parent maps to the 'ftRels' attribute in 'ftHier' object class.
+     */
+    public Hier(String child, String parent)
+    {
+        setRelationship(child, parent);
+    }
+
+    /**
+     * Operation type specifies if Add, Update or Deletion of relationship is being targeted.
+     */
+    public enum Op
+    {
+        /**
+         * Add a new hierarchical relationship to the data set.
+         */
+        ADD,
+
+        /**
+         * Modify an existing hierarchical relationship in the data set.
+         */
+        MOD,
+
+        /**
+         * Remove an existing hierarchical relationship from the data set.
+         */
+        REM
+    }
+
+    /**
+     * Return the operation to execute on behalf of this entity.
+     *
+     * @return Op value which maps to Add, Update or Delete attribute targets.
+     */
+    public Op getOp()
+    {
+        return op;
+    }
+
+    /**
+     * The the operation for which this entity is bound for.  Add, Update or Delete.
+     *
+     * @param op type contains 'ADD', 'MOD', or 'REM'.
+     */
+    public void setOp(Op op)
+    {
+        this.op = op;
+    }
+
+    /**
+     * Enumeration is used to specify which hierarchy node this entity is bound to.  RBAC Role, Admin Roles, User OU or Perm OU.
+     */
+    public enum Type
+    {
+        /**
+         * RBAC Role data set
+         */
+        ROLE,
+
+        /**
+         * Administrative Role data set
+         */
+        AROLE,
+
+        /**
+         * User OU data set
+         */
+        USER,
+
+        /**
+         * Permission OU data set
+         */
+        PERM
+    }
+
+    /**
+     * Return required the type of node this entity is bound to.
+     *
+     * @return variable specifies which directory node the hierarchy entity is bound to.
+     */
+    public Type getType()
+    {
+        return type;
+    }
+
+    /**
+     * Set the required type which determines which directory node this entity is bound to.
+     *
+     * @param type variable specifies which directory node the hierarchy entity is bound to.
+     */
+    public void setType(Type type)
+    {
+        this.type = type;
+    }
+
+
+    /**
+     * Return true if child and parent represent a valid relationship that is contained within the collection of
+     * relationships.
+     *
+     * @param role   attribute maps to the 'ftRels' attribute on 'ftHier' object class.
+     * @param parent attribute maps to the 'ftRels' attribute on 'ftHier' object class.
+     */
+    public boolean isRelationship(String role, String parent)
+    {
+        boolean result = false;
+        if (relationships != null)
+        {
+            result = relationships.contains(new Relationship(role.toUpperCase(), parent.toUpperCase()));
+        }
+
+        return result;
+    }
+
+    /**
+     * Set the child and parent into the collection of valid relationships stored in this entity.
+     *
+     * @param role   attribute maps to the 'ftRels' attribute on 'ftHier' object class.
+     * @param parent attribute maps to the 'ftRels' attribute on 'ftHier' object class.
+     */
+    public void setRelationship(String role, String parent)
+    {
+        if (relationships == null)
+        {
+            relationships = new ArrayList<>();
+        }
+
+        relationships.add(new Relationship(role.toUpperCase(), parent.toUpperCase()));
+    }
+
+    /**
+     * Set the relationship object into the collection of valid relationships stored in this entity.
+     *
+     * @param rel attribute maps to the 'ftRels' attribute on 'ftHier' object class.
+     */
+    public void setRelationship(Relationship rel)
+    {
+        if (relationships == null)
+        {
+            relationships = new ArrayList<>();
+        }
+
+        relationships.add(rel);
+    }
+
+    /**
+     * Remove the specified relationship from the collection of valid relationships stored in this entity.
+     *
+     * @param role   attribute maps to the 'ftRels' attribute on 'ftHier' object class.
+     * @param parent attribute maps to the 'ftRels' attribute on 'ftHier' object class.
+     */
+    public void removeRelationship(String role, String parent)
+    {
+        if (relationships != null)
+        {
+            relationships.remove(new Relationship(role.toUpperCase(), parent.toUpperCase()));
+        }
+    }
+
+    /**
+     * Return the list of relationships that are set in collection on this entity.
+     *
+     * @return List of relationships that map to the 'ftRels' attribute on the 'ftHier' object class.
+     */
+    public List<Relationship> getRelationships()
+    {
+        return relationships;
+    }
+
+    /**
+     * Set the list of relationships that are set in collection on this entity.
+     *
+     * @param relationships that map to the 'ftRels' attribute on the 'ftHier' object class.
+     */
+    public void setRelationships(List<Relationship> relationships)
+    {
+        this.relationships = relationships;
+    }
+}
\ 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/HierUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/HierUtil.java b/src/main/java/org/apache/directory/fortress/core/rbac/HierUtil.java
new file mode 100755
index 0000000..1305190
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/HierUtil.java
@@ -0,0 +1,716 @@
+/*
+ *   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.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+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.GlobalErrIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.ValidationException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * This utility performs base hierarchical processing using this software <a href="http://www.jgrapht.org/">JGraphT</a></li>.
+ * </p>
+ * It is used to provide hierarchical processing APIs for the following data sets:
+ * <ol>
+ * <li>RBAC Role relations are stored in {@code cn=Hierarchies,ou=Roles,ou=RBAC} ldap node and cached as singleton in {@link RoleUtil}</li>
+ * <li>ARBAC Admin Role relations are stored in {@code cn=Hierarchies,ou=AdminRoles,ou=ARBAC} ldap node and cached as singleton in {@link AdminRoleUtil}</li>
+ * <li>User Organizational Unit relations are stored in {@code cn=Hierarchies,ou=OS-U,ou=ARBAC} node and cached as {@link org.apache.directory.fortress.core.rbac.UsoUtil}</li>
+ * <li>Permission Organizational Unit relations are stored in {@code cn=Hierarchies,ou=OS-P,ou=ARBAC} node and cached as {@link org.apache.directory.fortress.core.rbac.PsoUtil}</li>
+ * </ol>
+ * This class...
+ * <ol>
+ * <li>manipulates data that is stored as singleton inside other classes 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>processes general hierarchical data structure i.e. allows multiple inheritance with parents.</li>
+ * <li>constructs and parses simple directed graphs.</li>
+ * </ol>
+ * Static methods on this class are intended for use by other Fortress classes, and cannot be directly invoked by outside programs.
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+final class HierUtil
+{
+    /**
+     * Constants used within this class:
+     */
+    private static final String CLS_NM = HierUtil.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final String VERTEX = "Vertex";
+
+    /**
+     * The 'Type' attribute corresponds to what type of hierarchy is being referred to.
+     */
+    static enum Type
+    {
+        ROLE,
+        ARLE,
+        USO,
+        PSO
+    }
+
+    private static final Map<String, Object> synchMap = new HashMap<>();
+
+
+    /**
+     *
+     * @param contextId
+     * @param type
+     * @return
+     */
+    static Object getLock( String contextId, Type type )
+    {
+        Object synchObj = synchMap.get( getSynchKey( contextId, type ) );
+        if ( synchObj == null )
+        {
+            synchObj = new Object();
+            synchMap.put( getSynchKey( contextId, type ), synchObj );
+        }
+        return synchObj;
+    }
+
+
+    /**
+     *
+     * @param contextId
+     * @param type
+     * @return
+     */
+    private static String getSynchKey( String contextId, Type type )
+    {
+        return type.toString() + ":" + contextId;
+    }
+
+
+    /**
+     * This api is used to determine parentage for Hierarchical processing.
+     * It evaluates three 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 graph     contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @param child     contains name of child.
+     * @param parent    contains 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( SimpleDirectedGraph<String, Relationship> graph, String child, String parent,
+        boolean mustExist )
+        throws ValidationException
+    {
+        // Ensure the two nodes aren't the same:
+        if ( child.equalsIgnoreCase( parent ) )
+        {
+            String error = "validateRelationship child [" + child + "] same as parent [" + parent + "]";
+            throw new ValidationException( GlobalErrIds.HIER_REL_INVLD, error );
+        }
+        Relationship rel = new Relationship( child.toUpperCase(), parent.toUpperCase() );
+        // Ensure there is a valid child to parent relationship.
+        if ( mustExist && !isRelationship( graph, rel ) )
+        {
+            String error = "validateRelationship child [" + child + "] does not have parent [" + parent + "]";
+            throw new ValidationException( GlobalErrIds.HIER_REL_NOT_EXIST, error );
+        }
+        // Ensure the child doesn't already have the parent as an ascendant.
+        else if ( !mustExist && isAscendant( child, parent, graph ) )
+        {
+            String error = "validateRelationship child [" + child + "] already has parent [" + parent + "]";
+            throw new ValidationException( GlobalErrIds.HIER_REL_EXIST, error );
+        }
+        // Prevent cycles by making sure the child isn't an ascendant of parent.
+        else if ( !mustExist && isDescedant( parent, child, graph ) )
+        {
+            String error = "validateRelationship child [" + child + "] is parent of [" + parent + "]";
+            throw new ValidationException( GlobalErrIds.HIER_REL_CYCLIC, error );
+        }
+    }
+
+
+    /**
+     * This method Convert from logical, {@code org.jgrapht.graph.SimpleDirectedGraph} to ldap entity, {@link org.apache.directory.fortress.core.rbac.Hier}.
+     * The conversion iterates over all edges in the graph and loads the corresponding {@link Relationship} data
+     * into the ldap entity.  The ldap entity stores this data physically in the {@code ftRels} attribute of {@code ftHier} object class.
+     *
+     * @param graph contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @return reference to hierarchical ldap entity {@link org.apache.directory.fortress.core.rbac.Hier}.
+     */
+    static Hier toHier( SimpleDirectedGraph<String, Relationship> graph )
+    {
+        Hier he = new Hier();
+        Set<Relationship> eSet = graph.edgeSet();
+        for ( Relationship edge : eSet )
+        {
+            he.setRelationship( edge );
+        }
+        return he;
+    }
+
+
+    /**
+     * This method converts from physical ldap entity format, {@link Hier} to logical {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     *
+     * @param hier contains parent-child relationship in preparation to storing in ldap {@code ftRels} attribute of {@code ftHier} object class.
+     * @return {@code org.jgrapht.graph.SimpleDirectedGraph} containing the vertices of {@code String}, and edges, as {@link Relationship}s that correspond to relational data.
+     */
+    private static SimpleDirectedGraph<String, Relationship> toGraph( Hier hier )
+    {
+        LOG.debug( "toGraph" );
+        SimpleDirectedGraph<String, Relationship> graph =
+            new SimpleDirectedGraph<>( Relationship.class );
+        List<Relationship> edges = hier.getRelationships();
+        if ( edges != null && edges.size() > 0 )
+        {
+            for ( Relationship edge : edges )
+            {
+                String child = edge.getChild();
+                String parent = edge.getParent();
+
+                try
+                {
+                    graph.addVertex( child );
+                    graph.addVertex( parent );
+                    graph.addEdge( child, parent, edge );
+                }
+                catch (java.lang.IllegalArgumentException e)
+                {
+                    // TODO: determine if this needs to throw exception here:
+                    String error = "toGraph child: " + child + " parent: " + parent + " caught IllegalArgumentException=" + e;
+                    LOG.error( error );
+                }
+                if ( LOG.isDebugEnabled() )
+                    LOG.debug( "toGraph child={}, parent={}", child, parent );
+            }
+        }
+        return graph;
+    }
+
+
+    /**
+     * This method is synchronized and adds an edge and its associated vertices to simple directed graph stored in static memory of this process.
+     *
+     * @param graph synchronized parameter contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @param relation contains parent-child relationship targeted for addition.
+     * @return {@code org.jgrapht.graph.SimpleDirectedGraph} containing the vertices of {@code String}, and edges, as {@link Relationship}s that correspond to relational data.
+     */
+    private static void addEdge( SimpleDirectedGraph<String, Relationship> graph, Relationship relation )
+    {
+        LOG.debug( "addEdge" );
+        synchronized ( graph )
+        {
+            graph.addVertex( relation.getChild().toUpperCase() );
+            graph.addVertex( relation.getParent().toUpperCase() );
+            graph.addEdge( relation.getChild().toUpperCase(), relation.getParent().toUpperCase(), relation );
+        }
+    }
+
+
+    /**
+     * This method is synchronized and removes an edge from a simple directed graph stored in static memory of this process.
+     *
+     * @param graph synchronized parameter contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @param relation contains parent-child relationship targeted for removal.
+     * @return {@code org.jgrapht.graph.SimpleDirectedGraph} containing the vertices of {@code String}, and edges, as {@link Relationship}s that correspond to relational data.
+     */
+    private static void removeEdge( SimpleDirectedGraph<String, Relationship> graph, Relationship relation )
+    {
+        LOG.debug( "removeEdge" );
+        synchronized ( graph )
+        {
+            graph.removeEdge( relation );
+        }
+    }
+
+
+    /**
+     * Return number of children (direct descendants) a given parent node has.
+     *
+     * @param name  contains the vertex of graph to gather descendants from.
+     * @param graph contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @return int value contains the number of children of a given parent vertex.
+     */
+    static int numChildren( String name, SimpleDirectedGraph<String, Relationship> graph )
+    {
+        Map<String, String> vx = new HashMap<>();
+        vx.put( VERTEX, name.toUpperCase() );
+        return numChildren( vx, graph );
+    }
+
+
+    /**
+     * Determine if parent-child relationship exists in supplied digraph.
+     *
+     * @param graph contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @param rel   contains parent and child names.
+     * @return boolean value.  true indicates parent-child relationship exists in digraph.
+     */
+    private static boolean isRelationship( SimpleDirectedGraph<String, Relationship> graph, Relationship rel )
+    {
+        return graph.containsEdge( rel );
+    }
+
+
+    /**
+     * Determine how many children a given parent node has.
+     *
+     * @param vertex of parent.
+     * @param graph  contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @return
+     */
+    private static int numChildren( Map<String, String> vertex, SimpleDirectedGraph<String, Relationship> graph )
+    {
+        int numChildren = 0;
+        try
+        {
+            String v = vertex.get( VERTEX );
+            if ( v == null )
+            {
+                //log.debug("getDescendants vertex is null");
+                return 0;
+            }
+            LOG.debug( "hasChildren [{}]", v );
+            numChildren = graph.inDegreeOf( v );
+        }
+        catch ( java.lang.IllegalArgumentException e )
+        {
+            // vertex is leaf.
+        }
+        return numChildren;
+    }
+
+
+    /**
+     * Recursively traverse the hierarchical graph and return all of the ascendants of a given node.
+     *
+     * @param childName maps to vertex to determine parentage.
+     * @param graph     contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @return Set of names that are parents of given child.
+     */
+    static Set<String> getAscendants( String childName, SimpleDirectedGraph<String, Relationship> graph )
+    {
+        Map<String, String> vx = new HashMap<>();
+        // TreeSet will return in sorted order:
+        // create Set with case insensitive comparator:
+        Set<String> parents = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        vx.put( VERTEX, childName.toUpperCase() );
+        getAscendants( vx, graph, parents );
+        return parents;
+    }
+
+
+    /**
+     * Utility function recursively traverses a given digraph to build a set of all ascendant names.
+     *
+     * @param vertex     contains the position of the cursor for traversal of graph.
+     * @param graph      contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @param ascendants contains the result set of ascendant names.
+     * @return value contains the vertex of current position.
+     */
+    private static String getAscendants( Map<String, String> vertex, SimpleDirectedGraph<String, Relationship> graph,
+        Set<String> ascendants )
+    {
+        String v = vertex.get( VERTEX );
+        if ( v == null )
+        {
+            return null;
+        }
+        else if ( graph == null )
+        {
+            return null;
+        }
+        LOG.debug( "getAscendants [{}]", v);
+        Set<Relationship> edges;
+        try
+        {
+            edges = graph.outgoingEdgesOf( v );
+
+        }
+        catch ( java.lang.IllegalArgumentException iae )
+        {
+            // vertex is leaf.
+            return null;
+        }
+        for ( Relationship edge : edges )
+        {
+            vertex.put( VERTEX, edge.getParent() );
+            ascendants.add( edge.getParent() );
+            v = getAscendants( vertex, graph, ascendants );
+        }
+        return v;
+    }
+
+
+    /**
+     * Recursively traverse the hierarchical graph and return all of the descendants for a given node.
+     *
+     * @param parentName maps to vertex to determine parentage.
+     * @param graph      contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @return Set of names that are children of given parent.
+     */
+    static Set<String> getDescendants( String parentName, SimpleDirectedGraph<String, Relationship> graph )
+    {
+        Map<String, String> vx = new HashMap<>();
+        // TreeSet will return in sorted order:
+        // create Set with case insensitive comparator:
+        Set<String> children = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        vx.put( VERTEX, parentName.toUpperCase() );
+        getDescendants( vx, graph, children );
+        return children;
+    }
+
+
+    /**
+     * Recursively traverse the hierarchical graph and determine child node contains a given parent as one of its ascendants.
+     *
+     * @param childName maps to vertex to determine parentage.
+     * @param parentName maps to vertex to determine parentage.
+     * @param graph      contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @return Set of names that are children of given parent.
+     */
+    private static boolean isAscendant( String childName, String parentName,
+        SimpleDirectedGraph<String, Relationship> graph )
+    {
+        boolean isAscendant = false;
+        Set<String> ascendants = getAscendants( childName, graph );
+        if ( ascendants.contains( parentName ) )
+        {
+            isAscendant = true;
+        }
+        return isAscendant;
+    }
+
+
+    /**
+     * Recursively traverse the hierarchical graph and determine if parent node contains a given child as one of its descendants.
+     *
+     * @param childName maps to vertex to determine parentage.
+     * @param parentName maps to vertex to determine parentage.
+     * @param graph      contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @return Set of names that are children of given parent.
+     */
+    private static boolean isDescedant( String childName, String parentName,
+        SimpleDirectedGraph<String, Relationship> graph )
+    {
+        boolean isDescendant = false;
+        Set<String> descendants = getDescendants( parentName, graph );
+        if ( descendants.contains( childName ) )
+        {
+            isDescendant = true;
+        }
+        return isDescendant;
+    }
+
+
+    /**
+     * Utility function recursively traverses a given digraph to build a set of all descendants names.
+     *
+     * @param vertex      contains the position of the cursor for traversal of graph.
+     * @param graph       contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @param descendants contains the result set of names of all descendants of node.
+     * @return value contains the vertex of current position.
+     */
+    private static String getDescendants( Map<String, String> vertex, SimpleDirectedGraph<String, Relationship> graph,
+        Set<String> descendants )
+    {
+        String v = vertex.get( VERTEX );
+        if ( v == null )
+        {
+            //log.debug("getDescendants vertex is null");
+            return null;
+        }
+        else if ( graph == null )
+        {
+            //log.debug("getDescendants graph is null");
+            return null;
+        }
+        LOG.debug( "getDescendants [{}]", v);
+        Set<Relationship> edges;
+        try
+        {
+            edges = graph.incomingEdgesOf( v );
+        }
+        catch ( java.lang.IllegalArgumentException iae )
+        {
+            // vertex is leaf.
+            return null;
+        }
+        for ( Relationship edge : edges )
+        {
+            vertex.put( VERTEX, edge.getChild() );
+            descendants.add( edge.getChild() );
+            v = getDescendants( vertex, graph, descendants );
+        }
+        return v;
+    }
+
+
+    /**
+     * Utility function returns a set of all children (direct descendant) names.
+     *
+     * @param vertex contains the position of the cursor for traversal of graph.
+     * @param graph  contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @return value contains the vertex of current position.
+     */
+    static Set<String> getChildren( String vertex, SimpleDirectedGraph<String, Relationship> graph )
+    {
+        Set<String> descendants = new HashSet<>();
+        if ( graph == null )
+        {
+            //log.debug("getChildren graph is null");
+            return null;
+        }
+        if ( LOG.isDebugEnabled() )
+            LOG.debug( "getChildren [" + vertex + "]" );
+
+        Set<Relationship> edges;
+        try
+        {
+            edges = graph.incomingEdgesOf( vertex );
+        }
+        catch ( java.lang.IllegalArgumentException iae )
+        {
+            // vertex is leaf.
+            return null;
+        }
+        for ( Relationship edge : edges )
+        {
+            descendants.add( edge.getChild() );
+        }
+        return descendants;
+    }
+
+
+    /**
+     * Recursively traverse the hierarchical graph and return all of the ascendants of a given node.
+     *
+     * @param childName   maps to vertex to determine parentage.
+     * @param parentName  points to top most ascendant where traversal must stop.
+     * @param isInclusive if set to true will include the parentName in the result set.  False will not return specified parentName.
+     * @param graph       contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @return Set of names that are parents of given child.
+     */
+    static Set<String> getAscendants( String childName, String parentName, boolean isInclusive,
+        SimpleDirectedGraph<String, Relationship> graph )
+    {
+        Map<String, String> vx = new HashMap<>();
+        // TreeSet will return in sorted order:
+        // create Set with case insensitive comparator:
+        Set<String> parents = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+
+        vx.put( VERTEX, childName.toUpperCase() );
+        getAscendants( vx, graph, parents, parentName, isInclusive );
+        return parents;
+    }
+
+
+    /**
+     * Private utility to recursively traverse the hierarchical graph and return all of the ascendants of a given child node.
+     *
+     * @param vertex      contains node name and acts as cursor for current location.
+     * @param graph       contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @param parents     contains the result set of parent nodes.
+     * @param stopName    contains the name of node where traversal ends.
+     * @param isInclusive if set to true will include the parentName in the result set. False will not return specified parentName.
+     * @return Set of names that are parents of given child.
+     */
+    private static String getAscendants( Map<String, String> vertex, SimpleDirectedGraph<String, Relationship> graph,
+        Set<String> parents, String stopName, boolean isInclusive )
+    {
+        String v = vertex.get( VERTEX );
+        if ( v == null )
+        {
+            //log.debug("getAscendants vertex is null");
+            return null;
+        }
+        else if ( graph == null )
+        {
+            //log.debug("getAscendants graph is null");
+            return null;
+        }
+        LOG.debug( "getAscendants [{}]", v);
+        Set<Relationship> edges;
+        try
+        {
+            edges = graph.outgoingEdgesOf( v );
+        }
+        catch ( java.lang.IllegalArgumentException iae )
+        {
+            // vertex is leaf.
+            return null;
+        }
+        for ( Relationship edge : edges )
+        {
+            if ( edge.getParent().equalsIgnoreCase( stopName ) )
+            {
+                if ( isInclusive )
+                {
+                    parents.add( edge.getParent() );
+                }
+                break;
+            }
+            else
+            {
+                vertex.put( VERTEX, edge.getParent() );
+                parents.add( edge.getParent() );
+                v = getAscendants( vertex, graph, parents, stopName, isInclusive );
+            }
+        }
+        return v;
+    }
+
+
+    /**
+     * Private utility to return the parents (direct ascendants) of a given child node.
+     *
+     * @param vertex contains node name and acts as cursor for current location.
+     * @param graph  contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @return Set of names that are parents of given child.
+     */
+    static Set<String> getParents( String vertex, SimpleDirectedGraph<String, Relationship> graph )
+    {
+        Set<String> parents = new HashSet<>();
+        if ( graph == null )
+        {
+            //log.debug("getParents graph is null");
+            return null;
+        }
+        LOG.debug( "getParents [{}]", vertex);
+        Set<Relationship> edges;
+        try
+        {
+            edges = graph.outgoingEdgesOf( vertex );
+        }
+        catch ( java.lang.IllegalArgumentException iae )
+        {
+            // vertex is leaf.
+            return null;
+        }
+        for ( Relationship edge : edges )
+        {
+            parents.add( edge.getParent() );
+        }
+        return parents;
+    }
+
+
+    /**
+     * This method will retrieve the list of all parent-child relationships for a given node.  If the node was not found in
+     * ldap this method will create a new node and store default data.
+     * The following ldap nodes are currently storing hierarchical data:
+     * <ol>
+     * <li>RBAC Role relations are stored in {@code cn=Hierarchies,ou=Roles,ou=RBAC} ldap node and cached as singleton in {@link RoleUtil}</li>
+     * <li>ARBAC Admin Role relations are stored in {@code cn=Hierarchies,ou=AdminRoles,ou=ARBAC} ldap node and cached as singleton in {@link AdminRoleUtil}</li>
+     * <li>User Organizational Unit relations are stored in {@code cn=Hierarchies,ou=OS-U,ou=ARBAC} node and cached as {@link org.apache.directory.fortress.core.rbac.UsoUtil}</li>
+     * <li>Permission Organizational Unit relations are stored in {@code cn=Hierarchies,ou=OS-P,ou=ARBAC} node and cached as {@link org.apache.directory.fortress.core.rbac.PsoUtil}</li>
+     * </ol>
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return reference the the Hier result set retrieved from ldap.
+     */
+    static Hier loadHier( String contextId, List<Graphable> descendants )
+    {
+        Hier hier = new Hier();
+        if ( VUtil.isNotNullOrEmpty( descendants ) )
+        {
+            hier.setContextId( contextId );
+            for ( Graphable descendant : descendants )
+            {
+                Set<String> parents = descendant.getParents();
+                if ( VUtil.isNotNullOrEmpty( parents ) )
+                {
+                    for ( String parent : parents )
+                    {
+                        Relationship relationship = new Relationship();
+                        relationship.setChild( descendant.getName().toUpperCase() );
+                        relationship.setParent( parent.toUpperCase() );
+                        hier.setRelationship( relationship );
+                    }
+                }
+            }
+        }
+        return hier;
+    }
+
+
+    /**
+     * 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 graph contains a reference to simple digraph {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     * @param relationship contains parent-child relationship targeted for addition.
+     * @param op   used to pass the ldap op {@link Hier.Op#ADD}, {@link 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( SimpleDirectedGraph<String, Relationship> graph, Relationship relationship, Hier.Op op )
+        throws SecurityException
+    {
+        if ( op == Hier.Op.ADD )
+            HierUtil.addEdge( graph, relationship );
+        else if ( op == Hier.Op.REM )
+            HierUtil.removeEdge( graph, relationship );
+        else
+            throw new SecurityException( GlobalErrIds.HIER_CANNOT_PERFORM, CLS_NM
+                + "updateHier Cannot perform hierarchical operation" );
+    }
+
+
+    /**
+     * Method instantiates a new digraph, {@code org.jgrapht.graph.SimpleDirectedGraph}, using data passed in via
+     * {@link Hier} entity.
+     *
+     * @param hier contains the source data for digraph.
+     * @return reference to {@code org.jgrapht.graph.SimpleDirectedGraph}.
+     */
+    static SimpleDirectedGraph<String, Relationship> buildGraph( Hier hier )
+    {
+        SimpleDirectedGraph<String, Relationship> graph;
+        LOG.debug( "buildGraph is initializing" );
+        if ( hier == null )
+        {
+            String error = "buildGraph detected null hier=";
+            LOG.error( error );
+            return null;
+        }
+        graph = toGraph( hier );
+        LOG.debug( "buildGraph success to toGraph" );
+        LOG.debug( "buildGraph is success" );
+        return graph;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/Manageable.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Manageable.java b/src/main/java/org/apache/directory/fortress/core/rbac/Manageable.java
new file mode 100755
index 0000000..196c2e6
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Manageable.java
@@ -0,0 +1,156 @@
+/*
+ *   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 org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.ValidationException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Abstract class allows outside clients to manage security and multi-tenant concerns within the Fortress runtime.
+ * The {@link #setAdmin(org.apache.directory.fortress.core.rbac.Session)} method allows A/RBAC sessions to be loaded and allows authorization
+ * to be performed on behalf of the user who is contained within the Session object itself.
+ * The ARBAC permissions will be checked each time outside client makes calls into Fortress API.
+ * This interface also allows Fortress clients to operate in a multi-tenant fashion using {@link #setContextId(String)}.
+ * <p/>
+ * Implementers of this abstract class will NOT be thread safe because of instance variables that may be set.
+ *
+ * @author Shawn McKinney
+ */
+public abstract class Manageable implements org.apache.directory.fortress.core.Manageable
+{
+    // These instance variables are the reason why children of this abstract class will not be thread safe:
+    protected Session adminSess;
+    protected String contextId;
+
+    /**
+     * Use this method to load an administrative user's ARBAC Session object into Manager object will enable authorization to
+     * be performed on behalf of admin user.  Setting Session into this object will enforce ARBAC controls and render this class'
+     * implementer thread unsafe.
+     *
+     * @param session contains a valid Fortress A/RBAC Session object.
+     */
+    public final void setAdmin(Session session)
+    {
+        this.adminSess = session;
+    }
+
+    /**
+     * Use this method to set the tenant id onto function call into Fortress which allows segregation of data by customer.
+     * The contextId is used for multi-tenancy to isolate data sets within a particular sub-tree within DIT.
+     * Setting contextId into this object will render this class' implementer thread unsafe.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     */
+    public final void setContextId(String contextId)
+    {
+        this.contextId = contextId;
+    }
+
+    /**
+     * Set A/RBAC session on entity and perform authorization on behalf of the caller if the {@link #adminSess} is set.
+     *
+     * @param className contains the class name.
+     * @param opName contains operation name.
+     * @param entity contains {@link org.apache.directory.fortress.core.rbac.FortEntity} instance.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    protected final void setEntitySession(String className, String opName, FortEntity entity) throws SecurityException
+    {
+        entity.setContextId(this.contextId);
+        if (this.adminSess != null)
+        {
+            Permission perm = new Permission(className, opName);
+            perm.setContextId(this.contextId);
+            AdminUtil.setEntitySession( this.adminSess, perm, entity, this.contextId );
+        }
+    }
+
+    /**
+     * Every Fortress Manager API (e.g. addUser, updateUser, addRole, ...) will perform authorization on behalf of the caller IFF the {@link AuditMgrImpl#adminSess} has been set before invocation.
+     *
+     * @param className contains the class name.
+     * @param opName contains operation name.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    protected final void checkAccess(String className, String opName) throws SecurityException
+    {
+        if (this.adminSess != null)
+        {
+            Permission perm = new Permission(className, opName);
+            perm.setContextId(this.contextId);
+            AdminUtil.checkAccess(this.adminSess, perm, this.contextId);
+        }
+    }
+
+    /**
+     * Method is called by Manager APIs to load contextual information on {@link FortEntity}.
+     * </p>
+     * The information is used to
+     * <ol>
+     * <li>Load the administrative User's {@link Session} object into entity.  This is used for checking to ensure administrator has privilege to perform administrative operation.</li>
+     * <li>Load the target operation's permission into the audit context.  This is used for Fortress audit log stored in OpenLDAP</li>
+     * </ol>
+     *
+     * @param className contains the class name.
+     * @param opName contains operation name.
+     * @param entity  used to pass contextual information through Fortress layers for administrative security checks and audit.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    protected final void setAdminData(String className, String opName, FortEntity entity)
+    {
+        if (this.adminSess != null)
+        {
+            Permission perm = new Permission(className, opName);
+            entity.setAdminSession(this.adminSess);
+            entity.setModCode(AdminUtil.getObjName(perm.getObjName()) + "." + perm.getOpName());
+        }
+        entity.setContextId(this.contextId);
+    }
+
+    /**
+     * Method will throw exception if entity reference is null, otherwise will set the contextId of the tenant onto the supplied entity reference.
+     * @param className contains the class name of caller.
+     * @param opName contains operation name of caller.
+     * @param entity  used here to pass the tenant id into the Fortress DAO layer..
+     * @param errorCode contains the error id to use if null.
+     * @throws org.apache.directory.fortress.core.ValidationException in the event object is null.
+     */
+    protected final void assertContext(String className, String opName, FortEntity entity, int errorCode)
+        throws ValidationException
+    {
+        VUtil.assertNotNull(entity, errorCode, getFullMethodName(className, opName));
+        entity.setContextId(this.contextId);
+    }
+
+    /**
+     * This method is used to generate log statements and returns the concatenation of class name to the operation name.
+     * @param className of the caller
+     * @param opName of the caller
+     * @return className + '.' + opName
+     */
+    protected final String getFullMethodName(String className, String opName)
+    {
+        return className + "." + opName;
+    }
+}
\ 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/Mod.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Mod.java b/src/main/java/org/apache/directory/fortress/core/rbac/Mod.java
new file mode 100755
index 0000000..3b52bd3
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Mod.java
@@ -0,0 +1,326 @@
+/*
+ *   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.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+ * This entity class contains OpenLDAP slapd access log records that correspond to modifications made to the directory.
+ * <p/>
+ * <p/>
+ * The auditModify Structural object class is used to store Fortress update and delete events that can later be queried via ldap API.<br />
+ * The deletions can be recorded in this manner and associated with Fortress context because deletions will perform a modification first
+ * if audit is enabled.
+ * <p/>
+ * <code>The Modify operation contains a description  of  modifications  in  the</code><br />
+ * <code>reqMod  attribute,  which  was  already  described  above  in  the  Add</code><br />
+ * <code>operation. It may optionally  contain  the  previous  contents  of  any</code><br />
+ * <code>modified  attributes  in the reqOld attribute, using the same format as</code><br />
+ * <code>described above for the Delete operation.  The reqOld attribute is only</code><br />
+ * <code>populated  if  the  entry  being modified matches the configured logold</code><br />
+ * <code>filter.</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass (  1.3.6.1.4.1.4203.666.11.5.2.9</code>
+ * <li> <code>NAME 'auditModify'</code>
+ * <li> <code>DESC 'Modify operation'</code>
+ * <li> <code>SUP auditWriteObject STRUCTURAL</code>
+ * <li> <code>MAY reqOld MUST reqMod )</code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <p/>
+ * Note this class uses descriptions pulled from man pages on slapd access log.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortMod")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "mod", propOrder = {
+    "reqSession",
+    "objectClass",
+    "reqAuthzID",
+    "reqDN",
+    "reqResult",
+    "reqStart",
+    "reqEnd",
+    "reqMod",
+    "reqType",
+    "sequenceId"
+})
+public class Mod extends FortEntity implements Serializable
+{
+    private String reqSession;
+    private String objectClass;
+    private String reqAuthzID;
+    private String reqDN;
+    private String reqResult;
+    private String reqStart;
+    private String reqEnd;
+    private String reqType;
+    @XmlElement(nillable = true)
+    private List<String> reqMod;
+    private long sequenceId;
+
+    /**
+     * The reqMod attribute carries all of the attributes of the original entry being added.
+     * (Or in the case of a Modify operation, all of the modifications being performed.)
+     * The values are formatted as attribute:<+|-|=|#> [ value] Where '+' indicates an Add of a value,
+     * '-' for Delete, '=' for Replace, and '#' for Increment. In an Add operation, all of  the
+     * reqMod  values will have the '+' designator.
+     *
+     * @return collection of Strings that map to 'reqMod' attribute on 'auditModify' object class.
+     */
+    public List<String> getReqMod()
+    {
+        return reqMod;
+    }
+
+    /**
+     * The reqMod attribute carries all of the attributes of the original entry being added.
+     * (Or in the case of a Modify operation, all of the modifications being performed.)
+     * The values are formatted as attribute:<+|-|=|#> [ value] Where '+' indicates an Add of a value,
+     * '-' for Delete, '=' for Replace, and '#' for Increment. In an Add operation, all of  the
+     * reqMod  values will have the '+' designator.
+     *
+     * @param reqMod contains collection of Strings that map to 'reqMod' attribute on 'auditModify' object class.
+     */
+    public void setReqMod(List<String> reqMod)
+    {
+        this.reqMod = reqMod;
+    }
+
+    /**
+     * reqEnd provide the end time of the operation. It uses generalizedTime syntax.
+     *
+     * @return value that maps to 'reqEnd' attribute on 'auditModify' object class.
+     */
+    public String getReqEnd()
+    {
+        return reqEnd;
+    }
+
+    /**
+     * reqEnd provide the end time of the operation. It uses generalizedTime syntax.
+     *
+     * @param reqEnd value that maps to same name on 'auditModify' object class.
+     */
+    public void setReqEnd(String reqEnd)
+    {
+        this.reqEnd = reqEnd;
+    }
+
+    /**
+     * The reqSession attribute is an implementation-specific identifier  that
+     * is  common to all the operations associated with the same LDAP session.
+     * Currently this is slapd's internal connection ID, stored in decimal.
+     *
+     * @return value that maps to 'reqSession' attribute on 'auditModify' object class.
+     */
+    public String getReqSession()
+    {
+        return reqSession;
+    }
+
+    /**
+     * The reqSession attribute is an implementation-specific identifier  that
+     * is  common to all the operations associated with the same LDAP session.
+     * Currently this is slapd's internal connection ID, stored in decimal.
+     *
+     * @param reqSession maps to same name on 'auditModify' object class.
+     */
+    public void setReqSession(String reqSession)
+    {
+        this.reqSession = reqSession;
+    }
+
+    /**
+     * Get the object class name of the audit record.  For this entity, this value will always be 'auditModify'.
+     *
+     * @return value that maps to 'objectClass' attribute on 'auditModify' obejct class.
+     */
+    public String getObjectClass()
+    {
+        return objectClass;
+    }
+
+    /**
+     * Set the object class name of the audit record.  For this entity, this value will always be 'auditModify'.
+     *
+     * @param objectClass value that maps to same name on 'auditModify' obejct class.
+     */
+    public void setObjectClass(String objectClass)
+    {
+        this.objectClass = objectClass;
+    }
+
+    /**
+     * The  reqAuthzID  attribute  is  the  distinguishedName of the user that
+     * performed the operation.  This will usually be the  same  name  as  was
+     * established  at  the  start of a session by a Bind request (if any) but
+     * may be altered in various circumstances.
+     * For Fortress bind operations this will map to {@link User#userId}
+     *
+     * @return value that maps to 'reqAuthzID' on 'auditModify' object class.
+     */
+    public String getReqAuthzID()
+    {
+        return reqAuthzID;
+    }
+
+    /**
+     * The  reqAuthzID  attribute  is  the  distinguishedName of the user that
+     * performed the operation.  This will usually be the  same  name  as  was
+     * established  at  the  start of a session by a Bind request (if any) but
+     * may be altered in various circumstances.
+     * For Fortress bind operations this will map to {@link User#userId}
+     *
+     */
+    public void setReqAuthzID(String reqAuthzID)
+    {
+        this.reqAuthzID = reqAuthzID;
+    }
+
+    /**
+     * The reqDN attribute is the  distinguishedName  of  the  target  of  the
+     * operation.  E.g.,for a Bind request, this is the Bind DN. For an Add
+     * request, this is the DN of the entry being added. For a Search request,
+     * this is the base DN of the search.
+     *
+     * @return value that map to 'reqDN' attribute on 'auditModify' object class.
+     */
+    public String getReqDN()
+    {
+        return reqDN;
+    }
+
+    /**
+     * The reqDN attribute is the  distinguishedName  of  the  target  of  the
+     * operation. E.g., for a Bind request, this is the Bind DN. For an Add
+     * request, this is the DN of the entry being added. For a Search request,
+     * this is the base DN of the search.
+     *
+     * @param reqDN maps to 'reqDN' attribute on 'auditModify' object class.
+     */
+    public void setReqDN(String reqDN)
+    {
+        this.reqDN = reqDN;
+    }
+
+    /**
+     * The reqResult attribute is the numeric LDAP result code of the
+     * operation, indicating either success or a particular LDAP  error  code.
+     * An  error code may be accompanied by a text error message which will be
+     * recorded in the reqMessage attribute.
+     *
+     * @return value that maps to 'reqResult' attribute on 'auditModify' object class.
+     */
+    public String getReqResult()
+    {
+        return reqResult;
+    }
+
+    /**
+     * The reqResult attribute is the numeric LDAP result code of the
+     * operation, indicating either success or a particular LDAP  error  code.
+     * An  error code may be accompanied by a text error message which will be
+     * recorded in the reqMessage attribute.
+     *
+     * @param reqResult maps to same name on 'auditModify' object class.
+     */
+    public void setReqResult(String reqResult)
+    {
+        this.reqResult = reqResult;
+    }
+
+    /**
+     * reqStart provide the start of the operation, They use generalizedTime syntax.
+     * The reqStart attribute is also used as the RDN for each log entry.
+     *
+     * @return value that maps to 'reqStart' attribute on 'auditModify' object class.
+     */
+    public String getReqStart()
+    {
+        return reqStart;
+    }
+
+    /**
+     * reqStart provide the start of the operation, They use generalizedTime syntax.
+     * The reqStart attribute is also used as the RDN for each log entry.
+     *
+     * @param reqStart maps to same name on 'auditModify' object class.
+     */
+    public void setReqStart(String reqStart)
+    {
+        this.reqStart = reqStart;
+    }
+
+    /**
+     * The reqType attribute is a simple string containing the type of
+     * operation being logged, e.g.  add, delete, search,  etc.  For  extended
+     * operations, the  type also includes the OID of the extended operation,
+     * e.g. extended(1.1.1.1)
+     *
+     * @return value that maps to 'reqType' attribute on 'auditModify' object class.
+     */
+    public String getReqType()
+    {
+        return reqType;
+    }
+
+    /**
+     * The reqType attribute is a simple string containing the type of
+     * operation being logged, e.g. add, delete, search, etc. For extended
+     * operations,  the  type also includes the OID of the extended operation,
+     * e.g.extended(1.1.1.1)
+     *
+     * @param reqType maps to same name on 'auditModify' object class.
+     */
+    public void setReqType(String reqType)
+    {
+        this.reqType = reqType;
+    }
+
+    /**
+     * Sequence id is used internal to Fortress.
+     * @return long value contains sequence id.
+     */
+    public long getSequenceId()
+    {
+        return sequenceId;
+    }
+
+    /**
+     * Sequence id is used internal to Fortress
+     * @param sequenceId contains sequence to use.
+     */
+    public void setSequenceId(long sequenceId)
+    {
+        this.sequenceId = sequenceId;
+    }
+}
\ 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/OrgUnit.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnit.java b/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnit.java
new file mode 100755
index 0000000..ddb20bd
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnit.java
@@ -0,0 +1,420 @@
+/*
+ *   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.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.directory.fortress.core.rbac.dao.AdminRoleDAO;
+import org.apache.directory.fortress.core.rbac.dao.OrgUnitDAO;
+
+
+/**
+ * All entities ({@link AdminRole}, {@link OrgUnit},
+ * {@link org.apache.directory.fortress.core.rbac.SDSet} etc...) are used to carry data between three Fortress
+ * layers.starting with the (1) Manager layer down thru middle (2) Process layer and it's processing rules into
+ * (3) DAO layer where persistence with the OpenLDAP server occurs.
+ * <h4>Fortress Processing Layers</h4>
+ * <ol>
+ * <li>Manager layer:  {@link DelAdminMgrImpl}, {@link DelAccessMgrImpl}, {@link DelReviewMgrImpl},...</li>
+ * <li>Process layer:  {@link AdminRoleP}, {@link OrgUnitP},...</li>
+ * <li>DAO layer: {@link AdminRoleDAO}, {@link OrgUnitDAO},...</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 />
+ * For example, this entity requires {@link #name} and {@link #type} set before passing into {@link DelAdminMgrImpl} or  {@link DelReviewMgrImpl} APIs.
+ * Create methods usually require more attributes (than Read) due to constraints enforced between entities.
+ * <p/>
+ * This entity implements both User and Permission OU pool functionality that defines org membership of entities for ARBAC02 style admin checks..
+ * <br />The unique key to locate an OrgUnit entity (which is subsequently assigned both to Users and Permissions) is 'OrgUnit.name' and 'OrgUnit.Type'.<br />
+ * <p/>
+ * An OrgUnit name may contain alphanumeric and simple symbols that are safe text (.,:;-_).  Any non-safe text will be
+ * encoded before persistence.  Valid names include:
+ * <ol>
+ * <li>123</li>
+ * <li>OneTwoThree</li>
+ * <li>One-Two-Three</li>
+ * <li>One_Two_Three</li>
+ * <li>One:2:3</li>
+ * <li>1:2:3</li>
+ * <li>1.2.3</li>
+ * <li>1,2,3</li>
+ * <li>1_2_3</li>
+ * <li>etc...</li>
+ * </ol>
+ * <p/>
+ * There is a Many-to-One relationship between a User and OrgUnit.
+ * <h3>{@link org.apache.directory.fortress.core.rbac.User}*<->1 {@link OrgUnit}</h3>
+ * <p/>
+ * There is a Many-to-One relationship between a {@link PermObj} object and {@link OrgUnit}.
+ * <h3>{@link PermObj}*<->1 {@link OrgUnit}</h3>
+ * <p/>
+ * Example to create new ARBAC User OrgUnit:
+ * <p/>
+ * <code>OrgUnit myUserOU = new OrgUnit("MyUserOrgName", OrgUnit.Type.USER);</code><br />
+ * <code>myUserOU.setDescription("This is a test User OrgUnit");</code><br />
+ * <code>DelAdminMgr delAdminMgr = DelAdminMgrFactory.createInstance();</code><br />
+ * <code>delAdminMgr.add(myUserOU);</code><br />
+ * <p/>
+ * This will create a User OrgUnit that can be used as a target for User OU and AdminRole OS-U assignments.
+ * <p/>
+ * Example to create new ARBAC Perm OrgUnit:
+ * <p/>
+ * <code>OrgUnit myPermOU = new OrgUnit("MyPermOrgName", OrgUnit.Type.PERM);</code><br />
+ * <code>myPermOU.setDescription("This is a test Perm OrgUnit");</code><br />
+ * <code>DelAdminMgr delAdminMgr = DelAdminMgrFactory.createInstance();</code><br />
+ * <code>delAdminMgr.add(myPermOU);</code><br />
+ * <p/>
+ * This will create a Perm OrgUnit that can be used as a target for Perm OU and AdminRole OS-P assignments.
+ * <p/>
+ * <h4>OrgUnit Schema</h4>
+ * The Fortress OrgUnit entity is a composite of the following other Fortress structural and aux object classes:
+ * <p/>
+ * 1. organizationalUnit Structural Object Class is used to store basic attributes like ou and description.
+ * <pre>
+ * ------------------------------------------
+ * objectclass ( 2.5.6.5 NAME 'organizationalUnit'
+ *  DESC 'RFC2256: an organizational unit'
+ *  SUP top STRUCTURAL
+ *  MUST ou
+ *  MAY (
+ *      userPassword $ searchGuide $ seeAlso $ businessCategory $
+ *      x121Address $ registeredAddress $ destinationIndicator $
+ *      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
+ *      telephoneNumber $ internationaliSDNNumber $
+ *      facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $
+ *      postalAddress $ physicalDeliveryOfficeName $ st $ l $ description
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 2. ftOrgUnit Structural objectclass is used to store the OrgUnit internal id.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Organizational Structural Object Class
+ * objectclass	( 1.3.6.1.4.1.38088.2.6
+ *  NAME 'ftOrgUnit'
+ *  DESC 'Fortress OrgUnit Structural Object Class'
+ *  SUP organizationalunit
+ *  STRUCTURAL
+ *  MUST (
+ *      ftId
+ *  )
+ *  MAY (
+ *      ftParents
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 3. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Audit Modification Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.4
+ *  NAME 'ftMods'
+ *  DESC 'Fortress Modifiers AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftModifier $
+ *      ftModCode $
+ *      ftModId
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortOrgUnit")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "orgUnit", propOrder =
+    {
+        "children",
+        "description",
+        "id",
+        "name",
+        "parents",
+        "type"
+})
+public class OrgUnit extends FortEntity
+    implements Graphable, java.io.Serializable
+{
+    /**
+     * Maps to the location for a particular OrgUnit entity to either the User, {@code ou=OS-U}, or Permission, {@code ou=OS-P}, tree in ldap.
+     *
+     */
+    public Type type;
+    private String name;
+    private String id;
+    private String description;
+    @XmlElement(nillable = true)
+    private Set<String> parents;
+    @XmlElement(nillable = true)
+    private Set<String> children;
+
+
+    /**
+     * Default constructor is used by internal Fortress classes.
+     */
+    public OrgUnit()
+    {
+    }
+
+
+    /**
+     * Construct a OrgUnit entity with a given ou name.
+     *
+     * @param ou maps to same name on on 'organizationalUnit' object class.
+     */
+    public OrgUnit( String ou )
+    {
+        this.name = ou;
+    }
+
+
+    /**
+     * Construct a OrgUnit entity with a given ou name and specified type - 'USER' or 'PERM'.
+     *
+     * @param ou   maps to same name on on 'organizationalUnit' object class.
+     * @param type is used to determine which OrgUnit tree is being targeted - 'USER' or 'PERM'.
+     */
+    public OrgUnit( String ou, Type type )
+    {
+        this.name = ou;
+        this.type = type;
+    }
+
+
+    /**
+     * Get the name required attribute of the OrgUnit object
+     *
+     * @return attribute maps to 'ou' attribute on 'organizationalUnit' object class.
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+
+    /**
+     * Sets the required name attribute on the OrgUnit object
+     *
+     */
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * Return the internal id that is associated with OrgUnit.  This attribute is generated automatically
+     * by Fortress when new OrgUnit is added to directory and is not known or changeable by external client.
+     *
+     * @return attribute maps to 'ftId' in 'ftOrgUnit' object class.
+     */
+    public String getId()
+    {
+        return id;
+    }
+
+
+    /**
+     * Set the internal Id that is associated with OrgUnit.  This method is used by DAO class and
+     * is generated automatically by Fortress.  Attribute stored in LDAP cannot be changed by external caller.
+     * This method can be used by client for search purposes only.
+     *
+     * @param id maps to 'ftId' in 'ftOrgUnit' object class.
+     */
+    public void setId( String id )
+    {
+        this.id = id;
+    }
+
+
+    /**
+     * Generate an internal Id that is associated with OrgUnit.  This method is used by DAO class and
+     * is not available to outside classes.   The generated attribute maps to 'ftId' in 'ftOrgUnit' object class.
+     */
+    public void setId()
+    {
+        // generate a unique id that will be used as the rDn for this entry:
+        UUID uuid = UUID.randomUUID();
+        this.id = uuid.toString();
+    }
+
+    /**
+     * The OrgUnit 'Type' attribute is required and used to specify which OrgUnit tree a particular entity is in reference to.
+     */
+    @XmlType(name = "type")
+    @XmlEnum
+    public enum Type
+    {
+        /**
+         * Type {@link org.apache.directory.fortress.core.rbac.User} nodes reside in User OU pool.
+         */
+        USER,
+        /**
+         * Type {@link Permission} nodes reside in Perm OU pool.
+         */
+        PERM
+    }
+
+
+    /**
+     * Return the type of OrgUnit for this entity.  This field is required for this entity.
+     *
+     * @return Type contains 'PERM' or 'USER'.
+     */
+    public Type getType()
+    {
+        return type;
+    }
+
+
+    /**
+     * Get the type of OrgUnit for this entity.  This field is required for this entity.
+     *
+     * @param type contains 'PERM' or 'USER'.
+     */
+    public void setType( Type type )
+    {
+        this.type = type;
+    }
+
+
+    /**
+     * Returns optional description that is associated with OrgUnit.  This attribute is validated but not constrained by Fortress.
+     *
+     * @return value that is mapped to 'description' in 'organizationalUnit' object class.
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+
+    /**
+     * Sets the optional description that is associated with OrgUnit.  This attribute is validated but not constrained by Fortress.
+     *
+     * @param description that is mapped to same name in 'organizationalUnit' object class.
+     */
+    public void setDescription( String description )
+    {
+        this.description = description;
+    }
+
+
+    /**
+     * Get the names of orgUnits that are parents (direct ascendants) of this orgUnit.
+     * @return Set of parent orgUnit names assigned to this orgUnit.
+     */
+    public Set<String> getParents()
+    {
+        return parents;
+    }
+
+
+    /**
+     * Set the names of orgUnit names that are parents (direct ascendants) of this orgUnit.
+     * @param parents contains the Set of parent orgUnit names assigned to this orgUnit.
+     */
+    public void setParents( Set<String> parents )
+    {
+        this.parents = parents;
+    }
+
+
+    /**
+     * Set the occupant attribute with the contents of the User dn.
+     * @param parent maps to 'ftParents' attribute on 'ftRls' object class.
+     */
+    public void setParent( String parent )
+    {
+        if ( this.parents == null )
+        {
+            this.parents = new HashSet<>();
+        }
+        this.parents.add( parent );
+    }
+
+
+    /**
+     * Set the occupant attribute with the contents of the User dn.
+     * @param parent maps to 'ftParents' attribute on 'ftRls' object class.
+     */
+    public void delParent( String parent )
+    {
+        if ( this.parents != null )
+        {
+            this.parents.remove( parent );
+        }
+    }
+
+
+    /**
+     * Return the Set of child orgUnit names (direct descendants) of this orgUnit.
+     * @return Set of child orgUnit names assigned to this orgUnit.
+     */
+    public Set<String> getChildren()
+    {
+        return children;
+    }
+
+
+    /**
+     * Set the Set of child orgUnit names (direct descendants) of this orgUnit
+     * @param children contains the Set of child orgUnit names assigned to this orgUnit.
+     */
+    public void setChildren( Set<String> children )
+    {
+        this.children = children;
+    }
+
+
+    /**
+     * @param thatObj
+     * @return boolean value of 'true if objects match
+     */
+    public boolean equals( Object thatObj )
+    {
+        if ( this == thatObj )
+            return true;
+        if ( this.getName() == null )
+            return false;
+        if ( !( thatObj instanceof OrgUnit ) )
+            return false;
+        OrgUnit thatOrg = ( OrgUnit ) thatObj;
+        if ( thatOrg.getName() == null )
+            return false;
+        return thatOrg.getName().equalsIgnoreCase( this.getName() );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnitAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnitAnt.java b/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnitAnt.java
new file mode 100755
index 0000000..58ff551
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnitAnt.java
@@ -0,0 +1,61 @@
+/*
+ *   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;
+
+
+/**
+ * Entity is used by custom Apache Ant task for special handling of collections.  This is necessary because the
+ * Ant parser cannot deal with complex data attribute types.  The class extends a base entity.
+ *
+ * @author Shawn McKinney
+ */
+public class OrgUnitAnt extends OrgUnit
+    implements java.io.Serializable
+{
+    private String typeName;
+    /**
+     * Return the type of OU in string format.
+     *
+     * @return String that represents static or dynamic relations.
+     */
+    public String getTypeName()
+    {
+        return typeName;
+    }
+
+    /**
+     * Method accepts a String variable that maps to its parent's set type.
+     *
+     * @param typeName String value represents perm or user ou data sets.
+     */
+    public void setTypeName(String typeName)
+    {
+        this.typeName = typeName;
+        if (typeName != null && typeName.equalsIgnoreCase("PERM"))
+        {
+            setType(OrgUnit.Type.PERM);
+        }
+        else
+        {
+            setType(OrgUnit.Type.USER);
+        }
+    }
+}
+


[37/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cli/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cli/package.html b/src/main/java/org/apache/directory/fortress/core/cli/package.html
new file mode 100755
index 0000000..6d32003
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cli/package.html
@@ -0,0 +1,2044 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+<head>
+    <title>Fortress Command Line Interpreter Reference Manual</title>
+</head>
+<body>
+<p>
+    <A HREF="package-summary.html">Click here</A> for Reference Manual which shows how the Command Line Interpreter
+    drives the Fortress APIs from a command prompt.
+</p>
+
+<h2>Instructions to start and use the Fortress CLI program</h2>
+<br>Note: Information to set up environment of Fortress runtime, check out file named <b>README.txt</b> found in root
+folder of Fortress SDK package.
+<ol>
+    <li>Open shell prompt within FORTRESS_HOME folder and enter the following</li>
+    <li>export JAVA_HOME=/path to the root folder of your java SDK, version 1.6 and beyond required</li>
+    <li>export ANT_HOME=/path to the root folder of your Apache Ant installation, version 1.8 and beyond required</li>
+    <li>$ANT_HOME/bin/ant cli</li>
+    <li>This will fire Fortress ant target which then starts the CLI. The CLI syntax will be described in detail
+        below.
+    </li>
+</ol>
+<h2>Command Line Interpreter Reference Manual</h2>
+Once started, the Fortress CLI runs in interactive mode which means it runs continously waiting for user to enter a
+valid commands or terminate. Every CLI command is structured in the following format:<br>
+
+<p>
+    <b>group function options</b><br><br>
+    For example:
+<pre>admin auser -u hounddog42 -p myNewP@$$w0rd -o development</pre>
+In this example the group is 'admin', the function is 'auser' or add user, and the options are -u for userid, -p for
+password and -o that points to a valid USERS OrgUnit node.
+Despite being called an 'option', so named parameters may or may not be required for a given function. Option names are
+always preceded by a dash ('-') when entered. Option values
+must be enclosed within single quotes '' or double quotes "" iff value contains multiple Strings separated by
+whitespace. For example the user description value can be entered like
+this: -d "This description contains more than one word" or this: -d 'This description also contains more than one word'.
+<br>
+<br>Below is reference manual for Fortress' CLI commands
+</p>
+
+<h2>Groups</h2>
+
+Currently the following groups of functions are supported:
+<ul>
+    <li>admin - used to setup RBAC policies</li>
+    <li>review - used to interrogate RBAC policies</li>
+    <li>system - used to test RBAC policies</li>
+    <li>dadmin - used to setup ARBAC (administrative role based access control) policies</li>
+    <li>group - used to setup LDAP Group policies</li>
+</ul>
+<h2>Sample run to add new User to LDAP</h2>
+   <pre>      
+iamuser@joshuatreesoftware:~/home/iamuser/openldap-fortress-core$ export JAVA_HOME=/opt/jdk1.6.0_27/
+iamuser@joshuatreesoftware:~/home/iamuser/fortressDev/openldap-fortress-core$ export ANT_HOME=/home/iamuser/apache-ant-1.8.2/
+iamuser@joshuatreesoftware:~/home/iamuser/fortressDev/openldap-fortress-core$ $ANT_HOME/bin/ant cli
+iamuser@joshuatreesoftware:~/home/iamuser/fortressDev/openldap-fortress-core/build.xml
+...
+[echo] Run the Fortress Command Line Interpreter
+[java] 2011-12-03 21:10:02,431 (INFO ) CLI Options include admin, review, system, dadmin
+[java] 2011-12-03 21:10:02,431 (INFO ) Enter one from above or 'q' to quit
+<b>admin auser -u hounddog42 -p myNewP@$$w0rd -o development</b>
+     [java] 2011-12-03 21:41:37,614 (INFO ) arg:admin
+     [java] 2011-12-03 21:41:37,614 (INFO ) arg:auser
+     [java] 2011-12-03 21:41:37,615 (INFO ) arg:-u
+     [java] 2011-12-03 21:41:37,615 (INFO ) arg:hounddog42
+     [java] 2011-12-03 21:41:37,615 (INFO ) arg:-p
+     [java] 2011-12-03 21:41:37,616 (INFO ) arg:-o
+     [java] 2011-12-03 21:41:37,616 (INFO ) arg:development
+     [java] 2011-12-03 21:41:37,617 (INFO ) auser
+     [java] 2011-12-03 21:41:37,750 (INFO ) command:auser was successful
+     [java] 2011-12-03 21:41:37,750 (INFO ) CLI Options include admin, review, system, dadmin
+     [java] 2011-12-03 21:41:37,751 (INFO ) Enter one from above or 'q' to quit
+   </pre>
+
+<p>
+    This remainder of document is a command reference document to show how the Fortress CLI works.
+<ol type="I">
+<li>
+<h2>Adminstrative Commands</h2>
+This section contains a guide for the <b>functions</b> and <b>options</b> that fall in the <b>admin</b> group.
+<ol type="A">
+<li>
+    <h3>auser : function to add a new User</h3>
+
+    <p>
+        This command creates a new RBAC user. The command is valid only if the new user is
+        not already a member of the USERS data set. The USER data set is updated. The new user
+        does not own any session at the time of its creation.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>u : userId - maps to INetOrgPerson uid</li>
+        <li>p : password - used to authenticate the User</li>
+        <li>o : orgUnit - contains the name of an already existing User OU node</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>w : pwPolicy - contains the name of an already existing OpenLDAP password policy node</li>
+        <li>c : cn - maps to INetOrgPerson common name attribute</li>
+        <li>s : sn - maps to INetOrgPerson surname attribute</li>
+        <li>d : description - maps to INetOrgPerson description attribute</li>
+        <li>3 : title - maps to INetOrgPerson title attribute</li>
+        <li>4 : employeeType - maps to INetOrgPerson employeeType attribute</li>
+        <li>y : phones * - multi-occurring attribute maps to organizationalPerson telephoneNumber attribute</li>
+        <li>Y : mobiles * - multi-occurring attribute maps to INetOrgPerson mobile attribute</li>
+        <li>@ : emails * - multi-occurring attribute maps to INetOrgPerson mail attribute</li>
+        <li>> : address * - multi-occurring attribute maps to organizationalPerson postalAddress attribute</li>
+        <li>< : state - maps to organizationalPerson st attribute</li>
+        <li>3 : city - maps to organizationalPerson l attribute</li>
+        <li>z : postalCode - maps to postalCode description attribute</li>
+        <li>2 : postalOfficeBox - maps to organizationalPerson postOfficeBox attribute</li>
+        <li>b : beginTime - HHMM - determines begin hour user may activate session</li>
+        <li>e : endTime - HHMM - determines end hour user may activate session.</li>
+        <li>B : beginDate - YYYYMMDD - determines date when user may sign on</li>
+        <li>E : endDate - YYYYMMDD - indicates latest date user may sign on</li>
+        <li>l : beginLockDate - YYYYMMDD - determines beginning of enforced inactive status</li>
+        <li>N : endLockDate - YYYYMMDD - determines end of enforced inactive status</li>
+        <li>m : dayMask - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of user may sign on</li>
+        <li>t : timeout - number in seconds of session inactivity time allowed</li>
+        <li>v : properties * - multi-occurring attribute contains property key and values are separated with a ':'. e.g.
+            mykey1:myvalue1
+        </li>
+        <li>r : roles * - multi-occurring attribute contains the name of already existing role to assign to user</li>
+        <li>a : adminRoles * - multi-occurring attribute contains the name of already existing adminRole to assign to
+            user
+        </li>
+        <li>X : protocol - alphanumeric string used for groups</li>
+        <li>M : member - contains userId of member to a group</li>
+    </ul>
+
+    <h4>example</h4>
+    <ul>
+        <li>admin auser -u testuser1 -p mypasword123 -o dev1</li>
+        <li>admin auser -u testuser2 -p mypasword456 -o dev1 -r oamRole1 -d mydescription -b 0800 -e 1700 -B 20111203 -E
+            20111231 -l 20111215 -n 20111217 -m 17 -t 30 -v n1:v1 -v n2:v2
+        </li>
+        <li>admin auser -u testuser3 -p mypasword789 -o dev1 -z 1111111 -2 123 -y 555-555-5555 -y 444-444-4444 ->
+            "joshuatree1 one two three" -> "joshuatree2 four five six" -< CA -3 twentyninepalms -Y 333-333-3333
+        </li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>uuser : function to update an existing user in LDAP</h3>
+
+    <p>
+        This method performs an update on User entity in directory. Prior to making this call the entity must exist in
+        directory.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>u : userId - maps to INetOrgPerson uid</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>p : password - used to authenticate the User</li>
+        <li>o : orgUnit - contains the name of an already existing User OU node</li>
+        <li>w : pwPolicy - contains the name of an already existing OpenLDAP password policy node</li>
+        <li>c : cn - maps to INetOrgPerson common name attribute</li>
+        <li>s : sn - maps to INetOrgPerson surname attribute</li>
+        <li>d : description - maps to INetOrgPerson description attribute</li>
+        <li>3 : title - maps to INetOrgPerson title attribute</li>
+        <li>4 : employeeType - maps to INetOrgPerson employeeType attribute</li>
+        <li>y : phones * - multi-occurring attribute maps to organizationalPerson telephoneNumber attribute</li>
+        <li>Y : mobiles * - multi-occurring attribute maps to INetOrgPerson mobile attribute</li>
+        <li>@ : emails * - multi-occurring attribute maps to INetOrgPerson mail attribute</li>
+        <li>> : address * - multi-occurring attribute maps to organizationalPerson postalAddress attribute</li>
+        <li>< : state - maps to organizationalPerson st attribute</li>
+        <li>3 : city - maps to organizationalPerson l attribute</li>
+        <li>z : postalCode - maps to postalCode description attribute</li>
+        <li>2 : postalOfficeBox - maps to organizationalPerson postOfficeBox attribute</li>
+        <li>b : beginTime - HHMM - determines begin hour user may activate session</li>
+        <li>e : endTime - HHMM - determines end hour user may activate session.</li>
+        <li>B : beginDate - YYYYYYMMDD - determines date when user may sign on</li>
+        <li>E : endDate - YYYYMMDD - indicates latest date user may sign on</li>
+        <li>l : beginLockDate - YYYYMMDD - determines beginning of enforced inactive status</li>
+        <li>N : endLockDate - YYYYMMDD - determines end of enforced inactive status</li>
+        <li>m : dayMask - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of user may sign on</li>
+        <li>t : timeout - number in seconds of session inactivity time allowed</li>
+        <li>v : properties * - multi-occurring attribute contains property key and values are separated with a ':'. e.g.
+            mykey1:myvalue1
+        </li>
+        <li>r : roles * - multi-occurring attribute contains the name of already existing role to assign to user</li>
+        <li>a : adminRoles * - multi-occurring attribute contains the name of already existing adminRole to assign to
+            user
+        </li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin uuser -u testuser1 -d mynewdescription</li>
+        <li>admin uuser -u testuser2 -p mynewpasword456 -r oamRole2 -b 0805 -e 1701 -B 20111203 -E 20111231 -l 20111215
+            -n 20111217 -m 17 -t 30 -v n1:v1 -v n2:v2
+        </li>
+        <li>admin uuser -u testuser3 -p password123 -z 1111111 -2 123 -y 555-555-5555 -y 444-444-4444 -> "joshuatree1
+            one two three" -> "joshuatree2 four five six" -< CA -3 twentyninepalms -Y 333-333-3333
+        </li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>duser : function to delete a user from LDAP</h3>
+
+    <p>
+        This command deletes an existing user from the RBAC database. The command is valid
+        if and only if the user to be deleted is a member of the USERS data set. The USERS and
+        UA data sets and the assigned_users function are updated. 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.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>u : userId - maps to INetOrgPerson uid</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin duser -u testuser1</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>change : function to change a user's password</h3>
+
+    <p>
+        OpenLDAP password policies will be enforced if in effect at the time of this function call.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>u : userId - maps to INetOrgPerson uid</li>
+        <li>p : password - contains the User's old password</li>
+        <li>V : newPassword - contains the User's new password</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin change -u testuser1 -p mypasword123 -V mynewpassword456</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>reset : function to perform an administrative reset on user password</h3>
+
+    <p>
+        Used by administrator to change a user's password when they have forgotten old password or if the password is
+        expired. When OpenLDAP policies are in effect this will force User to change their password the next time
+        authenticate.
+    </p>
+    <h4>required parameters</h4>
+    <ul>
+        <li>u : userId - maps to INetOrgPerson uid</li>
+        <li>V : newPassword - contains the User's new password</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin reset -u testuser1 -V temp777</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>lock : LOCK_USER_ACCOUNT</h3>
+
+    <p>
+        Used to lock a user's account in LDAP
+    </p>
+    <h4>required parameters</h4>
+    <ul>
+        <li>u : userId - maps to INetOrgPerson uid</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin lock -u testuser1</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>unlock : UNLOCK_USER_ACCOUNT</h3>
+
+    <p>
+        Used to unlock a user's account in so they may sign on again to LDAP. Note this will not fix an expired password
+        (which needs to be changed by user or reset by admin)
+    </p>
+    <h4>required parameters</h4>
+    <ul>
+        <li>u : userId - maps to INetOrgPerson uid</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin unlock -u testuser1</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>arole : Add a new Role</h3>
+
+    <p>
+        This command creates a new role. The command is valid if and only if the new role is not already
+        a member of the ROLES data set. The ROLES data set is updated. Initially, no user or permission is
+        assigned to the new role.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name to use for the Role to be created.</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>d : description - maps to description attribute on organizationalRole object class</li>
+        <li>b : beginTime - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+        <li>e : endTime - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+        <li>B : beginDate - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+        <li>E : endDate - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+        <li>l : beginLockDate - YYYYMMDD - determines beginning of enforced inactive status</li>
+        <li>N : endLockDate - YYYYMMDD - determines end of enforced inactive status</li>
+        <li>m : dayMask - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's
+            RBAC session
+        </li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin arole -n trole1</li>
+        <li>admin arole -n trole2 -d roledescription -b 0900 -e 1800 -B 20120101 -E 20990101 -m 1234567</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>urole : Update an existing Role</h3>
+
+    <p>
+        Method will update a Role entity in the directory. The role must exist in role container prior to this call.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name for already existing Role to be updated</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>d : description - maps to description attribute on organizationalRole object class</li>
+        <li>b : beginTime - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+        <li>e : endTime - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+        <li>B : beginDate - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+        <li>E : endDate - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+        <li>l : beginLockDate - YYYYMMDD - determines beginning of enforced inactive status</li>
+        <li>N : endLockDate - YYYYMMDD - determines end of enforced inactive status</li>
+        <li>m : dayMask - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's
+            RBAC session
+        </li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin urole -n trole1 -d newdesc</li>
+        <li>admin urole -n trole2 -b 0800 -B 20111231 -m 23456</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>drole : Delete a Role</h3>
+
+    <p>
+        This command deletes an existing role from the RBAC database. The command is valid
+        if and only if the role to be deleted is a member of the ROLES data set. If role
+        assignments to USERS or PERMISSIONS exist this command will delete those as well.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name for already existing Role to be deleted</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin drole -n trole1</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>asgnrole : Assign a Role to a User</h3>
+
+    <p>
+        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>
+        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>b : beginTime - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+                <li>e : endTime - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+                <li>B : beginDate - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+                <li>E : endDate - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+                <li>l : beginLockDate - YYYYMMDD - determines beginning of enforced inactive status</li>
+                <li>N : endLockDate - YYYYMMDD - determines end of enforced inactive status</li>
+                <li>m : dayMask - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into
+                    user's RBAC session
+                </li>
+            </ul>
+    </ul>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name for already existing Role to be assigned</li>
+        <li>u : userId - contains the userId for existing User</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>b : beginTime - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+        <li>e : endTime - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+        <li>B : beginDate - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+        <li>E : endDate - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+        <li>l : beginLockDate - YYYYMMDD - determines beginning of enforced inactive status</li>
+        <li>N : endLockDate - YYYYMMDD - determines end of enforced inactive status</li>
+        <li>m : dayMask - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's
+            RBAC session
+        </li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin asgnrole -u testuser2 -n trole2</li>
+        <li>admin asgnrole -u testuser2 -n trole2 -b 1200 -e 2359 -B 20120101 -E 20120131 -m 1234567</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>dsgnrole : Deassign a Role from a User</h3>
+
+    <p>
+        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.
+    </p>
+    <br>Successful completion includes:
+    <ul>
+        <li>User entity in USER data set has role assignment removed.</li>
+        <li>Role entity in ROLE data set has userId removed as role occupant.</li>
+        <li>(optional) Temporal constraints will be removed from user aux object if set prior to call.</li>
+    </ul>
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name for already existing Role to be deassigned</li>
+        <li>u : userId - contains the userId for existing User</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin dsgnrole -u testuser2 -n trole2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>arel : ADD_ROLE_INHERITANCE</h3>
+
+    <p>
+        This commands establishes a new immediate inheritance relationship parentRole <<-- childRole between existing
+        roles parentRole, childRole.
+
+    <p>
+        The command is valid if and only if:
+    </p>
+    <ul>
+        <li> The parentRole and childRole are members of the ROLES data set.
+        <li> The parentRole is not an immediate ascendant of childRole.
+        <li> The childRole does not properly inherit parentRole (in order to avoid cycle creation).
+    </ul>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>A : ascendant - contains the name of existing Role to be parent</li>
+        <li>D : descendant - contains the name of existing Role to be child</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin arel -A trole1 -D trole2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>drel : DELETE_ROLE_INHERITANCE</h3>
+    This command deletes an existing immediate inheritance relationship parentRole <<-- childRole.
+    <p>
+        command is valid if and only if:
+    </p>
+    <ul>
+        <li> The roles parentRole and childRole are members of the ROLES data set.
+        <li> The parentRole is an immediate ascendant of childRole.
+        <li> The new inheritance relation is computed as the reflexive-transitive closure of the immediate inheritance
+            relation resulted after deleting the relationship parentRole <<-- childRole.
+    </ul>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>A : ascendant - contains the name of parent Role to be removed as parent</li>
+        <li>D : descendant - contains the name of child Role to be removed as child</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin drel -A trole1 -D trole2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>asset : CREATE_SSD_SET</h3>
+    This command creates a named SSD set of roles and sets the cardinality n of its subsets
+    that cannot have common users.
+    <p>
+        The command is valid if and only if:
+    </p>
+    <ul>
+        <li>The name of the SSD set is not already in use.
+        <li> All the roles in the SSD set are members of the ROLES data set.
+        <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the SSD role
+            set.
+        <li> The SSD constraint for the new role set is satisfied.
+    </ul>
+
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of new SSD role set to be added</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>r : roles * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+        <li>C : cardinality - default is 2 which is one more than maximum number of Roles that may be assigned to User
+            from a particular set
+        </li>
+        <li>d : description - contains any safe text</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin asset -n mytestssd -r trole1 -r trole3 -r trole5 -r trole6 -c 2 -d only1of4canAssign</li>
+        <li>admin asset -n mytestssd -r trole1 -r trole3 -r trole5 -r trole6 -c 3 -d only2of4canAssign</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>dsset : DELETE_SSD_SET</h3>
+
+    <p>
+        This command deletes a SSD role set completely. The command is valid if and only if the SSD role set exists.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing SSD role set to be removed</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin dsset -n mytestssd</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>adset : CREATE_DSD_SET</h3>
+
+    <p>
+        This command creates a named DSD set of roles and sets an associated cardinality n.
+        The DSD constraint stipulates that the DSD role set cannot contain n or more roles
+        simultaneously active in the same session.
+
+    <p>
+        The command is valid if and only if:
+    <ul>
+        <li> The name of the DSD set is not already in use.
+        <li> All the roles in the DSD set are members of the ROLES data set.
+        <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the DSD role
+            set.
+        <li> The DSD constraint for the new role set is satisfied.
+    </ul>
+
+<h4>required parameters</h4>
+<ul>
+    <li>n : name - contains the name of new DSD role set to be added</li>
+</ul>
+<h4>optional parameters</h4>
+<ul>
+    <li>r : roles * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+    <li>C : cardinality - default is 2 which is one more than maximum number of Roles that may be activated into RBAC
+        Session from a particular set
+    </li>
+    <li>d : description - contains any safe text</li>
+</ul>
+<h4>example</h4>
+<ul>
+    <li>admin adset -n mytestdsd -r trole1 -r trole3 -r trole5 -r trole6 -c 2 -d only1of4canActivate</li>
+    <li>admin adset -n mytestdsd -r trole1 -r trole3 -r trole5 -r trole6 -c 3 -d only2of4canActivate</li>
+</ul>
+</li><br>
+
+<li>
+    <h3>ddset : DELETE_DSD_SET</h3>
+
+    <p>
+        This command deletes a DSD role set completely. The command is valid if and only if the DSD role set exists.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing DSD role set to be removed</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin ddset -n mytestdsd</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>aobj : ADD_POBJ</h3>
+
+    <p>
+        This method will add permission object to perms container in directory. The perm object must not exist before
+        making this call.
+        A PermObj instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap
+        tree: PermObj*->Permission.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of new object being added</li>
+        <li>o : orgUnit - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>d : description - any safe text</li>
+        <li>T : type - contains any safe text</li>
+        <li>v : properties * - multi-occurring property key and values are separated with a ':'. e.g. mykey1:myvalue1
+        </li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin aobj -n mytestobject -o app1</li>
+        <li>admin aobj -n myobject2 -o app1 -d TestObject -t anything -v key1:val1 -v key2:val2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>uobj : UPDATE_POBJ</h3>
+
+    <p>
+        This method will update permission object in perms container in directory. The perm object must exist before
+        making this call.
+        A PermObj instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap
+        tree: PermObj*->Permission.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of exising object being updated</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>o : orgUnit - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+        <li>d : description - any safe text</li>
+        <li>T : type - contains any safe text</li>
+        <li>v : properties * - multi-occurring property key and values are separated with a ':'. e.g. mykey1:myvalue1
+        </li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin uobj -n mytestobject -o app2 -d ChangedOrgUnit</li>
+        <li>admin uobj -n myobject2 -o app1 -d ChangeDescription</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>dobj : DELETE_POBJ</h3>
+
+    <p>
+        This method will remove permission object to perms container in directory. This method will also remove
+        in associated permission objects that are attached to this object.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of exising object being targeted for removal</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin dobj -n mytestobject -o app1</li>
+    </ul>
+</li>
+<br>
+<li>
+    <h3>aperm : ADD_PERM</h3>
+
+    <p>
+        This method will add permission operation to an existing permission object which resides under
+        ou=Permissions,ou=RBAC,dc=yourHostName,dc=com container in directory information tree.
+        The perm operation entity may have Role or User associations. The target Permission must not exist prior to
+        calling.
+        A Fortress Permission instance exists in a hierarchical, one-many relationship between its parent and itself as
+        stored in ldap tree: PermObj*->Permission.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing object being targeted for the permission add</li>
+        <li>O : opName - contains the name of new permission operation being added</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>r : roles * - multi occurring attribute contains RBAC Roles that permission operation is being granted to
+        </li>
+        <li>v : properties * - multi-occurring property key and values are separated with a ':'. e.g. mykey1:myvalue1
+        </li>
+        <li>T : type - any safe text</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin aperm -n mytestobject -O myoperation -d CreateNewPermission</li>
+        <li>admin aperm -n myobject2 -O myoperation2 -r trole1 -r trole5</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>uperm : UPDATE_PERM</h3>
+
+    <p>
+        This method will update permission operation pre-existing in target directory under
+        ou=Permissions,ou=RBAC,dc=yourHostName,dc=com container in directory information tree.
+        The perm operation entity may also contain Role or User associations to add or remove using this function.
+        The perm operation must exist before making this call. Only non-null attributes will be updated.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing object being targeted for the permission update</li>
+        <li>O : opName - contains the name of existing permission operation being updated</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>r : roles * - multi-occurring attribute contains RBAC Roles that permission operation is being granted to
+        </li>
+        <li>v : properties * - multi-occurring property key and values are separated with a ':'. e.g. mykey1:myvalue1
+        </li>
+        <li>T : type - any safe text</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin uperm -n myobject2 -O myoperation2 -r trole6 -D ReplaceExistingGrantsWithThisRole</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>dperm : DELETE_PERM</h3>
+
+    <p>
+        This method will remove permission operation entity from permission object. A Fortress permission is
+        PermObj*->Permission.
+        The perm operation must exist before making this call.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing object being targeted for the permission delete</li>
+        <li>O : opName - contains the name of existing permission operation that will be deleted</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin dperm -n mytestobject -O myoperation -d CreateNewPermission</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>grant : GRANT</h3>
+
+    <p>
+        This command grants a role the permission to perform an operation on an object to a role.
+        The command is implemented by granting permission by setting the access control list of the object involved.
+        The command is valid if and only if the pair (operation, object) represents a permission, and the role is a
+        member of the ROLES data set.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the object name</li>
+        <li>O : opName - contains the operation name</li>
+        <li>R : roleName - contains the role name</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin grant -n mytestobject -O myoperation -R trole1</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>revoke : REVOKE </h3>
+
+    <p>
+        This command revokes the permission to perform an operation on an object from the set
+        of permissions assigned to a role. The command is implemented by setting the access control
+        list of the object involved.
+        The command is valid if and only if the pair (operation, object) represents a permission,
+        the role is a member of the ROLES data set, and the permission is assigned to that role.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the object name</li>
+        <li>O : opName - contains the operation name</li>
+        <li>R : roleName - contains the role name</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>admin revoke -n mytestobject -O myoperation -R trole1</li>
+    </ul>
+</li>
+<br>
+
+</ol>
+</li>
+<li>
+
+<h3>Delegated Admin Commands</h3>
+
+<ol type="A">
+
+<li>
+    <h3>arole : Add a new ADMIN_Role</h3>
+
+    <p>
+        This command creates a new admin role. The command is valid if and only if the new admin role is not
+        already a member of the ADMIN ROLES data set. The ADMIN ROLES data set is updated.
+        Initially, no user or permission is assigned to the new role.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of the new AdminRole being targeted for addition to LDAP</li>
+    </ul>
+
+    <h4>optional parameters</h4>
+    <ul>
+        <li>d : description - contains any safe text</li>
+        <li>P : osPs * - multi-occurring attribute used to set associations to existing PERMS OrgUnits</li>
+        <li>U : osUs * - multi-occurring attribute used to set associations to existing USERS OrgUnits</li>
+        <li>x : beginRange - contains the name of an existing RBAC Role that represents the lowest role in hierarchy
+            that administrator (whoever has this AdminRole activated) controls
+        </li>
+        <li>w : endRange - contains the name of an existing RBAC Role that represents that highest role in hierarchy
+            that administrator may control
+        </li>
+        <li>y : beginInclusive - if 'true' the RBAC Role specified in beginRange is also controlled by the posessor of
+            this AdminRole
+        </li>
+        <li>z : endInclusive - if 'true' the RBAC Role specified in endRange is also controlled by the
+            administratrator
+        </li>
+        <li>b : beginTime - HHMM - determines begin hour adminRole may be activated into user's ARBAC session</li>
+        <li>e : endTime - HHMM - determines end hour adminRole may be activated into user's ARBAC session.</li>
+        <li>B : beginDate - YYYYMMDD - determines date when adminRole may be activated into user's ARBAC session</li>
+        <li>E : endDate - YYYYMMDD - indicates latest date adminRole may be activated into user's ARBAC session</li>
+        <li>l : beginLockDate - YYYYMMDD - determines beginning of enforced inactive status</li>
+        <li>N : endLockDate - YYYYMMDD - determines end of enforced inactive status</li>
+        <li>m : dayMask - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's
+            ARBAC session
+        </li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin arole -n arole1</li>
+        <li>dadmin arole -n arole2 -P app1 -P app2 -U dev1 -U dev2 -x role3 -w role1 -y true -z true -d
+            adminroledescription -b 0900 -e 1800 -B 20120101 -E 20990101 -m 1234567
+        </li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>urole : Update an existing ADMIN_Role</h3>
+
+    <p>
+        Method will update a admin Role entity in the directory. The role must exist in admin role container prior to
+        this call.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing AdminRole being targeted for update</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>d : description - contains any safe text</li>
+        <li>P : osPs * - multi-occurring attribute used to set associations to existing PERMS OrgUnits</li>
+        <li>U : osUs * - multi-occurring attribute used to set associations to existing USERS OrgUnits</li>
+        <li>x : beginRange - contains the name of an existing RBAC Role that represents the lowest role in hierarchy
+            that administrator (whoever has this AdminRole activated) controls
+        </li>
+        <li>w : endRange - contains the name of an existing RBAC Role that represents that highest role in hierarchy
+            that administrator may control
+        </li>
+        <li>y : beginInclusive - if 'true' the RBAC Role specified in beginRange is also controlled by the posessor of
+            this AdminRole
+        </li>
+        <li>z : endInclusive - if 'true' the RBAC Role specified in endRange is also controlled by the
+            administratrator
+        </li>
+        <li>b : beginTime - HHMM - determines begin hour adminRole may be activated into user's ARBAC session</li>
+        <li>e : endTime - HHMM - determines end hour adminRole may be activated into user's ARBAC session.</li>
+        <li>B : beginDate - YYYYMMDD - determines date when adminRole may be activated into user's ARBAC session</li>
+        <li>E : endDate - YYYYMMDD - indicates latest date adminRole may be activated into user's ARBAC session</li>
+        <li>l : beginLockDate - YYYYMMDD - determines beginning of enforced inactive status</li>
+        <li>N : endLockDate - YYYYMMDD - determines end of enforced inactive status</li>
+        <li>m : dayMask - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's
+            ARBAC session
+        </li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin urole -n arole1 -d updatedescription</li>
+        <li>dadmin urole -n arole2 -x role4 -w role1 -y true -z false</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>drole : Delete an ADMIN_Role</h3>
+
+    <p>
+        This command deletes an existing admin role from the ARBAC database. The command is valid
+        if and only if the admin role to be deleted is a member of the ADMIN ROLES data set and has been
+        deassigned from all users.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing AdminRole being targeted for deletion.</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin drole -n arole1</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>asgnrole : Assign an ADMIN_Role to a User</h3>
+
+    <p>
+        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>
+    <ul>
+        <li> timeout - number in seconds of session inactivity time allowed.
+        <li> beginDate - YYYYMMDD - determines date when role may be activated.
+        <li> endDate - YYYYMMDD - indicates latest date role may be activated.
+        <li> beginLockDate - YYYYMMDD - determines beginning of enforced inactive status
+        <li> endLockDate - YYYYMMDD - 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>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name for already existing AdminRole to be assigned</li>
+        <li>u : userId - contains the userId for existing User</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>b : beginTime - HHMM - determines begin hour AdminRole may be activated into user's RBAC session</li>
+        <li>e : endTime - HHMM - determines end hour AdminRole may be activated into user's RBAC session.</li>
+        <li>B : beginDate - YYYYMMDD - determines date when AdminRole may be activated into user's RBAC session</li>
+        <li>E : endDate - YYYYMMDD - indicates latest date AdminRole may be activated into user's RBAC session</li>
+        <li>l : beginLockDate - YYYYMMDD - determines beginning of enforced inactive status</li>
+        <li>N : endLockDate - YYYYMMDD - determines end of enforced inactive status</li>
+        <li>m : dayMask - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's
+            ARBAC session
+        </li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin asgnrole -u testuser2 -n arole1</li>
+        <li>dadmin asgnrole -u testuser2 -n arole2 -b 1200 -e 2359 -B 20120101 -E 20120131 -m 1234567</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>dsgnrole : Deassign a ADMIN_Role from a User</h3>
+
+    <p>
+        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.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name for already existing AdminRole to be deassigned</li>
+        <li>u : userId - contains the userId for existing User</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin dsgnrole -u testuser2 -n arole1</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>arel : ADD_ADMIN_ROLE_INHERITANCE</h3>
+
+        This commands establishes a new immediate inheritance relationship with parent orgunit <<-- child orgunit
+    <p>
+        The command is valid if and only if:
+    </p>
+    <ul>
+        <li> The parent and child are members of the ORGUNITS data set.
+        <li> The parent is not an immediate ascendant of child.
+        <li> The child does not properly inherit parent (in order to avoid cycle creation).
+    </ul>
+
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>A : ascendant - contains the name of parent AdminRole to be added as parent</li>
+        <li>D : descendant - contains the name of child AdminRole to be added as child</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin arel -A arole1 -D arole2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>drel : DELETE_ADMIN_ROLE_INHERITANCE</h3>
+
+        This command deletes an existing immediate inheritance relationship parent <<-- child.
+
+    <p>
+        The command is valid if and only if:
+    </p>
+    <ul>
+        <li> The orgunits parent and child are members of the ORGUNITS data set.
+        <li> The parent is an immediate ascendant of child.
+        <li> The new inheritance relation is computed as the reflexive-transitive closure of the immediate inheritance
+            relation resulted after deleting the relationship parent <<-- child.
+    </ul>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>A : ascendant - contains the name of parent AdminRole to be removed as parent</li>
+        <li>D : descendant - contains the name of child AdminRole to be removed as child</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin drel -A arole1 -D arole2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>auou : ADD_USERORG</h3>
+
+    <p>
+        Command adds a new USERS OrgUnit entity to OrgUnit dataset.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of new USERS OrgUnit to be added</li>
+        <li>d : description - contains any safe text</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin auou -n UserOrg1</li>
+        <li>dadmin auou -n UserOrg2 -d description-contains-any-safe-text</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>uuou : UPDATE_USERORG</h3>
+
+    <p>
+        Command updates a USERS OrgUnit entity to OrgUnit dataset.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing USERS OrgUnit to be updated</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>d : description - contains any safe text</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin uuou -n UserOrg2 -d updated-description-contains-any-safe-text</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>duou : DELETE_USERORG</h3>
+
+    <p>
+        Command removes an existing USERS OrgUnit entity from the OrgUnit dataset.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing USERS OrgUnit to be deleted</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin duou -n UserOrg1</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>aurel : ADD_USERORG_INHERITANCE</h3>
+
+        This commands establishes a new immediate inheritance relationship with parent USERS orgunit <<-- child orgunit
+    <p>
+        The command is valid if and only if:
+    </p>
+    <ul>
+        <li> The parent and child are members of the USERS ORGUNITS data set.
+        <li> The parent is not an immediate ascendant of child.
+        <li> The child does not properly inherit parent (in order to avoid cycle creation).
+    </ul>
+
+    <p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>A : ascendant - contains the name of existing USERS OrgUnit to be new parent</li>
+        <li>D : descendant - contains the name of existing USERS OrgUnit to be new child</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin aurel -A UserOrg1 -D UserOrg2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>durel : DELETE_USERORG_INHERITANCE</h3>
+        This command deletes an existing immediate inheritance relationship parent <<-- child.
+
+    <p>
+        The command is valid if and only if:
+    </p>
+    <ul>
+        <li> The orgunits parent and child are members of the USERS ORGUNITS data set.
+        <li> The parent is an immediate ascendant of child.
+        <li> The new inheritance relation is computed as the reflexive-transitive closure of the immediate inheritance
+            relation resulted after deleting the relationship parent <<-- child.
+    </ul>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>A : ascendant - contains the name of existing USERS OrgUnit to be removed as parent</li>
+        <li>D : descendant - contains the name of existing USERS OrgUnit to be removed as child</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin durel -A UserOrg1 -D UserOrg2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>apou : ADD_PERMORG</h3>
+
+    <p>
+        Command adds a new PERMS OrgUnit entity to OrgUnit dataset.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of new existing PERMS OrgUnit to be added</li>
+        <li>d : description - contains any safe text</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin apou -n PermOrg1</li>
+        <li>dadmin apou -n PermOrg2 -d description-contains-any-safe-text</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>upou : UPDATE_PERMORG</h3>
+
+    <p>
+        Command updates a PERMS OrgUnit entity to OrgUnit dataset.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing PERMS OrgUnit to be updated</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>d : description - contains any safe text</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin upou -n PermOrg1 -d description-contains-any-safe-text</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>dpou : DELETE_PERMORG</h3>
+
+    <p>
+        Command removes an existing PERMS OrgUnit entity from the OrgUnit dataset.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing PERMS OrgUnit to be deleted</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin dpou -n PermOrg2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>aprel : ADD_PERMORG_INHERITANCE</h3>
+
+        This commands establishes a new immediate inheritance relationship with parent PERMS orgunit <<-- child orgunit
+
+    <p>
+        The command is valid if and only if:
+    </p>
+    <ul>
+        <li> The parent and child are members of the USERS ORGUNITS data set.
+        <li> The parent is not an immediate ascendant of child.
+        <li> The child does not properly inherit parent (in order to avoid cycle creation).
+    </ul>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>A : ascendant - contains the name of existing PERMS OrgUnit to be new parent</li>
+        <li>D : descendant - contains the name of existing PERMS OrgUnit to be new child</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin aprel -A PermOrg1 -D PermOrg2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>dprel : DELETE_PERMORG_INHERITANCE</h3>
+
+        This command deletes an existing immediate inheritance relationship parent <<-- child.
+    <p>
+        The command is valid if and only if:
+    </p>
+    <ul>
+        <li> The orgunits parent and child are members of the PERMS ORGUNITS data set.
+        <li> The parent is an immediate ascendant of child.
+        <li> The new inheritance relation is computed as the reflexive-transitive closure of the immediate inheritance
+            relation resulted after deleting the relationship parent <<-- child.
+    </ul>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>A : ascendant - contains the name of existing PERMS OrgUnit to be removed as parent</li>
+        <li>D : descendant - contains the name of existing PERMS OrgUnit to be removed as child</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin dprel -A PermOrg1 -D PermOrg2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>aobj : ADD_ADMIN_POBJ</h3>
+
+    <p>
+        This method will add administrative permission object to perms container in directory. The perm object must not
+        exist before making this call.
+        A PermObj instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap
+        tree: PermObj*->Permission.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of new administrative object being added</li>
+        <li>o : orgUnit - contains the name of an existing PERMS OrgUnit this administrative object is associated with
+        </li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>d : description - contains safe text</li>
+        <li>T : type - any safe text</li>
+        <li>v : properties * - multi-occurring property key and values are separated with a ':'. e.g. mykey1:myvalue1
+        </li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin aobj -n mytestobject -o app1</li>
+        <li>dadmin aobj -n myobject2 -o app1 -d TestObject -t anything -v key1:val1 -v key2:val2</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>uobj : UPDATE_ADMIN_POBJ</h3>
+
+    <p>
+        This method will update an administrative permission object in perms container in directory. The perm object
+        must exist before making this call.
+        A PermObj instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap
+        tree: PermObj*->Permission.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing administrative object being targeted for update</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>o : orgUnit - contains the name of existing PERMS OrgUnit to associate administrative object with</li>
+        <li>d : description - contains any safe text</li>
+        <li>T : type - any safe text</li>
+        <li>v : properties * - multi-occurring property key and values are separated with a ':'. e.g. mykey1:myvalue1
+        </li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin uobj -n mytestobject -o app2 -d ChangedOrgUnit</li>
+        <li>dadmin uobj -n myobject2 -o app1 -d ChangeDescription</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>dobj : DELETE_POBJ</h3>
+
+    <p>
+        This method will remove an administrative permission object to perms container in directory. This method will
+        also remove
+        in associated permission objects that are attached to this object.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing administrative object being targeted for delete</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin dobj -n mytestobject -o app1</li>
+    </ul>
+</li>
+<br>
+<li>
+    <h3>aperm : ADD_ADMIN_PERM</h3>
+
+    <p>
+        This method will add an administrative permission operation to an existing permission object which resides under
+        ou=AdminPermis,ou=ARBAC,dc=yourHostName,dc=com container in directory information tree.
+        The perm operation entity may have AdminRole or User associations. The target Permission must not exist prior to
+        calling.
+        A Fortress Administrative Permission instance exists in a hierarchical, one-many relationship between its parent
+        and itself as stored in ldap tree: PermObj*->Permission.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing administrative object being targeted for the permission add</li>
+        <li>O : opName - contains the name of new administrative permission operation being added</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>v : properties * - multi-occurring property key and values are separated with a ':'. e.g. mykey1:myvalue1
+        </li>
+        <li>T : type - any safe text</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin aperm -n mytestobject -O myoperation -d CreateNewAdminPermission</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>uperm : UPDATE_ADMIN_PERM</h3>
+
+    <p>
+        This method will update an administrative permission operation pre-existing in target directory under
+        ou=AdminPermis,ou=ARBAC,dc=yourHostName,dc=com container in directory information tree.
+        The perm operation entity may also contain AdminRole or User associations to add or remove using this function.
+        The perm operation must exist before making this call. Only non-null attributes will be updated.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing administrative object being targeted for the permission update</li>
+        <li>O : opName - contains the name of existing administrative permission operation being updated</li>
+    </ul>
+    <h4>optional parameters</h4>
+    <ul>
+        <li>v : properties * - multi-occurring property key and values are separated with a ':'. e.g. mykey1:myvalue1
+        </li>
+        <li>T : type - any safe text</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin uperm -n mytestobject -O myoperation -d new-description</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>dperm : DELETE_ADMIN_PERM</h3>
+
+    <p>
+        This method will remove an administrative permission operation entity from permission object. A Fortress
+        administrative permission is PermObj*->Permission.
+        The perm operation must exist before making this call.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the name of existing administrative object being targeted for the permission delete</li>
+        <li>O : opName - contains the name of existing administrative permission operation that will be deleted</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin dperm -n mytestobject -O myoperation -d CreateNewAdminPermission</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>grant : GRANT ADMIN</h3>
+
+    <p>
+        This command grants an adminRole the administrative permission to perform an operation on an object to a role.
+        The command is implemented by granting permission by setting the access control list of the object involved.
+        The command is valid if and only if the pair (operation, object) represents a permission, and the role is a
+        member of the ADMIN_ROLES data set.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the administrative object name</li>
+        <li>O : opName - contains the administrative operation name</li>
+        <li>R : roleName - contains the adminRole name</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin grant -n mytestobject -O myoperation -R arole1</li>
+    </ul>
+</li>
+<br>
+
+<li>
+    <h3>revoke : REVOKE ADMIN</h3>
+
+    <p>
+        This command revokes the permission to perform an operation on an object from the set
+        of permissions assigned to an adminRole. The command is implemented by setting the access control
+        list of the object involved.
+        The command is valid if and only if the pair (operation, object) represents a permission,
+        the role is a member of the ADMIN_ROLES data set, and the permission is assigned to that role.
+    </p>
+
+    <h4>required parameters</h4>
+    <ul>
+        <li>n : name - contains the administrative object name</li>
+        <li>O : opName - contains the administrative operation name</li>
+        <li>R : roleName - contains the adminRole name</li>
+    </ul>
+    <h4>example</h4>
+    <ul>
+        <li>dadmin revoke -n mytestobject -O myoperation -R arole1</li>
+    </ul>
+</li>
+<br>
+</ol>
+
+</li>
+<li>
+
+    <h3>Review Commands</h3>
+
+    <ol type="A">
+        <li>
+            <h3>ruser : READ_USER</h3>
+
+            <p>
+                This function reads a User object from the directory. The userId is not case sensitive.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>u : userId - maps to INetOrgPerson uid</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>review ruser -u testuser1</li>
+            </ul>
+        </li>
+        <br>
+
+        <li>
+            <h3>fuser : FIND_USERS</h3>
+
+                This function searches for matching users on the userId field. It uses a search filter of:
+<pre>
+ String filter = "(&(objectclass=" + objectClassImpl + ")(" + GlobalIds.UID + "=" + searchVal + "*))";
+</pre>
+            which will return all Users that match the leading characters of the search field which is case insensitive.
+            This logs the results using log4j to allow output to be logged to console or file.
+
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>u : userId - contains the leading characters that map to INetOrgPerson uid field in LDAP</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>review fuser -u test</li>
+            </ul>
+        </li>
+        <br>
+
+        <li>
+            <h3>asgnuser : ASSIGNED_USERS</h3>
+
+            <p>
+                This function returns all Users who are assigned a particular Role.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the name for already existing RBAC Role</li>
+            </ul>
+            <h4>example</h4>
+            Return all Users who are assigned an RBAC role named 'role1'.
+            <ul>
+                <li>review asgnuser -n -role1</li>
+            </ul>
+        </li>
+        <br>
+
+        <li>
+            <h3>rrole : READ_ROLE</h3>
+
+            <p>
+                This function reads a Role object from the directory. The Role name is not case sensitive.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the name for already existing RBAC Role</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>review rrole -n role1</li>
+            </ul>
+        </li>
+        <br>
+
+        <li>
+            <h3>frole : FIND_ROLES</h3>
+
+            <p>
+                This function searches for matching Roles on the name field. It will return all Roles that match the
+                leading characters of the search field which is case insensitive. This logs the results using log4j to
+                allow output to be logged to console or file.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains all or some of the leading characters to a matching set of Roles in the
+                    directory
+                </li>
+            </ul>
+            <h4>example</h4>
+            Return all Roles where the name begins with the characters 'role':
+            <ul>
+                <li>review frole -n role</li>
+            </ul>
+        </li>
+        <br>
+
+        <li>
+            <h3>robj : READ_POBJ</h3>
+
+            <p>
+                This function reads a Permission Object from the directory. The object name is not case sensitive.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the name for already existing RBAC PermObj</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>review robj -n mytestobject</li>
+            </ul>
+        </li>
+        <br>
+
+        <li>
+            <h3>fobj : FIND_POBJS</h3>
+
+            <p>
+                This function searches for matching Permission Objects on the name field. It will return all PermObjs
+                that match the leading characters of the search field which is case insensitive. This logs the results
+                using log4j to allow output to be logged to console or file.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains all or some of the leading characters to a matching set of Permission Objects in
+                    the directory
+                </li>
+            </ul>
+            <h4>example</h4>
+            Return all PermObjs where the name begins with the characters 'my':
+            <ul>
+                <li>review robj -n my</li>
+            </ul>
+        </li>
+        <br>
+
+        <li>
+            <h3>rperm : READ_PERM</h3>
+
+            <p>
+                This function reads a Permission Operation from the directory. The permission object and operation names
+                are not case sensitive.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the name of existing object being targeted for the query</li>
+                <li>O : opName - contains the name of permission operation being targeted for the query</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>review rperm -n mytestobject -O myoperation</li>
+            </ul>
+        </li>
+        <br>
+
+        <li>
+            <h3>fperm : FIND_PERMS</h3>
+
+            <p>
+                This function searches for matching Permission Operations on the name fields of the Permission Object
+                and Operation attributes. It will return all Permissions that match the leading characters of the search
+                fields which are not case insensitive. This logs the results using log4j to allow output to be logged to
+                console or file.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains all or some of the leading characters of the set of existing objects being
+                    targeted for the query
+                </li>
+                <li>O : opName - contains all or some of the leading characters of the set of permission operations
+                    (that correpond with the result set of PermObjs) being targeted for the query
+                </li>
+            </ul>
+            <h4>example</h4>
+            Return all Permissions where the Object name begins with name field 'mytest' and Operation name begins with
+            the characters 'my':
+            <ul>
+                <li>review fperm -n mytest -O my</li>
+            </ul>
+        </li>
+        <br>
+
+    </ol>
+</li>
+
+<li>
+
+    <h3>Group Commands</h3>
+
+    <ol type="A">
+
+        <li>
+            <h3>agroup : ADD_GROUP</h3>
+
+            <p>
+                This function adds a new LDAP group to the directory.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the name to use for new LDAP group.  It must be unique.</li>
+                <li>M : members * - multi-occurring attribute (must include at least one) - maps to userId in LDAP directory"</li>
+            </ul>
+            <h4>optional parameters</h4>
+            <ul>
+                <li>d : description - maps to description attribute on object class</li>
+                <li>X : protocol - used to specify protocol</li>
+                <li>v : properties * - multi-occurring attribute contains property key and values are separated with a '='.  e.g.: key1=val1</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>group agroup -n footest1 -d "Test LDAP Groups 001" -M demouser4 -v key1=val1 -v key2=val2 -X ssh</li>
+                <li>group agroup -n footest2 -d "Test LDAP Groups 001" -M demouser5 -M demouser6 -v key3=val3 -v key4=val4 -X rdp</li>
+            </ul>
+        </li>
+
+
+        <li>
+            <h3>ugroup : UPDATE_GROUP</h3>
+
+            <p>
+                Modify existing group node.  The name is required.  Does not update members or properties.
+                Use ASSIGN_GROUP, DEASSIGN_GROUP, ADD_GROUP_PROP or DEL_GROUP_PROP for multi-occurring attributes.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the name of an existing LDAP group.</li>
+            </ul>
+            <h4>optional parameters</h4>
+            <ul>
+                <li>M : members * - multi-occurring attribute maps to a userId in the LDAP directory"</li>
+                <li>d : description - maps to description attribute on object class</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>group ugroup -n footest1 -d "Update Test LDAP Groups 001" -X ssh2</li>
+            </ul>
+        </li>
+
+
+        <li>
+            <h3>dgroup : DELETE_GROUP</h3>
+
+            <p>
+                This function removes an LDAP group from the directory.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the name of an existing LDAP group.</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>group dgroup -n footest1</li>
+            </ul>
+        </li>
+
+
+        <li>
+            <h3>asgngroup : ASSIGN_GROUP</h3>
+
+            <p>
+                This function adds a user as a member to an existing LDAP group in the directory.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the name of an existing LDAP group.</li>
+                <li>M : members * - multi-occurring attribute (must include at least one) - maps to userId in LDAP directory"</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>group asgngroup -n footest1 -M demouser5</li>
+            </ul>
+        </li>
+
+        <li>
+            <h3>dsgngroup : DEASSIGN_GROUP</h3>
+
+            <p>
+                This function removes a user as a member from an existing LDAP group in the directory.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the name of an existing LDAP group.</li>
+                <li>M : members * - multi-occurring attribute (must include at least one) - maps to userId in LDAP directory"</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>group dsgngroup -n footest1 -M demouser5</li>
+            </ul>
+        </li>
+
+        <li>
+            <h3>agprop : ADD_GROUP_PROP</h3>
+
+            <p>
+                This function adds one or more properties to an existing LDAP group.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the name of an existing LDAP group.</li>
+                <li>v : properties * - multi-occurring property key and values are separated with a '='. e.g. mykey1=myvalue1</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>group agprop -n footest1 -v key5=val5</li>
+            </ul>
+        </li>
+
+        <li>
+            <h3>dgprop : DEL_GROUP_PROP</h3>
+
+            <p>
+                This function removes one or more properties from an existing LDAP group.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the name of an existing LDAP group.</li>
+                <li>v : properties * - multi-occurring property key and values are separated with a '='. e.g. mykey1=myvalue1</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>group dgprop -n footest1 -v key5=val5</li>
+            </ul>
+        </li>
+
+        <li>
+            <h3>rgroup : READ_GROUP</h3>
+
+            <p>
+                This function reads and displays to console an existing LDAP group. The Group name is not case sensitive.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the full name for already existing Group</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>group fgroup -n footest1</li>
+            </ul>
+        </li>
+
+        <li>
+            <h3>fgroup : FIND_GROUPS</h3>
+
+            <p>
+                This function searches and displays to console existing LDAP groups found as target of search. The Group name is not case sensitive.
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li>n : name - contains the full name for already existing Group</li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li>group fgroup -n fo</li>
+            </ul>
+        </li>
+
+        <br>
+    </ol>
+    <!-- end group -->
+</li>
+
+
+<li>
+
+    <h3>System Commands</h3>
+
+    <ol type="A">
+        <li>
+            <h3>createsession : CREATE_SESSION</h3>
+
+            <p>
+
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+            <h4>optional parameters</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+        </li>
+        <br>
+
+        <li>
+            <h3>authenticate : AUTHENTICATE</h3>
+
+            <p>
+
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+            <h4>optional parameters</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+        </li>
+        <br>
+
+        <li>
+            <h3>assignedroles : ASSIGNED_ROLES</h3>
+
+            <p>
+
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+            <h4>optional parameters</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+        </li>
+        <br>
+
+        <li>
+            <h3>checkaccess : CHECK_ACCESS</h3>
+
+            <p>
+
+            </p>
+
+            <h4>required parameters</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+            <h4>optional parameters</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+            <h4>example</h4>
+            <ul>
+                <li></li>
+                <li></li>
+            </ul>
+        </li>
+        <br>
+    </ol>
+</li>
+<p>
+    The <b>org.apache.directory.fortress.cli.CommandLineInterpreter</b> drives the Fortress APIs. For more info on how the Fortress
+    APIs work, check out Fortress SDK Javadoc.
+</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/doc-files/ARbac.png
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/doc-files/ARbac.png b/src/main/java/org/apache/directory/fortress/core/doc-files/ARbac.png
new file mode 100755
index 0000000..21c6900
Binary files /dev/null and b/src/main/java/org/apache/directory/fortress/core/doc-files/ARbac.png differ

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/doc-files/Audit.png
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/doc-files/Audit.png b/src/main/java/org/apache/directory/fortress/core/doc-files/Audit.png
new file mode 100755
index 0000000..474bbc0
Binary files /dev/null and b/src/main/java/org/apache/directory/fortress/core/doc-files/Audit.png differ

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/doc-files/PasswordPolicy.png
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/doc-files/PasswordPolicy.png b/src/main/java/org/apache/directory/fortress/core/doc-files/PasswordPolicy.png
new file mode 100755
index 0000000..f793d70
Binary files /dev/null and b/src/main/java/org/apache/directory/fortress/core/doc-files/PasswordPolicy.png differ

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/doc-files/RbacCore.png
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/doc-files/RbacCore.png b/src/main/java/org/apache/directory/fortress/core/doc-files/RbacCore.png
new file mode 100644
index 0000000..fdc858a
Binary files /dev/null and b/src/main/java/org/apache/directory/fortress/core/doc-files/RbacCore.png differ

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/doc-files/RbacCorex.png
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/doc-files/RbacCorex.png b/src/main/java/org/apache/directory/fortress/core/doc-files/RbacCorex.png
new file mode 100755
index 0000000..82ad224
Binary files /dev/null and b/src/main/java/org/apache/directory/fortress/core/doc-files/RbacCorex.png differ

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/doc-files/RbacDSD.png
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/doc-files/RbacDSD.png b/src/main/java/org/apache/directory/fortress/core/doc-files/RbacDSD.png
new file mode 100644
index 0000000..80e7360
Binary files /dev/null and b/src/main/java/org/apache/directory/fortress/core/doc-files/RbacDSD.png differ

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/doc-files/RbacHier.png
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/doc-files/RbacHier.png b/src/main/java/org/apache/directory/fortress/core/doc-files/RbacHier.png
new file mode 100644
index 0000000..7a085a4
Binary files /dev/null and b/src/main/java/org/apache/directory/fortress/core/doc-files/RbacHier.png differ

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/doc-files/RbacSSD.png
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/doc-files/RbacSSD.png b/src/main/java/org/apache/directory/fortress/core/doc-files/RbacSSD.png
new file mode 100644
index 0000000..e96fb4b
Binary files /dev/null and b/src/main/java/org/apache/directory/fortress/core/doc-files/RbacSSD.png differ

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/doc-files/TemporalRbac.png
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/doc-files/TemporalRbac.png b/src/main/java/org/apache/directory/fortress/core/doc-files/TemporalRbac.png
new file mode 100755
index 0000000..148e120
Binary files /dev/null and b/src/main/java/org/apache/directory/fortress/core/doc-files/TemporalRbac.png differ


[29/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/AuditP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AuditP.java b/src/main/java/org/apache/directory/fortress/core/rbac/AuditP.java
new file mode 100755
index 0000000..fd4a8ee
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AuditP.java
@@ -0,0 +1,150 @@
+/*
+ *   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 org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.dao.unboundid.AuditDAO;
+
+
+/**
+ * This class is process layer for Fortress audit data.  It performs data validation
+ * and data mapping functions.
+ * Process module for the for Fortress audit data.  It performs data validation and data mapping functions.
+ * The audit data is passed using {@link org.apache.directory.fortress.core.rbac.AuthZ} class.  This class does perform simple data validations to ensure data reasonability and
+ * the required fields are present..<BR>
+ * The methods in this class are called by {@link AuditMgrImpl} methods during audit log interrogations.
+ * <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 exception {@link org.apache.directory.fortress.core.FinderException},
+ * 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 performs simple data validations.
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+public final class AuditP
+{
+    private static final AuditDAO aDao = new AuditDAO();
+
+
+    /**
+     * Package private constructor
+     */
+    AuditP()
+    {
+    }
+
+
+    /**
+     * This method returns a list of authorization events for a particular user {@link UserAudit#userId}
+     * and given timestamp field {@link UserAudit#beginDate}.<BR>
+     * Method also can discriminate between all events or failed only by setting {@link UserAudit#failedOnly}.
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one authorization event.
+     * @throws SecurityException if a runtime system error occurs.
+     */
+    final List<AuthZ> getAuthZs( UserAudit uAudit ) throws SecurityException
+    {
+        return aDao.getAllAuthZs( uAudit );
+    }
+
+
+    /**
+     * This method returns a list of authorization events for a particular user {@link UserAudit#userId},
+     * object {@link UserAudit#objName}, and given timestamp field {@link UserAudit#beginDate}.<BR>
+     * Method also can discriminate between all events or failed only by setting flag {@link UserAudit#failedOnly}..
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one authorization event.
+     * @throws SecurityException if a runtime system error occurs.
+     */
+    final List<AuthZ> searchAuthZs( UserAudit uAudit ) throws SecurityException
+    {
+        return aDao.searchAuthZs( uAudit );
+    }
+
+
+    /**
+     * This method returns a list of authentication audit events for a particular user {@link UserAudit#userId},
+     * and given timestamp field {@link UserAudit#beginDate}.<BR>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type Bind.  Each Bind object contains one bind event.
+     * @throws SecurityException if a runtime system error occurs.
+     */
+    final List<Bind> searchBinds( UserAudit uAudit ) throws SecurityException
+    {
+        return aDao.searchBinds( uAudit );
+    }
+
+
+    /**
+     * This method returns a list of sessions created for a given user {@link UserAudit#userId},
+     * and timestamp {@link UserAudit#beginDate}.<BR>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one authorization event.
+     * @throws SecurityException if a runtime system error occurs.
+     */
+    final List<Mod> searchUserMods( UserAudit uAudit ) throws SecurityException
+    {
+        return aDao.searchUserMods( uAudit );
+    }
+
+
+    /**
+     * This method returns a list of admin operations events for a particular entity {@link UserAudit#dn},
+     * object {@link UserAudit#objName} and timestamp {@link UserAudit#beginDate}.  If the internal
+     * userId {@link UserAudit#internalUserId} is set it will limit search by that field.
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one authorization event.
+     * @throws SecurityException if a runtime system error occurs.
+     */
+    final List<Mod> searchAdminMods( UserAudit uAudit ) throws SecurityException
+    {
+        return aDao.searchAdminMods( uAudit );
+    }
+
+
+    /**
+     * This method returns a list of failed authentication events for a particular invalid user {@link UserAudit#userId},
+     * and given timestamp {@link UserAudit#beginDate}.  If the {@link UserAudit#failedOnly} is true it will
+     * return only authentication attempts made with invalid userId.
+     * </p>
+     * This is possible because Fortress performs read on user before the bind.
+     * </p>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one failed authentication event.
+     * @throws SecurityException if a runtime system error occurs.
+     */
+    final List<AuthZ> searchInvalidAuthNs( UserAudit uAudit ) throws SecurityException
+    {
+        return aDao.searchInvalidAuthNs( uAudit );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/AuthZ.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AuthZ.java b/src/main/java/org/apache/directory/fortress/core/rbac/AuthZ.java
new file mode 100755
index 0000000..b4ffe16
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AuthZ.java
@@ -0,0 +1,769 @@
+/*
+ *   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.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import java.io.Serializable;
+
+/**
+ * This entity class contains OpenLDAP slapo-accesslog records that correspond to authorization attempts made to the directory.
+ * <p/>
+ * The auditCompare Structural object class is used by the slapo-accesslog overlay to store record of fortress authorization events.
+ * These events can later be pulled as audit trail using ldap protocol.  The data pertaining to authZ events are stored in this entity record.<br/>
+ * <p/>
+ * <pre>
+ * ------------------------------------------
+ * objectclass (  1.3.6.1.4.1.4203.666.11.5.2.7
+ * NAME 'auditCompare'
+ * DESC 'Compare operation'
+ * SUP auditObject STRUCTURAL
+ * MUST reqAssertion )
+ * ------------------------------------------
+ * </pre>
+ * For the Compare operation the reqAssertion attribute carries the Attribute Value Assertion used in the compare request
+ * <p/>
+ * Note this class uses descriptions pulled from man pages on slapo-accesslog.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortAuthZ")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "authZ", propOrder = {
+    "createTimestamp",
+    "creatorsName",
+    "entryCSN",
+    "entryDN",
+    "entryUUID",
+    "hasSubordinates",
+    "modifiersName",
+    "modifyTimestamp",
+    "objectClass",
+    "reqAttr",
+    "reqAttrsOnly",
+    "reqAuthzID",
+    "reqControls",
+    "reqDN",
+    "reqDerefAliases",
+    "reqEnd",
+    "reqEntries",
+    "reqFilter",
+    "reqResult",
+    "reqScope",
+    "reqSession",
+    "reqSizeLimit",
+    "reqStart",
+    "reqTimeLimit",
+    "reqType",
+    "reqAssertion",
+    "structuralObjectClass",
+    "subschemaSubentry",
+    "sequenceId"
+})
+public class AuthZ extends FortEntity implements Serializable
+{
+    private String createTimestamp;
+    private String creatorsName;
+    private String entryCSN;
+    private String entryDN;
+    private String entryUUID;
+    private String hasSubordinates;
+    private String modifiersName;
+    private String modifyTimestamp;
+    private String objectClass;
+    private String reqAttr;
+    private String reqAttrsOnly;
+    private String reqAuthzID;
+    private String reqControls;
+    private String reqDN;
+    private String reqDerefAliases;
+    private String reqEnd;
+    private String reqEntries;
+    private String reqFilter;
+    private String reqResult;
+    private String reqScope;
+    private String reqSession;
+    private String reqSizeLimit;
+    private String reqStart;
+    private String reqTimeLimit;
+    private String reqType;
+    private String reqAssertion;
+    private String structuralObjectClass;
+    private String subschemaSubentry;
+    private long sequenceId;
+
+    /**
+     * Get the attribute that maps to 'reqStart' which provides the start time of the operation which is also the rDn for the node.
+     * These time attributes use generalizedTime syntax. The reqStart attribute is also used as the RDN for each log entry.
+     *
+     * @return attribute that maps to 'reqStart' in 'auditSearch' object class.
+     */
+    public String getCreateTimestamp()
+    {
+        return createTimestamp;
+    }
+
+    /**
+     * Set the attribute that maps to 'reqStart' which provides the start time of the operation which is also the rDn for the node.
+     * These time attributes use generalizedTime syntax. The reqStart attribute is also used as the RDN for each log entry.
+     *
+     * @param createTimestamp attribute that maps to 'reqStart' in 'auditSearch' object class.
+     */
+    public void setCreateTimestamp(String createTimestamp)
+    {
+        this.createTimestamp = createTimestamp;
+    }
+
+    /**
+     * Return the user dn containing the identity of log user who added the audit record.  This will be the system user that
+     * is configured for performing slapd access log operations on behalf of Fortress.
+     * The config property name {@link org.apache.directory.fortress.ldap.PoolMgr#LDAP_LOG_POOL_UID} contains the audit log system user id.
+     *
+     * @return value that maps to 'creatorsName' attribute on 'auditSearch' object class.
+     */
+    public String getCreatorsName()
+    {
+        return creatorsName;
+    }
+
+    /**
+     * Set the user dn containing the identity of log user who added the audit record.  This will be the system user that
+     * is configured for performing slapd access log operations on behalf of Fortress.
+     * The config property name {@link org.apache.directory.fortress.ldap.PoolMgr#LDAP_LOG_POOL_UID} contains the audit log system user id.
+     *
+     * @param creatorsName maps to 'creatorsName' attribute on 'auditSearch' object class.
+     */
+    public void setCreatorsName(String creatorsName)
+    {
+        this.creatorsName = creatorsName;
+    }
+
+    /**
+     * Return the Change Sequence Number (CSN) containing sequence number that is used for OpenLDAP synch replication functionality.
+     *
+     * @return attribute that maps to 'entryCSN' on 'auditSearch' object class.
+     */
+    public String getEntryCSN()
+    {
+        return entryCSN;
+    }
+
+    /**
+     * Set the Change Sequence Number (CSN) containing sequence number that is used for OpenLDAP synch replication functionality.
+     *
+     * @param entryCSN maps to 'entryCSN' attribute on 'auditSearch' object class.
+     */
+    public void setEntryCSN(String entryCSN)
+    {
+        this.entryCSN = entryCSN;
+    }
+
+    /**
+     * Get the entry dn for bind object stored in directory.  This attribute uses the 'reqStart' along with suffix for log.
+     *
+     * @return attribute that maps to 'entryDN' on 'auditSearch' object class.
+     */
+    public String getEntryDN()
+    {
+        return entryDN;
+    }
+
+    /**
+     * Set the entry dn for bind object stored in directory.  This attribute uses the 'reqStart' along with suffix for log.
+     *
+     * @param entryDN attribute that maps to 'entryDN' on 'auditSearch' object class.
+     */
+    public void setEntryDN(String entryDN)
+    {
+        this.entryDN = entryDN;
+    }
+
+    /**
+     * Get the attribute that contains the Universally Unique ID (UUID) of the corresponding 'auditSearch' record.
+     *
+     * @return value that maps to 'entryUUID' attribute on 'auditSearch' object class.
+     */
+    public String getEntryUUID()
+    {
+        return entryUUID;
+    }
+
+    /**
+     * Set the attribute that contains the Universally Unique ID (UUID) of the corresponding 'auditSearch' record.
+     *
+     * @param entryUUID that maps to 'entryUUID' attribute on 'auditSearch' object class.
+     */
+    public void setEntryUUID(String entryUUID)
+    {
+        this.entryUUID = entryUUID;
+    }
+
+    /**
+     * Get the attribute that corresponds to the boolean value hasSubordinates.
+     *
+     * @return value that maps to 'hasSubordinates' attribute on 'auditSearch' object class.
+     */
+    public String getHasSubordinates()
+    {
+        return hasSubordinates;
+    }
+
+    /**
+     * Set the attribute that corresponds to the boolean value hasSubordinates.
+     *
+     * @param hasSubordinates maps to same name on 'auditSearch' object class.
+     */
+    public void setHasSubordinates(String hasSubordinates)
+    {
+        this.hasSubordinates = hasSubordinates;
+    }
+
+    /**
+     * Return the user dn containing the identity of log user who last modified the audit record.  This will be the system user that
+     * is configured for performing slapd access log operations on behalf of Fortress.
+     * The config property name {@link org.apache.directory.fortress.ldap.PoolMgr#LDAP_LOG_POOL_UID} contains the audit log system user id.
+     *
+     * @return value that maps to 'modifiersName' attribute on 'auditSearch' object class.
+     */
+    public String getModifiersName()
+    {
+        return modifiersName;
+    }
+
+    /**
+     * Set the user dn containing the identity of log user who modified the audit record.  This will be the system user that
+     * is configured for performing slapd access log operations on behalf of Fortress.
+     * The config property name {@link org.apache.directory.fortress.ldap.PoolMgr#LDAP_LOG_POOL_UID} contains the audit log system user id.
+     *
+     * @param modifiersName maps to 'modifiersName' attribute on 'auditSearch' object class.
+     */
+    public void setModifiersName(String modifiersName)
+    {
+        this.modifiersName = modifiersName;
+    }
+
+    /**
+     * Get the attribute that maps to 'modifyTimestamp' which provides the last time audit record was changed.
+     * The time attributes use generalizedTime syntax.
+     *
+     * @return attribute that maps to 'modifyTimestamp' in 'auditSearch' object class.
+     */
+    public String getModifyTimestamp()
+    {
+        return modifyTimestamp;
+    }
+
+    /**
+     * Set the attribute that maps to 'modifyTimestamp' which provides the last time audit record was changed.
+     * The time attributes use generalizedTime syntax.
+     *
+     * @param modifyTimestamp attribute that maps to same name in 'auditSearch' object class.
+     */
+    public void setModifyTimestamp(String modifyTimestamp)
+    {
+        this.modifyTimestamp = modifyTimestamp;
+    }
+
+    /**
+     * Get the object class name of the audit record.  For this entity, this value will always be 'auditSearch'.
+     *
+     * @return value that maps to 'objectClass' attribute on 'auditSearch' obejct class.
+     */
+    public String getObjectClass()
+    {
+        return objectClass;
+    }
+
+    /**
+     * Set the object class name of the audit record.  For this entity, this value will always be 'auditSearch'.
+     *
+     * @param objectClass value that maps to same name on 'auditSearch' obejct class.
+     */
+    public void setObjectClass(String objectClass)
+    {
+        this.objectClass = objectClass;
+    }
+
+    /**
+     * The  reqAuthzID  attribute  is  the  distinguishedName of the user that
+     * performed the operation.  This will usually be the  same  name  as  was
+     * established  at  the  start of a session by a Bind request (if any) but
+     * may be altered in various circumstances.
+     * For Fortress bind operations this will map to {@link org.apache.directory.fortress.core.rbac.User#userId}
+     *
+     * @return value that maps to 'reqAuthzID' on 'auditSearch' object class.
+     */
+    public String getReqAuthzID()
+    {
+        return reqAuthzID;
+    }
+
+    /**
+     * The  reqAuthzID  attribute  is  the  distinguishedName of the user that
+     * performed the operation.  This will usually be the  same  name  as  was
+     * established  at  the  start of a session by a Bind request (if any) but
+     * may be altered in various circumstances.
+     * For Fortress bind operations this will map to {@link org.apache.directory.fortress.core.rbac.User#userId}
+     *
+     */
+    public void setReqAuthzID(String reqAuthzID)
+    {
+        this.reqAuthzID = reqAuthzID;
+    }
+
+    /**
+     * The reqControls and reqRespControls attributes carry any controls  sent
+     * by  the  client  on  the  request  and  returned  by  the server in the
+     * response, respectively. The attribute  values  are  just  uninterpreted
+     * octet strings.
+     *
+     * @return value that maps to 'reqControls' attribute on 'auditSearch' object class.
+     */
+    public String getReqControls()
+    {
+        return reqControls;
+    }
+
+    /**
+     * The reqControls and reqRespControls attributes carry any controls  sent
+     * by  the  client  on  the  request  and  returned  by  the server in the
+     * response, respectively. The attribute  values  are  just  uninterpreted
+     * octet strings.
+     *
+     * @param reqControls maps to same name attribute on 'auditSearch' object class.
+     */
+    public void setReqControls(String reqControls)
+    {
+        this.reqControls = reqControls;
+    }
+
+    /**
+     * The reqDN attribute is the  distinguishedName  of  the  target  of  the
+     * operation.  E.g.,  for  a Bind request, this is the Bind DN. For an Add
+     * request, this is the DN of the entry being added. For a Search request,
+     * this is the base DN of the search.
+     *
+     * @return value that map to 'reqDN' attribute on 'auditSearch' object class.
+     */
+    public String getReqDN()
+    {
+        return reqDN;
+    }
+
+    /**
+     * The reqDN attribute is the  distinguishedName  of  the  target  of  the
+     * operation.  E.g.,  for  a Bind request, this is the Bind DN. For an Add
+     * request, this is the DN of the entry being added. For a Search request,
+     * this is the base DN of the search.
+     *
+     * @param reqDN maps to 'reqDN' attribute on 'auditSearch' object class.
+     */
+    public void setReqDN(String reqDN)
+    {
+        this.reqDN = reqDN;
+    }
+
+    /**
+     * reqEnd provide the end time of the operation. It uses generalizedTime syntax.
+     *
+     * @return value that maps to 'reqEnd' attribute on 'auditSearch' object class.
+     */
+    public String getReqEnd()
+    {
+        return reqEnd;
+    }
+
+    /**
+     * reqEnd provide the end time of the operation. It uses generalizedTime syntax.
+     *
+     * @param reqEnd value that maps to same name on 'auditSearch' object class.
+     */
+    public void setReqEnd(String reqEnd)
+    {
+        this.reqEnd = reqEnd;
+    }
+
+    /**
+     * The  reqResult  attribute  is  the  numeric  LDAP  result  code  of the
+     * operation, indicating either success or a particular LDAP  error  code.
+     * An  error code may be accompanied by a text error message which will be
+     * recorded in the reqMessage attribute.
+     *
+     * @return value that maps to 'reqResult' attribute on 'auditSearch' object class.
+     */
+    public String getReqResult()
+    {
+        return reqResult;
+    }
+
+    /**
+     * The  reqResult  attribute  is  the  numeric  LDAP  result  code  of the
+     * operation, indicating either success or a particular LDAP  error  code.
+     * An  error code may be accompanied by a text error message which will be
+     * recorded in the reqMessage attribute.
+     *
+     * @param reqResult maps to same name on 'auditSearch' object class.
+     */
+    public void setReqResult(String reqResult)
+    {
+        this.reqResult = reqResult;
+    }
+
+    /**
+     * The reqSession attribute is an implementation-specific identifier  that
+     * is  common to all the operations associated with the same LDAP session.
+     * Currently this is slapd's internal connection ID, stored in decimal.
+     *
+     * @return value that maps to 'reqSession' attribute on 'auditSearch' object class.
+     */
+    public String getReqSession()
+    {
+        return reqSession;
+    }
+
+    /**
+     * The reqSession attribute is an implementation-specific identifier  that
+     * is  common to all the operations associated with the same LDAP session.
+     * Currently this is slapd's internal connection ID, stored in decimal.
+     *
+     * @param reqSession maps to same name on 'auditSearch' object class.
+     */
+    public void setReqSession(String reqSession)
+    {
+        this.reqSession = reqSession;
+    }
+
+    /**
+     * reqStart provide the start of the operation,  They  use generalizedTime syntax.
+     * The reqStart attribute is also used as the RDN for each log entry.
+     *
+     * @return value that maps to 'reqStart' attribute on 'auditSearch' object class.
+     */
+    public String getReqStart()
+    {
+        return reqStart;
+    }
+
+    /**
+     * reqStart provide the start of the operation,  They  use generalizedTime syntax.
+     * The reqStart attribute is also used as the RDN for each log entry.
+     *
+     * @param reqStart maps to same name on 'auditSearch' object class.
+     */
+    public void setReqStart(String reqStart)
+    {
+        this.reqStart = reqStart;
+    }
+
+    /**
+     * The  reqType  attribute  is  a  simple  string  containing  the type of
+     * operation being logged, e.g.  add, delete, search,  etc.  For  extended
+     * operations,  the  type also includes the OID of the extended operation,
+     * e.g.  extended(1.1.1.1)
+     *
+     * @return value that maps to 'reqType' attribute on 'auditSearch' object class.
+     */
+    public String getReqType()
+    {
+        return reqType;
+    }
+
+    /**
+     * The  reqType  attribute  is  a  simple  string  containing  the type of
+     * operation being logged, e.g.  add, delete, search,  etc.  For  extended
+     * operations,  the  type also includes the OID of the extended operation,
+     * e.g.  extended(1.1.1.1)
+     *
+     * @param reqType maps to same name on 'auditSearch' object class.
+     */
+    public void setReqType(String reqType)
+    {
+        this.reqType = reqType;
+    }
+
+    /**
+     * Get the Compare operation the reqAssertion attribute carries the Attribute Value Assertion used in the compare request.
+     *
+     * @return value that maps to 'reqAssertion' attribute on 'auditCompare' object class.
+     */
+    public String getReqAssertion()
+    {
+        return reqAssertion;
+    }
+
+    /**
+     * Set the Compare operation the reqAssertion attribute carries the Attribute Value Assertion used in the compare request.
+     *
+     * @param reqAssertion value maps to 'reqAssertion' attribute contained in the 'auditCompare' object class.
+     */
+    public void setReqAssertion( String reqAssertion )
+    {
+        this.reqAssertion = reqAssertion;
+    }
+
+    /**
+     * Returns the name of the structural object class that is used to log the event.  For this entity
+     * this value will always be 'auditSearch'.
+     *
+     * @return value that maps to 'structuralObjectClass' attribute that contains the name 'auditSearch'.
+     */
+    public String getStructuralObjectClass()
+    {
+        return structuralObjectClass;
+    }
+
+    /**
+     * Returns the name of the structural object class that is used to log the event.  For this entity
+     * this value will always be 'auditSearch'.
+     *
+     * @param structuralObjectClass maps to same name on 'auditSearch' object class.
+     */
+    public void setStructuralObjectClass(String structuralObjectClass)
+    {
+        this.structuralObjectClass = structuralObjectClass;
+    }
+
+    /**
+     * The reqEntries attribute is the integer count of  how  many entries  were  returned  by  this search request.
+     *
+     * @return value that maps to 'reqEntries' attribute on 'auditSearch' object class
+     */
+    public String getReqEntries()
+    {
+        return reqEntries;
+    }
+
+    /**
+     * The reqEntries attribute is the integer count of  how  many entries  were  returned  by  this search request.
+     *
+     * @param reqEntries maps to same name on 'auditSearch' object class
+     */
+    public void setReqEntries(String reqEntries)
+    {
+        this.reqEntries = reqEntries;
+    }
+
+    /**
+     * The reqAttr attribute lists the requested attributes if specific attributes were requested.
+     *
+     * @return value maps to 'reqAttr' on 'auditSearch' object class.
+     */
+    public String getReqAttr()
+    {
+        return reqAttr;
+    }
+
+    /**
+     * The reqAttr attribute lists the requested attributes if specific attributes were requested.
+     *
+     * @param reqAttr maps to same name on 'auditSearch' object class.
+     */
+    public void setReqAttr(String reqAttr)
+    {
+        this.reqAttr = reqAttr;
+    }
+
+    /**
+     * The reqAttrsOnly attribute is a Boolean value showing TRUE if only attribute names
+     * were  requested, or FALSE if attributes and their values were requested.
+     * For Fortress authorization requests this value will always be TRUE.
+     *
+     * @return value maps to 'reqAttrsOnly' on 'auditSearch' object class.
+     */
+    public String getReqAttrsOnly()
+    {
+        return reqAttrsOnly;
+    }
+
+    /**
+     * The reqAttrsOnly attribute is a Boolean value showing TRUE if only attribute names
+     * were  requested, or FALSE if attributes and their values were requested.
+     * For Fortress authorization requests this value will always be TRUE.
+     *
+     * @param reqAttrsOnly maps to same name on 'auditSearch' object class.
+     */
+    public void setReqAttrsOnly(String reqAttrsOnly)
+    {
+        this.reqAttrsOnly = reqAttrsOnly;
+    }
+
+    /**
+     * The reqFilter attribute carries the filter used in the search request.
+     * <p/>
+     * For Fortress authorization events this will contain the following:
+     * <ul>
+     * <li>userId: {@link org.apache.directory.fortress.core.rbac.User#userId}
+     * <li>activated roles: {@link UserRole#name}
+     * <li>object name: {@link Permission#objName}
+     * <li>operation name: {@link Permission#opName}
+     * </ul>
+     *
+     * @return value that maps to 'reqFilter' attribute on 'auditSearch' object class.
+     */
+    public String getReqFilter()
+    {
+        return reqFilter;
+    }
+
+    /**
+     * The reqFilter attribute carries the filter used in the search request.
+     * <p/>
+     * For Fortress authorization events this will contain the following:
+     * <ul>
+     * <li>userId: {@link org.apache.directory.fortress.core.rbac.User#userId}
+     * <li>activated roles: {@link UserRole#name}
+     * <li>object name: {@link Permission#objName}
+     * <li>operation name: {@link Permission#opName}
+     * </ul>
+     *
+     * @param reqFilter maps to same name on 'auditSearch' object class.
+     */
+    public void setReqFilter(String reqFilter)
+    {
+        this.reqFilter = reqFilter;
+    }
+
+    /**
+     * The reqScope attribute contains the scope of the original search request, using
+     * the values specified for the LDAP URL format. I.e. base, one, sub, or subord.
+     *
+     * @return value that maps to 'reqScope' attribute on 'auditSearch' object class.
+     */
+    public String getReqScope()
+    {
+        return reqScope;
+    }
+
+    /**
+     * The reqScope attribute contains the scope of the original search request, using
+     * the values specified for the LDAP URL format. I.e. base, one, sub, or subord.
+     *
+     * @param reqScope maps to same name on 'auditSearch' object class.
+     */
+    public void setReqScope(String reqScope)
+    {
+        this.reqScope = reqScope;
+    }
+
+    /**
+     * The reqSizeLimit attribute indicate what limits were requested on the search operation.
+     *
+     * @return value that maps to 'reqSizeLimit' attribute on 'auditSearch' object class.
+     */
+    public String getReqSizeLimit()
+    {
+        return reqSizeLimit;
+    }
+
+    /**
+     * The reqSizeLimit attribute indicate what limits were requested on the search operation.
+     *
+     * @param reqSizeLimit maps to same name on 'auditSearch' object class.
+     */
+    public void setReqSizeLimit(String reqSizeLimit)
+    {
+        this.reqSizeLimit = reqSizeLimit;
+    }
+
+    /**
+     * The reqTimeLimit attribute indicate what limits were requested on the search operation.
+     *
+     * @return value that maps to 'reqTimeLimit' attribute on 'auditSearch' object class.
+     */
+    public String getReqTimeLimit()
+    {
+        return reqTimeLimit;
+    }
+
+    /**
+     * The reqTimeLimit attribute indicate what limits were requested on the search operation.
+     *
+     * @param reqTimeLimit maps to same name on 'auditSearch' object class.
+     */
+    public void setReqTimeLimit(String reqTimeLimit)
+    {
+        this.reqTimeLimit = reqTimeLimit;
+    }
+
+    /**
+     * Return the subschemaSubentry attribute from the audit entry.
+     *
+     * @return value that maps to 'subschemaSubentry' on 'auditSearch' object class.
+     */
+    public String getSubschemaSubentry()
+    {
+        return subschemaSubentry;
+    }
+
+    /**
+     * Set the subschemaSubentry attribute from the audit entry.
+     *
+     * @param subschemaSubentry maps to same name on 'auditSearch' object class.
+     */
+    public void setSubschemaSubentry(String subschemaSubentry)
+    {
+        this.subschemaSubentry = subschemaSubentry;
+    }
+
+    /**
+     * The reqDerefAliases attribute is on of never, finding, searching, or always, denoting how aliases
+     * will be processed during the search.
+     *
+     * @return value that maps to 'reqDerefAliases' on 'auditSearch' object class.
+     */
+    public String getReqDerefAliases()
+    {
+        return reqDerefAliases;
+    }
+
+    /**
+     * The reqDerefAliases attribute is on of never, finding, searching, or always, denoting how aliases
+     * will be processed during the search.
+     *
+     * @param reqDerefAliases maps to same name on 'auditSearch' object class.
+     */
+    public void setReqDerefAliases(String reqDerefAliases)
+    {
+        this.reqDerefAliases = reqDerefAliases;
+    }
+
+    /**
+     * Sequence id is used internal to Fortress.
+     * @return long value contains sequence id.
+     */
+    public long getSequenceId()
+    {
+        return sequenceId;
+    }
+
+    /**
+     * Sequence id is used internal to Fortress
+     * @param sequenceId contains sequence to use.
+     */
+    public void setSequenceId(long sequenceId)
+    {
+        this.sequenceId = sequenceId;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/Bind.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Bind.java b/src/main/java/org/apache/directory/fortress/core/rbac/Bind.java
new file mode 100755
index 0000000..34edddc
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Bind.java
@@ -0,0 +1,579 @@
+/*
+ *   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.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import java.io.Serializable;
+
+/**
+ * This entity class contains OpenLDAP slapd access log records that correspond to bind attempts made to the directory.
+ * <p/>
+ * The auditBind Structural object class is used to store authentication events that can later be queried via ldap API.<br />
+ * <code># The Bind class includes the reqVersion attribute which contains the LDAP</code>
+ * <code># protocol version specified in the Bind as well as the reqMethod attribute</code>
+ * <code># which contains the Bind Method used in the Bind. This will be the string</code>
+ * <code># SIMPLE for LDAP Simple Binds or SASL(mech) for SASL Binds. Note that unless</code>
+ * <code># configured as a global overlay, only Simple Binds using DNs that reside in</code>
+ * <code># the current database will be logged:</code>
+ * <pre>
+ * ------------------------------------------
+ * objectclass (  1.3.6.1.4.1.4203.666.11.5.2.6 NAME 'auditBind'</code>
+ * DESC 'Bind operation'</code>
+ * SUP auditObject STRUCTURAL</code>
+ * MUST ( reqVersion $ reqMethod ) )</code>
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * Note this class used descriptions pulled from man pages on slapd access log.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortBind")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "bind", propOrder = {
+    "createTimestamp",
+    "creatorsName",
+    "entryCSN",
+    "entryDN",
+    "entryUUID",
+    "hasSubordinates",
+    "modifiersName",
+    "modifyTimestamp",
+    "objectClass",
+    "reqAuthzID",
+    "reqControls",
+    "reqDN",
+    "reqEnd",
+    "reqMethod",
+    "reqResult",
+    "reqSession",
+    "reqStart",
+    "reqType",
+    "reqVersion",
+    "structuralObjectClass",
+    "sequenceId"
+})
+public class Bind extends FortEntity implements Serializable
+{
+    private String createTimestamp;
+    private String creatorsName;
+    private String entryCSN;
+    private String entryDN;
+    private String entryUUID;
+    private String hasSubordinates;
+    private String modifiersName;
+    private String modifyTimestamp;
+    private String objectClass;
+    private String reqAuthzID;
+    private String reqControls;
+    private String reqDN;
+    private String reqEnd;
+    private String reqMethod;
+    private String reqResult;
+    private String reqSession;
+    private String reqStart;
+    private String reqType;
+    private String reqVersion;
+    private String structuralObjectClass;
+    private long sequenceId;
+
+    /**
+     * Get the attribute that maps to 'reqStart' which provides the start time of the operation which is also the rDn for the node.
+     * These time attributes use generalizedTime syntax. The reqStart attribute is also used as the RDN for each log entry.
+     *
+     * @return attribute that maps to 'reqStart' in 'auditBind' object class.
+     */
+    public String getCreateTimestamp()
+    {
+        return createTimestamp;
+    }
+
+    /**
+     * Set the attribute that maps to 'reqStart' which provides the start time of the operation which is also the rDn for the node.
+     * These time attributes use generalizedTime syntax. The reqStart attribute is also used as the RDN for each log entry.
+     *
+     * @param createTimestamp attribute that maps to 'reqStart' in 'auditBind' object class.
+     */
+    public void setCreateTimestamp(String createTimestamp)
+    {
+        this.createTimestamp = createTimestamp;
+    }
+
+    /**
+     * Return the user dn containing the identity of log user who added the audit record.  This will be the system user that
+     * is configured for performing slapd access log operations on behalf of Fortress.
+     * The config property name {@link org.apache.directory.fortress.ldap.PoolMgr#LDAP_LOG_POOL_UID} contains the audit log system user id.
+     *
+     * @return value that maps to 'creatorsName' attribute on 'auditBind' object class.
+     */
+    public String getCreatorsName()
+    {
+        return creatorsName;
+    }
+
+    /**
+     * Set the user dn containing the identity of log user who added the audit record.  This will be the system user that
+     * is configured for performing slapd access log operations on behalf of Fortress.
+     * The config property name {@link org.apache.directory.fortress.ldap.PoolMgr#LDAP_LOG_POOL_UID} contains the audit log system user id.
+     *
+     * @param creatorsName maps to 'creatorsName' attribute on 'auditBind' object class.
+     */
+    public void setCreatorsName(String creatorsName)
+    {
+        this.creatorsName = creatorsName;
+    }
+
+    /**
+     * Return the Change Sequence Number (CSN) containing sequence number that is used for OpenLDAP synch replication functionality.
+     *
+     * @return attribute that maps to 'entryCSN' on 'auditBind' object class.
+     */
+    public String getEntryCSN()
+    {
+        return entryCSN;
+    }
+
+    /**
+     * Set the Change Sequence Number (CSN) containing sequence number that is used for OpenLDAP synch replication functionality.
+     *
+     * @param entryCSN maps to 'entryCSN' attribute on 'auditBind' object class.
+     */
+    public void setEntryCSN(String entryCSN)
+    {
+        this.entryCSN = entryCSN;
+    }
+
+    /**
+     * Get the entry dn for bind object stored in directory.  This attribute uses the 'reqStart' along with suffix for log.
+     *
+     * @return attribute that maps to 'entryDN' on 'auditBind' object class.
+     */
+    public String getEntryDN()
+    {
+        return entryDN;
+    }
+
+    /**
+     * Set the entry dn for bind object stored in directory.  This attribute uses the 'reqStart' along with suffix for log.
+     *
+     * @param entryDN attribute that maps to 'entryDN' on 'auditBind' object class.
+     */
+    public void setEntryDN(String entryDN)
+    {
+        this.entryDN = entryDN;
+    }
+
+    /**
+     * Get the attribute that contains the Universally Unique ID (UUID) of the corresponding 'auditBind' record.
+     *
+     * @return value that maps to 'entryUUID' attribute on 'auditBind' object class.
+     */
+    public String getEntryUUID()
+    {
+        return entryUUID;
+    }
+
+    /**
+     * Set the attribute that contains the Universally Unique ID (UUID) of the corresponding 'auditBind' record.
+     *
+     * @param entryUUID that maps to 'entryUUID' attribute on 'auditBind' object class.
+     */
+    public void setEntryUUID(String entryUUID)
+    {
+        this.entryUUID = entryUUID;
+    }
+
+    /**
+     * Get the attribute that corresponds to the boolean value hasSubordinates.
+     *
+     * @return value that maps to 'hasSubordinates' attribute on 'auditBind' object class.
+     */
+    public String getHasSubordinates()
+    {
+        return hasSubordinates;
+    }
+
+    /**
+     * Set the attribute that corresponds to the boolean value hasSubordinates.
+     *
+     * @param hasSubordinates maps to same name on 'auditBind' object class.
+     */
+    public void setHasSubordinates(String hasSubordinates)
+    {
+        this.hasSubordinates = hasSubordinates;
+    }
+
+    /**
+     * Return the user dn containing the identity of log user who last modified the audit record.  This will be the system user that
+     * is configured for performing slapd access log operations on behalf of Fortress.
+     * The config property name {@link org.apache.directory.fortress.ldap.PoolMgr#LDAP_LOG_POOL_UID} contains the audit log system user id.
+     *
+     * @return value that maps to 'modifiersName' attribute on 'auditBind' object class.
+     */
+    public String getModifiersName()
+    {
+        return modifiersName;
+    }
+
+    /**
+     * Set the user dn containing the identity of log user who modified the audit record.  This will be the system user that
+     * is configured for performing slapd access log operations on behalf of Fortress.
+     * The config property name {@link org.apache.directory.fortress.ldap.PoolMgr#LDAP_LOG_POOL_UID} contains the audit log system user id.
+     *
+     * @param modifiersName maps to 'modifiersName' attribute on 'auditBind' object class.
+     */
+    public void setModifiersName(String modifiersName)
+    {
+        this.modifiersName = modifiersName;
+    }
+
+    /**
+     * Get the attribute that maps to 'modifyTimestamp' which provides the last time audit record was changed.
+     * The time attributes use generalizedTime syntax.
+     *
+     * @return attribute that maps to 'modifyTimestamp' in 'auditBind' object class.
+     */
+    public String getModifyTimestamp()
+    {
+        return modifyTimestamp;
+    }
+
+    /**
+     * Set the attribute that maps to 'modifyTimestamp' which provides the last time audit record was changed.
+     * The time attributes use generalizedTime syntax.
+     *
+     * @param modifyTimestamp attribute that maps to same name in 'auditBind' object class.
+     */
+    public void setModifyTimestamp(String modifyTimestamp)
+    {
+        this.modifyTimestamp = modifyTimestamp;
+    }
+
+    /**
+     * Get the object class name of the audit record.  For this entity, this value will always be 'auditBind'.
+     *
+     * @return value that maps to 'objectClass' attribute on 'auditBind' obejct class.
+     */
+    public String getObjectClass()
+    {
+        return objectClass;
+    }
+
+    /**
+     * Set the object class name of the audit record.  For this entity, this value will always be 'auditBind'.
+     *
+     * @param objectClass value that maps to same name on 'auditBind' obejct class.
+     */
+    public void setObjectClass(String objectClass)
+    {
+        this.objectClass = objectClass;
+    }
+
+    /**
+     * The  reqAuthzID  attribute  is  the  distinguishedName of the user that
+     * performed the operation.  This will usually be the  same  name  as  was
+     * established  at  the  start of a session by a Bind request (if any) but
+     * may be altered in various circumstances.
+     * For Fortress bind operations this will map to {@link User#userId}
+     *
+     * @return value that maps to 'reqAuthzID' on 'auditBind' object class.
+     */
+    public String getReqAuthzID()
+    {
+        return reqAuthzID;
+    }
+
+    /**
+     * The  reqAuthzID  attribute  is  the  distinguishedName of the user that
+     * performed the operation.  This will usually be the  same  name  as  was
+     * established  at  the  start of a session by a Bind request (if any) but
+     * may be altered in various circumstances.
+     * For Fortress bind operations this will map to {@link User#userId}
+     *
+     */
+    public void setReqAuthzID(String reqAuthzID)
+    {
+        this.reqAuthzID = reqAuthzID;
+    }
+
+    /**
+     * The reqControls and reqRespControls attributes carry any controls  sent
+     * by  the  client  on  the  request  and  returned  by  the server in the
+     * response, respectively. The attribute  values  are  just  uninterpreted
+     * octet strings.
+     *
+     * @return value that maps to 'reqControls' attribute on 'auditBind' object class.
+     */
+    public String getReqControls()
+    {
+        return reqControls;
+    }
+
+    /**
+     * The reqControls and reqRespControls attributes carry any controls  sent
+     * by  the  client  on  the  request  and  returned  by  the server in the
+     * response, respectively. The attribute  values  are  just  uninterpreted
+     * octet strings.
+     *
+     * @param reqControls maps to same name attribute on 'auditBind' object class.
+     */
+    public void setReqControls(String reqControls)
+    {
+        this.reqControls = reqControls;
+    }
+
+    /**
+     * The reqDN attribute is the  distinguishedName  of  the  target  of  the
+     * operation.  E.g.,  for  a Bind request, this is the Bind DN. For an Add
+     * request, this is the DN of the entry being added. For a Search request,
+     * this is the base DN of the search.
+     *
+     * @return value that map to 'reqDN' attribute on 'auditBind' object class.
+     */
+    public String getReqDN()
+    {
+        return reqDN;
+    }
+
+    /**
+     * The reqDN attribute is the  distinguishedName  of  the  target  of  the
+     * operation.  E.g.,  for  a Bind request, this is the Bind DN. For an Add
+     * request, this is the DN of the entry being added. For a Search request,
+     * this is the base DN of the search.
+     *
+     * @param reqDN maps to 'reqDN' attribute on 'auditBind' object class.
+     */
+    public void setReqDN(String reqDN)
+    {
+        this.reqDN = reqDN;
+    }
+
+    /**
+     * reqEnd provide the end time of the operation. It uses generalizedTime syntax.
+     *
+     * @return value that maps to 'reqEnd' attribute on 'auditBind' object class.
+     */
+    public String getReqEnd()
+    {
+        return reqEnd;
+    }
+
+    /**
+     * reqEnd provide the end time of the operation. It uses generalizedTime syntax.
+     *
+     * @param reqEnd value that maps to same name on 'auditBind' object class.
+     */
+    public void setReqEnd(String reqEnd)
+    {
+        this.reqEnd = reqEnd;
+    }
+
+    /**
+     * The reqMethod attribute contains the Bind Method used in the Bind. This will be
+     * the string SIMPLE for LDAP Simple Binds or SASL(<mech>) for SASL Binds.
+     * Note  that  unless  configured  as  a global overlay, only Simple Binds
+     * using DNs that reside in the current database will be logged.
+     *
+     * @return String that maps to 'reqMethod' attribute on 'auditBind' object class.
+     */
+    public String getReqMethod()
+    {
+        return reqMethod;
+    }
+
+    /**
+     * The reqMethod attribute contains the Bind Method used in the Bind. This will be
+     * the string SIMPLE for LDAP Simple Binds or SASL(<mech>) for SASL Binds.
+     * Note  that  unless  configured  as  a global overlay, only Simple Binds
+     * using DNs that reside in the current database will be logged.
+     *
+     * @param reqMethod maps to same name on 'auditBind' object class.
+     */
+    public void setReqMethod(String reqMethod)
+    {
+        this.reqMethod = reqMethod;
+    }
+
+    /**
+     * The  reqResult  attribute  is  the  numeric  LDAP  result  code  of the
+     * operation, indicating either success or a particular LDAP  error  code.
+     * An  error code may be accompanied by a text error message which will be
+     * recorded in the reqMessage attribute.
+     *
+     * @return value that maps to 'reqResult' attribute on 'auditBind' object class.
+     */
+    public String getReqResult()
+    {
+        return reqResult;
+    }
+
+    /**
+     * The  reqResult  attribute  is  the  numeric  LDAP  result  code  of the
+     * operation, indicating either success or a particular LDAP  error  code.
+     * An  error code may be accompanied by a text error message which will be
+     * recorded in the reqMessage attribute.
+     *
+     * @param reqResult maps to same name on 'auditBind' object class.
+     */
+    public void setReqResult(String reqResult)
+    {
+        this.reqResult = reqResult;
+    }
+
+    /**
+     * The reqSession attribute is an implementation-specific identifier  that
+     * is  common to all the operations associated with the same LDAP session.
+     * Currently this is slapd's internal connection ID, stored in decimal.
+     *
+     * @return value that maps to 'reqSession' attribute on 'auditBind' object class.
+     */
+    public String getReqSession()
+    {
+        return reqSession;
+    }
+
+    /**
+     * The reqSession attribute is an implementation-specific identifier  that
+     * is  common to all the operations associated with the same LDAP session.
+     * Currently this is slapd's internal connection ID, stored in decimal.
+     *
+     * @param reqSession maps to same name on 'auditBind' object class.
+     */
+    public void setReqSession(String reqSession)
+    {
+        this.reqSession = reqSession;
+    }
+
+    /**
+     * reqStart provide the start of the operation,  They  use generalizedTime syntax.
+     * The reqStart attribute is also used as the RDN for each log entry.
+     *
+     * @return value that maps to 'reqStart' attribute on 'auditBind' object class.
+     */
+    public String getReqStart()
+    {
+        return reqStart;
+    }
+
+    /**
+     * reqStart provide the start of the operation,  They  use generalizedTime syntax.
+     * The reqStart attribute is also used as the RDN for each log entry.
+     *
+     * @param reqStart maps to same name on 'auditBind' object class.
+     */
+    public void setReqStart(String reqStart)
+    {
+        this.reqStart = reqStart;
+    }
+
+    /**
+     * The  reqType  attribute  is  a  simple  string  containing  the type of
+     * operation being logged, e.g.  add, delete, search,  etc.  For  extended
+     * operations,  the  type also includes the OID of the extended operation,
+     * e.g.  extended(1.1.1.1)
+     *
+     * @return value that maps to 'reqType' attribute on 'auditBind' object class.
+     */
+    public String getReqType()
+    {
+        return reqType;
+    }
+
+    /**
+     * The  reqType  attribute  is  a  simple  string  containing  the type of
+     * operation being logged, e.g.  add, delete, search,  etc.  For  extended
+     * operations,  the  type also includes the OID of the extended operation,
+     * e.g.  extended(1.1.1.1)
+     *
+     * @param reqType maps to same name on 'auditBind' object class.
+     */
+    public void setReqType(String reqType)
+    {
+        this.reqType = reqType;
+    }
+
+    /**
+     * The reqVersion attribute which contains the
+     * LDAP protocol version specified in the Bind
+     *
+     * @return value that maps to the 'reqVersion' attribute on 'auditBind' object class.
+     */
+    public String getReqVersion()
+    {
+        return reqVersion;
+    }
+
+    /**
+     * The reqVersion attribute which contains the
+     * LDAP protocol version specified in the Bind
+     *
+     * @param reqVersion maps to same name on 'auditBind' object class.
+     */
+    public void setReqVersion(String reqVersion)
+    {
+        this.reqVersion = reqVersion;
+    }
+
+    /**
+     * Returns the name of the structural object class that is used to log the event.  For this entity
+     * this value will always be 'auditBind'.
+     *
+     * @return value that maps to 'structuralObjectClass' attribute that contains the name 'auditBind'.
+     */
+    public String getStructuralObjectClass()
+    {
+        return structuralObjectClass;
+    }
+
+    /**
+     * Returns the name of the structural object class that is used to log the event.  For this entity
+     * this value will always be 'auditBind'.
+     *
+     * @param structuralObjectClass maps to same name on 'auditBind' object class.
+     */
+    public void setStructuralObjectClass(String structuralObjectClass)
+    {
+        this.structuralObjectClass = structuralObjectClass;
+    }
+
+    /**
+     * Sequence id is used internal to Fortress.
+     * @return long value contains sequence id.
+     */
+    public long getSequenceId()
+    {
+        return sequenceId;
+    }
+
+    /**
+     * Sequence id is used internal to Fortress
+     * @param sequenceId contains sequence to use.
+     */
+    public void setSequenceId(long sequenceId)
+    {
+        this.sequenceId = sequenceId;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/CharArrayAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/CharArrayAdapter.java b/src/main/java/org/apache/directory/fortress/core/rbac/CharArrayAdapter.java
new file mode 100755
index 0000000..e5ce164
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/CharArrayAdapter.java
@@ -0,0 +1,42 @@
+/*
+ *   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.adapters.XmlAdapter;
+import java.util.Arrays;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Shawn McKinney
+ * Date: 1/8/12
+ * Time: 7:29 AM
+ */
+public class CharArrayAdapter extends XmlAdapter<String, char[]>
+{
+    public char[] unmarshal(String val) throws Exception
+    {
+        return val.toCharArray();
+    }
+
+    public String marshal(char[] val) throws Exception
+    {
+        return Arrays.toString(val);
+    }
+}
\ 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/ClassUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/ClassUtil.java b/src/main/java/org/apache/directory/fortress/core/rbac/ClassUtil.java
new file mode 100755
index 0000000..9dde185
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/ClassUtil.java
@@ -0,0 +1,103 @@
+/*
+ *   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 org.apache.directory.fortress.core.CfgException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+
+import java.io.InputStream;
+
+
+/**
+ * General purpose factory uses java reflection to instantiate new Manager object.
+ * </p>
+ * This class is called by the Manager factories:
+ * <ol>
+ * <li>{@link org.apache.directory.fortress.core.AccessMgrFactory}</li>
+ * <li>{@link org.apache.directory.fortress.core.AdminMgrFactory}</li>
+ * <li>{@link org.apache.directory.fortress.core.AuditMgrFactory}</li>
+ * <li>{@link org.apache.directory.fortress.core.DelAccessMgrFactory}</li>
+ * <li>{@link org.apache.directory.fortress.core.DelAdminMgrFactory}</li>
+ * <li>{@link org.apache.directory.fortress.core.DelReviewMgrFactory}</li>
+ * <li>{@link org.apache.directory.fortress.core.PwPolicyMgrFactory}</li>
+ * <li>{@link org.apache.directory.fortress.core.ReviewMgrFactory}</li>
+ * <li>{@link org.apache.directory.fortress.core.cfg.ConfigMgrFactory}</li>
+ * </ol>
+ *
+ * @author Shawn McKinney
+ */
+public class ClassUtil
+{
+    /**
+     * Given a valid class name call the default constructor through reflexion and return the reference to the caller.
+     * @param className contains fully qualified java class name to be instantiated.  Must have a public default constructor to be successful.
+     * @return reference to instantiated ManagerImpl object.
+     * @throws org.apache.directory.fortress.core.CfgException in the event of failure to instantiate.
+     *
+     */
+    public static Object createInstance(String className)
+        throws CfgException
+    {
+        Object target;
+        try
+        {
+            if (className == null || className.length() == 0)
+            {
+                String error = "createInstance() null or empty classname";
+                throw new CfgException(GlobalErrIds.FT_MGR_CLASS_NAME_NULL, error);
+            }
+            target = Class.forName(className).newInstance();
+        }
+        catch (java.lang.ClassNotFoundException e)
+        {
+            String error = "createInstance() className [" + className + "] caught java.lang.ClassNotFoundException=" + e;
+            throw new CfgException(GlobalErrIds.FT_MGR_CLASS_NOT_FOUND, error, e);
+        }
+        catch (java.lang.InstantiationException e)
+        {
+            String error = "createInstance()  [" + className + "] caught java.lang.InstantiationException=" + e;
+            throw new CfgException(GlobalErrIds.FT_MGR_INST_EXCEPTION, error, e);
+        }
+        catch (java.lang.IllegalAccessException e)
+        {
+            String error = "createInstance()  [" + className + "] caught java.lang.IllegalAccessException=" + e;
+            throw new CfgException(GlobalErrIds.FT_MGR_ILLEGAL_ACCESS, error, e);
+        }
+        return target;
+	}
+
+
+    /**
+     * Find a file on the classloader and return as InputStream.
+     * @param name contains the name of the file resource.
+     * @return handle to the InputStream
+     * @throws org.apache.directory.fortress.core.CfgException in the event resource is not found on classloader.
+     */
+    public static InputStream resourceAsStream(String name) throws CfgException
+    {
+        InputStream is;
+        is = ClassUtil.class.getClassLoader().getResourceAsStream(name);
+        if (is == null)
+        {
+            throw new CfgException(GlobalErrIds.FT_RESOURCE_NOT_FOUND, name);
+        }
+        return is;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/Context.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Context.java b/src/main/java/org/apache/directory/fortress/core/rbac/Context.java
new file mode 100644
index 0000000..e7a646d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Context.java
@@ -0,0 +1,95 @@
+/*
+ *   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;
+
+
+/**
+ * This class contains the Context id which is used as container for segregating data by customer within the LDAP Directory Information Tree.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class Context
+{
+    private String name;
+    private String description;
+
+
+    /**
+     * Generate instance of context.
+     *
+     * @param name        contains the id to use for sub-directory within the DIT.
+     * @param description maps to 'description' attribute in 'organizationalUnit' object class.
+     */
+    public Context(String name, String description)
+    {
+        this.name = name;
+        this.description = description;
+    }
+
+    /**
+     * Default constructor used by {@link org.apache.directory.fortress.core.ant.FortressAntTask}
+     */
+    public Context()
+    {
+    }
+
+    /**
+     * Get the id to use for sub-directory within the DIT.  This attribute is required.
+     *
+     * @return name maps to 'dcObject' object class.
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * Set the id to use for sub-directory within the DIT.  This attribute is required.
+     *
+     * @param name maps to 'dcObject' object class.
+     */
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    /**
+     * Get the description for the context.  This value is not required or constrained
+     * but is validated on reasonability.
+     *
+     * @return field maps to 'description' attribute on 'organizationalUnit'.
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+    /**
+     * Set the description for the context.  This value is not required or constrained
+     * but is validated on reasonability.
+     *
+     * @param description maps to to 'description' attribute on 'organizationalUnit'.
+     */
+    public void setDescription(String description)
+    {
+        this.description = description;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/DSDChecker.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/DSDChecker.java b/src/main/java/org/apache/directory/fortress/core/rbac/DSDChecker.java
new file mode 100755
index 0000000..ed5c928
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/DSDChecker.java
@@ -0,0 +1,152 @@
+/*
+ *   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.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.directory.fortress.core.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.util.time.Constraint;
+import org.apache.directory.fortress.core.util.time.Time;
+import org.apache.directory.fortress.core.util.time.Validator;
+
+
+/**
+ * This class performs Dynamic Separation of Duty checking on a collection of roles targeted for
+ * activation within a particular user's session.  This method is called from {@link org.apache.directory.fortress.core.util.time.CUtil#validateConstraints} during createSession
+ * sequence for users.  If DSD constraint violation is detected for a particular role method will remove the role
+ * from collection of activation candidates and log a warning.  This proc will also consider hierarchical relations
+ * between roles (RBAC spec calls these authorized roles).
+ * This validator will ensure the role being targeted for activation does not violate RBAC dynamic separation of duty constraints.
+ * <h4> Constraint Targets include</h4>
+ * <ol>
+ * <li>{@link org.apache.directory.fortress.core.rbac.User} maps to 'ftCstr' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserRole} maps to 'ftRC' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.Role}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link UserAdminRole}  maps to 'ftARC' attribute on 'ftRls' object class</li>
+ * </ol>
+ * </p>
+ *
+ * @author Shawn McKinney
+ */
+public class DSDChecker
+    implements Validator
+{
+    private static final String CLS_NM = DSDChecker.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+
+    /**
+     * This method is called during entity activation, {@link org.apache.directory.fortress.core.util.time.CUtil#validateConstraints} and ensures the role does not violate dynamic separation of duty constraints.
+     *
+     * @param session    contains list of RBAC roles {@link org.apache.directory.fortress.core.rbac.UserRole} targeted for activation.
+     * @param constraint required for Validator interface, not used here..
+     * @param time       required for Validator interface, not used here.
+     * @return '0' if validation succeeds else {@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_DSD} if failed.
+     */
+    @Override
+    public int validate( Session session, Constraint constraint, Time time ) throws org.apache.directory.fortress.core.SecurityException
+    {
+        int rc = 0;
+        int matchCount;
+
+        // get all candidate activated roles user:
+        List<UserRole> activeRoleList = session.getRoles();
+        if ( activeRoleList == null || activeRoleList.size() == 0 )
+        {
+            return rc;
+        }
+        // get the list of authorized roles for this user:
+        Set<String> authorizedRoleSet = RoleUtil.getInheritedRoles( activeRoleList, session.getUser().getContextId() );
+        // only need to check DSD constraints if more than one role is being activated:
+        if ( authorizedRoleSet != null && authorizedRoleSet.size() > 1 )
+        {
+            // get all DSD sets that contain the candidate activated and authorized roles,
+            //If DSD cache is disabled, this will search the directory using authorizedRoleSet
+            Set<SDSet> dsdSets = SDUtil.getDsdCache( authorizedRoleSet, session.getUser().getContextId() );
+            if ( dsdSets != null && dsdSets.size() > 0 )
+            {
+                for ( SDSet dsd : dsdSets )
+                {
+                    Iterator activatedRoles = activeRoleList.iterator();
+                    matchCount = 0;
+                    Set<String> map = dsd.getMembers();
+
+                    // now check the DSD on every role activation candidate contained within session object:
+                    while ( activatedRoles.hasNext() )
+                    {
+                        UserRole activatedRole = ( UserRole ) activatedRoles.next();
+                        if ( map.contains( activatedRole.getName() ) )
+                        {
+                            matchCount++;
+                            if ( matchCount >= dsd.getCardinality() )
+                            {
+                                activatedRoles.remove();
+                                String warning = "validate userId [" + session.getUserId()
+                                    + "] failed activation of assignedRole [" + activatedRole.getName()
+                                    + "] validates DSD Set Name:" + dsd.getName() + " Cardinality:"
+                                    + dsd.getCardinality();
+                                LOG.warn( warning );
+                                rc = GlobalErrIds.ACTV_FAILED_DSD;
+                                session.setWarning( new ObjectFactory().createWarning( rc, warning,
+                                    Warning.Type.ROLE, activatedRole.getName() ) );
+                            }
+                        }
+                        else
+                        {
+                            Set<String> parentSet = RoleUtil.getAscendants( activatedRole.getName(), session.getUser()
+                                .getContextId() );
+                            // now check for every role inherited from this activated role:
+                            for ( String parentRole : parentSet )
+                            {
+                                if ( map.contains( parentRole ) )
+                                {
+                                    matchCount++;
+                                    if ( matchCount >= dsd.getCardinality() )
+                                    {
+                                        // remove the assigned role from session (not the authorized role):
+                                        activatedRoles.remove();
+                                        String warning = "validate userId [" + session.getUserId()
+                                            + "] assignedRole [" + activatedRole.getName() + "] parentRole ["
+                                            + parentRole + "] validates DSD Set Name:" + dsd.getName()
+                                            + " Cardinality:" + dsd.getCardinality();
+                                        LOG.warn( warning );
+                                        rc = GlobalErrIds.ACTV_FAILED_DSD;
+                                        session.setWarning( new ObjectFactory().createWarning( rc, warning, Warning.Type.ROLE, activatedRole.getName() ) );
+                                    }
+                                    // Breaking out of the loop here means the DSD algorithm will only match one
+                                    // role per parent.
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return rc;
+    }
+}
\ No newline at end of file


[51/51] [partial] git commit: 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.

Posted by sm...@apache.org.
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.


Project: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/commit/687ee1ad
Tree: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/tree/687ee1ad
Diff: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/diff/687ee1ad

Branch: refs/heads/master
Commit: 687ee1add5a47bcff272703cdcf315e2a509f0b0
Parents: b368289
Author: Shawn <sm...@apache.org>
Authored: Wed Oct 22 10:43:59 2014 -0500
Committer: Shawn <sm...@apache.org>
Committed: Wed Oct 22 10:43:59 2014 -0500

----------------------------------------------------------------------
 build.properties                                |    6 +-
 build.xml                                       |   26 +-
 config/bootstrap/fortress.properties.src        |   14 +-
 config/fortress.properties.src                  |   20 +-
 config/log4j.xml                                |    4 +-
 ldap/setup/CommanderDemoUsers.xml               |    2 +-
 ldap/setup/DelegatedAdminManagerLoad.xml        |  460 +-
 ldap/setup/FortressDemoUsers.xml                |   28 +-
 ldap/setup/HierarchicalAdminRoleExample.xml     |    2 +-
 ldap/setup/HierarchicalRoleExample.xml          |    2 +-
 ldap/setup/LdapGroupSetup.xml                   |    2 +-
 ldap/setup/LoadTestUsers.xml                    |    2 +-
 ldap/setup/OrgUnitExample.xml                   |    2 +-
 ldap/setup/RbacAcceleratorTestUsers.xml         |    2 +-
 ldap/setup/demo-fortressproject-users.xml       |   14 +-
 ldap/setup/refreshLDAPData-src.xml              |   34 +-
 .../directory/fortress/core/AccelMgr.java       |  215 +
 .../fortress/core/AccelMgrFactory.java          |   74 +
 .../directory/fortress/core/AccessMgr.java      |  295 +
 .../fortress/core/AccessMgrFactory.java         |   82 +
 .../directory/fortress/core/AdminMgr.java       | 1041 +++
 .../fortress/core/AdminMgrFactory.java          |  114 +
 .../directory/fortress/core/AuditMgr.java       |  199 +
 .../fortress/core/AuditMgrFactory.java          |  111 +
 .../fortress/core/AuthorizationException.java   |   42 +
 .../directory/fortress/core/BaseException.java  |   68 +
 .../fortress/core/BaseRuntimeException.java     |   83 +
 .../directory/fortress/core/CfgException.java   |   53 +
 .../fortress/core/CfgRuntimeException.java      |   66 +
 .../fortress/core/CreateException.java          |   52 +
 .../directory/fortress/core/DelAccessMgr.java   |  192 +
 .../fortress/core/DelAccessMgrFactory.java      |  114 +
 .../directory/fortress/core/DelAdminMgr.java    |  697 ++
 .../fortress/core/DelAdminMgrFactory.java       |  112 +
 .../directory/fortress/core/DelReviewMgr.java   |  146 +
 .../fortress/core/DelReviewMgrFactory.java      |  112 +
 .../fortress/core/FinderException.java          |   53 +
 .../directory/fortress/core/GlobalErrIds.java   | 1639 +++++
 .../directory/fortress/core/GlobalIds.java      |  580 ++
 .../directory/fortress/core/Manageable.java     |   54 +
 .../directory/fortress/core/ObjectFactory.java  |  476 ++
 .../fortress/core/PasswordException.java        |   42 +
 .../directory/fortress/core/PwPolicyMgr.java    |  305 +
 .../fortress/core/PwPolicyMgrFactory.java       |  112 +
 .../fortress/core/RemoveException.java          |   52 +
 .../directory/fortress/core/RestException.java  |   52 +
 .../directory/fortress/core/ReviewMgr.java      |  612 ++
 .../fortress/core/ReviewMgrFactory.java         |  112 +
 .../fortress/core/SecurityException.java        |  474 ++
 .../fortress/core/StandardException.java        |   37 +
 .../fortress/core/UpdateException.java          |   54 +
 .../fortress/core/ValidationException.java      |   44 +
 .../fortress/core/ant/Addadminrole.java         |   88 +
 .../core/ant/Addadminroleinheritance.java       |   85 +
 .../directory/fortress/core/ant/Addconfig.java  |   96 +
 .../fortress/core/ant/Addcontainer.java         |   94 +
 .../directory/fortress/core/ant/Addcontext.java |   85 +
 .../directory/fortress/core/ant/Addgroup.java   |   84 +
 .../fortress/core/ant/Addgroupmember.java       |   85 +
 .../fortress/core/ant/Addgroupproperty.java     |   85 +
 .../directory/fortress/core/ant/Addorgunit.java |   89 +
 .../fortress/core/ant/AddpermGrant.java         |   90 +
 .../directory/fortress/core/ant/AddpermObj.java |   88 +
 .../directory/fortress/core/ant/AddpermOp.java  |   92 +
 .../core/ant/Addpermorgunitinheritance.java     |   85 +
 .../fortress/core/ant/Addpwpolicy.java          |   97 +
 .../directory/fortress/core/ant/Addrole.java    |   84 +
 .../fortress/core/ant/Addroleinheritance.java   |   85 +
 .../directory/fortress/core/ant/Addsdset.java   |   91 +
 .../directory/fortress/core/ant/Addsuffix.java  |   84 +
 .../directory/fortress/core/ant/Adduser.java    |   92 +
 .../fortress/core/ant/Adduseradminrole.java     |   92 +
 .../core/ant/Adduserorgunitinheritance.java     |   85 +
 .../fortress/core/ant/Adduserrole.java          |   89 +
 .../fortress/core/ant/AdminRoleAnt.java         |  110 +
 .../directory/fortress/core/ant/ConfigAnt.java  |   61 +
 .../fortress/core/ant/Deladminrole.java         |   80 +
 .../core/ant/Deladminroleinheritance.java       |   86 +
 .../directory/fortress/core/ant/Delconfig.java  |   97 +
 .../fortress/core/ant/Delcontainer.java         |  105 +
 .../directory/fortress/core/ant/Delgroup.java   |   83 +
 .../fortress/core/ant/Delgroupmember.java       |   83 +
 .../fortress/core/ant/Delgroupproperty.java     |   83 +
 .../directory/fortress/core/ant/Delorgunit.java |   89 +
 .../fortress/core/ant/DelpermGrant.java         |   92 +
 .../directory/fortress/core/ant/DelpermObj.java |   85 +
 .../directory/fortress/core/ant/DelpermOp.java  |   96 +
 .../core/ant/Delpermorgunitinheritance.java     |   87 +
 .../fortress/core/ant/Delpwpolicy.java          |   84 +
 .../directory/fortress/core/ant/Delrole.java    |   85 +
 .../fortress/core/ant/Delroleinheritance.java   |   86 +
 .../directory/fortress/core/ant/Delsdset.java   |   84 +
 .../directory/fortress/core/ant/Delsuffix.java  |   96 +
 .../directory/fortress/core/ant/Deluser.java    |   87 +
 .../fortress/core/ant/Deluseradminrole.java     |   83 +
 .../core/ant/Deluserorgunitinheritance.java     |   87 +
 .../fortress/core/ant/Deluserrole.java          |   85 +
 .../fortress/core/ant/FortressAntTask.java      | 2435 ++++++
 .../directory/fortress/core/ant/PermAnt.java    |   68 +
 .../directory/fortress/core/ant/SDSetAnt.java   |   99 +
 .../directory/fortress/core/ant/UserAnt.java    |  301 +
 .../directory/fortress/core/ant/package.html    |   35 +
 .../directory/fortress/core/cfg/Config.java     |  347 +
 .../directory/fortress/core/cfg/ConfigDAO.java  |  299 +
 .../directory/fortress/core/cfg/ConfigMgr.java  |   96 +
 .../fortress/core/cfg/ConfigMgrFactory.java     |   68 +
 .../fortress/core/cfg/ConfigMgrImpl.java        |  119 +
 .../directory/fortress/core/cfg/ConfigP.java    |  202 +
 .../directory/fortress/core/cfg/package.html    |   37 +
 .../fortress/core/cli/CmdLineParser.java        |  690 ++
 .../core/cli/CommandLineInterpreter.java        | 1435 ++++
 .../directory/fortress/core/cli/Options.java    |  698 ++
 .../directory/fortress/core/cli/package.html    | 2044 ++++++
 .../directory/fortress/core/doc-files/ARbac.png |  Bin 0 -> 89522 bytes
 .../directory/fortress/core/doc-files/Audit.png |  Bin 0 -> 63789 bytes
 .../fortress/core/doc-files/PasswordPolicy.png  |  Bin 0 -> 90672 bytes
 .../fortress/core/doc-files/RbacCore.png        |  Bin 0 -> 39821 bytes
 .../fortress/core/doc-files/RbacCorex.png       |  Bin 0 -> 34087 bytes
 .../fortress/core/doc-files/RbacDSD.png         |  Bin 0 -> 55284 bytes
 .../fortress/core/doc-files/RbacHier.png        |  Bin 0 -> 45689 bytes
 .../fortress/core/doc-files/RbacSSD.png         |  Bin 0 -> 51303 bytes
 .../fortress/core/doc-files/TemporalRbac.png    |  Bin 0 -> 60020 bytes
 .../core/ldap/ApacheDsDataProvider.java         | 1384 ++++
 .../fortress/core/ldap/ConnectionPool.java      |  664 ++
 .../core/ldap/LdapClientTrustStoreManager.java  |  251 +
 .../fortress/core/ldap/LdapCounters.java        |  122 +
 .../directory/fortress/core/ldap/PoolMgr.java   |  619 ++
 .../core/ldap/UnboundIdDataProvider.java        | 1277 ++++
 .../core/ldap/container/OrganizationalUnit.java |  179 +
 .../ldap/container/OrganizationalUnitDAO.java   |  162 +
 .../ldap/container/OrganizationalUnitP.java     |  147 +
 .../fortress/core/ldap/container/package.html   |   36 +
 .../fortress/core/ldap/group/Group.java         |  421 ++
 .../fortress/core/ldap/group/GroupDAO.java      |  463 ++
 .../fortress/core/ldap/group/GroupMgr.java      |  135 +
 .../core/ldap/group/GroupMgrFactory.java        |  107 +
 .../fortress/core/ldap/group/GroupMgrImpl.java  |  244 +
 .../fortress/core/ldap/group/GroupP.java        |  213 +
 .../fortress/core/ldap/group/package.html       |   33 +
 .../core/ldap/openldap/OLPWControlImpl.java     |  417 ++
 .../fortress/core/ldap/openldap/package.html    |   33 +
 .../directory/fortress/core/ldap/package.html   |   33 +
 .../fortress/core/ldap/suffix/Suffix.java       |  134 +
 .../fortress/core/ldap/suffix/SuffixDAO.java    |  178 +
 .../fortress/core/ldap/suffix/SuffixP.java      |  146 +
 .../fortress/core/ldap/suffix/package.html      |   38 +
 .../directory/fortress/core/overview.html       |   68 +
 .../apache/directory/fortress/core/package.html |  148 +
 .../fortress/core/rbac/AccelMgrImpl.java        |  282 +
 .../fortress/core/rbac/AccessMgrImpl.java       |  439 ++
 .../directory/fortress/core/rbac/Address.java   |  469 ++
 .../fortress/core/rbac/AdminMgrImpl.java        | 1638 +++++
 .../directory/fortress/core/rbac/AdminRole.java |  488 ++
 .../fortress/core/rbac/AdminRoleP.java          |  403 +
 .../core/rbac/AdminRoleRelationship.java        |   63 +
 .../fortress/core/rbac/AdminRoleUtil.java       |  290 +
 .../directory/fortress/core/rbac/AdminUtil.java |  207 +
 .../fortress/core/rbac/Administrator.java       |  149 +
 .../fortress/core/rbac/AuditMgrImpl.java        |  259 +
 .../directory/fortress/core/rbac/AuditP.java    |  150 +
 .../directory/fortress/core/rbac/AuthZ.java     |  769 ++
 .../directory/fortress/core/rbac/Bind.java      |  579 ++
 .../fortress/core/rbac/CharArrayAdapter.java    |   42 +
 .../directory/fortress/core/rbac/ClassUtil.java |  103 +
 .../directory/fortress/core/rbac/Context.java   |   95 +
 .../fortress/core/rbac/DSDChecker.java          |  152 +
 .../fortress/core/rbac/DelAccessMgrImpl.java    |  455 ++
 .../fortress/core/rbac/DelAdminMgrImpl.java     | 1171 +++
 .../fortress/core/rbac/DelReviewMgrImpl.java    |  207 +
 .../fortress/core/rbac/FortEntity.java          |  236 +
 .../fortress/core/rbac/GlobalPwMsgIds.java      |  197 +
 .../directory/fortress/core/rbac/Graphable.java |   90 +
 .../directory/fortress/core/rbac/Hier.java      |  321 +
 .../directory/fortress/core/rbac/HierUtil.java  |  716 ++
 .../fortress/core/rbac/Manageable.java          |  156 +
 .../directory/fortress/core/rbac/Mod.java       |  326 +
 .../directory/fortress/core/rbac/OrgUnit.java   |  420 ++
 .../fortress/core/rbac/OrgUnitAnt.java          |   61 +
 .../directory/fortress/core/rbac/OrgUnitP.java  |  370 +
 .../fortress/core/rbac/OrgUnitRelationship.java |   65 +
 .../directory/fortress/core/rbac/PermGrant.java |  169 +
 .../directory/fortress/core/rbac/PermObj.java   |  554 ++
 .../directory/fortress/core/rbac/PermP.java     |  614 ++
 .../fortress/core/rbac/Permission.java          |  750 ++
 .../directory/fortress/core/rbac/PolicyP.java   |  378 +
 .../directory/fortress/core/rbac/Props.java     |  200 +
 .../directory/fortress/core/rbac/PsoUtil.java   |  274 +
 .../directory/fortress/core/rbac/PwMessage.java |  136 +
 .../directory/fortress/core/rbac/PwPolicy.java  |  779 ++
 .../fortress/core/rbac/PwPolicyControl.java     |   41 +
 .../fortress/core/rbac/PwPolicyMgrImpl.java     |  375 +
 .../fortress/core/rbac/Relationship.java        |  133 +
 .../fortress/core/rbac/ReviewMgrImpl.java       |  937 +++
 .../directory/fortress/core/rbac/Role.java      |  798 ++
 .../directory/fortress/core/rbac/RoleP.java     |  307 +
 .../directory/fortress/core/rbac/RolePerm.java  |   63 +
 .../fortress/core/rbac/RoleRelationship.java    |   63 +
 .../directory/fortress/core/rbac/RoleUtil.java  |  358 +
 .../directory/fortress/core/rbac/SDSet.java     |  413 ++
 .../directory/fortress/core/rbac/SDUtil.java    |  533 ++
 .../directory/fortress/core/rbac/SdP.java       |  221 +
 .../directory/fortress/core/rbac/Session.java   |  688 ++
 .../fortress/core/rbac/SetAdapter.java          |   77 +
 .../directory/fortress/core/rbac/User.java      | 1547 ++++
 .../fortress/core/rbac/UserAdminRole.java       |  613 ++
 .../directory/fortress/core/rbac/UserAudit.java |  289 +
 .../directory/fortress/core/rbac/UserP.java     |  843 +++
 .../directory/fortress/core/rbac/UserRole.java  |  618 ++
 .../directory/fortress/core/rbac/UsoUtil.java   |  262 +
 .../directory/fortress/core/rbac/Warning.java   |  157 +
 .../fortress/core/rbac/dao/AcceleratorDAO.java  |   39 +
 .../fortress/core/rbac/dao/AdminRoleDAO.java    |  200 +
 .../fortress/core/rbac/dao/AuditDAO.java        |  193 +
 .../fortress/core/rbac/dao/DAOType.java         |   27 +
 .../fortress/core/rbac/dao/DaoFactory.java      |  272 +
 .../fortress/core/rbac/dao/OrgUnitDAO.java      |  152 +
 .../fortress/core/rbac/dao/PermDAO.java         |  317 +
 .../fortress/core/rbac/dao/PolicyDAO.java       |  127 +
 .../fortress/core/rbac/dao/RoleDAO.java         |  177 +
 .../directory/fortress/core/rbac/dao/SdDAO.java |  154 +
 .../fortress/core/rbac/dao/UserDAO.java         |  200 +
 .../core/rbac/dao/apache/AcceleratorDAO.java    |  379 +
 .../core/rbac/dao/apache/AdminRoleDAO.java      |  694 ++
 .../fortress/core/rbac/dao/apache/AuditDAO.java |  784 ++
 .../core/rbac/dao/apache/OrgUnitDAO.java        |  706 ++
 .../fortress/core/rbac/dao/apache/PermDAO.java  | 1513 ++++
 .../core/rbac/dao/apache/PolicyDAO.java         |  685 ++
 .../fortress/core/rbac/dao/apache/RoleDAO.java  |  657 ++
 .../fortress/core/rbac/dao/apache/SdDAO.java    |  633 ++
 .../fortress/core/rbac/dao/apache/UserDAO.java  | 2383 ++++++
 .../core/rbac/dao/unboundid/AdminRoleDAO.java   |  656 ++
 .../core/rbac/dao/unboundid/AuditDAO.java       |  835 +++
 .../core/rbac/dao/unboundid/OrgUnitDAO.java     |  621 ++
 .../core/rbac/dao/unboundid/PermDAO.java        | 1405 ++++
 .../core/rbac/dao/unboundid/PolicyDAO.java      |  623 ++
 .../core/rbac/dao/unboundid/RoleDAO.java        |  593 ++
 .../fortress/core/rbac/dao/unboundid/SdDAO.java |  557 ++
 .../core/rbac/dao/unboundid/UserDAO.java        | 2365 ++++++
 .../directory/fortress/core/rbac/package.html   |   52 +
 .../fortress/core/rest/AccessMgrRestImpl.java   |  525 ++
 .../fortress/core/rest/AdminMgrRestImpl.java    | 1872 +++++
 .../fortress/core/rest/AuditMgrRestImpl.java    |  384 +
 .../fortress/core/rest/CachedJaxbContext.java   |   90 +
 .../fortress/core/rest/ConfigMgrRestImpl.java   |  199 +
 .../core/rest/DelAccessMgrRestImpl.java         |  450 ++
 .../fortress/core/rest/DelAdminMgrRestImpl.java | 1291 ++++
 .../core/rest/DelReviewMgrRestImpl.java         |  306 +
 .../fortress/core/rest/FortRequest.java         |  105 +
 .../fortress/core/rest/FortResponse.java        |  146 +
 .../directory/fortress/core/rest/HttpIds.java   |  156 +
 .../fortress/core/rest/JAXBCachedEntry.java     |   68 +
 .../fortress/core/rest/PwPolicyMgrRestImpl.java |  453 ++
 .../directory/fortress/core/rest/RestUtils.java |  483 ++
 .../fortress/core/rest/ReviewMgrRestImpl.java   | 1446 ++++
 .../directory/fortress/core/rest/package.html   |   43 +
 .../directory/fortress/core/util/LogUtil.java   |   76 +
 .../directory/fortress/core/util/Testable.java  |   32 +
 .../fortress/core/util/attr/AttrHelper.java     |  308 +
 .../fortress/core/util/attr/RegExUtil.java      |   68 +
 .../fortress/core/util/attr/VUtil.java          |  706 ++
 .../fortress/core/util/attr/package.html        |   33 +
 .../fortress/core/util/cache/Cache.java         |   82 +
 .../core/util/cache/CacheException.java         |   70 +
 .../fortress/core/util/cache/CacheFactory.java  |   52 +
 .../fortress/core/util/cache/CacheMgr.java      |  110 +
 .../fortress/core/util/cache/DsdCacheEntry.java |  153 +
 .../fortress/core/util/cache/EhCacheImpl.java   |  221 +
 .../fortress/core/util/cache/package.html       |   34 +
 .../fortress/core/util/crypto/EncryptUtil.java  |   94 +
 .../fortress/core/util/crypto/package.html      |   33 +
 .../directory/fortress/core/util/package.html   |   33 +
 .../fortress/core/util/time/CUtil.java          |  494 ++
 .../fortress/core/util/time/ClockTime.java      |   81 +
 .../fortress/core/util/time/Constraint.java     |  223 +
 .../directory/fortress/core/util/time/Date.java |  101 +
 .../directory/fortress/core/util/time/Day.java  |   71 +
 .../fortress/core/util/time/LockDate.java       |   88 +
 .../fortress/core/util/time/TUtil.java          |   74 +
 .../directory/fortress/core/util/time/Time.java |   44 +
 .../fortress/core/util/time/Timeout.java        |   73 +
 .../fortress/core/util/time/Validator.java      |   81 +
 .../fortress/core/util/time/package.html        |   34 +
 .../java/org/openldap/fortress/AccelMgr.java    |  214 -
 .../org/openldap/fortress/AccelMgrFactory.java  |   74 -
 .../java/org/openldap/fortress/AccessMgr.java   |  294 -
 .../org/openldap/fortress/AccessMgrFactory.java |   82 -
 .../java/org/openldap/fortress/AdminMgr.java    | 1041 ---
 .../org/openldap/fortress/AdminMgrFactory.java  |  114 -
 .../java/org/openldap/fortress/AuditMgr.java    |  199 -
 .../org/openldap/fortress/AuditMgrFactory.java  |  111 -
 .../fortress/AuthorizationException.java        |   42 -
 .../org/openldap/fortress/BaseException.java    |   68 -
 .../openldap/fortress/BaseRuntimeException.java |   83 -
 .../org/openldap/fortress/CfgException.java     |   53 -
 .../openldap/fortress/CfgRuntimeException.java  |   66 -
 .../org/openldap/fortress/CreateException.java  |   52 -
 .../org/openldap/fortress/DelAccessMgr.java     |  192 -
 .../openldap/fortress/DelAccessMgrFactory.java  |  114 -
 .../java/org/openldap/fortress/DelAdminMgr.java |  697 --
 .../openldap/fortress/DelAdminMgrFactory.java   |  112 -
 .../org/openldap/fortress/DelReviewMgr.java     |  146 -
 .../openldap/fortress/DelReviewMgrFactory.java  |  112 -
 .../org/openldap/fortress/FinderException.java  |   53 -
 .../org/openldap/fortress/GlobalErrIds.java     | 1639 -----
 .../java/org/openldap/fortress/GlobalIds.java   |  580 --
 .../java/org/openldap/fortress/Manageable.java  |   54 -
 .../org/openldap/fortress/ObjectFactory.java    |  476 --
 .../openldap/fortress/PasswordException.java    |   42 -
 .../java/org/openldap/fortress/PwPolicyMgr.java |  305 -
 .../openldap/fortress/PwPolicyMgrFactory.java   |  112 -
 .../org/openldap/fortress/RemoveException.java  |   52 -
 .../org/openldap/fortress/RestException.java    |   52 -
 .../java/org/openldap/fortress/ReviewMgr.java   |  612 --
 .../org/openldap/fortress/ReviewMgrFactory.java |  112 -
 .../openldap/fortress/SecurityException.java    |  474 --
 .../openldap/fortress/StandardException.java    |   37 -
 .../org/openldap/fortress/UpdateException.java  |   52 -
 .../openldap/fortress/ValidationException.java  |   42 -
 .../org/openldap/fortress/ant/Addadminrole.java |   88 -
 .../fortress/ant/Addadminroleinheritance.java   |   85 -
 .../org/openldap/fortress/ant/Addconfig.java    |   96 -
 .../org/openldap/fortress/ant/Addcontainer.java |   94 -
 .../org/openldap/fortress/ant/Addcontext.java   |   85 -
 .../org/openldap/fortress/ant/Addgroup.java     |   84 -
 .../openldap/fortress/ant/Addgroupmember.java   |   85 -
 .../openldap/fortress/ant/Addgroupproperty.java |   85 -
 .../org/openldap/fortress/ant/Addorgunit.java   |   89 -
 .../org/openldap/fortress/ant/AddpermGrant.java |   90 -
 .../org/openldap/fortress/ant/AddpermObj.java   |   88 -
 .../org/openldap/fortress/ant/AddpermOp.java    |   92 -
 .../fortress/ant/Addpermorgunitinheritance.java |   85 -
 .../org/openldap/fortress/ant/Addpwpolicy.java  |   97 -
 .../java/org/openldap/fortress/ant/Addrole.java |   84 -
 .../fortress/ant/Addroleinheritance.java        |   85 -
 .../org/openldap/fortress/ant/Addsdset.java     |   90 -
 .../org/openldap/fortress/ant/Addsuffix.java    |   84 -
 .../java/org/openldap/fortress/ant/Adduser.java |   92 -
 .../openldap/fortress/ant/Adduseradminrole.java |   92 -
 .../fortress/ant/Adduserorgunitinheritance.java |   85 -
 .../org/openldap/fortress/ant/Adduserrole.java  |   89 -
 .../org/openldap/fortress/ant/AdminRoleAnt.java |  110 -
 .../org/openldap/fortress/ant/ConfigAnt.java    |   61 -
 .../org/openldap/fortress/ant/Deladminrole.java |   80 -
 .../fortress/ant/Deladminroleinheritance.java   |   86 -
 .../org/openldap/fortress/ant/Delconfig.java    |   97 -
 .../org/openldap/fortress/ant/Delcontainer.java |  105 -
 .../org/openldap/fortress/ant/Delgroup.java     |   83 -
 .../openldap/fortress/ant/Delgroupmember.java   |   83 -
 .../openldap/fortress/ant/Delgroupproperty.java |   83 -
 .../org/openldap/fortress/ant/Delorgunit.java   |   89 -
 .../org/openldap/fortress/ant/DelpermGrant.java |   92 -
 .../org/openldap/fortress/ant/DelpermObj.java   |   85 -
 .../org/openldap/fortress/ant/DelpermOp.java    |   96 -
 .../fortress/ant/Delpermorgunitinheritance.java |   87 -
 .../org/openldap/fortress/ant/Delpwpolicy.java  |   84 -
 .../java/org/openldap/fortress/ant/Delrole.java |   85 -
 .../fortress/ant/Delroleinheritance.java        |   86 -
 .../org/openldap/fortress/ant/Delsdset.java     |   83 -
 .../org/openldap/fortress/ant/Delsuffix.java    |   96 -
 .../java/org/openldap/fortress/ant/Deluser.java |   87 -
 .../openldap/fortress/ant/Deluseradminrole.java |   83 -
 .../fortress/ant/Deluserorgunitinheritance.java |   87 -
 .../org/openldap/fortress/ant/Deluserrole.java  |   85 -
 .../openldap/fortress/ant/FortressAntTask.java  | 2433 ------
 .../java/org/openldap/fortress/ant/PermAnt.java |   68 -
 .../org/openldap/fortress/ant/SDSetAnt.java     |   99 -
 .../java/org/openldap/fortress/ant/UserAnt.java |  301 -
 .../java/org/openldap/fortress/ant/package.html |   35 -
 .../java/org/openldap/fortress/cfg/Config.java  |  347 -
 .../org/openldap/fortress/cfg/ConfigDAO.java    |  298 -
 .../org/openldap/fortress/cfg/ConfigMgr.java    |   96 -
 .../openldap/fortress/cfg/ConfigMgrFactory.java |   68 -
 .../openldap/fortress/cfg/ConfigMgrImpl.java    |  119 -
 .../java/org/openldap/fortress/cfg/ConfigP.java |  202 -
 .../java/org/openldap/fortress/cfg/package.html |   37 -
 .../openldap/fortress/cli/CmdLineParser.java    |  690 --
 .../fortress/cli/CommandLineInterpreter.java    | 1427 ----
 .../java/org/openldap/fortress/cli/Options.java |  693 --
 .../java/org/openldap/fortress/cli/package.html | 2044 ------
 .../org/openldap/fortress/doc-files/ARbac.png   |  Bin 89522 -> 0 bytes
 .../org/openldap/fortress/doc-files/Audit.png   |  Bin 63789 -> 0 bytes
 .../fortress/doc-files/PasswordPolicy.png       |  Bin 90672 -> 0 bytes
 .../openldap/fortress/doc-files/RbacCore.png    |  Bin 39821 -> 0 bytes
 .../openldap/fortress/doc-files/RbacCorex.png   |  Bin 34087 -> 0 bytes
 .../org/openldap/fortress/doc-files/RbacDSD.png |  Bin 55284 -> 0 bytes
 .../openldap/fortress/doc-files/RbacHier.png    |  Bin 45689 -> 0 bytes
 .../org/openldap/fortress/doc-files/RbacSSD.png |  Bin 51303 -> 0 bytes
 .../fortress/doc-files/TemporalRbac.png         |  Bin 60020 -> 0 bytes
 .../fortress/ldap/ApacheDsDataProvider.java     | 1384 ----
 .../openldap/fortress/ldap/ConnectionPool.java  |  665 --
 .../ldap/LdapClientTrustStoreManager.java       |  251 -
 .../openldap/fortress/ldap/LdapCounters.java    |  122 -
 .../org/openldap/fortress/ldap/PoolMgr.java     |  619 --
 .../fortress/ldap/UnboundIdDataProvider.java    | 1277 ----
 .../ldap/container/OrganizationalUnit.java      |  179 -
 .../ldap/container/OrganizationalUnitDAO.java   |  160 -
 .../ldap/container/OrganizationalUnitP.java     |  147 -
 .../fortress/ldap/container/package.html        |   36 -
 .../org/openldap/fortress/ldap/group/Group.java |  421 --
 .../openldap/fortress/ldap/group/GroupDAO.java  |  463 --
 .../openldap/fortress/ldap/group/GroupMgr.java  |  134 -
 .../fortress/ldap/group/GroupMgrFactory.java    |  108 -
 .../fortress/ldap/group/GroupMgrImpl.java       |  245 -
 .../openldap/fortress/ldap/group/GroupP.java    |  213 -
 .../openldap/fortress/ldap/group/package.html   |   33 -
 .../fortress/ldap/openldap/OLPWControlImpl.java |  417 --
 .../fortress/ldap/openldap/package.html         |   33 -
 .../org/openldap/fortress/ldap/package.html     |   33 -
 .../openldap/fortress/ldap/suffix/Suffix.java   |  134 -
 .../fortress/ldap/suffix/SuffixDAO.java         |  178 -
 .../openldap/fortress/ldap/suffix/SuffixP.java  |  145 -
 .../openldap/fortress/ldap/suffix/package.html  |   38 -
 .../java/org/openldap/fortress/overview.html    |   68 -
 .../java/org/openldap/fortress/package.html     |  148 -
 .../openldap/fortress/rbac/AccelMgrImpl.java    |  282 -
 .../openldap/fortress/rbac/AccessMgrImpl.java   |  439 --
 .../org/openldap/fortress/rbac/Address.java     |  469 --
 .../openldap/fortress/rbac/AdminMgrImpl.java    | 1638 -----
 .../org/openldap/fortress/rbac/AdminRole.java   |  488 --
 .../org/openldap/fortress/rbac/AdminRoleP.java  |  403 -
 .../fortress/rbac/AdminRoleRelationship.java    |   63 -
 .../openldap/fortress/rbac/AdminRoleUtil.java   |  290 -
 .../org/openldap/fortress/rbac/AdminUtil.java   |  204 -
 .../openldap/fortress/rbac/Administrator.java   |  149 -
 .../openldap/fortress/rbac/AuditMgrImpl.java    |  259 -
 .../java/org/openldap/fortress/rbac/AuditP.java |  150 -
 .../java/org/openldap/fortress/rbac/AuthZ.java  |  769 --
 .../java/org/openldap/fortress/rbac/Bind.java   |  579 --
 .../fortress/rbac/CharArrayAdapter.java         |   42 -
 .../org/openldap/fortress/rbac/ClassUtil.java   |  103 -
 .../org/openldap/fortress/rbac/Context.java     |   95 -
 .../org/openldap/fortress/rbac/DSDChecker.java  |  153 -
 .../fortress/rbac/DelAccessMgrImpl.java         |  454 --
 .../openldap/fortress/rbac/DelAdminMgrImpl.java | 1171 ---
 .../fortress/rbac/DelReviewMgrImpl.java         |  207 -
 .../org/openldap/fortress/rbac/FortEntity.java  |  236 -
 .../openldap/fortress/rbac/GlobalPwMsgIds.java  |  197 -
 .../org/openldap/fortress/rbac/Graphable.java   |   90 -
 .../java/org/openldap/fortress/rbac/Hier.java   |  321 -
 .../org/openldap/fortress/rbac/HierUtil.java    |  716 --
 .../org/openldap/fortress/rbac/Manageable.java  |  156 -
 .../java/org/openldap/fortress/rbac/Mod.java    |  326 -
 .../org/openldap/fortress/rbac/OrgUnit.java     |  420 --
 .../org/openldap/fortress/rbac/OrgUnitAnt.java  |   61 -
 .../org/openldap/fortress/rbac/OrgUnitP.java    |  370 -
 .../fortress/rbac/OrgUnitRelationship.java      |   65 -
 .../org/openldap/fortress/rbac/PermGrant.java   |  169 -
 .../org/openldap/fortress/rbac/PermObj.java     |  554 --
 .../java/org/openldap/fortress/rbac/PermP.java  |  614 --
 .../org/openldap/fortress/rbac/Permission.java  |  749 --
 .../org/openldap/fortress/rbac/PolicyP.java     |  377 -
 .../java/org/openldap/fortress/rbac/Props.java  |  200 -
 .../org/openldap/fortress/rbac/PsoUtil.java     |  274 -
 .../org/openldap/fortress/rbac/PwMessage.java   |  136 -
 .../org/openldap/fortress/rbac/PwPolicy.java    |  779 --
 .../openldap/fortress/rbac/PwPolicyControl.java |   41 -
 .../openldap/fortress/rbac/PwPolicyMgrImpl.java |  375 -
 .../openldap/fortress/rbac/Relationship.java    |  133 -
 .../openldap/fortress/rbac/ReviewMgrImpl.java   |  937 ---
 .../java/org/openldap/fortress/rbac/Role.java   |  798 --
 .../java/org/openldap/fortress/rbac/RoleP.java  |  307 -
 .../org/openldap/fortress/rbac/RolePerm.java    |   63 -
 .../fortress/rbac/RoleRelationship.java         |   63 -
 .../org/openldap/fortress/rbac/RoleUtil.java    |  358 -
 .../java/org/openldap/fortress/rbac/SDSet.java  |  413 --
 .../java/org/openldap/fortress/rbac/SDUtil.java |  533 --
 .../java/org/openldap/fortress/rbac/SdP.java    |  221 -
 .../org/openldap/fortress/rbac/Session.java     |  688 --
 .../org/openldap/fortress/rbac/SetAdapter.java  |   77 -
 .../java/org/openldap/fortress/rbac/User.java   | 1547 ----
 .../openldap/fortress/rbac/UserAdminRole.java   |  613 --
 .../org/openldap/fortress/rbac/UserAudit.java   |  289 -
 .../java/org/openldap/fortress/rbac/UserP.java  |  844 ---
 .../org/openldap/fortress/rbac/UserRole.java    |  618 --
 .../org/openldap/fortress/rbac/UsoUtil.java     |  262 -
 .../org/openldap/fortress/rbac/Warning.java     |  157 -
 .../fortress/rbac/dao/AcceleratorDAO.java       |   39 -
 .../fortress/rbac/dao/AdminRoleDAO.java         |  200 -
 .../openldap/fortress/rbac/dao/AuditDAO.java    |  193 -
 .../org/openldap/fortress/rbac/dao/DAOType.java |   27 -
 .../openldap/fortress/rbac/dao/DaoFactory.java  |  272 -
 .../openldap/fortress/rbac/dao/OrgUnitDAO.java  |  152 -
 .../org/openldap/fortress/rbac/dao/PermDAO.java |  317 -
 .../openldap/fortress/rbac/dao/PolicyDAO.java   |  127 -
 .../org/openldap/fortress/rbac/dao/RoleDAO.java |  177 -
 .../org/openldap/fortress/rbac/dao/SdDAO.java   |  154 -
 .../org/openldap/fortress/rbac/dao/UserDAO.java |  200 -
 .../rbac/dao/apache/AcceleratorDAO.java         |  378 -
 .../fortress/rbac/dao/apache/AdminRoleDAO.java  |  694 --
 .../fortress/rbac/dao/apache/AuditDAO.java      |  784 --
 .../fortress/rbac/dao/apache/OrgUnitDAO.java    |  706 --
 .../fortress/rbac/dao/apache/PermDAO.java       | 1513 ----
 .../fortress/rbac/dao/apache/PolicyDAO.java     |  685 --
 .../fortress/rbac/dao/apache/RoleDAO.java       |  657 --
 .../fortress/rbac/dao/apache/SdDAO.java         |  633 --
 .../fortress/rbac/dao/apache/UserDAO.java       | 2383 ------
 .../rbac/dao/unboundid/AdminRoleDAO.java        |  656 --
 .../fortress/rbac/dao/unboundid/AuditDAO.java   |  835 ---
 .../fortress/rbac/dao/unboundid/OrgUnitDAO.java |  621 --
 .../fortress/rbac/dao/unboundid/PermDAO.java    | 1405 ----
 .../fortress/rbac/dao/unboundid/PolicyDAO.java  |  623 --
 .../fortress/rbac/dao/unboundid/RoleDAO.java    |  593 --
 .../fortress/rbac/dao/unboundid/SdDAO.java      |  557 --
 .../fortress/rbac/dao/unboundid/UserDAO.java    | 2365 ------
 .../org/openldap/fortress/rbac/package.html     |   52 -
 .../fortress/rest/AccessMgrRestImpl.java        |  525 --
 .../fortress/rest/AdminMgrRestImpl.java         | 1865 -----
 .../fortress/rest/AuditMgrRestImpl.java         |  384 -
 .../fortress/rest/CachedJaxbContext.java        |   90 -
 .../fortress/rest/ConfigMgrRestImpl.java        |  199 -
 .../fortress/rest/DelAccessMgrRestImpl.java     |  450 --
 .../fortress/rest/DelAdminMgrRestImpl.java      | 1282 ----
 .../fortress/rest/DelReviewMgrRestImpl.java     |  306 -
 .../org/openldap/fortress/rest/FortRequest.java |  105 -
 .../openldap/fortress/rest/FortResponse.java    |  146 -
 .../org/openldap/fortress/rest/HttpIds.java     |  156 -
 .../openldap/fortress/rest/JAXBCachedEntry.java |   68 -
 .../fortress/rest/PwPolicyMgrRestImpl.java      |  453 --
 .../org/openldap/fortress/rest/RestUtils.java   |  484 --
 .../fortress/rest/ReviewMgrRestImpl.java        | 1446 ----
 .../org/openldap/fortress/rest/package.html     |   43 -
 .../org/openldap/fortress/util/LogUtil.java     |   76 -
 .../org/openldap/fortress/util/Testable.java    |   32 -
 .../openldap/fortress/util/attr/AttrHelper.java |  308 -
 .../openldap/fortress/util/attr/RegExUtil.java  |   66 -
 .../org/openldap/fortress/util/attr/VUtil.java  |  706 --
 .../openldap/fortress/util/attr/package.html    |   33 -
 .../org/openldap/fortress/util/cache/Cache.java |   82 -
 .../fortress/util/cache/CacheException.java     |   70 -
 .../fortress/util/cache/CacheFactory.java       |   52 -
 .../openldap/fortress/util/cache/CacheMgr.java  |  110 -
 .../fortress/util/cache/DsdCacheEntry.java      |  153 -
 .../fortress/util/cache/EhCacheImpl.java        |  221 -
 .../openldap/fortress/util/cache/package.html   |   34 -
 .../fortress/util/crypto/EncryptUtil.java       |   94 -
 .../openldap/fortress/util/crypto/package.html  |   33 -
 .../org/openldap/fortress/util/package.html     |   33 -
 .../org/openldap/fortress/util/time/CUtil.java  |  495 --
 .../openldap/fortress/util/time/ClockTime.java  |   81 -
 .../openldap/fortress/util/time/Constraint.java |  223 -
 .../org/openldap/fortress/util/time/Date.java   |  101 -
 .../org/openldap/fortress/util/time/Day.java    |   71 -
 .../openldap/fortress/util/time/LockDate.java   |   88 -
 .../org/openldap/fortress/util/time/TUtil.java  |   74 -
 .../org/openldap/fortress/util/time/Time.java   |   44 -
 .../openldap/fortress/util/time/Timeout.java    |   73 -
 .../openldap/fortress/util/time/Validator.java  |   81 -
 .../openldap/fortress/util/time/package.html    |   34 -
 src/test/build.xml                              |    4 +-
 .../fortress/core/AccessMgrConsole.java         |  559 ++
 .../fortress/core/AdminMgrConsole.java          | 1311 ++++
 .../fortress/core/AuditMgrConsole.java          |  846 +++
 .../fortress/core/ConfigMgrConsole.java         |  159 +
 .../core/DelegatedAccessMgrConsole.java         |  216 +
 .../fortress/core/DelegatedAdminMgrConsole.java |  682 ++
 .../core/DelegatedReviewMgrConsole.java         |  192 +
 .../fortress/core/EncryptMgrConsole.java        |   54 +
 .../fortress/core/FortressConsole.java          |   41 +
 .../fortress/core/GroupMgrConsole.java          |  334 +
 .../fortress/core/PolicyMgrConsole.java         |  165 +
 .../fortress/core/ProcessMenuCommand.java       | 1131 +++
 .../directory/fortress/core/ReaderUtil.java     |  116 +
 .../fortress/core/ReviewMgrConsole.java         | 1000 +++
 .../fortress/core/ant/TestAddUsers.xml          |  183 +
 .../fortress/core/example/Addexample.java       |   45 +
 .../fortress/core/example/Delexample.java       |   45 +
 .../fortress/core/example/EErrIds.java          |   36 +
 .../directory/fortress/core/example/EIds.java   |   45 +
 .../fortress/core/example/Example.java          |  228 +
 .../fortress/core/example/ExampleAdminMgr.java  |   38 +
 .../core/example/ExampleAdminMgrFactory.java    |   49 +
 .../core/example/ExampleAdminMgrImpl.java       |   59 +
 .../fortress/core/example/ExampleDAO.java       |  331 +
 .../fortress/core/example/ExampleP.java         |  149 +
 .../fortress/core/example/example.schema        |   53 +
 .../fortress/core/group/GroupAntTest.java       |  197 +
 .../fortress/core/group/LoadGroupTest1.xml      |   90 +
 .../fortress/core/group/LoadGroupTest2.xml      |  154 +
 .../fortress/core/group/LoadGroupTest3.xml      |   40 +
 .../core/jmeter/AccelCreateSession.java         |  142 +
 .../fortress/core/jmeter/CheckAccess.java       |  243 +
 .../core/jmeter/FortressCreateSession.java      |  139 +
 .../fortress/core/rbac/AccelMgrImplTest.java    |  455 ++
 .../fortress/core/rbac/AccessMgrImplTest.java   | 1261 ++++
 .../fortress/core/rbac/AdminMgrImplTest.java    | 2427 ++++++
 .../fortress/core/rbac/AdminRoleTestData.java   | 1019 +++
 .../fortress/core/rbac/AuditMgrImplTest.java    |  458 ++
 .../fortress/core/rbac/CacheSample.java         |  180 +
 .../core/rbac/DelegatedMgrImplTest.java         | 2079 ++++++
 .../fortress/core/rbac/FortressAntLoadTest.java |  413 ++
 .../fortress/core/rbac/FortressJUnitTest.java   |  360 +
 .../fortress/core/rbac/MyAnnotation.java        |   33 +
 .../fortress/core/rbac/OrgUnitTestData.java     |  925 +++
 .../directory/fortress/core/rbac/PRA.java       |  130 +
 .../fortress/core/rbac/PRATestData.java         | 1039 +++
 .../fortress/core/rbac/PermTestData.java        | 2899 ++++++++
 .../fortress/core/rbac/PolicyTestData.java      |  764 ++
 .../core/rbac/PswdPolicyMgrImplTest.java        | 1459 ++++
 .../fortress/core/rbac/ReviewMgrImplTest.java   | 1555 ++++
 .../fortress/core/rbac/RoleTestData.java        | 3922 ++++++++++
 .../directory/fortress/core/rbac/TestUtils.java |  293 +
 .../directory/fortress/core/rbac/URA.java       |  130 +
 .../fortress/core/rbac/URATestData.java         | 1038 +++
 .../fortress/core/rbac/UserTestData.java        | 6916 ++++++++++++++++++
 .../core/rbac/accelerator/TestAccelerator.java  |  277 +
 .../core/rbac/apacheds/AdminManagerTest.java    |  177 +
 .../apacheds/FortressJUnitApachedsTest.java     | 2502 +++++++
 .../fortress/core/samples/AccessMgrSample.java  |  492 ++
 .../core/samples/AllSamplesJUnitTest.java       |   92 +
 .../samples/CreatePermOrgHierarchySample.java   |  353 +
 .../core/samples/CreatePermOrgSample.java       |  164 +
 .../fortress/core/samples/CreatePermSample.java |  451 ++
 .../core/samples/CreateRoleHierarchySample.java |  324 +
 .../fortress/core/samples/CreateRoleSample.java |  304 +
 .../core/samples/CreateSessionSample.java       |  290 +
 .../samples/CreateUserOrgHierarchySample.java   |  354 +
 .../core/samples/CreateUserOrgSample.java       |  119 +
 .../core/samples/CreateUserRoleSample.java      |  174 +
 .../fortress/core/samples/CreateUserSample.java |  197 +
 .../samples/doc-files/HierPermOrgAscendants.png |  Bin 0 -> 11763 bytes
 .../doc-files/HierPermOrgDescendants.png        |  Bin 0 -> 11245 bytes
 .../samples/doc-files/HierPermOrgSimple.png     |  Bin 0 -> 16012 bytes
 .../samples/doc-files/HierRoleAscendants.png    |  Bin 0 -> 11015 bytes
 .../samples/doc-files/HierRoleDescendants.png   |  Bin 0 -> 10451 bytes
 .../core/samples/doc-files/HierRoleSimple.png   |  Bin 0 -> 14799 bytes
 .../samples/doc-files/HierUserOrgAscendants.png |  Bin 0 -> 11585 bytes
 .../doc-files/HierUserOrgDescendants.png        |  Bin 0 -> 11197 bytes
 .../samples/doc-files/HierUserOrgSimple.png     |  Bin 0 -> 16043 bytes
 .../fortress/core/samples/overview.html         |   82 +
 .../fortress/core/samples/package.html          |   46 +
 .../org/openldap/fortress/AccessMgrConsole.java |  559 --
 .../org/openldap/fortress/AdminMgrConsole.java  | 1312 ----
 .../org/openldap/fortress/AuditMgrConsole.java  |  846 ---
 .../org/openldap/fortress/ConfigMgrConsole.java |  159 -
 .../fortress/DelegatedAccessMgrConsole.java     |  216 -
 .../fortress/DelegatedAdminMgrConsole.java      |  682 --
 .../fortress/DelegatedReviewMgrConsole.java     |  192 -
 .../openldap/fortress/EncryptMgrConsole.java    |   54 -
 .../org/openldap/fortress/FortressConsole.java  |   41 -
 .../org/openldap/fortress/GroupMgrConsole.java  |  334 -
 .../org/openldap/fortress/PolicyMgrConsole.java |  165 -
 .../openldap/fortress/ProcessMenuCommand.java   | 1132 ---
 .../java/org/openldap/fortress/ReaderUtil.java  |  116 -
 .../org/openldap/fortress/ReviewMgrConsole.java | 1000 ---
 .../org/openldap/fortress/ant/TestAddUsers.xml  |  183 -
 .../openldap/fortress/example/Addexample.java   |   45 -
 .../openldap/fortress/example/Delexample.java   |   45 -
 .../org/openldap/fortress/example/EErrIds.java  |   36 -
 .../org/openldap/fortress/example/EIds.java     |   45 -
 .../org/openldap/fortress/example/Example.java  |  226 -
 .../fortress/example/ExampleAdminMgr.java       |   38 -
 .../example/ExampleAdminMgrFactory.java         |   48 -
 .../fortress/example/ExampleAdminMgrImpl.java   |   58 -
 .../openldap/fortress/example/ExampleDAO.java   |  329 -
 .../org/openldap/fortress/example/ExampleP.java |  149 -
 .../openldap/fortress/example/example.schema    |   53 -
 .../openldap/fortress/group/GroupAntTest.java   |  197 -
 .../openldap/fortress/group/LoadGroupTest1.xml  |   90 -
 .../openldap/fortress/group/LoadGroupTest2.xml  |  154 -
 .../openldap/fortress/group/LoadGroupTest3.xml  |   40 -
 .../fortress/jmeter/AccelCreateSession.java     |  141 -
 .../openldap/fortress/jmeter/CheckAccess.java   |  243 -
 .../fortress/jmeter/FortressCreateSession.java  |  138 -
 .../fortress/rbac/AccelMgrImplTest.java         |  455 --
 .../fortress/rbac/AccessMgrImplTest.java        | 1261 ----
 .../fortress/rbac/AdminMgrImplTest.java         | 2427 ------
 .../fortress/rbac/AdminRoleTestData.java        | 1018 ---
 .../fortress/rbac/AuditMgrImplTest.java         |  458 --
 .../org/openldap/fortress/rbac/CacheSample.java |  180 -
 .../fortress/rbac/DelegatedMgrImplTest.java     | 2079 ------
 .../fortress/rbac/FortressAntLoadTest.java      |  413 --
 .../fortress/rbac/FortressJUnitTest.java        |  360 -
 .../openldap/fortress/rbac/MyAnnotation.java    |   33 -
 .../openldap/fortress/rbac/OrgUnitTestData.java |  925 ---
 .../java/org/openldap/fortress/rbac/PRA.java    |  130 -
 .../org/openldap/fortress/rbac/PRATestData.java | 1039 ---
 .../openldap/fortress/rbac/PermTestData.java    | 2899 --------
 .../openldap/fortress/rbac/PolicyTestData.java  |  764 --
 .../fortress/rbac/PswdPolicyMgrImplTest.java    | 1459 ----
 .../fortress/rbac/ReviewMgrImplTest.java        | 1555 ----
 .../openldap/fortress/rbac/RoleTestData.java    | 3922 ----------
 .../org/openldap/fortress/rbac/TestUtils.java   |  292 -
 .../java/org/openldap/fortress/rbac/URA.java    |  130 -
 .../org/openldap/fortress/rbac/URATestData.java | 1038 ---
 .../openldap/fortress/rbac/UserTestData.java    | 6916 ------------------
 .../rbac/accelerator/TestAccelerator.java       |  276 -
 .../rbac/apacheds/AdminManagerTest.java         |  177 -
 .../apacheds/FortressJUnitApachedsTest.java     | 2502 -------
 .../fortress/samples/AccessMgrSample.java       |  492 --
 .../fortress/samples/AllSamplesJUnitTest.java   |   92 -
 .../samples/CreatePermOrgHierarchySample.java   |  353 -
 .../fortress/samples/CreatePermOrgSample.java   |  164 -
 .../fortress/samples/CreatePermSample.java      |  451 --
 .../samples/CreateRoleHierarchySample.java      |  324 -
 .../fortress/samples/CreateRoleSample.java      |  304 -
 .../fortress/samples/CreateSessionSample.java   |  290 -
 .../samples/CreateUserOrgHierarchySample.java   |  354 -
 .../fortress/samples/CreateUserOrgSample.java   |  119 -
 .../fortress/samples/CreateUserRoleSample.java  |  174 -
 .../fortress/samples/CreateUserSample.java      |  197 -
 .../samples/doc-files/HierPermOrgAscendants.png |  Bin 11763 -> 0 bytes
 .../doc-files/HierPermOrgDescendants.png        |  Bin 11245 -> 0 bytes
 .../samples/doc-files/HierPermOrgSimple.png     |  Bin 16012 -> 0 bytes
 .../samples/doc-files/HierRoleAscendants.png    |  Bin 11015 -> 0 bytes
 .../samples/doc-files/HierRoleDescendants.png   |  Bin 10451 -> 0 bytes
 .../samples/doc-files/HierRoleSimple.png        |  Bin 14799 -> 0 bytes
 .../samples/doc-files/HierUserOrgAscendants.png |  Bin 11585 -> 0 bytes
 .../doc-files/HierUserOrgDescendants.png        |  Bin 11197 -> 0 bytes
 .../samples/doc-files/HierUserOrgSimple.png     |  Bin 16043 -> 0 bytes
 .../org/openldap/fortress/samples/overview.html |   82 -
 .../org/openldap/fortress/samples/package.html  |   46 -
 711 files changed, 128730 insertions(+), 128675 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/build.properties
----------------------------------------------------------------------
diff --git a/build.properties b/build.properties
index dc24129..c7a3583 100644
--- a/build.properties
+++ b/build.properties
@@ -63,12 +63,12 @@ http.protocol=http
 ########################################################################
 
 # This param tells fortress what type of ldap server in use:
-ldap.server.type=openldap
+#ldap.server.type=openldap
 #ldap.server.type=apacheds
 # This is the default:
 #ldap.client.type=unboundid
 # To override and use apache ldap API uncomment this:
-#ldap.client.type=apache
+ldap.client.type=apache
 
 # These parameters point fortress to LDAP host:
 ldap.host=localhost
@@ -91,7 +91,7 @@ ldap.uris=ldap://${ldap.host}:${ldap.port}
 #tls.key.file=server-key.pem
 
 # These are used to construct suffix for DIT, i.e. dc=example,dc=com.
-suffix.name=openldap
+suffix.name=apache
 suffix.dc=org
 
 #suffix.name=example

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/build.xml
----------------------------------------------------------------------
diff --git a/build.xml b/build.xml
index 68d4ca9..3a26e68 100644
--- a/build.xml
+++ b/build.xml
@@ -37,8 +37,8 @@
        <property name="title" value="Fortress Identity and Access Management SDK for Java ${version}"/>
        <property name="title.samples" value="Fortress Identity and Access Management Samples for Java ${version}"/>
        <property name="vendor" value="Joshua Tree Software"/>
-       <property name="package" value="org.openldap.fortress.*"/>
-       <property name="package.samples" value="org.openldap.fortress.samples"/>
+       <property name="package" value="org.apache.directory.fortress.*"/>
+       <property name="package.samples" value="org.apache.directory.fortress.core.samples"/>
        <property name="images.dir" value="${basedir}/images"/>
 
        <!-- ########### Env specific properties ########################### -->
@@ -136,9 +136,9 @@
        <property name="javadoc.dir" value="${dist.dir}/docs/api"/>
        <property name="javadoc.images.dir" value="${javadoc.dir}/images"/>
        <property name="javadoc.bottom" value="&lt;small&gt;Copyright &amp;copy; 2009-2014, The OpenLDAP Foundation. All Rights Reserved. Generated ${TODAY}&lt;/small&gt;"/>
-       <property name="javadoc.overview" value="${src.java.dir}/org/openldap/fortress/overview.html" />
+       <property name="javadoc.overview" value="/org/apache/directory/fortress/overview.html" />
        <property name="javadoc.dist.zip" value="${dist.dir}/${name}-${version}-javadoc.jar"/>
-       <property name="javadoc.stylesheet" value="${src.java.dir}/org/openldap/fortress/fortress-javadoc.css" />
+       <property name="javadoc.stylesheet" value="/org/apache/directory/fortress/fortress-javadoc.css" />
        <property name="javadoc.samples.dir" value="${dist.dir}/docs/samples"/>
        <property name="javadoc.samples.images.dir" value="${javadoc.samples.dir}/images"/>
        <property name="javadoc.samples.dist.zip" value="${dist.dir}/${name}-${version}-javadocsamples.jar"/>
@@ -263,8 +263,8 @@
        </path>
 
        <!-- ########### Test properties ########################### -->
-       <property name="test.sample.entry" value="org.openldap.fortress.samples.AllSamplesJUnitTest"/>
-       <property name="test.regression.entry"  value="org.openldap.fortress.rbac.FortressJUnitTest"/>
+       <property name="test.sample.entry" value="org.apache.directory.fortress.core.samples.AllSamplesJUnitTest"/>
+       <property name="test.regression.entry"  value="org.apache.directory.fortress.core.rbac.FortressJUnitTest"/>
        <property name="test.failonerror" value="false" />
        <property name="test.showoutput" value="yes" />
 
@@ -507,7 +507,7 @@
             <sysproperty key="tenant" value="${tenant}"/>
             <classpath refid="test.class.path"/>
             <formatter type="plain" usefile="false"/>
-            <test name="org.openldap.fortress.rbac.apacheds.FortressJUnitApachedsTest"/>
+            <test name="org.apache.directory.fortress.core.rbac.apacheds.FortressJUnitApachedsTest"/>
         </junit>
     </target>
 
@@ -520,7 +520,7 @@
             <sysproperty key="tenant" value="${tenant}"/>
             <classpath refid="test.class.path"/>
             <formatter type="plain" usefile="false"/>
-            <test name="org.openldap.fortress.rbac.accelerator.TestAccelerator"/>
+            <test name="org.apache.directory.fortress.core.rbac.accelerator.TestAccelerator"/>
         </junit>
     </target>
 
@@ -533,7 +533,7 @@
             <sysproperty key="tenant" value="${tenant}"/>
             <classpath refid="test.class.path"/>
             <formatter type="plain" usefile="false"/>
-            <test name="org.openldap.fortress.rbac.AccelMgrImplTest"/>
+            <test name="org.apache.directory.fortress.core.rbac.AccelMgrImplTest"/>
         </junit>
     </target>
 
@@ -543,7 +543,7 @@
      <target name="console" depends="build-jar,compile-test,init-fortress-config" description="--> start Fortress Console app">
          <echo message="Run the Fortress console app"/>
          <java
-                 classname="org.openldap.fortress.FortressConsole"
+                 classname="org.apache.directory.fortress.core.FortressConsole"
                  fork="false"
                  failonerror="true"
                  timeout="4000000"
@@ -560,7 +560,7 @@
      <target name="cli" depends="build-jar,compile,init-fortress-config" description="--> start Fortress Command Line Interpreter">
          <echo message="Run the Fortress Command Line Interpreter"/>
          <java
-                 classname="org.openldap.fortress.cli.CommandLineInterpreter"
+                 classname="org.apache.directory.fortress.core.cli.CommandLineInterpreter"
                  fork="false"
                  failonerror="true"
                  timeout="4000000"
@@ -577,7 +577,7 @@
      <target name="encrypt" depends="compile" description="--> encrypt -Dparam1=value : encrypts value from clear text to encrypted cypher string that is hex encoded">
          <echo message="Encrypt a value"/>
          <java
-                 classname="org.openldap.fortress.util.crypto.EncryptUtil"
+                 classname="org.apache.directory.fortress.core.util.crypto.EncryptUtil"
                  fork="false"
                  failonerror="true"
                  timeout="4000000"
@@ -1309,7 +1309,7 @@
     <target name="compile-schema" depends="init-jaxb,generate-schema" description="--> generates Java classes based on Fortress schema">
         <echo message="Compiling the schema..."/>
         <mkdir dir="${generated.classes.dir}"/>
-        <xjc schema="${generated.schema.dir}/schema1.xsd" destdir="${src.java.dir}" package="org.openldap.fortress.model" removeOldOutput="yes"/>
+        <xjc schema="${generated.schema.dir}/schema1.xsd" destdir="${src.java.dir}" package="org.apache.directory.fortress.model" removeOldOutput="yes"/>
     </target>
 
     <!-- =================================

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/config/bootstrap/fortress.properties.src
----------------------------------------------------------------------
diff --git a/config/bootstrap/fortress.properties.src b/config/bootstrap/fortress.properties.src
index 713adbe..d5dafd8 100755
--- a/config/bootstrap/fortress.properties.src
+++ b/config/bootstrap/fortress.properties.src
@@ -72,11 +72,11 @@ example.root=ou=Examples,@SUFFIX@
 superadmin.role=oamSuperAdmin
 
 # these properties will enable temporal constraint checks on role activations:
-temporal.validator.0=org.openldap.fortress.util.time.Date
-temporal.validator.1=org.openldap.fortress.util.time.LockDate
-temporal.validator.2=org.openldap.fortress.util.time.Timeout
-temporal.validator.3=org.openldap.fortress.util.time.ClockTime
-temporal.validator.4=org.openldap.fortress.util.time.Day
+temporal.validator.0=org.apache.directory.fortress.core.util.time.Date
+temporal.validator.1=org.apache.directory.fortress.core.util.time.LockDate
+temporal.validator.2=org.apache.directory.fortress.core.util.time.Timeout
+temporal.validator.3=org.apache.directory.fortress.core.util.time.ClockTime
+temporal.validator.4=org.apache.directory.fortress.core.util.time.Day
 
 # enabling this property will enable Dynamic Separation of Duty constraint checks on role activations:
 temporal.validator.dsd=us.jts.fortress.rbac.DSDChecker
@@ -89,8 +89,8 @@ sys.user.4=oamTU6User4
 sys.user.5=oamTU6User5
 
 # Fortress Class Definitions:  NOT NEEDED UNLESS OVERIDING DEFAULT IMPLEMENTATIONS
-accessmgr.implementation=org.openldap.fortress.rbac.AccessMgrImpl
-auditmgr.implementation=org.openldap.fortress.rbac.AuditMgrImpl
+accessmgr.implementation=org.apache.directory.fortress.core.rbac.AccessMgrImpl
+auditmgr.implementation=org.apache.directory.fortress.core.rbac.AuditMgrImpl
 
 dao.connector=@LDAP_CLIENT_TYPE@
 

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/config/fortress.properties.src
----------------------------------------------------------------------
diff --git a/config/fortress.properties.src b/config/fortress.properties.src
index fda8446..563c2d7 100755
--- a/config/fortress.properties.src
+++ b/config/fortress.properties.src
@@ -70,15 +70,15 @@ http.port=@REST_HTTP_PORT@
 
 dao.connector=@LDAP_CLIENT_TYPE@
 
-GroupTest=org.openldap.fortress.group.GroupAntTest
+GroupTest=org.apache.directory.fortress.core.group.GroupAntTest
 
 # These may be used to override default LDAP or REST with OTHER implementations:
-#reviewmgr.implementation=org.openldap.fortress.rest.ReviewMgrOtherImpl
-#adminmgr.implementation=org.openldap.fortress.rest.AdminMgrOtherImpl
-#accessmgr.implementation=org.openldap.fortress.rest.AccessMgrOtherImpl
-#delegated.adminmgr.implementation=org.openldap.fortress.rest.DelAdminMgrOtherImpl
-#delegated.reviewmgr.implementation=org.openldap.fortress.rest.DelReviewMgrOtherImpl
-#policymgr.implementation=org.openldap.fortress.rest.PwPolicyMgrOtherImpl
-#delegated.accessmgr.implementation=org.openldap.fortress.rest.DelAccessMgrOtherImpl
-#auditmgr.implementation=org.openldap.fortress.rest.AuditMgrOtherImpl
-#configmgr.implementation=org.openldap.fortress.rest.ConfigMgrOtherImpl
\ No newline at end of file
+#reviewmgr.implementation=org.apache.directory.fortress.core.rest.ReviewMgrOtherImpl
+#adminmgr.implementation=org.apache.directory.fortress.core.rest.AdminMgrOtherImpl
+#accessmgr.implementation=org.apache.directory.fortress.core.rest.AccessMgrOtherImpl
+#delegated.adminmgr.implementation=org.apache.directory.fortress.core.rest.DelAdminMgrOtherImpl
+#delegated.reviewmgr.implementation=org.apache.directory.fortress.core.rest.DelReviewMgrOtherImpl
+#policymgr.implementation=org.apache.directory.fortress.core.rest.PwPolicyMgrOtherImpl
+#delegated.accessmgr.implementation=org.apache.directory.fortress.core.rest.DelAccessMgrOtherImpl
+#auditmgr.implementation=org.apache.directory.fortress.core.rest.AuditMgrOtherImpl
+#configmgr.implementation=org.apache.directory.fortress.core.rest.ConfigMgrOtherImpl
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/config/log4j.xml
----------------------------------------------------------------------
diff --git a/config/log4j.xml b/config/log4j.xml
index e2097b6..71a7b1f 100755
--- a/config/log4j.xml
+++ b/config/log4j.xml
@@ -37,13 +37,13 @@
     </appender>
 
     <!-- Uncomment to store REST log statements to file:
-        <category name="org.openldap.fortress.rest.RestUtils" class="org.apache.log4j.Logger" additivity="false">
+        <category name="org.apache.directory.fortress.core.rest.RestUtils" class="org.apache.log4j.Logger" additivity="false">
             <priority value="INFO" class="org.apache.log4j.Level"/>
             <appender-ref ref="file"/>
         </category>
     -->
 
-    <category name="org.openldap.fortress.example" class="org.apache.log4j.Logger" additivity="false">
+    <category name="org.apache.directory.fortress.core.example" class="org.apache.log4j.Logger" additivity="false">
         <priority value="DEBUG" class="org.apache.log4j.Level"/>
         <appender-ref ref="console"/>
     </category>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/ldap/setup/CommanderDemoUsers.xml
----------------------------------------------------------------------
diff --git a/ldap/setup/CommanderDemoUsers.xml b/ldap/setup/CommanderDemoUsers.xml
index e67032f..55e4a2f 100644
--- a/ldap/setup/CommanderDemoUsers.xml
+++ b/ldap/setup/CommanderDemoUsers.xml
@@ -18,7 +18,7 @@
    under the License.
 -->
 <project basedir="." default="all" name="Fortress Sample Data">
-    <taskdef classname="org.openldap.fortress.ant.FortressAntTask" name="FortressAdmin" >
+    <taskdef classname="org.apache.directory.fortress.core.ant.FortressAntTask" name="FortressAdmin" >
         <classpath path="${java.class.path}"/>
     </taskdef>
 


[28/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/DelAccessMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/DelAccessMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/rbac/DelAccessMgrImpl.java
new file mode 100755
index 0000000..f9681ca
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/DelAccessMgrImpl.java
@@ -0,0 +1,455 @@
+/*
+ *   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 org.apache.directory.fortress.core.DelAccessMgr;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.util.time.CUtil;
+
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * This class implements the ARBAC02 DelAccessMgr interface for performing runtime delegated access control operations on objects that are provisioned Fortress ARBAC entities
+ * that reside in LDAP directory.  These APIs map directly to similar named APIs specified by ARBAC02 functions.  The ARBAC Functional specification describes delegated administrative
+ * operations for the creation and maintenance of ARBAC element sets and relations.  Delegated administrative review functions for performing administrative queries
+ * and system functions for creating and managing ARBAC attributes on user sessions and making delegated administrative access control decisions.
+ *
+ * This class also extends the RBAC AccessMgrImpl object which is used for performing runtime session creation and
+ * access control decisions based on behalf of administrative user who is logged onto the system.  (See the AccessMgr javadoc for more info of how RBAC works).
+ *
+ * This class provides both sets of functionality as is necessary to fulfill runtime delegated administrative access control functionality
+ * within RBAC provisioning systems.
+ * <h3>Administrative Role Based Access Control (ARBAC)</h3>
+ * <img src="../doc-files/ARbac.png">
+ * <p/>
+ * Fortress fully supports the Oh/Sandhu/Zhang ARBAC02 model for delegated administration.  ARBAC provides large enterprises the capability to delegate administrative authority to users that reside outside of the security admin group.
+ * Decentralizing administration helps because it provides security provisioning capability to work groups without sacrificing regulations for accountability or traceability.
+ * <p/>
+ * This class is NOT thread safe if parent instance variables ({@link #contextId} or {@link #adminSess}) are set.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class DelAccessMgrImpl extends AccessMgrImpl implements DelAccessMgr
+{
+    private static final String CLS_NM = DelAccessMgrImpl.class.getName();
+    private static final UserP userP = new UserP();
+    private static final PermP permP = new PermP();
+    private static final String SUPER_ADMIN = Config.getProperty("superadmin.role", "FortressSuperAdmin");
+
+    // package private constructor ensures outside classes cannot use:
+    DelAccessMgrImpl()
+    {}
+
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized assignment control over
+     * User-Role Assignment (URA).  This adheres to the ARBAC02 functional specification for can-assign URA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession(org.apache.directory.fortress.core.rbac.User, boolean)} before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param user    Instantiated User entity requires only valid userId attribute set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws org.apache.directory.fortress.core.SecurityException In the event of data validation error (i.e. invalid userId or role name) or system error.
+     */
+    @Override
+    public boolean canAssign(Session session, User user, Role role)
+        throws SecurityException
+    {
+        String methodName = "canAssign";
+        assertContext(CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL);
+        assertContext(CLS_NM, methodName, user, GlobalErrIds.USER_NULL);
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL);
+        return checkUserRole(session, user, role);
+    }
+
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized revoke control over
+     * User-Role Assignment (URA).  This adheres to the ARBAC02 functional specification for can-revoke URA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param user    Instantiated User entity requires only valid userId attribute set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws SecurityException In the event of data validation error (i.e. invalid userId or role name) or system error.
+     */
+    @Override
+    public boolean canDeassign(Session session, User user, Role role)
+        throws SecurityException
+    {
+        String methodName = "canDeassign";
+        assertContext(CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL);
+        assertContext(CLS_NM, methodName, user, GlobalErrIds.USER_NULL);
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL);
+        return checkUserRole(session, user, role);
+    }
+
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized assignment control over
+     * Permission-Role Assignment (PRA).  This adheres to the ARBAC02 functional specification for can-assign-p PRA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param perm    Instantiated Permission entity requires valid object name and operation name attributes set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws org.apache.directory.fortress.core.SecurityException In the event of data validation error (i.e. invalid perm or role name) or system error.
+     */
+    @Override
+    public boolean canGrant(Session session, Role role, Permission perm)
+        throws SecurityException
+    {
+        String methodName = "canGrant";
+        assertContext(CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL);
+        assertContext(CLS_NM, methodName, perm, GlobalErrIds.PERM_OBJECT_NULL);
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL);
+        return checkRolePermission(session, role, perm);
+    }
+
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized revoke control over
+     * Permission-Role Assignment (PRA).  This adheres to the ARBAC02 functional specification for can-revoke-p PRA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param perm    Instantiated Permission entity requires valid object name and operation name attributes set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws SecurityException In the event of data validation error (i.e. invalid perm or role name) or system error.
+     */
+    @Override
+    public boolean canRevoke(Session session, Role role, Permission perm)
+        throws SecurityException
+    {
+        String methodName = "canRevoke";
+        assertContext(CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL);
+        assertContext(CLS_NM, methodName, perm, GlobalErrIds.PERM_OBJECT_NULL);
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL);
+        return checkRolePermission(session, role, perm);
+    }
+
+    /**
+     * This function overrides same in RBAC's AccessMgrImpl, but instead processes permissions contained within AdminPerm dataset.
+     * Function returns a Boolean value containing result of a given administrator's access to perform a given operation on a given object.
+     * The function is valid if and only if the session is a valid Fortress session, the object is a member of the AdminPerm OBJS data set,
+     * and the operation is a member of the AdminPerms OPS data set. The session's subject has the permission
+     * to perform the operation on that object if and only if that permission is assigned to (at least)
+     * one of the session's active roles. This implementation will verify the roles or userId correspond
+     * to the subject's active roles are registered in the object's access control list.
+     *
+     * @param perm object contains obj attribute which is a String and contains the name of the object user is trying to access;
+     * perm object contains operation attribute which is also a String and contains the operation name for the object.
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return True of user has access, false otherwise.
+     * @throws SecurityException In the event of data validation error (i.e. invalid perm name) or system error.
+     */
+    @Override
+    public boolean checkAccess(Session session, Permission perm)
+        throws SecurityException
+    {
+        String methodName =  "checkAccess";
+        assertContext(CLS_NM, methodName, perm, GlobalErrIds.PERM_NULL);
+        VUtil.assertNotNullOrEmpty(perm.getOpName(), GlobalErrIds.PERM_OPERATION_NULL, methodName);
+        VUtil.assertNotNullOrEmpty(perm.getObjName(), GlobalErrIds.PERM_OBJECT_NULL, methodName);
+        assertContext(CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL);
+        // This flag set will check administrative permission data set.
+        perm.setAdmin(true);
+        return super.checkAccess(session, perm);
+    }
+
+
+    /**
+     * This function adds an adminRole as an active role of a session whose owner is a given user.
+     * <p>
+     * The function is valid if and only if:
+     * <ul>
+     *  <li> the user is a member of the USERS data set
+     *  <li> the role is a member of the ADMIN ROLES data set
+     *  <li> the session is a valid Fortress session
+     *  <li> the user is authorized to that admin role
+     *  <li> the session is owned by that user.
+     * </ul>
+     * </p>
+     * @param session object contains the user's returned RBAC and ARBAC sessions from the createSession method.
+     * @param role    object contains the adminRole name to be activated into session.
+     * @throws org.apache.directory.fortress.core.SecurityException is thrown if user is not allowed to activate or runtime error occurs with system.
+     */
+    @Override
+    public void addActiveRole(Session session, UserAdminRole role)
+        throws SecurityException
+    {
+        String methodName = "addActiveRole";
+        assertContext(CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL);
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ARLE_NULL);
+        role.setUserId(session.getUserId());
+        List<UserAdminRole> sRoles = session.getAdminRoles();
+        // If session already has admin role activated log an error and throw an exception:
+        if (sRoles != null && sRoles.contains(role))
+        {
+            String info = getFullMethodName(CLS_NM, methodName) + " User [" + session.getUserId() + "] Role [" + role.getName() + "] role already activated.";
+            throw new SecurityException(GlobalErrIds.ARLE_ALREADY_ACTIVE, info);
+        }
+
+        User ue = userP.read(session.getUser(), true);
+        List<UserAdminRole> uRoles = ue.getAdminRoles();
+        int indx;
+        // Is the admin role activation target valid for this user?
+        if (!VUtil.isNotNullOrEmpty(uRoles) || ((indx = uRoles.indexOf(role)) == -1))
+        {
+            String info = getFullMethodName(CLS_NM, methodName) + " Admin Role [" + role.getName() + "] User [" + session.getUserId() + "] adminRole not authorized for user.";
+            throw new SecurityException(GlobalErrIds.ARLE_ACTIVATE_FAILED, info);
+        }
+        SDUtil.validateDSD( session, role );
+
+        // now activate the role to the session:
+        session.setRole(uRoles.get(indx));
+    }
+
+    /**
+     * This function deactivates adminRole from the active adminRole set of a session owned by a given user.
+     * The function is valid if and only if the user is a member of the USERS data set, the
+     * session object contains a valid Fortress session, the session is owned by the user,
+     * and the adminRole is an active adminRole of that session.
+     *
+     * @param session object contains the user's returned RBAC and ARBAC sessions from the createSession method.
+     * @param role    object contains the adminRole name to be deactivated.
+     * @throws org.apache.directory.fortress.core.SecurityException is thrown if user is not allowed to deactivate or runtime error occurs with system.
+     */
+    @Override
+    public void dropActiveRole(Session session, UserAdminRole role)
+        throws SecurityException
+    {
+        String methodName = "dropActiveRole";
+        assertContext(CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL);
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ARLE_NULL);
+        role.setUserId(session.getUserId());
+        List<UserAdminRole> roles = session.getAdminRoles();
+        VUtil.assertNotNull(roles, GlobalErrIds.ARLE_DEACTIVE_FAILED, methodName);
+        int indx = roles.indexOf(role);
+        if (indx != -1)
+        {
+            roles.remove(role);
+        }
+        else
+        {
+            String info = methodName + " Admin Role [" + role.getName() + "] User [" + session.getUserId() + "], not previously activated";
+            throw new SecurityException(GlobalErrIds.ARLE_NOT_ACTIVE, info);
+        }
+    }
+
+    /**
+     * This function returns the active admin roles associated with a session. The function is valid if
+     * and only if the session is a valid Fortress session.
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return List<UserAdminRole> containing all adminRoles active in user's session.  This will NOT contain inherited roles.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    @Override
+    public List<UserAdminRole> sessionAdminRoles(Session session)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, CLS_NM + ".sessionAdminRoles");
+        return session.getAdminRoles();
+    }
+
+    /**
+     * This function returns the authorized admin roles associated with a session based on hierarchical relationships. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned ARBAC session from the createSession method.
+     * @return Set<String> containing all adminRoles authorized in user's session.  This will contain inherited roles.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    @Override
+    public Set<String> authorizedAdminRoles(Session session)
+        throws SecurityException
+    {
+        String methodName = "authorizedAdminRoles";
+        assertContext(CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL);
+        assertContext( CLS_NM, methodName, session.getUser(), GlobalErrIds.USER_NULL );
+        return AdminRoleUtil.getInheritedRoles( session.getAdminRoles(), this.contextId );
+    }
+
+    /**
+     * This function returns the ARBAC (administrative) permissions of the session, i.e., the permissions assigned
+     * to its authorized admin roles. The function is valid if and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned ARBAC session from the createSession method.
+     * @return List<Permission> containing admin permissions (op, obj) active for user's session.
+     * @throws SecurityException in the event runtime error occurs with system.
+     */
+    @Override
+    public List<Permission> sessionPermissions(Session session)
+        throws SecurityException
+    {
+        String methodName = "sessionPermissions";
+        assertContext(CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL);
+        CUtil.validateConstraints( session, CUtil.ConstraintType.USER, false );
+        CUtil.validateConstraints( session, CUtil.ConstraintType.ROLE, false );
+        return permP.search( session, true );
+    }
+
+    /**
+     * This helper function processes ARBAC URA "can assign".
+     * @param session
+     * @param user
+     * @param role
+     * @return boolean
+     * @throws SecurityException
+     */
+    private boolean checkUserRole(Session session, User user, Role role)
+        throws SecurityException
+    {
+        boolean result = false;
+        List<UserAdminRole> uaRoles = session.getAdminRoles();
+        if(VUtil.isNotNullOrEmpty(uaRoles))
+        {
+            // validate user and retrieve user' ou:
+            User ue = userP.read(user, false);
+            for(UserAdminRole uaRole : uaRoles)
+            {
+                if(uaRole.getName().equalsIgnoreCase(SUPER_ADMIN))
+                {
+                    result = true;
+                    break;
+                }
+                Set<String> osUs = uaRole.getOsU();
+                if(VUtil.isNotNullOrEmpty(osUs))
+                {
+                    // create Set with case insensitive comparator:
+                    Set<String> osUsFinal = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+                    for(String osU : osUs)
+                    {
+                        // Add osU children to the set:
+                        osUsFinal.add(osU);
+                        Set<String> children = UsoUtil.getDescendants( osU, this.contextId );
+                        osUsFinal.addAll(children);
+                    }
+                    // does the admin role have authority over the user object?
+                    if(osUsFinal.contains(ue.getOu()))
+                    {
+                        // Get the Role range for admin role:
+                        Set<String> range;
+                        if(!uaRole.getBeginRange().equalsIgnoreCase(uaRole.getEndRange()))
+                        {
+                            range = RoleUtil.getAscendants( uaRole.getBeginRange(), uaRole.getEndRange(),
+                                uaRole.isEndInclusive(), this.contextId );
+                            if(uaRole.isBeginInclusive())
+                            {
+                                range.add(uaRole.getBeginRange());
+                            }
+                            if(VUtil.isNotNullOrEmpty(range))
+                            {
+                                // Does admin role have authority over a role contained with the allowable role range?
+                                if(range.contains(role.getName()))
+                                {
+                                    result = true;
+                                    break;
+                                }
+                            }
+                        }
+                        // Does admin role have authority over the role?
+                        else if(uaRole.getBeginRange().equalsIgnoreCase(role.getName()))
+                        {
+                            result = true;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * This helper function processes ARBAC PRA "can assign".
+     * @param session
+     * @param role
+     * @param perm
+     * @return boolean
+     * @throws SecurityException
+     */
+    private boolean checkRolePermission(Session session, Role role, Permission perm)
+        throws SecurityException
+    {
+        boolean result = false;
+        List<UserAdminRole> uaRoles = session.getAdminRoles();
+        if(VUtil.isNotNullOrEmpty(uaRoles))
+        {
+            // validate perm and retrieve perm's ou:
+            PermObj inObj = new PermObj(perm.getObjName());
+            inObj.setContextId(contextId);
+            PermObj pObj = permP.read(inObj);
+            for(UserAdminRole uaRole : uaRoles)
+            {
+                if(uaRole.getName().equalsIgnoreCase(SUPER_ADMIN))
+                {
+                    result = true;
+                    break;
+                }
+                Set<String> osPs = uaRole.getOsP();
+                if(VUtil.isNotNullOrEmpty(osPs))
+                {
+                    // create Set with case insensitive comparator:
+                    Set<String> osPsFinal = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+                    for(String osP : osPs)
+                    {
+                        // Add osU children to the set:
+                        osPsFinal.add(osP);
+                        Set<String> children = PsoUtil.getDescendants( osP, this.contextId );
+                        osPsFinal.addAll(children);
+                    }
+                    // does the admin role have authority over the perm object?
+                    if(osPsFinal.contains(pObj.getOu()))
+                    {
+                        // Get the Role range for admin role:
+                        Set<String> range;
+                        if(!uaRole.getBeginRange().equalsIgnoreCase(uaRole.getEndRange()))
+                        {
+                            range = RoleUtil.getAscendants(uaRole.getBeginRange(), uaRole.getEndRange(), uaRole.isEndInclusive(), this.contextId);
+                            if(uaRole.isBeginInclusive())
+                            {
+                                range.add(uaRole.getBeginRange());
+                            }
+                            if(VUtil.isNotNullOrEmpty(range))
+                            {
+                                // Does admin role have authority over a role contained with the allowable role range?
+                                if(range.contains(role.getName()))
+                                {
+                                    result = true;
+                                    break;
+                                }
+                            }
+                        }
+                        // Does admin role have authority over the role?
+                        else if(uaRole.getBeginRange().equalsIgnoreCase(role.getName()))
+                        {
+                            result = true;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+}
\ No newline at end of file


[40/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java b/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java
new file mode 100755
index 0000000..c865deb
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java
@@ -0,0 +1,68 @@
+/*
+ *   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.ant;
+
+
+import org.apache.directory.fortress.core.rbac.Permission;
+
+import java.util.StringTokenizer;
+
+/**
+ * Entity is used by custom Apache Ant task for special handling of collections.  This is necessary because the
+ * Ant parser cannot deal with complex data attribute types.  The class extends a base entity.
+ *
+ * @author Shawn McKinney
+ */
+public class PermAnt extends Permission
+{
+    private String antRoles;
+
+    /**
+     * Return the roles as a String.
+     *
+     * @return String contains a comma delimited set of role names assigned to permission.
+     */
+    public String getAntRoles()
+    {
+        return antRoles;
+    }
+
+    /**
+     * Accept a comma delimited String containing a list of Roles to be granted to a permission.  This function
+     * will parse the String and call the setter on its parent.
+     *
+     * @param antRoles contains a comma delimited set of role names.
+     */
+    public void setAntRoles(String antRoles)
+    {
+        this.antRoles = antRoles;
+        // allow the setter to process comma delimited strings:
+        StringTokenizer tkn = new StringTokenizer(antRoles, ",");
+        if (tkn.countTokens() > 0)
+        {
+            while (tkn.hasMoreTokens())
+            {
+                String rTkn = tkn.nextToken();
+                setRole(rTkn);
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java b/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java
new file mode 100755
index 0000000..c9dbda9
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java
@@ -0,0 +1,99 @@
+/*
+ *   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.ant;
+
+
+import org.apache.directory.fortress.core.rbac.SDSet;
+
+import java.util.StringTokenizer;
+
+/**
+ * Entity is used by custom Apache Ant task for special handling of collections.  This is necessary because the
+ * Ant parser cannot deal with complex data attribute types.  The class extends a base entity.
+ *
+ * @author Shawn McKinney
+ */
+public class SDSetAnt extends SDSet
+{
+    private String type;
+    private String members;
+
+    /**
+     * Return the members as a String.
+     *
+     * @return String contain comma delimited list of members.
+     */
+    public String getSetMembers()
+    {
+        return members;
+    }
+
+    /**
+     * Accept a comma delimited list of members, iterate of each and call the setter on the parent class.
+     *
+     * @param members contains comma delimited set of members.
+     */
+    public void setSetMembers(String members)
+    {
+        this.members = members;
+        if (members != null)
+        {
+            StringTokenizer tkn = new StringTokenizer(members, ",");
+            if (tkn.countTokens() > 0)
+            {
+                while (tkn.hasMoreTokens())
+                {
+                    String member = tkn.nextToken();
+                    addMember(member);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Return the type of SD set in string format.
+     *
+     * @return String that represents static or dynamic relations.
+     */
+    public String getSetType()
+    {
+        return type;
+    }
+
+    /**
+     * Method accepts a String variable that maps to its parent's set type.
+     *
+     * @param type String value represents static or dynamic set relations.
+     */
+    public void setSetType(String type)
+    {
+        this.type = type;
+        if (type != null && type.equals("DYNAMIC"))
+        {
+            setType(SDSet.SDType.DYNAMIC);
+        }
+        else
+        {
+            setType(SDSet.SDType.STATIC);
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java b/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java
new file mode 100755
index 0000000..b75775a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java
@@ -0,0 +1,301 @@
+/*
+ *   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.ant;
+
+
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.StringTokenizer;
+
+/**
+ * Entity is used by custom Apache Ant task for special handling of collections.  This is necessary because the
+ * Ant parser cannot deal with complex data attribute types.  The class extends a base entity.
+ *
+ * @author Shawn McKinney
+ */
+public class UserAnt extends User
+{
+    private String userProps;
+    private String email;
+    private String phone;
+    private String mobile;
+    private String city;
+    private String state;
+    private String addresses;
+    private String postalCode;
+    private String postOfficeBox;
+    private String building;
+    private String departmentNumber;
+    private String roomNumber;
+    private String photo;
+    private static final String CLS_NM = UserAnt.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    public String getAddresses()
+    {
+        return addresses;
+    }
+
+    public void setAddresses(String addresses)
+    {
+        this.addresses = addresses;
+         // allow the setter to process comma delimited strings:
+         StringTokenizer tkn = new StringTokenizer(addresses, ",");
+         if (tkn.countTokens() > 0)
+         {
+             while (tkn.hasMoreTokens())
+             {
+                 String aTkn = tkn.nextToken();
+                 getAddress().setAddress(aTkn);
+             }
+         }
+    }
+
+    public String getUserProps()
+    {
+        return userProps;
+    }
+
+    public void setUserProps( String userProps )
+    {
+        this.userProps = userProps;
+        addProperties(AttrHelper.getProperties(userProps));
+    }
+
+    public String getPostalCode()
+    {
+        return postalCode;
+    }
+
+    public void setPostalCode(String postalCode)
+    {
+        getAddress().setPostalCode(postalCode);
+    }
+
+    public String getPostOfficeBox()
+    {
+        return postOfficeBox;
+    }
+
+    public void setPostOfficeBox(String postOfficeBox)
+    {
+        getAddress().setPostOfficeBox(postOfficeBox);
+    }
+
+    public String getBuilding()
+    {
+        return building;
+    }
+
+    public void setBuilding(String building)
+    {
+        getAddress().setBuilding(building);
+    }
+
+    public String getDepartmentNumber()
+    {
+        return departmentNumber;
+    }
+
+    public void setDepartmentNumber(String departmentNumber)
+    {
+        getAddress().setDepartmentNumber(departmentNumber);
+    }
+
+    public String getRoomNumber()
+    {
+        return roomNumber;
+    }
+
+    public void setRoomNumber(String roomNumber)
+    {
+        getAddress().setRoomNumber(roomNumber);
+    }
+
+    public String getCity()
+    {
+        return city;
+    }
+
+    public void setCity(String city)
+    {
+        getAddress().setCity(city);
+    }
+
+    public String getState()
+    {
+        return state;
+    }
+
+    public void setState(String state)
+    {
+        getAddress().setState(state);
+    }
+
+    public String getCountry()
+    {
+        return country;
+    }
+
+    public void setCountry(String country)
+    {
+        getAddress().setCountry(country);
+    }
+
+    private String country;
+
+
+    /**
+     * Generally not good practice to handle passwords as Strings in Java but this method allows Ant's digester to consume field in String format from the xml input file.
+     * It subsequently converts to char[] as needed by the parent entity - {@link User}.
+     *
+     * @param password String format will be converted to char[].
+     */
+    public void setPassword(String password)
+    {
+        super.setPassword(password.toCharArray());
+    }
+
+    public String getPhone()
+    {
+        return phone;
+    }
+
+    public void setPhone(String phone)
+    {
+        this.phone = phone;
+        // allow the setter to process comma delimited strings:
+        StringTokenizer tkn = new StringTokenizer(phone, ",");
+        if (tkn.countTokens() > 0)
+        {
+            while (tkn.hasMoreTokens())
+            {
+                String pTkn = tkn.nextToken();
+                getPhones().add(pTkn);
+            }
+        }
+    }
+
+    public String getEmail()
+    {
+        return email;
+    }
+
+    public void setEmail(String email)
+    {
+        this.email = email;
+        // allow the setter to process comma delimited strings:
+        StringTokenizer tkn = new StringTokenizer(email, ",");
+        if (tkn.countTokens() > 0)
+        {
+            while (tkn.hasMoreTokens())
+            {
+                String eTkn = tkn.nextToken();
+                getEmails().add(eTkn);
+            }
+        }
+    }
+
+    public String getMobile()
+    {
+        return mobile;
+    }
+
+    public void setMobile(String mobile)
+    {
+        this.mobile = mobile;
+        // allow the setter to process comma delimited strings:
+        StringTokenizer tkn = new StringTokenizer(mobile, ",");
+        if (tkn.countTokens() > 0)
+        {
+            while (tkn.hasMoreTokens())
+            {
+                String pTkn = tkn.nextToken();
+                getMobiles().add(pTkn);
+            }
+        }
+    }
+
+    public String getPhoto()
+    {
+        return photo;
+    }
+
+    public void setPhoto( String photo )
+    {
+        this.photo = photo;
+        if( VUtil.isNotNullOrEmpty( photo ))
+        {
+            byte[] jpeg = getJpegPhoto( photo );
+            if( VUtil.isNotNullOrEmpty( jpeg ))
+            {
+                setJpegPhoto( jpeg );
+            }
+        }
+    }
+
+    private static byte[] getJpegPhoto( String fileName )
+    {
+        byte[] value = null;
+        try
+        {
+            value = readJpegFile( fileName );
+        }
+        catch ( ArrayIndexOutOfBoundsException ae )
+        {
+            // attribute is optional, do nothing here
+        }
+
+        return value;
+    }
+
+    public static byte[] readJpegFile( String fileName )
+    {
+        URL fUrl = UserAnt.class.getClassLoader().getResource( fileName );
+        byte[] image = null;
+        try
+        {
+            if ( fUrl != null )
+            {
+                image = FileUtils.readFileToByteArray( new File( fUrl.toURI() ) );
+            }
+        }
+        catch ( URISyntaxException se )
+        {
+            String warn = "readJpegFile caught URISyntaxException=" + se;
+            LOG.warn( warn );
+        }
+        catch ( IOException ioe )
+        {
+            String warn = "readJpegFile caught IOException=" + ioe;
+            LOG.warn( warn );
+        }
+        return image;
+    }
+}
\ 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/ant/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/package.html b/src/main/java/org/apache/directory/fortress/core/ant/package.html
new file mode 100755
index 0000000..ab32115
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/package.html
@@ -0,0 +1,35 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.core.ant</title>
+   </head>
+   <body>
+      <p>
+         This package use <a href="http://ant.apache.org/">Apache Ant</a> to provide utility to provision fortress entities and policies
+         using XML files.
+      </p>
+      <p>
+         The <A HREF="package-summary.html">org.apache.directory.fortress.core.ant</a> package provides a provisioning utility that uses
+         xml files that use Apache Ant to drive fortress administrative APIs.
+         See the {@link org.apache.directory.fortress.core.ant.FortressAntTask FortressAntTask} java doc for more info on how it works.
+      </p>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/Config.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/Config.java b/src/main/java/org/apache/directory/fortress/core/cfg/Config.java
new file mode 100755
index 0000000..782c28e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/Config.java
@@ -0,0 +1,347 @@
+/*
+ *   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.cfg;
+
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.CfgException;
+import org.apache.directory.fortress.core.CfgRuntimeException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.SecurityException;
+
+
+/**
+ * This class wraps <a href="http://commons.apache.org/cfg/">Apache Commons Config</a> utility and is used by internal components to retrieve name-value
+ * pair properties from its cfg context.  The class will combine properties that it finds in its local property
+ * file along with data that is retrieved by name from the ldap server if name is specified within
+ * the {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM} switch.
+ * <p>
+ * The class will bootstrap itself during startup and must initialize correctly for the Fortress APIs to work correctly.
+ * <p>
+ * This object is thread safe but stores a static reference to Apache Commons Configuration {@link #config} object.
+ * </p>
+ *
+ * @author Shawn McKinney
+ */
+public class Config
+{
+    final private static String propFile = "fortress.properties";
+    final private static String userPropFile = "fortress.user.properties";
+    private static final PropertiesConfiguration config;
+    private static final String CLS_NM = Config.class.getName();
+    final private static Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    static
+    {
+        try
+        {
+            // Load the system config bootstrap xml file.
+            URL fUrl = Config.class.getClassLoader().getResource( propFile );
+
+            if ( fUrl == null )
+            {
+                String error = "static init: Error, null cfg file: " + propFile;
+                LOG.error( error );
+                throw new java.lang.RuntimeException( error );
+            }
+
+            LOG.info( "static init: found from: {} path: {}", propFile, fUrl.getPath() );
+
+            config = new PropertiesConfiguration();
+            config.setDelimiterParsingDisabled( true );
+            config.load( fUrl );
+            LOG.info( "static init: loading from: {}", propFile );
+
+            URL fUserUrl = Config.class.getClassLoader().getResource( userPropFile );
+            if ( fUserUrl != null )
+            {
+                LOG.info( "static init: found user properties from: {} path: {}",
+                    userPropFile, fUserUrl.getPath() );
+                config.load( fUserUrl );
+            }
+
+            String realmName = config.getString( GlobalIds.CONFIG_REALM );
+            if ( realmName != null && realmName.length() > 0 )
+            {
+                LOG.info( "static init: load config realm [{}]", realmName );
+                Properties props = getRemoteConfig( realmName );
+                if ( props != null )
+                {
+                    for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+                    {
+                        String key = ( String ) e.nextElement();
+                        String val = props.getProperty( key );
+                        config.addProperty( key, val );
+                    }
+                }
+            }
+            else
+            {
+                LOG.info( "static init: config realm not setup" );
+            }
+        }
+        catch ( org.apache.commons.configuration.ConfigurationException ex )
+        {
+            String error = "static init: Error loading from cfg file: [" + propFile
+                + "] ConfigurationException=" + ex;
+            LOG.error( error );
+            throw new CfgRuntimeException( GlobalErrIds.FT_CONFIG_BOOTSTRAP_FAILED, error, ex );
+        }
+        catch ( SecurityException se )
+        {
+            String error = "static init: Error loading from cfg file: [" + propFile + "] SecurityException="
+                + se;
+            LOG.error( error );
+            throw new CfgRuntimeException( GlobalErrIds.FT_CONFIG_INITIALIZE_FAILED, error, se );
+        }
+    }
+
+
+    /**
+     * Fetch the remote cfg params from ldap with given name.
+     *
+     * @param realmName required attribute contains the name of config node name on ldap.
+     * @return {@link Properties} containing collection of name/value pairs found in directory.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of system or validation error.
+     */
+    private static Properties getRemoteConfig( String realmName ) throws SecurityException
+    {
+        Properties props = null;
+        try
+        {
+            ConfigMgr cfgMgr = ConfigMgrFactory.createInstance();
+            props = cfgMgr.read( realmName );
+        }
+        catch ( CfgException ce )
+        {
+            if ( ce.getErrorId() == GlobalErrIds.FT_CONFIG_NOT_FOUND )
+            {
+                String warning = "getRemoteConfig could not find cfg entry";
+                LOG.warn( warning );
+            }
+            else
+            {
+                throw ce;
+            }
+        }
+        return props;
+    }
+
+
+    /**
+     * Gets the prop attribute as String value from the apache commons cfg component.
+     *
+     * @param name contains the name of the property.
+     * @return contains the value associated with the property or null if not not found.
+     */
+    public static String getProperty( String name )
+    {
+        String value = null;
+        if ( config != null )
+        {
+            value = ( String ) config.getProperty( name );
+            if ( LOG.isDebugEnabled() )
+                LOG.debug( "getProperty name [{}] value [{}]", name, value );
+        }
+        else
+        {
+            String error = "getProperty invalid config, can't read prop [" + name + "]";
+            LOG.error( error );
+        }
+        return value;
+    }
+
+
+    /**
+     * Get the property value from the apache commons config but specify a default value if not found.
+     *
+     * @param name         contains the name of the property.
+     * @param defaultValue specified by client will be returned if property value is not found.
+     * @return contains the value for the property as a String.
+     */
+    public static String getProperty( String name, String defaultValue )
+    {
+        String value = null;
+        if ( config != null )
+        {
+            value = ( String ) config.getProperty( name );
+        }
+        else
+        {
+            String warn = "getProperty invalid config, can't read prop [" + name + "]";
+            LOG.warn( warn );
+        }
+        if ( value == null || value.length() == 0 )
+        {
+            value = defaultValue;
+        }
+        return value;
+    }
+
+
+    /**
+     * Gets the prop attribute as char value from the apache commons cfg component.
+     *
+     * @param name contains the name of the property.
+     * @return contains the value associated with the property or 0 if not not found.
+     */
+    public static char getChar( String name )
+    {
+        char value = 0;
+        if ( config != null )
+        {
+            value = ( char ) config.getProperty( name );
+            if ( LOG.isDebugEnabled() )
+                LOG.debug( "getChar name [{}] value [{}]", name, value );
+        }
+        else
+        {
+            String error = "getChar invalid config, can't read prop [" + name + "]";
+            LOG.error( error );
+        }
+        return value;
+    }
+
+
+    /**
+     * Get the property value from the apache commons config but specify a default value if not found.
+     *
+     * @param name         contains the name of the property.
+     * @param defaultValue specified by client will be returned if property value is not found.
+     * @return contains the value for the property as a char.
+     */
+    public static char getChar( String name, char defaultValue )
+    {
+        char value = 0;
+        if ( config != null )
+        {
+            value = ( char ) config.getProperty( name );
+        }
+        else
+        {
+            String warn = "getChar invalid config, can't read prop [" + name + "]";
+            LOG.warn( warn );
+        }
+        if ( value == 0 )
+        {
+            value = defaultValue;
+        }
+        return value;
+    }
+
+
+    /**
+     * Gets the int attribute of the Config class, or 0 if not found.
+     *
+     * @param key name of the property name.
+     * @return The int value or 0 if not found.
+     */
+    public static int getInt( String key )
+    {
+        int value = 0;
+        if ( config != null )
+        {
+            value = config.getInt( key );
+        }
+        else
+        {
+            String warn = "getInt invalid config, can't read prop [" + key + "]";
+            LOG.warn( warn );
+        }
+        return value;
+    }
+
+
+    /**
+     * Gets the int attribute of the Config class or default value if not found.
+     *
+     * @param key          name of the property name.
+     * @param defaultValue to use if property not found.
+     * @return The int value or default value if not found.
+     */
+    public static int getInt( String key, int defaultValue )
+    {
+        int value = 0;
+        if ( config != null )
+        {
+            value = config.getInt( key, defaultValue );
+        }
+        else
+        {
+            String warn = "getInt invalid config, can't read prop [" + key + "]";
+            LOG.warn( warn );
+        }
+        return value;
+    }
+
+
+    /**
+     * Gets the boolean attribute associated with the name or false if not found.
+     *
+     * @param key name of the property name.
+     * @return The boolean value or false if not found.
+     */
+    public static boolean getBoolean( String key )
+    {
+        boolean value = false;
+        if ( config != null )
+        {
+            value = config.getBoolean( key );
+        }
+        else
+        {
+            String warn = "getBoolean - invalid config, can't read prop [" + key + "]";
+            LOG.warn( warn );
+        }
+        return value;
+    }
+
+
+    /**
+     * Gets the boolean attribute associated with the name or false if not found.
+     *
+     * @param key          name of the property name.
+     * @param defaultValue specified by client will be returned if property value is not found.
+     * @return The boolean value or false if not found.
+     */
+    public static boolean getBoolean( String key, boolean defaultValue )
+    {
+        boolean value = defaultValue;
+        if ( config != null )
+        {
+            value = config.getBoolean( key, defaultValue );
+        }
+        else
+        {
+            String warn = "getBoolean - invalid config, can't read prop [" + key + "]";
+            LOG.warn( warn );
+        }
+        return value;
+    }
+}
\ 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/cfg/ConfigDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigDAO.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigDAO.java
new file mode 100755
index 0000000..1d8f07a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigDAO.java
@@ -0,0 +1,299 @@
+/*
+ *   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.cfg;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Modification;
+import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.RemoveException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * This class provides data access for the standard ldap object device that has been extended to support name/value pairs.
+ * Fortress uses this data structure to store its remote cfg parameters.
+ * <p/>
+ * The Fortress Config node is a combination of:
+ * <p/>
+ * 'device' Structural Object Class is used to store basic attributes like cn which will be used for config node name.
+ * <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>
+ * <p/>
+ * 'ftProperties' AUXILIARY Object Class is used to store name/value pairs on target node.<br />
+ * <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>
+ * <p/>
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+final class ConfigDAO extends ApacheDsDataProvider
+
+{
+    private static final String CLS_NM = ConfigDAO.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final String CONFIG_ROOT_PARAM = "config.root";
+    private static final String CONFIG_ROOT_DN = Config.getProperty( CONFIG_ROOT_PARAM );
+    private static final String DEVICE_OBJECT_CLASS_NM = "device";
+
+    private static final String CONFIG_OBJ_CLASS[] =
+        {
+            DEVICE_OBJECT_CLASS_NM, GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME
+    };
+
+    private static final String[] CONFIG_ATRS =
+        {
+            GlobalIds.CN, GlobalIds.PROPS
+    };
+
+    /**
+     * Package private default constructor.
+     */
+    ConfigDAO()
+    {
+    }
+
+    /**
+     * @param name
+     * @param props
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     */
+    final Properties create( String name, Properties props )
+        throws CreateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( name );
+        LOG.info( "create dn [" + dn + "]" );
+        try
+        {
+            Entry myEntry = new DefaultEntry( dn );
+            myEntry.add( GlobalIds.OBJECT_CLASS, CONFIG_OBJ_CLASS );
+            ld = getAdminConnection();
+            myEntry.add( GlobalIds.CN, name );
+            loadProperties( props, myEntry, GlobalIds.PROPS );
+            add( ld, myEntry );
+        }
+        catch ( LdapEntryAlreadyExistsException e )
+        {
+            String warning = "create config dn [" + dn + "] caught LdapEntryAlreadyExistsException="
+                + e.getMessage() + " msg=" + e.getMessage();
+            throw new CreateException( GlobalErrIds.FT_CONFIG_ALREADY_EXISTS, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error;
+            error = "create config dn [" + dn + "] caught LDAPException=" + e.getMessage();
+            LOG.error( error, e );
+            throw new CreateException( GlobalErrIds.FT_CONFIG_CREATE_FAILED, error );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return props;
+    }
+
+
+    /**
+     * @param name
+     * @param props
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     */
+    final Properties update( String name, Properties props )
+        throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( name );
+        LOG.info( "update dn [" + dn + "]" );
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            if ( VUtil.isNotNullOrEmpty( props ) )
+            {
+                loadProperties( props, mods, GlobalIds.PROPS, true );
+            }
+            ld = getAdminConnection();
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "update dn [" + dn + "] caught LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.FT_CONFIG_UPDATE_FAILED, error );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return props;
+    }
+
+
+    /**
+     * @param name
+     * @throws org.apache.directory.fortress.core.RemoveException
+     */
+    final void remove( String name )
+        throws RemoveException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( name );
+        LOG.info( "remove dn [" + dn + "]" );
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, dn );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove dn [" + dn + "] LDAPException=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.FT_CONFIG_DELETE_FAILED, error );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param name
+     * @param props
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     */
+    final Properties remove( String name, Properties props )
+        throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( name );
+        LOG.info( "remove props dn [" + dn + "]" );
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            if ( VUtil.isNotNullOrEmpty( props ) )
+            {
+                removeProperties( props, mods, GlobalIds.PROPS );
+            }
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove props dn [" + dn + "] caught LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.FT_CONFIG_DELETE_PROPS_FAILED, error );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return props;
+    }
+
+
+    /**
+     * @param name
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     */
+    final Properties getConfig( String name )
+        throws FinderException
+    {
+        Properties props = null;
+        LdapConnection ld = null;
+        String dn = getDn( name );
+        LOG.info( "getConfig dn [" + dn + "]" );
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, dn, CONFIG_ATRS );
+            props = AttrHelper.getProperties( getAttributes( findEntry, GlobalIds.PROPS ) );
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getConfig COULD NOT FIND ENTRY for dn [" + dn + "]";
+            throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getConfig dn [" + dn + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.FT_CONFIG_READ_FAILED, error );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return props;
+    }
+
+
+    /**
+     *
+     * @param name
+     * @return
+     */
+    private String getDn( String name )
+    {
+        return GlobalIds.CN + "=" + name + "," + CONFIG_ROOT_DN;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java
new file mode 100755
index 0000000..e0e15c9
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java
@@ -0,0 +1,96 @@
+/*
+ *   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.cfg;
+
+import org.apache.directory.fortress.core.SecurityException;
+
+import java.util.Properties;
+
+/**
+ * This interface prescribes CRUD methods used to manage properties stored within the ldap directory.
+ * The Fortress config nodes are used to remotely share Fortress client specific properties between processes.
+ * Fortress places no limits on the number of unique configurations that can be present at one time in the directory.
+ * The Fortress client will specify the preferred cfg node by name via a property named, {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM}.
+ * Each process using Fortress client is free to share an existing node with other processes or create its own unique config
+ * instance using the methods within this class.<BR>
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public interface ConfigMgr
+{
+    /**
+     * Create a new cfg node with given name and properties.  The name is required.  If node already exists,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_ALREADY_EXISTS} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to add to existing config node.
+     * @return {@link Properties} containing the collection of name/value pairs just added.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry already present or other system error.
+     */
+    public Properties add(String name, Properties inProps) throws SecurityException;
+
+    /**
+     * Update existing cfg node with additional properties, or, replace existing properties.  The name is required.  If node does not exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to add or udpate from existing config node.
+     * @return {@link Properties} containing the collection of name/value pairs to be added to existing node.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+     */
+    public Properties update(String name, Properties inProps) throws SecurityException;
+
+    /**
+     * Completely removes named cfg node from the directory.
+     * <p/>
+     * <font size="3" color="red">This method is destructive and will remove the cfg node completely from directory.<BR>
+     * Care should be taken during execution to ensure target name is correct and permanent removal of all parameters located
+     * there is intended.  There is no 'undo' for this operation.
+     * </font>
+     *
+     * @param name is required and maps to 'cn' attribute on 'device' object class of node targeted for operation.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event of system error.
+     */
+    public void delete(String name) throws SecurityException;
+
+    /**
+     * Delete properties from existing cfg node.  The name is required.  If node does not exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+     */
+    public void delete(String name, Properties inProps) throws SecurityException;
+
+    /**
+     * Read an existing cfg node with given name and return to caller.  The name is required.  If node doesn't exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @return {@link Properties} containing the collection of name/value pairs just added. Maps to 'ftProps' attribute in 'ftProperties' object class.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry doesn't exist or other system error.
+     */
+    public Properties read(String name) throws SecurityException;
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java
new file mode 100755
index 0000000..8211769
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java
@@ -0,0 +1,68 @@
+/*
+ *   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.cfg;
+
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rest.ConfigMgrRestImpl;
+
+/**
+ * Creates an instance of the ConfigMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link ConfigMgrImpl} but can be overridden by
+ * adding the {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_IMPLEMENTATION} config property.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class ConfigMgrFactory
+{
+    private static String configClassName = Config.getProperty(GlobalIds.CONFIG_IMPLEMENTATION);
+    private final static String ENABLE_REST = "enable.mgr.impl.rest";
+    private static final boolean IS_REST = ((Config.getProperty(ENABLE_REST) != null) && (Config.getProperty(ENABLE_REST).equalsIgnoreCase("true")));
+
+    /**
+     * Create and return a reference to {@link ConfigMgr} object.
+     *
+     * @return instance of {@link ConfigMgr}.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event of failure during instantiation.
+     */
+    public static ConfigMgr createInstance()
+        throws SecurityException
+    {
+        // TODO: Don't reuse {@link VUtil#isNotNullOrEmpty} here until it is determined why it forces different execution path through GlobalIds.IS_OPENLDAP:
+        //if (!VUtil.isNotNullOrEmpty(configClassName))
+        if (configClassName == null || configClassName.compareTo("") == 0)
+        {
+            if(IS_REST)
+            {
+                configClassName = ConfigMgrRestImpl.class.getName();
+            }
+            else
+            {
+                configClassName = ConfigMgrImpl.class.getName();
+            }
+        }
+
+        return (ConfigMgr) ClassUtil.createInstance(configClassName);
+    }
+}
\ 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/cfg/ConfigMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrImpl.java
new file mode 100755
index 0000000..1358f7e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrImpl.java
@@ -0,0 +1,119 @@
+/*
+ *   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.cfg;
+
+import org.apache.directory.fortress.core.SecurityException;
+
+import java.util.Properties;
+
+
+/**
+ * This Manager impl supplies CRUD methods used to manage properties stored within the ldap directory.
+ * The Fortress config nodes are used to remotely share Fortress client specific properties between processes.
+ * Fortress places no limits on the number of unique configurations that can be present at one time in the directory.
+ * The Fortress client will specify the preferred cfg node by name via a property named, {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM}.
+ * Each process using Fortress client is free to share an existing node with other processes or create its own unique config
+ * instance using the methods within this class.<BR>
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class ConfigMgrImpl implements ConfigMgr
+{
+    private static final ConfigP cfgP = new ConfigP();
+
+    /**
+     * Create a new cfg node with given name and properties.  The name is required.  If node already exists,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_ALREADY_EXISTS} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to add to existing config node.
+     * @return {@link Properties} containing the collection of name/value pairs just added.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry already present or other system error.
+     */
+    @Override
+    public Properties add(String name, Properties inProps) throws SecurityException
+    {
+        return cfgP.add(name, inProps);
+    }
+
+
+    /**
+     * Update existing cfg node with additional properties, or, replace existing properties.  The name is required.  If node does not exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to add or udpate from existing config node.
+     * @return {@link Properties} containing the collection of name/value pairs to be added to existing node.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+     */
+    @Override
+    public Properties update(String name, Properties inProps) throws SecurityException
+    {
+        return cfgP.update(name, inProps);
+    }
+
+    /**
+     * Completely removes named cfg node from the directory.
+     * <p/>
+     * <font size="3" color="red">This method is destructive and will remove the cfg node completely from directory.<BR>
+     * Care should be taken during execution to ensure target name is correct and permanent removal of all parameters located
+     * there is intended.  There is no 'undo' for this operation.
+     * </font>
+     *
+     * @param name is required and maps to 'cn' attribute on 'device' object class of node targeted for operation.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event of system error.
+     */
+    @Override
+    public void delete(String name) throws SecurityException
+    {
+        cfgP.delete(name);
+    }
+
+    /**
+     * Delete properties from existing cfg node.  The name is required.  If node does not exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+     */
+    @Override
+    public void delete(String name, Properties inProps) throws SecurityException
+    {
+        cfgP.delete(name, inProps);
+    }
+
+    /**
+     * Read an existing cfg node with given name and return to caller.  The name is required.  If node doesn't exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @return {@link Properties} containing the collection of name/value pairs just added. Maps to 'ftProps' attribute in 'ftProperties' object class.
+     * @throws SecurityException in the event entry doesn't exist or other system error.
+     */
+    @Override
+    public Properties read(String name) throws SecurityException
+    {
+        return cfgP.read(name);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java
new file mode 100755
index 0000000..ad8b1d2
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java
@@ -0,0 +1,202 @@
+/*
+ *   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.cfg;
+
+
+import java.util.Properties;
+
+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.SecurityException;
+import org.apache.directory.fortress.core.ValidationException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * Process module for the configurations node used for remotely storing Fortress specific properties.
+ * Fortress places no limits on the number of unique configurations that can be present.  The Fortress client will specify
+ * the preferred cfg node by name via a property named, {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM}.  Each
+ * process using Fortress client is free to share existing node with other processes or create its own unique config
+ * instance using the methods within this class.<BR>
+ * This class does perform simple data validations to ensure data reasonability and the required fields are present.<BR>
+ * The {@link org.apache.directory.fortress.core.ant.FortressAntTask#addConfig()} method calls the {@link #add} from this class during initial base loads.
+ * Removal {@link org.apache.directory.fortress.core.ant.FortressAntTask#deleteConfig()} is performed when removal of properties is the aim.<BR>
+ * This class will accept {@link Properties}, and forward on to it's corresponding DAO class {@link ConfigDAO} for updating properties stored on behalf of Fortress.
+ * <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 org.apache.directory.fortress.core.SecurityException}s with appropriate
+ *  error id from {@link org.apache.directory.fortress.core.GlobalErrIds}.
+ * <p>
+ * This class performs simple data validation on properties to ensure length does not exceed 100 and contents are safe text.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+final class ConfigP
+{
+    private static final String CLS_NM = ConfigP.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+
+    /**
+     * Package private constructor
+     */
+    ConfigP()
+    {
+    }
+
+
+    /**
+     * Create a new cfg node with given name and properties.  The name is required.  If node already exists,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link GlobalErrIds#FT_CONFIG_ALREADY_EXISTS} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to remove from existing config node.
+     * @return {@link Properties} containing the collection of name/value pairs just added.
+     * @throws SecurityException in the event entry already present or other system error.
+     */
+    final Properties add( String name, Properties inProps )
+        throws SecurityException
+    {
+        validate( name, inProps );
+        ConfigDAO cfgDao = new ConfigDAO();
+        return cfgDao.create( name, inProps );
+    }
+
+
+    /**
+     * Update existing cfg node with additional properties, or, replace existing properties.  The name is required.  If node does not exist,
+     * a {@link SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProps contains {@link Properties} with list of name/value pairs to add or udpate from existing config node.
+     * @return {@link Properties} containing the collection of name/value pairs to be added to existing node.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+     */
+    final Properties update( String name, Properties inProps )
+        throws SecurityException
+    {
+        validate( name, inProps );
+        ConfigDAO cfgDao = new ConfigDAO();
+        return cfgDao.update( name, inProps );
+    }
+
+
+    /**
+     * Delete existing cfg node which will remove all properties associated with that node.
+     * The name is required.  If node does not exist, a {@link SecurityException} with error
+     * {@link GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     * <p/>
+     * <font size="2" color="red">
+     * This method is destructive and will remove the cfg node completely from directory.<BR>
+     * Care should be taken during execution to ensure target name is correct and permanent removal of all parameters located
+     * there is intended.  There is no 'undo' for this operation.
+     * </font>
+     * <p/>
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @return {@link Properties} containing the collection of name/value pairs to be added to existing node.
+     * @throws SecurityException in the event entry not present or other system error.
+     */
+    final void delete( String name )
+        throws SecurityException
+    {
+        if ( !VUtil.isNotNullOrEmpty( name ) )
+        {
+            String error = "delete detected null config realm name";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.FT_CONFIG_NAME_NULL, error );
+        }
+        ConfigDAO cfgDao = new ConfigDAO();
+        cfgDao.remove( name );
+    }
+
+
+    /**
+     * Delete existing cfg node with additional properties, or, replace existing properties.  The name is required.  If node does not exist,
+     * a {@link SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+     */
+    final void delete( String name, Properties inProps )
+        throws SecurityException
+    {
+        validate( name, inProps );
+        ConfigDAO cfgDao = new ConfigDAO();
+        cfgDao.remove( name, inProps );
+    }
+
+
+    /**
+     * Read an existing cfg node with given name and return to caller.  The name is required.  If node doesn't exist,
+     * a {@link SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @return {@link Properties} containing the collection of name/value pairs just added. Maps to 'ftProps' attribute in 'ftProperties' object class.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry doesn't exist or other system error.
+     */
+    final Properties read( String name )
+        throws SecurityException
+    {
+        Properties outProps;
+        ConfigDAO cfgDao = new ConfigDAO();
+        outProps = cfgDao.getConfig( name );
+        return outProps;
+    }
+
+
+    /**
+     * Method will perform simple validations to ensure the integrity of the {@link Properties} entity targeted for insertion
+     * or deletion in directory.
+     *
+     * @param name contains the name of the cfg node.
+     * @param entity contains the name/value properties targeted for operation.
+     * @throws org.apache.directory.fortress.core.ValidationException thrown in the event the validations fail.
+     */
+    private void validate( String name, Properties entity )
+        throws ValidationException
+    {
+        if ( !VUtil.isNotNullOrEmpty( name ) )
+        {
+            String error = "validate detected null config realm name";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.FT_CONFIG_NAME_NULL, error );
+        }
+        if ( name.length() > GlobalIds.OU_LEN )
+        {
+            String error = "validate name [" + name + "] invalid length [" + name.length() + "]";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.FT_CONFIG_NAME_INVLD, error );
+        }
+        if ( entity == null || entity.size() == 0 )
+        {
+            String error = "validate name [" + name + "] config props null";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.FT_CONFIG_PROPS_NULL, error );
+        }
+        VUtil.properties( entity );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/package.html b/src/main/java/org/apache/directory/fortress/core/cfg/package.html
new file mode 100755
index 0000000..0bc922e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/package.html
@@ -0,0 +1,37 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.config</title>
+   </head>
+   <body>
+      <p>
+         This package uses <a href="http://commons.apache.org/configuration/">Apache Commons Configuration</a> APIs to provide configuration data to fortress along with CRUD APIs for storing config data on the ldap server.
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress.config</b> can store its data both in a flat file or within the LDAP directory itself.
+          The <b>oamConfig.xml</b> contains the location of the bootstrap property file.  The bootstrap properties
+          can then point to a remote LDAP configuration node, called a 'realm', and referenced with this property:
+          <b>config.realm</b>.  An empty or null value for the config.realm property means the properties will all be stored locally in the file specified within oamConfig.xml.
+          The package also contains entities and apis that are used to perform CRUD on remote configuration parameters.
+          See the corresponding javadoc contained with this package for more info.
+      </p>
+   </body>
+</html>


[04/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rest/ReviewMgrRestImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/ReviewMgrRestImpl.java b/src/main/java/org/apache/directory/fortress/core/rest/ReviewMgrRestImpl.java
new file mode 100755
index 0000000..7c4f8db
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/ReviewMgrRestImpl.java
@@ -0,0 +1,1446 @@
+/*
+ *   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.rest;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.ReviewMgr;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.Manageable;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.SDSet;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.UserRole;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * This class performs administrative review functions on already provisioned Fortress RBAC entities using HTTP access to En Masse REST server.
+ * These APIs map directly to similar named APIs specified by ANSI and NIST RBAC models.
+ * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
+ * The RBAC Functional specification describes administrative operations for the creation
+ * and maintenance of RBAC element sets and relations; administrative review functions for
+ * performing administrative queries; and system functions for creating and managing
+ * RBAC attributes on user sessions and making access control decisions.
+ * <p/>
+ * <hr>
+ * <h4>RBAC0 - Core</h4>
+ * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
+ * <p/>
+ * <img src="../doc-files/RbacCore.png">
+ * <hr>
+ * <h4>RBAC1 - General Hierarchical Roles</h4>
+ * Simplifies role engineering tasks using inheritance of one or more parent roles.
+ * <p/>
+ * <img src="../doc-files/RbacHier.png">
+ * <hr>
+ * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+ * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
+ * <p/>
+ * <img src="../doc-files/RbacSSD.png">
+ * <hr>
+ * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+ * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+ * <p/>
+ * <img src="../doc-files/RbacDSD.png">
+ * <hr>
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class ReviewMgrRestImpl extends Manageable implements ReviewMgr
+{
+    private static final String CLS_NM = ReviewMgrRestImpl.class.getName();
+
+    /**
+     * This method returns a matching permission entity to caller.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param permission must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return Permission entity that is loaded with data.
+     * @throws SecurityException if permission not found or system error occurs.
+     */
+    @Override
+    public Permission readPermission(Permission permission)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(permission, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".readPermission");
+        Permission retPerm;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(permission);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_READ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPerm = (Permission) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPerm;
+    }
+
+    /**
+     * Method reads permission object from perm container in directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param permObj entity contains the {@link PermObj#objName} of target record.
+     * @return PermObj loaded with perm object data.
+     * @throws SecurityException is thrown if object not found or system error.
+     */
+    @Override
+    public PermObj readPermObj(PermObj permObj)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(permObj, GlobalErrIds.PERM_OBJECT_NULL, CLS_NM + ".readPermObj");
+        PermObj retObj;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(permObj);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.OBJ_READ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retObj = (PermObj) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retObj;
+    }
+
+    /**
+     * Method returns a list of type Permission that match the perm object search string.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains one or more characters of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains one or more characters of existing permission operation</li>
+     * </ul>
+     *
+     * @param permission contains object and operation name search strings.  Each contains 1 or more leading chars that correspond to object or op name.
+     * @return List of type Permission.  Fortress permissions are object->operation mappings.  The permissions may contain
+     *         assigned user, role or group entities as well.
+     * @throws SecurityException thrown in the event of system error.
+     */
+    @Override
+    public List<Permission> findPermissions(Permission permission)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(permission, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".findPermissions");
+        List<Permission> retPerms;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(permission);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_SEARCH);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPerms = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPerms;
+    }
+
+    /**
+     * Method returns a list of type PermObj that match the perm object search string.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains one or more characters of existing object being targeted</li>
+     * </ul>
+     *
+     * @param permObj contains object name search string.  The search val contains 1 or more leading chars that correspond to object name.
+     * @return List of type PermObj.  Fortress permissions are object->operation mappings.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of system error.
+     */
+    @Override
+    public List<PermObj> findPermObjs(PermObj permObj)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(permObj, GlobalErrIds.PERM_OBJECT_NULL, CLS_NM + ".findPermObjs");
+        List<PermObj> retObjs;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(permObj);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.OBJ_SEARCH);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retObjs = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retObjs;
+    }
+
+    /**
+     * Method returns a list of type Permission that match the perm object search string.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link OrgUnit#name} - contains one or more characters of org unit associated with existing object being targeted</li>
+     * </ul>
+     *
+     * @param ou contains org unit name {@link org.apache.directory.fortress.core.rbac.OrgUnit#name}.  The search val contains the full name of matching ou in OS-P data set.
+     * @return List of type PermObj.  Fortress permissions are object->operation mappings.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of system error.
+     */
+    @Override
+    public List<PermObj> findPermObjs(OrgUnit ou)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(ou, GlobalErrIds.ORG_NULL_PERM, CLS_NM + ".findPermObjs");
+        List<PermObj> retObjs;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        PermObj inObj = new PermObj();
+        inObj.setOu(ou.getName());
+        request.setEntity(inObj);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.OBJ_SEARCH);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retObjs = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retObjs;
+    }
+
+    /**
+     * Method reads Role entity from the role container in directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role to read.</li>
+     * </ul>
+     *
+     * @param role contains role name, {@link Role#name}, to be read.
+     * @return Role entity that corresponds with role name.
+     * @throws SecurityException will be thrown if role not found or system error occurs.
+     */
+    @Override
+    public Role readRole(Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".readRole");
+        Role retRole;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_READ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retRole = (Role) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRole;
+    }
+
+    /**
+     * Method will return a list of type Role matching all or part of Role name, {@link Role#name}.
+     *
+     * @param searchVal contains all or some of the chars corresponding to role entities stored in directory.
+     * @return List of type Role containing role entities that match the search criteria.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of system error.
+     */
+    @Override
+    public List<Role> findRoles(String searchVal)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(searchVal, GlobalErrIds.ROLE_NM_NULL, CLS_NM + ".findRoles");
+        List<Role> retRoles;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setValue(searchVal);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_SEARCH);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retRoles = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRoles;
+    }
+
+    /**
+     * Method returns a list of roles of type String.  This method can be limited by integer value that indicates max
+     * number of records that may be contained in the result set.  This number can further limit global default but can
+     * not increase the max.  This method is called by the Websphere Realm impl.
+     *
+     * @param searchVal contains all or some leading chars that correspond to roles stored in the role container in the directory.
+     * @param limit     integer value specifies the max records that may be returned in the result set.
+     * @return List of type Role containing role entities that match the search criteria.
+     * @throws SecurityException in the event of system error.
+     */
+    @Override
+    public List<String> findRoles(String searchVal, int limit)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(searchVal, GlobalErrIds.ROLE_NM_NULL, CLS_NM + ".findRoles");
+        List<String> retRoles;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setValue(searchVal);
+        request.setLimit(limit);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_SEARCH);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retRoles = response.getValues();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRoles;
+    }
+
+    /**
+     * Method returns matching User entity that is contained within the people container in the directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for read.</li>
+     * </ul>
+     *
+     * @param user entity contains a value {@link User#userId} that matches record in the directory.  userId is globally unique in
+     *             people container.
+     * @return entity containing matching user data.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if record not found or system error occurs.
+     */
+    @Override
+    public final User readUser(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".readUser");
+        User retUser;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_READ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUser = (User) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUser;
+    }
+
+
+    /**
+     * Return a list of type User of all users in the people container that match all or part of the {@link User#userId} field passed in User entity.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains all or some leading chars that match userId(s) stored in the directory.</li>
+     * </ul>
+     *
+     * @param user contains all or some leading chars that match userIds stored in the directory.
+     * @return List of type User.
+     * @throws SecurityException In the event of system error.
+     */
+    @Override
+    public final List<User> findUsers(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".findUsers");
+        List<User> retUsers;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_SEARCH);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUsers = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUsers;
+    }
+
+    /**
+     * Return a list of type User of all users in the people container that match the name field passed in OrgUnit entity.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link OrgUnit#name} - contains one or more characters of org unit associated with existing object(s) being targeted</li>
+     * </ul>
+     *
+     * @param ou contains name of User OU, {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} that match ou attribute associated with User entity in the directory.
+     * @return List of type User.
+     * @throws SecurityException In the event of system error.
+     */
+    @Override
+    public List<User> findUsers(OrgUnit ou)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(ou, GlobalErrIds.ORG_NULL_USER, CLS_NM + ".findUsers");
+        List<User> retUsers;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        User inUser = new User();
+        inUser.setOu(ou.getName());
+        request.setEntity(inUser);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_SEARCH);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUsers = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUsers;
+    }
+
+    /**
+     * Return a list of type String of all users in the people container that match the userId field passed in User entity.
+     * This method is used by the Websphere realm component.  The max number of returned users may be set by the integer limit arg.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for read.</li>
+     * <li>limit - max number of objects to return.</li>
+     * </ul>
+     *
+     * @param user  contains all or some leading chars that correspond to users stored in the directory.
+     * @param limit integer value sets the max returned records.
+     * @return List of type String containing matching userIds.
+     * @throws SecurityException in the event of system error.
+     */
+    @Override
+    public final List<String> findUsers(User user, int limit)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".findUsers");
+        List<String> retUsers;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setLimit(limit);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_SEARCH);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUsers = response.getValues();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUsers;
+    }
+
+    /**
+     * This function returns the set of users assigned to a given role. The function is valid if and
+     * only if the role is a member of the ROLES data set.
+     * The max number of users returned is constrained by limit argument.
+     * This method is used by the Websphere realm component.  This method does NOT use hierarchical rbac.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * <li>limit - max number of objects to return.</li>
+     * </ul>
+     *
+     * @param role  Contains {@link Role#name} of Role entity assigned to user.
+     * @param limit integer value sets the max returned records.
+     * @return List of type String containing userIds assigned to a particular role.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public List<String> assignedUsers(Role role, int limit)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".assignedUsers");
+        List<String> retUsers;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setLimit(limit);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_ASGNED);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUsers = response.getValues();
+            // do not return a null list to the caller:
+            if (retUsers == null)
+            {
+                retUsers = new ArrayList<>();
+            }
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUsers;
+    }
+
+    /**
+     * This method returns the data set of all users who are assigned the given role.  This searches the User data set for
+     * Role relationship.  This method does NOT search for hierarchical RBAC Roles relationships.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role contains the role name, {@link Role#name} used to search the User data set.
+     * @return List of type User containing the users assigned data.
+     * @throws SecurityException If system error occurs.
+     */
+    @Override
+    public List<User> assignedUsers(Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".assignedUsers");
+        List<User> retUsers;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_ASGNED);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUsers = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUsers;
+    }
+
+    /**
+     * This function returns the set of roles assigned to a given user. The function is valid if and
+     * only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains {@link User#userId} matching User entity targeted in the directory.
+     * @return List of type UserRole containing the Roles assigned to User.
+     * @throws SecurityException If user not found or system error occurs.
+     */
+    @Override
+    public List<UserRole> assignedRoles(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".assignedRoles");
+        List<UserRole> retUserRoles;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_ASGNED);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUserRoles = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUserRoles;
+    }
+
+    /**
+     * This function returns the set of roles assigned to a given user. The function is valid if and
+     * only if the user is a member of the USERS data set.
+     *
+     * @param userId matches userId stored in the directory.
+     * @return List of type String containing the role names of all roles assigned to user.
+     * @throws SecurityException If user not found or system error occurs.
+     */
+    @Override
+    public List<String> assignedRoles(String userId)
+        throws SecurityException
+    {
+        VUtil.assertNotNullOrEmpty(userId, GlobalErrIds.USER_NULL, CLS_NM + ".assignedRoles");
+        List<String> retUserRoles;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setValue(userId);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_ASGNED);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUserRoles = response.getValues();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUserRoles;
+    }
+
+    /**
+     * This function returns the set of users authorized to a given role, i.e., the users that are assigned to a role that
+     * inherits the given role. The function is valid if and only if the given role is a member of the ROLES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role Contains role name, {@link Role#name} of Role entity assigned to User.
+     * @return List of type User containing all user's that having matching role assignment.
+     * @throws SecurityException In the event the role is not present in directory or system error occurs.
+     */
+    @Override
+    public List<User> authorizedUsers(Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".authorizedUsers");
+        List<User> retUsers;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_AUTHZED);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUsers = response.getEntities();
+            if (retUsers == null)
+            {
+                retUsers = new ArrayList<>();
+            }
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUsers;
+    }
+
+    /**
+     * This function returns the set of roles authorized for a given user. The function is valid if
+     * and only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains the {@link User#userId} matching User entity stored in the directory.
+     * @return Set of type String containing the roles assigned and roles inherited.
+     * @throws SecurityException If user not found or system error occurs.
+     */
+    @Override
+    public Set<String> authorizedRoles(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".authorizedRoles");
+        Set<String> retRoleNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_AUTHZED);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Set<String> tempNames = response.getValueSet();
+            // This is done to use a case insensitive TreeSet for returned names.
+            retRoleNames.addAll(tempNames);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRoleNames;
+    }
+
+    /**
+     * This function returns the set of all permissions (op, obj), granted to or inherited by a
+     * given role. The function is valid if and only if the role is a member of the ROLES data
+     * set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role contains role name, {@link Role#name} of Role entity Permission is granted to.
+     * @return List of type Permission that contains all perms granted to a role.
+     * @throws SecurityException In the event system error occurs.
+     */
+    @Override
+    public List<Permission> rolePermissions(Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".rolePermissions");
+        List<Permission> retPerms;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_PERMS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPerms = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPerms;
+    }
+
+    /**
+     * This function returns the set of permissions a given user gets through his/her authorized
+     * roles. The function is valid if and only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains the {@link User#userId} of User targeted for search.
+     * @return List of type Permission containing matching permission entities.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *
+     */
+    @Override
+    public List<Permission> userPermissions(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".userPermissions");
+        List<Permission> retPerms;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_PERMS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPerms = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPerms;
+    }
+
+    /**
+     * Return a list of type String of all roles that have granted a particular permission.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return List of type string containing the role names that have the matching perm granted.
+     * @throws SecurityException in the event permission not found or system error occurs.
+     */
+    @Override
+    public List<String> permissionRoles(Permission perm)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OBJECT_NULL, CLS_NM + ".permissionRoles");
+        List<String> retRoleNames;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(perm);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_ROLES);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retRoleNames = response.getValues();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRoleNames;
+    }
+
+    /**
+     * Return all role names that have been authorized for a given permission.  This will process role hierarchies to determine set of all Roles who have access to a given permission.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return Set of type String containing all roles names that have been granted a particular permission.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of validation or system error.
+     */
+    @Override
+    public Set<String> authorizedPermissionRoles(Permission perm)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".authorizedPermissionRoles");
+        Set<String> retRoleNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(perm);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_ROLES_AUTHZED);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Set<String> tempNames = response.getValueSet();
+            // This is done to use a case insensitive TreeSet for returned names.
+            retRoleNames.addAll(tempNames);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRoleNames;
+    }
+
+    /**
+     * Return all userIds that have been granted (directly) a particular permission.  This will not consider assigned or authorized Roles.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return List of type String containing all userIds that have been granted a particular permission.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of validation or system error.
+     */
+    @Override
+    public List<String> permissionUsers(Permission perm)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".permissionUsers");
+        List<String> retUsers;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(perm);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_USERS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUsers = response.getValues();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUsers;
+    }
+
+    /**
+     * Return all userIds that have been authorized for a given permission.  This will process role hierarchies to determine set of all Users who have access to a given permission.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return Set of type String containing all userIds that have been granted a particular permission.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of validation or system error.
+     */
+    @Override
+    public Set<String> authorizedPermissionUsers(Permission perm)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".authorizedPermissionUsers");
+        Set<String> retUserIds = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(perm);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_USERS_AUTHZED);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Set<String> tempNames = response.getValueSet();
+            // This is done to use a case insensitive TreeSet for returned names.
+            retUserIds.addAll(tempNames);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUserIds;
+    }
+
+    /**
+     * This function returns the list of all SSD role sets that have a particular Role as member or Role's
+     * parent as a member.  If the Role parameter is left blank, function will return all SSD role sets.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role Will contain the role name, {@link Role#name}, for targeted SSD set or null to return all
+     * @return List containing all matching SSD's.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data or system error.
+     */
+    @Override
+    public List<SDSet> ssdRoleSets(Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".ssdRoleSets");
+        List<SDSet> retSsdRoleSets;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.SSD_ROLE_SETS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSsdRoleSets = response.getEntities();
+            if (retSsdRoleSets == null)
+            {
+                retSsdRoleSets = new ArrayList<>();
+            }
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSsdRoleSets;
+    }
+
+    /**
+     * This function returns the SSD data set that matches a particular set name.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param set Will contain the name for existing SSD data set
+     * @return SDSet containing all attributes from matching SSD name.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data or system error.
+     */
+    @Override
+    public SDSet ssdRoleSet(SDSet set)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(set, GlobalErrIds.SSD_NULL, CLS_NM + ".ssdRoleSet");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(set);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.SSD_READ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet;
+    }
+
+    /**
+     * This function returns the list of SSDs that match a given ssd name value.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param ssd contains the name for the SSD set targeted, {@link SDSet#name}.
+     * @return List containing all SSDSets that match a given SSDSet name.
+     * @throws SecurityException in the event of data or system error.
+     */
+    public List<SDSet> ssdSets(SDSet ssd)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(ssd, GlobalErrIds.ROLE_NULL, CLS_NM + ".ssdSets");
+         List<SDSet> retSsdSets;
+         FortRequest request = new FortRequest();
+         request.setContextId(this.contextId);
+         request.setEntity(ssd);
+         if (this.adminSess != null)
+         {
+             request.setSession(adminSess);
+         }
+         String szRequest = RestUtils.marshal(request);
+         String szResponse = RestUtils.post(szRequest, HttpIds.SSD_SETS);
+         FortResponse response = RestUtils.unmarshall(szResponse);
+         if (response.getErrorCode() == 0)
+         {
+             retSsdSets = response.getEntities();
+             if (retSsdSets == null)
+             {
+                 retSsdSets = new ArrayList<>();
+             }
+         }
+         else
+         {
+             throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+         }
+         return retSsdSets;
+    }
+
+    /**
+     * This function returns the set of roles of a SSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param ssd contains the name for the SSD set targeted.
+     * @return Map containing all Roles that are members of SSD data set.
+     * @throws SecurityException in the event of data or system error.
+     */
+    @Override
+    public Set<String> ssdRoleSetRoles(SDSet ssd)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(ssd, GlobalErrIds.SSD_NULL, CLS_NM + ".ssdRoleSetRoles");
+        Set<String> retRoleNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(ssd);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.SSD_ROLES);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Set<String> tempNames = response.getValueSet();
+            // This is done to use a case insensitive TreeSet for returned names.
+            retRoleNames.addAll(tempNames);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRoleNames;
+    }
+
+    /**
+     * This function returns the cardinality associated with a SSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param ssd contains the name of the SSD set targeted, {@link SDSet#name}.
+     * @return int value containing cardinality of SSD set.
+     * @throws SecurityException in the event of data or system error.
+     */
+    @Override
+    public int ssdRoleSetCardinality(SDSet ssd)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(ssd, GlobalErrIds.SSD_NULL, CLS_NM + ".ssdRoleSetCardinality");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(ssd);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.SSD_CARD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet.getCardinality();
+    }
+
+    /**
+     * This function returns the list of all dSD role sets that have a particular Role as member or Role's
+     * parent as a member.  If the Role parameter is left blank, function will return all dSD role sets.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role Will contain the role name, {@link Role#name}, for targeted dSD set or null to return all
+     * @return List containing all matching dSD's.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data or system error.
+     */
+    @Override
+    public List<SDSet> dsdRoleSets(Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".dsdRoleSets");
+        List<SDSet> retDsdRoleSets;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.DSD_ROLE_SETS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retDsdRoleSets = response.getEntities();
+            if (retDsdRoleSets == null)
+            {
+                retDsdRoleSets = new ArrayList<>();
+            }
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retDsdRoleSets;
+    }
+
+    /**
+     * This function returns the DSD data set that matches a particular set name.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param set Will contain the name for existing DSD data set, {@link SDSet#name}.
+     * @return SDSet containing all attributes from matching DSD name.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data or system error.
+     */
+    @Override
+    public SDSet dsdRoleSet(SDSet set)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(set, GlobalErrIds.DSD_NULL, CLS_NM + ".dsdRoleSet");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(set);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.DSD_READ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet;
+    }
+
+    /**
+     * This function returns the list of DSDs that match a given dsd name value.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param dsd contains the name for the DSD set targeted, {@link SDSet#name}.
+     * @return List containing all DSDSets that match a given DSDSet name.
+     * @throws SecurityException in the event of data or system error.
+     */
+    public List<SDSet> dsdSets(SDSet dsd)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(dsd, GlobalErrIds.ROLE_NULL, CLS_NM + ".dsdSets");
+         List<SDSet> retDsdSets;
+         FortRequest request = new FortRequest();
+         request.setContextId(this.contextId);
+         request.setEntity(dsd);
+         if (this.adminSess != null)
+         {
+             request.setSession(adminSess);
+         }
+         String szRequest = RestUtils.marshal(request);
+         String szResponse = RestUtils.post(szRequest, HttpIds.DSD_SETS);
+         FortResponse response = RestUtils.unmarshall(szResponse);
+         if (response.getErrorCode() == 0)
+         {
+             retDsdSets = response.getEntities();
+             if (retDsdSets == null)
+             {
+                 retDsdSets = new ArrayList<>();
+             }
+         }
+         else
+         {
+             throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+         }
+         return retDsdSets;
+    }
+
+    /**
+     * This function returns the set of roles of a DSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param dsd contains the name for the DSD set targeted, {@link SDSet#name}.
+     * @return List containing all Roles that are members of DSD data set.
+     * @throws SecurityException in the event of data or system error.
+     */
+    @Override
+    public Set<String> dsdRoleSetRoles(SDSet dsd)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(dsd, GlobalErrIds.SSD_NULL, CLS_NM + ".dsdRoleSetRoles");
+        Set<String> retRoleNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(dsd);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.DSD_ROLES);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Set<String> tempNames = response.getValueSet();
+            // This is done to use a case insensitive TreeSet for returned names.
+            retRoleNames.addAll(tempNames);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRoleNames;
+    }
+
+    /**
+     * This function returns the cardinality associated with a DSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param dsd contains the name of the DSD set targeted, {@link SDSet#name}.
+     * @return int value containing cardinality of DSD set.
+     * @throws SecurityException in the event of data or system error.
+     */
+    @Override
+    public int dsdRoleSetCardinality(SDSet dsd)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(dsd, GlobalErrIds.DSD_NULL, CLS_NM + ".dsdRoleSetCardinality");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(dsd);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.DSD_CARD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet.getCardinality();
+    }
+}
\ 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/rest/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/package.html b/src/main/java/org/apache/directory/fortress/core/rest/package.html
new file mode 100755
index 0000000..850a58c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/package.html
@@ -0,0 +1,43 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.rest</title>
+   </head>
+   <body>
+      <p>
+         This package uses <a href="http://hc.apache.org/">Commons HTTP</a> to provide HTTP functionality that is reused across several components in this package.
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress.rest</b> package implements HTTP REST access to En Masse server for Fortress APIs
+      </p>
+      <h3>Fortress Manager APIs implemented in this package</h3>
+       <ol>
+       <li><a href="AccessMgrRestImpl.html">AccessMgrRestImpl</a> - This implements using REST runtime access control operations on objects that are provisioned <a href="http://csrc.nist.gov/groups/SNS/rbac/documents/draft-rbac-implementation-std-v01.pdf">RBAC</a> entities that reside in LDAP directory.</li>
+       <li><a href="AdminMgrRestImpl.html">AdminMgrRestImpl</a> - This implements using REST administrative functions to provision Fortress <a href="http://csrc.nist.gov/groups/SNS/rbac/documents/draft-rbac-implementation-std-v01.pdf">RBAC</a> entities into the LDAP directory.</li>
+       <li><a href="AuditMgrRestImpl.html">AuditMgrRestImpl</a> - This implements using REST methods used to search OpenLDAP's slapd access log.</li>
+       <li><a href="DelegatedAccessMgrRestImpl.html">DelegatedAccessMgrRestImpl</a> - This implements using REST APIs for performing runtime delegated access control operations on objects that are provisioned Fortress <a href="http://profsandhu.com/journals/tissec/p113-oh.pdf">ARBAC02</a> entities that reside in LDAP directory.</li>
+       <li><a href="DelegatedAdminMgrRestImpl.html">DelegatedAdminMgrRestImpl</a> - This implements using REST the <a href="http://profsandhu.com/journals/tissec/p113-oh.pdf">ARBAC02</a> DelegatedAdminMgr interface for performing policy administration of Fortress ARBAC entities that reside in LDAP directory.</li>
+       <li><a href="DelegatedReviewMgrRestImpl.html">DelegatedReviewMgrRestImpl</a> - This implements using REST the <a href="http://profsandhu.com/journals/tissec/p113-oh.pdf">ARBAC02</a> DelegatedReviewMgr interface for performing policy interrogation of provisioned Fortress ARBAC02 entities that reside in LDAP directory.</li>
+       <li><a href="PswdPolicyMgr.html">PswdPolicyMgrRestImpl</a> - This implements using REST <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10">IETF PW policy draft</a> and is used to perform administrative and review functions on the <a href="org/openldap/fortress/pwpolicy/PswdPolicy.html">PWPOLICIES</a> and <a href="org/openldap/fortress/rbac/User.html">USERS</a> data sets within Fortress.</li>
+       <li><a href="ReviewMgr.html">ReviewMgrRestImpl</a> - This implements using REST the administrative review functions on already provisioned Fortress <a href="http://csrc.nist.gov/groups/SNS/rbac/documents/draft-rbac-implementation-std-v01.pdf">RBAC</a> entities that reside in LDAP directory.</li>
+       </ol>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/LogUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/LogUtil.java b/src/main/java/org/apache/directory/fortress/core/util/LogUtil.java
new file mode 100755
index 0000000..402663a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/LogUtil.java
@@ -0,0 +1,76 @@
+/*
+ *   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.util;
+
+import org.slf4j.LoggerFactory;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Contains a simple wrapper for log4j that is used by test utilities.
+ *
+ * @author Shawn McKinney
+ */
+public class LogUtil
+{
+    //final private static Logger log = Logger.getLogger(LogUtil.class.getName());
+    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger( LogUtil.class.getName() );
+
+
+    /**
+     * Write a message out to the appropriate log level.
+     *
+     * @param msg Contains message to write out to log.
+     */
+    public static void logIt(String msg)
+    {
+        if(VUtil.isNotNullOrEmpty( getContext() ))
+            msg = getContext() + " " + msg;
+
+        if(LOG.isDebugEnabled())
+        {
+            LOG.debug( msg );
+        }
+        else if(LOG.isInfoEnabled())
+        {
+            LOG.info( msg );
+        }
+        else if(LOG.isWarnEnabled())
+        {
+            LOG.warn( msg );
+        }
+        else if(LOG.isErrorEnabled())
+        {
+            LOG.error( msg );
+        }
+	}
+
+    public static String getContext()
+    {
+        String contextId = null;
+        String tenant = System.getProperty( GlobalIds.TENANT );
+        if ( VUtil.isNotNullOrEmpty( tenant ) && !tenant.equals( "${tenant}" ) )
+        {
+            contextId = tenant;
+        }
+        return contextId;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/Testable.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/Testable.java b/src/main/java/org/apache/directory/fortress/core/util/Testable.java
new file mode 100644
index 0000000..69d54f0
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/Testable.java
@@ -0,0 +1,32 @@
+/*
+ *   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.util;
+
+import org.apache.tools.ant.Task;
+
+/**
+ * Interface is extended by custom Ant tasks that require JUnit validation.
+ *
+ * @author Shawn McKinney
+ */
+public interface Testable
+{
+    public void execute( Task task );
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/attr/AttrHelper.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/attr/AttrHelper.java b/src/main/java/org/apache/directory/fortress/core/util/attr/AttrHelper.java
new file mode 100755
index 0000000..27ae3a7
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/attr/AttrHelper.java
@@ -0,0 +1,308 @@
+/*
+ *   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.util.attr;
+
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.rbac.Administrator;
+import org.apache.directory.fortress.core.rbac.AuthZ;
+import org.apache.directory.fortress.core.rbac.Permission;
+
+import java.text.ParseException;
+import java.util.Date;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Properties;
+
+/**
+ * Class contains static utilities for various conversions of ldap data to application entity and back.  These methods are called by the
+ * Fortress DAO's, i.e. {@link org.apache.directory.fortress.core.rbac.dao.UserDAO}.
+ * These are low-level data utilities and no validations are performed.  These apis should not be called by outside programs.
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+
+ * @author Shawn McKinney
+ */
+public class AttrHelper
+{
+
+
+    /**
+     * Perform copy on ARBAC attributes.  This is used during assignment of {@link org.apache.directory.fortress.core.rbac.AdminRole} to {@link org.apache.directory.fortress.core.rbac.User}.
+     * This method does not perform input validations.
+     *
+     * @param srcR contains source attributes to copy.
+     * @param trgR contains the target reference.
+     */
+    public static void copyAdminAttrs(Administrator srcR, Administrator trgR)
+    {
+        trgR.setBeginInclusive(srcR.isBeginInclusive());
+        trgR.setEndInclusive(srcR.isEndInclusive());
+        trgR.setBeginRange(srcR.getBeginRange());
+        trgR.setEndRange(srcR.getEndRange());
+        // copy the user and perm pools:
+        trgR.setOsP(srcR.getOsP());
+        trgR.setOsU(srcR.getOsU());
+
+    }
+
+    /**
+     * Convert from a {@link java.util.List} of properties stored as name:value pairs to
+     * a {@link java.util.Properties}.
+     *
+     * @param propList contains a list of name-value pairs separated by a ':'.
+     * @return reference to a Properties collection.
+     */
+    public static Properties getProperties(List<String> propList)
+    {
+        return getProperties(propList, GlobalIds.PROP_SEP );
+    }
+
+    /**
+     * Convert from a {@link java.util.List} of properties stored as name:value pairs to
+     * a {@link java.util.Properties}.
+     *
+     * @param propList contains a list of name-value pairs separated by a ':'.
+     * @param separator contains char to be used to separate key and value.
+     * @return reference to a Properties collection.
+     */
+    public static Properties getProperties( List<String> propList, char separator )
+    {
+        Properties props = null;
+        if (propList != null && propList.size() > 0)
+        {
+            props = new Properties();
+            propList.size();
+            for (String raw : propList)
+            {
+
+                int indx = raw.indexOf(separator);
+                if (indx >= 1)
+                {
+                    props.setProperty(raw.substring(0, indx), raw.substring(indx + 1));
+                }
+            }
+        }
+        return props;
+    }
+
+    /**
+     * Convert from a comma delimited list of name-value pairs separated by a ':'.  Return the pros as {@link java.util.Properties}.
+     *
+     * @param inputString contains comma delimited list of properties.
+     * @return java collection class containing props.
+     */
+    public static Properties getProperties( String inputString )
+    {
+        return getProperties( inputString, GlobalIds.PROP_SEP );
+    }
+
+    /**
+     * Convert from a comma delimited list of name-value pairs separated by a ':'.  Return the pros as {@link java.util.Properties}.
+     *
+     * @param inputString contains comma delimited list of properties.
+     * @param separator contains char to be used to separate key and value.
+     * @return java collection class containing props.
+     */
+    public static Properties getProperties( String inputString, char separator )
+    {
+        return getProperties( inputString, separator, GlobalIds.DELIMITER );
+    }
+
+    /**
+     * Convert from a comma delimited list of name-value pairs separated by a ':'.  Return the pros as {@link java.util.Properties}.
+     *
+     * @param inputString contains comma delimited list of properties.
+     * @param separator contains char to be used to separate key and value.
+     * @param delimiter contains a single char specifying delimiter between properties.
+     * @return java collection class containing props.
+     */
+    public static Properties getProperties( String inputString, char separator, String delimiter )
+    {
+        Properties props = new Properties();
+        if (inputString != null && inputString.length() > 0)
+        {
+            StringTokenizer maxTkn = new StringTokenizer(inputString, delimiter);
+            if (maxTkn.countTokens() > 0)
+            {
+                while (maxTkn.hasMoreTokens())
+                {
+                    String val = maxTkn.nextToken();
+                    int indx = val.indexOf(separator);
+                    if (indx >= 1)
+                    {
+                        String name = val.substring(0, indx).trim();
+                        String value = val.substring(indx + 1).trim();
+                        props.setProperty(name, value);
+                    }
+                }
+            }
+        }
+        return props;
+    }
+
+    /**
+     * Parse a raw slapd access log format data string for userId.
+     *
+     * @param inputString raw slapd access log data.
+     * @return string containing userId.
+     */
+    public static String getAuthZId(String inputString)
+    {
+        //reqAuthzID               <uid=fttu3user4,ou=people,dc=jts,dc=com>
+        String userId = null;
+        if (inputString != null && inputString.length() > 0)
+        {
+            StringTokenizer maxTkn = new StringTokenizer(inputString, ",");
+            if (maxTkn.countTokens() > 0)
+            {
+                String val = maxTkn.nextToken();
+                int indx = val.indexOf('=');
+                if (indx >= 1)
+                {
+                    userId = val.substring(indx + 1);
+                }
+            }
+        }
+        return userId;
+    }
+
+
+    /**
+     * Convert from raw ldap generalized time format to {@link java.util.Date}.  Use the UnboundID SDK, <a href="http://www.unboundid.com/products/ldap-sdk/">JGraphT</a>
+     * to decode the string.
+     *
+     * @param inputString containing raw ldap generalized time formatted string.
+     * @return converted to {@link java.util.Date}.
+     */
+    public static Date decodeGeneralizedTime(String inputString) throws ParseException
+    {
+        Date aDate;
+        aDate = com.unboundid.util.StaticUtils.decodeGeneralizedTime(inputString);
+        return aDate;
+    }
+
+
+    /**
+     * Convert from java date {@link java.util.Date} format to raw ldap generalized time format.  Use the UnboundID SDK, <a href="http://www.unboundid.com/products/ldap-sdk/">JGraphT</a>
+     * to encode the string.
+     *
+     * @param date reference to standard java date.
+     * @return converted to standardized ldap generalized time format.
+     */
+    public static String encodeGeneralizedTime(Date date)
+    {
+        String szTime;
+        szTime = com.unboundid.util.StaticUtils.encodeGeneralizedTime(date);
+        return szTime;
+    }
+
+    /**
+     * Parse slapd access raw data to pull the permission name out.
+     *
+     * @param authZ raw data contained in Fortress audit entity.
+     * @return Permission contains {@link org.apache.directory.fortress.core.rbac.Permission#objName} and {@link org.apache.directory.fortress.core.rbac.Permission#opName}
+     */
+    public static Permission getAuthZPerm(AuthZ authZ)
+    {
+        int indx = 0;
+        //final int objectClass = 1;
+        final int oPNm = 2;
+        final int oBjNm = 3;
+        final int user = 4;
+        final int roles = 6;
+
+        // reqFilter
+        // <(&(objectClass=ftOperation)
+        // (ftOpNm=top1_10)(ftObjNm=tob2_4)
+        // (|(ftUsers=fttu3user4)
+        // (ftRoles=ftt3role1)
+        // (ftRoles=ftt3role2)
+        // (ftRoles=ftt3role3)
+        // (ftRoles=ftt3role4)
+        // (ftRoles=ftt3role5)
+        // (ftRoles=ftt3role6)
+        // (ftRoles=ftt3role7)
+        // (ftRoles=ftt3role8)
+        // (ftRoles=ftt3role9)
+        // (ftRoles=ftt3role10)))>
+
+        Permission pOp = new Permission();
+        if (authZ.getReqFilter() != null && authZ.getReqFilter().length() > 0)
+        {
+            StringTokenizer maxTkn = new StringTokenizer(authZ.getReqFilter(), "(");
+            //System.out.println("maxTken size=" + maxTkn.countTokens());
+            int numTokens = maxTkn.countTokens();
+            for (int i = 0; i < numTokens; i++)
+            {
+                String val = maxTkn.nextToken();
+                //System.out.println("token[" + i + "]=" + val);
+                switch (i)
+                {
+                    //case objectClass:
+                    //    indx = val.indexOf('=');
+                    //    if (indx >= 1)
+                    //    {
+                    //        String value = val.substring(indx + 1, val.length() - 1);
+                    //    }
+                    //    break;
+
+                    case oPNm:
+                        indx = val.indexOf('=');
+                        if (indx >= 1)
+                        {
+                            pOp.setOpName(val.substring(indx + 1, val.length() - 1));
+                        }
+                        break;
+
+                    case oBjNm:
+                        indx = val.indexOf('=');
+                        if (indx >= 1)
+                        {
+                            pOp.setObjName( val.substring( indx + 1, val.length() - 1 ) );
+                        }
+                        break;
+
+                    case user:
+                        indx = val.indexOf('=');
+                        if (indx >= 1)
+                        {
+                            pOp.setUser(val.substring(indx + 1, val.length() - 1));
+                        }
+                        break;
+
+                    default:
+                        int indx2 = 0;
+                        if (i >= roles)
+                        {
+                            indx = val.indexOf('=');
+                            indx2 = val.indexOf(')');
+                        }
+                        if (indx >= 1)
+                        {
+                            pOp.setRole(val.substring(indx + 1, indx2));
+                        }
+                        break;
+                }
+            }
+        }
+        return pOp;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/attr/RegExUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/attr/RegExUtil.java b/src/main/java/org/apache/directory/fortress/core/util/attr/RegExUtil.java
new file mode 100755
index 0000000..08d1f80
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/attr/RegExUtil.java
@@ -0,0 +1,68 @@
+/*
+ *   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.util.attr;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.ValidationException;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ *  Regular expression utilities to perform data validations on Fortress attributes.  These utils use the standard
+ * java regular expression library.
+ *
+ * @author     Shawn McKinney
+ */
+class RegExUtil
+{
+    private static final String CLS_NM = RegExUtil.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+	private static final String safeTextPatternStr = Config.getProperty( GlobalIds.REG_EX_SAFE_TEXT );
+
+	/**
+	 *  Perform safe text validation on character string.
+	 *
+	 * @param  value Contains the string to check.
+	 * @exception org.apache.directory.fortress.core.ValidationException  In the event the data validation fails.
+	 */
+	public static void safeText(String value)
+		throws ValidationException
+	{
+		if (safeTextPatternStr == null || safeTextPatternStr.compareTo("") == 0)
+		{
+			LOG.debug("safeText can't find safeText regular expression pattern.  Check your Fortress cfg");
+		}
+		else
+		{
+			Pattern safeTextPattern = Pattern.compile(safeTextPatternStr);
+			Matcher safeTextMatcher = safeTextPattern.matcher(value);
+			if (!safeTextMatcher.find())
+			{
+				String error = "safeText has detected invalid value [" + value + "]";
+				throw new ValidationException(GlobalErrIds.CONST_INVLD_TEXT, error);
+			}
+		}
+	}
+}
\ No newline at end of file


[25/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnitP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnitP.java b/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnitP.java
new file mode 100755
index 0000000..7a53ea8
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnitP.java
@@ -0,0 +1,370 @@
+/*
+ *   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 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.SecurityException;
+import org.apache.directory.fortress.core.rbac.dao.DaoFactory;
+import org.apache.directory.fortress.core.rbac.dao.OrgUnitDAO;
+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;
+
+
+/**
+ * Process module for the OrgUnit entity. The Fortress OrgUnit data set can be associated with two entities:
+ * {@link org.apache.directory.fortress.core.rbac.User} class or {@link org.apache.directory.fortress.core.rbac.PermObj} class.  The OrgUnit entity itself is stored in two separate locations in the ldap tree one
+ * for each entity listed above.  The type of OU entity is set via the enum attribute {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type} which is equal to 'PERM' or 'USER'.
+ * This class performs data validations.  The methods of this class are called by internal Fortress manager impl classes
+ * {@link DelAdminMgrImpl} and {@link DelReviewMgrImpl} but is also called by {@link org.apache.directory.fortress.core.rbac.PermP#validate} method and {@link org.apache.directory.fortress.core.rbac.UserP#validate} functions
+ * which ensure the entities are related to valid OU entries. This class is not intended to be called external
+ * to Fortress Core itself.  This class will accept Fortress entity {@link org.apache.directory.fortress.core.rbac.OrgUnit}, validate its contents and forward on to it's
+ * corresponding DAO class {@link OrgUnitDAO} for data access.
+ * <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 GlobalErrIds}.
+ * <p>
+ * This class uses synchronized data sets ({@link #ouCache} but is thread safe.
+ * <p/>
+
+ * @author Shawn McKinney
+ */
+public final class OrgUnitP
+{
+    // init the logger:
+    private static final String CLS_NM = OrgUnitP.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    // these fields are used to synchronize access to the above static pools:
+    private static final Object userPoolSynchLock = new Object();
+    private static final Object permPoolSynchLock = new Object();
+    private static Cache ouCache;
+
+    // DAO class for OU data sets must be initializer before the other statics:
+    private static final OrgUnitDAO oDao = DaoFactory.createOrgUnitDAO();
+    private static final String USER_OUS = "user.ous";
+    private static final String PERM_OUS = "perm.ous";
+    private static final String FORTRESS_OUS = "fortress.ous";
+
+    static
+    {
+        CacheMgr cacheMgr = CacheMgr.getInstance();
+        OrgUnitP.ouCache = cacheMgr.getCache( FORTRESS_OUS );
+    }
+
+
+    /**
+     * Package private constructor.
+     */
+    OrgUnitP()
+    {
+    }
+
+
+    /**
+     * This function uses a case insensitive search.
+     * @param entity
+     * @return
+     */
+    final boolean isValid( OrgUnit entity )
+    {
+        boolean result = false;
+        if ( entity.type == OrgUnit.Type.USER )
+        {
+            Set<String> userPool = getOrgSet( entity );
+            if ( userPool != null && entity.getType() == OrgUnit.Type.USER )
+            {
+                result = userPool.contains( entity.getName() );
+            }
+        }
+        else
+        {
+            Set<String> permPool = getOrgSet( entity );
+            if ( permPool != null )
+            {
+                result = permPool.contains( entity.getName() );
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * @param orgUnit
+     * @return
+     */
+    private static Set<String> loadOrgSet( OrgUnit orgUnit )
+    {
+        Set<String> ouSet = null;
+        try
+        {
+            ouSet = oDao.getOrgs( orgUnit );
+        }
+        catch ( SecurityException se )
+        {
+            String warning = "loadOrgSet static initializer caught SecurityException=" + se;
+            LOG.info( warning, se );
+        }
+        if ( orgUnit.getType() == OrgUnit.Type.USER )
+        {
+            // TODO:  add context id to this cache
+            ouCache.put( getKey( USER_OUS, orgUnit.getContextId() ), ouSet );
+        }
+        else
+        {
+            ouCache.put( getKey( PERM_OUS, orgUnit.getContextId() ), ouSet );
+        }
+
+        return ouSet;
+    }
+
+
+    /**
+     *
+     * @param orgUnit will either be a User or Perm OU.
+     * @return Set containing the OU mapping to a particular type and tenant.
+     */
+    private static Set<String> getOrgSet( OrgUnit orgUnit )
+    {
+        Set<String> orgSet;
+        if ( orgUnit.getType() == OrgUnit.Type.USER )
+        {
+            orgSet = ( Set<String> ) ouCache.get( getKey( USER_OUS, orgUnit.getContextId() ) );
+        }
+        else
+        {
+            orgSet = ( Set<String> ) ouCache.get( getKey( PERM_OUS, orgUnit.getContextId() ) );
+        }
+
+        if ( orgSet == null )
+        {
+            orgSet = loadOrgSet( orgUnit );
+        }
+        return orgSet;
+    }
+
+
+    /**
+     * Return a fully populated OrgUnit entity for a given Perm or User orgUnitId.  If matching record not found a
+     * SecurityException will be thrown.
+     *
+     * @param entity contains full orgUnit name used for User or Perm OU data sets in directory.
+     * @return OrgUnit entity containing all attributes associated with ou in directory.
+     * @throws SecurityException in the event OrgUnit not found or DAO search error.
+     */
+    final OrgUnit read( OrgUnit entity ) throws SecurityException
+    {
+        validate( entity, false );
+        return oDao.findByKey( entity );
+    }
+
+
+    /**
+     * Will search either User or Perm OrgUnit data sets depending on which type is passed.
+     * The search string that contains full or partial OrgUnit name associated with OU node in directory.
+     *
+     * @param orgUnit contains full or partial OU name.
+     * @return List of type OrgUnit containing fully populated matching OU entities.  If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<OrgUnit> search( OrgUnit orgUnit ) throws SecurityException
+    {
+        // Call the finder.
+        return oDao.findOrgs( orgUnit );
+    }
+
+
+    /**
+     * Adds a new OrgUnit to directory. The OrgUnit type enum will determine which data set insertion will
+     * occur - User or Perm.  The OrgUnit entity input will be validated to ensure that:
+     * orgUnit name is present and type is specified, and reasonability checks on all of the other populated values.
+     *
+     * @param entity OrgUnit contains data targeted for insertion.
+     * @return OrgUnit 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 OrgUnit add( OrgUnit entity ) throws SecurityException
+    {
+        validate( entity, false );
+        OrgUnit oe = oDao.create( entity );
+        if ( entity.getType() == OrgUnit.Type.USER )
+        {
+            Set<String> userPool = getOrgSet( entity );
+            synchronized ( userPoolSynchLock )
+            {
+                if ( userPool != null )
+                    userPool.add( entity.getName() );
+            }
+        }
+        else
+        {
+            Set<String> permPool = getOrgSet( entity );
+            synchronized ( permPoolSynchLock )
+            {
+                if ( permPool != null )
+                    permPool.add( entity.getName() );
+            }
+        }
+        return oe;
+    }
+
+
+    /**
+     * Updates existing OrgUnit in directory. The OrgUnit type enum will determine which data set insertion will
+     * occur - User or Perm.  The OrgUnit entity input will be validated to ensure that:
+     * orgUnit name is present, and reasonability checks on all of the other populated values.
+     * Null or empty attributes are ignored.
+     *
+     * @param entity OrgUnit contains data targeted for updating.  Null attributes ignored.
+     * @return OrgUnit entity copy of input + additional attributes (internalId) that were updated by op.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final OrgUnit update( OrgUnit entity ) throws SecurityException
+    {
+        validate( entity, false );
+        return oDao.update( entity );
+    }
+
+
+    /**
+     * Remove the parent attribute from the OrgUnit entry in directory. The OrgUnit type enum will determine which data set insertion will
+     * occur - User or Perm.  The OrgUnit entity input will be validated to ensure that:
+     * orgUnit name is present.
+     *
+     * @param entity OrgUnit contains data targeted for updating.  Null attributes ignored.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final void deleteParent( OrgUnit entity ) throws SecurityException
+    {
+        validate( entity, false );
+        oDao.deleteParent( entity );
+    }
+
+
+    /**
+     * This method performs a "hard" delete.  It completely the OrgUnit node from the ldap directory.
+     * The OrgUnit type enum will determine where deletion will occur - User or Perm OU data sets.
+     * OrgUnit entity must exist in directory prior to making this call else exception will be thrown.
+     *
+     * @param entity Contains the name of the OrgUnit node targeted for deletion.
+     * @return OrgUnit entity copy of input.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final OrgUnit delete( OrgUnit entity ) throws SecurityException
+    {
+        oDao.remove( entity );
+        if ( entity.getType() == OrgUnit.Type.USER )
+        {
+            Set<String> userPool = getOrgSet( entity );
+            synchronized ( userPoolSynchLock )
+            {
+                if ( userPool != null )
+                    userPool.remove( entity.getName() );
+            }
+        }
+        else
+        {
+            Set<String> permPool = getOrgSet( entity );
+            synchronized ( permPoolSynchLock )
+            {
+                if ( permPool != null )
+                    permPool.remove( entity.getName() );
+            }
+        }
+        return entity;
+    }
+
+
+    /**
+     * Return all OrgUnits that have a parent assignment.  This used for hierarchical processing.
+     *
+     * @param orgUnit will either be a User or Perm OU.
+     * @return List of type OrgUnit containing {@link OrgUnit#name} and {@link OrgUnit#parents} populated.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<Graphable> getAllDescendants( OrgUnit orgUnit ) throws SecurityException
+    {
+        return oDao.getAllDescendants( orgUnit );
+    }
+
+
+    /**
+     * Method will perform simple validations to ensure the integrity of the OrgUnit entity targeted for insertion
+     * or updating in directory.  This method will ensure the name and type enum are specified.  It will also perform
+     * reasonability check on description if set.
+     *
+     * @param entity   contains the enum type to validate
+     * @param isUpdate not used at this time.
+     * @throws SecurityException thrown in the event the attribute is null.
+     */
+    private void validate( OrgUnit entity, boolean isUpdate )
+        throws SecurityException
+    {
+        VUtil.safeText( entity.getName(), GlobalIds.OU_LEN );
+        if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+        {
+            VUtil.description( entity.getDescription() );
+        }
+        if ( entity.getType() == null )
+        {
+            String error = "validate null or empty org unit type";
+            int errCode;
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_TYPE_NULL_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_TYPE_NULL_USER;
+            }
+            throw new SecurityException( errCode, error );
+        }
+    }
+
+
+    /**
+     * Build a key that is composed of the OU type ({@link #USER_OUS} or {@link #PERM_OUS}) and the contextId which is the id of tenant.
+     *
+     * @param type either {@link #USER_OUS} or {@link #PERM_OUS}.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return
+     */
+    private static String getKey( String type, String contextId )
+    {
+        String key = type;
+        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/OrgUnitRelationship.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnitRelationship.java b/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnitRelationship.java
new file mode 100755
index 0000000..3756c93
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnitRelationship.java
@@ -0,0 +1,65 @@
+/*
+ *   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.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * This entity is used by en masse to communicate parent and child {@link org.apache.directory.fortress.core.rbac.OrgUnit} information to the server.
+ * <p/>
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortOrgUnitRelationship")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "orgrelationship", propOrder = {
+    "child",
+    "parent"
+})
+public class OrgUnitRelationship extends FortEntity
+    implements java.io.Serializable
+{
+    private OrgUnit parent;
+    private OrgUnit child;
+
+    public OrgUnit getParent()
+    {
+        return parent;
+    }
+
+    public void setParent(OrgUnit parent)
+    {
+        this.parent = parent;
+    }
+
+    public OrgUnit getChild()
+    {
+        return child;
+    }
+
+    public void setChild(OrgUnit child)
+    {
+        this.child = child;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/PermGrant.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/PermGrant.java b/src/main/java/org/apache/directory/fortress/core/rbac/PermGrant.java
new file mode 100755
index 0000000..42bf322
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PermGrant.java
@@ -0,0 +1,169 @@
+/*
+ *   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.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * This entity is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to add {@link Permission} grants to
+ * RBAC {@link org.apache.directory.fortress.core.rbac.Role}, or ARBAC {@link org.apache.directory.fortress.core.rbac.AdminRole}.
+ * Can also be used to grant Permissions directly to {@link org.apache.directory.fortress.core.rbac.User}s.
+ * This entity is used for Ant and En Masse processing only.
+ * <p/>
+
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortGrant")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "permGrant", propOrder = {
+    "objName",
+    "opName",
+    "objId",
+    "userId",
+    "roleNm",
+    "admin"
+})
+public class PermGrant extends FortEntity
+    implements java.io.Serializable
+{
+    private String objName;
+    private String opName;
+    private String objId;
+    private String userId;
+    private String roleNm;
+    private boolean admin;
+
+    /**
+     * Return the permission object name.
+     * @return maps to 'ftObjNm' attribute on 'ftOperation' object class.
+     */
+    public String getObjName()
+    {
+        return objName;
+    }
+
+    /**
+     * Set the permission object name.
+     * @param objName maps to 'ftObjNm' attribute on 'ftOperation' object class.
+     */
+    public void setObjName(String objName)
+    {
+        this.objName = objName;
+    }
+
+    /**
+     * Return the permission object id.
+     * @return maps to 'ftObjId' attribute on 'ftOperation' object class.
+     */
+    public String getObjId()
+    {
+        return objId;
+    }
+
+    /**
+     * Set the permission object id.
+     * @param objId maps to 'ftObjId' attribute on 'ftOperation' object class.
+     */
+    public void setObjId(String objId)
+    {
+        this.objId = objId;
+    }
+
+    /**
+     * Return the permission operation name.
+     * @return maps to 'ftOpNm' attribute on 'ftOperation' object class.
+     */
+    public String getOpName()
+    {
+        return opName;
+    }
+
+    /**
+     * Set the permission operation name.
+     * @param opName maps to 'ftOpNm' attribute on 'ftOperation' object class.
+     */
+    public void setOpName(String opName)
+    {
+        this.opName = opName;
+    }
+
+    /**
+     * Get the userId attribute from this entity.
+     *
+     * @return maps to 'ftUsers' attribute on 'ftOperation' object class.
+     */
+    public String getUserId()
+    {
+        return userId;
+    }
+
+    /**
+     * Set the userId attribute on this entity.
+     *
+     * @param userId maps to 'ftUsers' attribute on 'ftOperation' object class.
+     */
+    public void setUserId(String userId)
+    {
+        this.userId = userId;
+    }
+
+    /**
+     * Get the role name associated from this entity.
+     *
+     * @return maps to 'ftRoles' attribute on 'ftOperation' object class.
+     */
+    public String getRoleNm()
+    {
+        return roleNm;
+    }
+
+    /**
+     * Set the role name associated with this entity.
+     *
+     * @param roleNm maps to 'ftRoles' attribute on 'ftOperation' object class.
+     */
+    public void setRoleNm(String roleNm)
+    {
+        this.roleNm = roleNm;
+    }
+
+
+    /**
+     * If set to true entity will be stored in ldap subdirectory associated with administrative permissions {@link org.apache.directory.fortress.core.GlobalIds#ADMIN_PERM_ROOT}.
+     * otherwise will be RBAC permissions {@link org.apache.directory.fortress.core.GlobalIds#PERM_ROOT}
+     * @return boolean if administrative entity.
+     */
+    public boolean isAdmin()
+    {
+        return admin;
+    }
+
+    /**
+     * Return boolean value that will be set to true if this entity will be stored in Administrative Permissions.
+     * @param admin will be true if administrative entity.
+     */
+    public void setAdmin(boolean admin)
+    {
+        this.admin = admin;
+    }
+}
\ 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/PermObj.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/PermObj.java b/src/main/java/org/apache/directory/fortress/core/rbac/PermObj.java
new file mode 100755
index 0000000..17e9fb8
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PermObj.java
@@ -0,0 +1,554 @@
+/*
+ *   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.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.UUID;
+
+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.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;
+
+
+/**
+ * All entities ({@link org.apache.directory.fortress.core.rbac.User}, {@link org.apache.directory.fortress.core.rbac.Role}, {@link Permission},
+ * {@link PwPolicy} {@link org.apache.directory.fortress.core.rbac.SDSet} etc...) are used to carry data between three Fortress
+ * layers.starting with the (1) Manager layer down thru middle (2) Process layer and it's processing rules into
+ * (3) DAO layer where persistence with the OpenLDAP server occurs.
+ * <h4>Fortress Processing Layers</h4>
+ * <ol>
+ * <li>Manager layer:  {@link AdminMgrImpl}, {@link AccessMgrImpl}, {@link ReviewMgrImpl},...</li>
+ * <li>Process layer:  {@link org.apache.directory.fortress.core.rbac.UserP}, {@link org.apache.directory.fortress.core.rbac.RoleP}, {@link org.apache.directory.fortress.core.rbac.PermP},...</li>
+ * <li>DAO layer: {@link UserDAO}, {@link RoleDAO}, {@link org.apache.directory.fortress.core.rbac.dao.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 />
+ * For example, this entity requires {@link #objName} and {@link #ou} attributes set before passing into {@link AdminMgrImpl} or  {@link ReviewMgrImpl} APIs.
+ * Create methods usually require more attributes (than Read) due to constraints enforced between entities.
+ * <p/>
+ * <h4>PermObj entity attribute usages include</h4>
+ * <ul>
+ * <li>{@link #setObjName} and {@link #setOu} attributes set before calling {@link AdminMgrImpl#addPermObj(PermObj)}.
+ * <li>{@link #addProperty} may be set before calling {@link AdminMgrImpl#addPermObj(PermObj)}.
+ * <li>{@link #getProperty} may be set after calling {@link ReviewMgrImpl#findPermObjs(PermObj)}.
+ * </ul>
+ * <p/>
+ * <h4>More Permission entity notes</h4>
+ * <ul>
+ * <li>The {@link PermObj} entity is not used for authorization checks, rather contains {@link Permission} which are themselves authorization targets.<br />
+ * <li>This entity must be associated with a valid Perm OU {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM} that is contained within the {@code ou=OS-P,ou=ARBAC,dc=example,dc=com} location in ldap.
+ * <li>The object to operation pairings enable application resources to be mapped to Fortress permissions in a way that is natural for object oriented programming.
+ * <li>Permissions = Object {@link PermObj} 1<->* Operations {@link Permission}
+ * <p/>
+ * <img src="../doc-files/RbacCore.png">
+ * <li>The unique key to locate an Fortress PermObj entity is {@code PermObj#objName}.
+ * <li>For sample code usages check out {@link Permission} javadoc.
+ * </ul>
+ * <p/>
+ * <h4>PermObj Schema</h4>
+ * The Fortress PermObj Entity Class is a composite of 3 different LDAP Schema object classes:
+ * <p/>
+ * 1. ftObject STRUCTURAL Object Class is used to store object name, id and type variables on target entity.
+ * <pre>
+ * Fortress Permission Structural Object Class
+ * objectclass	( 1.3.6.1.4.1.38088.2.2
+ *  NAME 'ftObject'
+ *  DESC 'Fortress Permission Object Class'
+ *  SUP organizationalunit
+ *  STRUCTURAL
+ *  MUST (
+ *      ftId $
+ *      ftObjNm
+ *  )
+ *  MAY (
+ *      ftType
+ *  )
+ * )
+ * 2. ftProperties AUXILIARY Object Class is used to store client specific name/value pairs on target entity.
+ * This aux object class can be used to store custom attributes<br />
+ * The properties collections consist of name/value pairs and are not constrainted by Fortress.<br />
+ * <pre>
+ * ------------------------------------------
+ * AC2: Fortress Properties Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.2
+ *  NAME 'ftProperties'
+ *  DESC 'Fortress Properties AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftProps
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 3. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Audit Modification Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.4
+ *  NAME 'ftMods'
+ *  DESC 'Fortress Modifiers AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftModifier $
+ *      ftModCode $
+ *      ftModId
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortObject")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "permObj", propOrder =
+    {
+        "objName",
+        "description",
+        "internalId",
+        "ou",
+        "type",
+        "props",
+        "admin"
+})
+public class PermObj extends FortEntity
+    implements java.io.Serializable
+{
+    private boolean admin;
+    private String internalId;
+    private String objName;
+    private String description;
+    @XmlElement(nillable = true)
+    private Props props = new Props();
+    //private Properties props;
+    private String ou;
+    private String type;
+    @XmlTransient
+    private String dn;
+
+
+    /**
+     * Default Constructor used internal to Fortress.
+     */
+    public PermObj()
+    {
+
+    }
+
+
+    /**
+     * Construct an Fortress PermObj entity given an object name.
+     *
+     * @param objName maps to 'ftObjNm' attribute in 'ftObject' object class.
+     */
+    public PermObj( String objName )
+    {
+        this.objName = objName;
+    }
+
+
+    /**
+     * Construct an Fortress PermObj entity given an object and perm ou name.
+     *
+     * @param objName maps to 'ftObjNm' attribute in 'ftObject' object class.
+     * @param ou maps to 'ou' attribute in 'ftObject' object class.
+     */
+    public PermObj( String objName, String ou )
+    {
+        this.objName = objName;
+        this.ou = ou;
+    }
+
+
+    /**
+     * Get the authorization target's object name.  This is typically mapped to the class name for component
+     * that is the target for Fortress authorization check. For example 'PatientRelationshipInquire'.
+     *
+     * @return the name of the object which maps to 'ftObjNm' attribute in 'ftObject' object class.
+     */
+    public String getObjName()
+    {
+        return objName;
+    }
+
+
+    /**
+     * This attribute is required and sets the authorization target object name.  This name is typically derived from the class name
+     * for component that is the target for Fortress authorization check. For example 'CustomerCheckOutPage'.
+     *
+     */
+    public void setObjName( String objName )
+    {
+        this.objName = objName;
+    }
+
+
+    /**
+     * This attribute is required but is set automatically by Fortress DAO class before object is persisted to ldap.
+     * This generated internal id is associated with PermObj.  This method is used by DAO class and
+     * is not available to outside classes.   The generated attribute maps to 'ftId' in 'ftObject' object class.
+     */
+    public void setInternalId()
+    {
+        // generate a unique id that will be used as the rDn for this entry:
+        UUID uuid = UUID.randomUUID();
+        this.internalId = uuid.toString();
+
+        //UID iid = new UID();
+        // assign the unique id to the internal id of the entity:
+        //this.internalId = iid.toString();
+    }
+
+
+    /**
+     * Set the internal id that is associated with PermObj.  This method is used by DAO class and
+     * is generated automatically by Fortress.  Attribute stored in LDAP cannot be changed by external caller.
+     * This method can be used by client for search purposes only.
+     *
+     * @param internalId maps to 'ftId' in 'ftObject' object class.
+     */
+    public void setInternalId( String internalId )
+    {
+        this.internalId = internalId;
+    }
+
+
+    /**
+     * Return the internal id that is associated with PermObj.  This attribute is generated automatically
+     * by Fortress when new PermObj is added to directory and is not known or changeable by external client.
+     *
+     * @return attribute maps to 'ftId' in 'ftObject' object class.
+     */
+    public String getInternalId()
+    {
+        return internalId;
+    }
+
+
+    /**
+     * If set to true, this entity will be loaded into the Admin Permission data set.
+     *
+     * @return boolean indicating if entity is an RBAC (false) or Admin (true) Permission Object.
+     */
+    public boolean isAdmin()
+    {
+        return admin;
+    }
+
+
+    /**
+     * If set to true, this entity will be loaded into the Admin Permission data set.
+     *
+     * @param admin boolean variable indicates if entity is an RBAC or ARBAC Permission Object.
+     */
+
+    public void setAdmin( boolean admin )
+    {
+        this.admin = admin;
+    }
+
+
+    /**
+     * Sets the optional description that is associated with PermObj.  This attribute is validated but not constrained by Fortress.
+     *
+     * @param description that is mapped to same name in 'organizationalUnit' object class.
+     */
+    public void setDescription( String description )
+    {
+        this.description = description;
+    }
+
+
+    /**
+     * Returns optional description that is associated with PermObj.  This attribute is validated but not constrained by Fortress.
+     *
+     * @return value that is mapped to 'description' in 'organizationalUnit' object class.
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+
+    /**
+      * Gets the value of the Props property.  This method is used by Fortress and En Masse and should not be called by external programs.
+      *
+      * @return
+      *     possible object is
+      *     {@link Props }
+      *
+      */
+    public Props getProps()
+    {
+        return props;
+    }
+
+
+    /**
+     * Sets the value of the Props property.  This method is used by Fortress and En Masse and should not be called by external programs.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link Props }
+     *
+     */
+    public void setProps( Props value )
+    {
+        this.props = value;
+    }
+
+
+    /**
+     * Add name/value pair to list of properties associated with PermObj.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param key   contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     * @param value
+     */
+    public void addProperty( String key, String value )
+    {
+        Props.Entry entry = new Props.Entry();
+        entry.setKey( key );
+        entry.setValue( value );
+        this.props.getEntry().add( entry );
+    }
+
+
+    /**
+     * Get a name/value pair attribute from list of properties associated with PermObj.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param key contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     * @return value containing name/value pair that maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public String getProperty( String key )
+    {
+        List<Props.Entry> props = this.props.getEntry();
+        Props.Entry keyObj = new Props.Entry();
+        keyObj.setKey( key );
+
+        String value = null;
+        int indx = props.indexOf( keyObj );
+        if ( indx != -1 )
+        {
+            Props.Entry entry = props.get( props.indexOf( keyObj ) );
+            value = entry.getValue();
+        }
+
+        return value;
+    }
+
+
+    /**
+     * Add new collection of name/value pairs to attributes associated with PermObj.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param props contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public void addProperties( Properties props )
+    {
+        if ( props != null )
+        {
+            for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+                addProperty( key, val );
+            }
+        }
+    }
+
+
+    /**
+     * Return the collection of name/value pairs to attributes associated with PermObj.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @return Properties contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public Properties getProperties()
+    {
+        Properties properties = null;
+        List<Props.Entry> props = this.props.getEntry();
+        if ( props.size() > 0 )
+        {
+            properties = new Properties();
+            //int size = props.size();
+            for ( Props.Entry entry : props )
+            {
+                String key = entry.getKey();
+                String val = entry.getValue();
+                properties.setProperty( key, val );
+            }
+        }
+        return properties;
+    }
+
+
+    /**
+    * Add name/value pair to list of properties associated with PermObj.  These values are not constrained by Fortress.
+    * Properties are optional.
+    *
+    * @param key   contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+    * @param value
+    */
+    //public void addProperty(String key, String value)
+    //{
+    //    if (props == null)
+    //    {
+    //        props = new Properties();
+    //    }
+
+    //    this.props.setProperty(key, value);
+    //}
+
+    /**
+     * Add new collection of name/value pairs to attributes associated with PermObj.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param props contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    //public void addProperties(Properties props)
+    //{
+    //    this.props = props;
+    //}
+
+    /**
+     * Return the collection of name/value pairs to attributes associated with PermObj.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @return Properties contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    //public Properties getProperties()
+    //{
+    //    return this.props;
+    //}
+
+    /**
+     * Set the orgUnit name associated with PermObj.  This attribute is validated and constrained by Fortress and must contain name of existing Perm OU.
+     * This attribute is required on add but not on read.
+     *
+     * @param ou mapped to same name in 'ftObject' object class.
+     */
+    public void setOu( String ou )
+    {
+        this.ou = ou;
+    }
+
+
+    /**
+     * Return orgUnit name for PermObj.  This attribute is validated and constrained by Fortress and must contain name of existing Perm OU.
+     * This attribute is required on add but not on read.
+     *
+     * @return value that is mapped to 'ou' in 'ftObject' object class.
+     */
+    public String getOu()
+    {
+        return ou;
+    }
+
+
+    /**
+     * Sets the type attribute of the Perm object.  Currently the type is not constrained to any
+     * preexisting Fortress data set meaning the type is user defined and can be used for grouping like permissions.
+     *
+     * @param type maps to attribute name 'ftType' in 'ftObject' object class.
+     */
+    public void setType( String type )
+    {
+        this.type = type;
+    }
+
+
+    /**
+     * Get the type attribute of the Perm object.  Currently the type is not constrained to any
+     * preexisting Fortress data set meaning the type is user defined and can be used for grouping like permissions.
+     *
+     * @return maps to attribute name 'ftType' in 'ftObject' object class.
+     */
+    public String getType()
+    {
+        return type;
+    }
+
+
+    /**
+     * Set distinguished name associated with PermObj.  This attribute is used by DAO and is not allowed for outside classes.
+     * This attribute should not be set by external callers.
+     *
+     * @param dn that is mapped to same name in 'organizationalUnit' object class.
+     */
+    public void setDn( String dn )
+    {
+        this.dn = dn;
+    }
+
+
+    /**
+     * Returns distinguished name associated with PermObj.  This attribute is generated by DAO and is not allowed for outside classes to modify.
+     * This attribute is for internal user only and need not be processed by external clients.
+     *
+     * @return value that is mapped to 'dn' in 'organizationalUnit' object class.
+     */
+    public String getDn()
+    {
+        return dn;
+    }
+
+
+    /**
+     * Matches the objName from two PermObj entities.
+     *
+     * @param thatObj contains a PermObj entity.
+     * @return boolean indicating both objects contain matching objNames.
+     */
+    public boolean equals( Object thatObj )
+    {
+        if ( this == thatObj )
+            return true;
+        if ( this.getObjName() == null )
+            return false;
+        if ( !( thatObj instanceof PermObj ) )
+            return false;
+        PermObj thatPermObj = ( PermObj ) thatObj;
+        if ( thatPermObj.getObjName() == null )
+            return false;
+        return thatPermObj.getObjName().equalsIgnoreCase( this.getObjName() );
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Permission Object {" +
+            "name='" + objName + '\'' +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/PermP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/PermP.java b/src/main/java/org/apache/directory/fortress/core/rbac/PermP.java
new file mode 100755
index 0000000..d38da50
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PermP.java
@@ -0,0 +1,614 @@
+/*
+ *   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 org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+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.PermDAO;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * Process module for the Permission 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 PermObj} or {@link Permission}, validate its contents and forward on to it's corresponding DAO class {@link org.apache.directory.fortress.core.rbac.dao.PermDAO}.
+ * <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 PermP
+{
+    /**
+     * Description of the Field
+     */
+    private static final String CLS_NM = PermP.class.getName();
+    private static final PermDAO pDao = DaoFactory.createPermDAO();
+    private final OrgUnitP orgUnitP = new OrgUnitP();
+
+
+    /**
+     * Package private constructor
+     */
+    PermP()
+    {
+    }
+
+
+    /**
+     * This function returns a Boolean value meaning whether the subject of a given session is
+     * allowed or not to perform a given operation on a given object. The function is valid if and
+     * only if the session is a valid Fortress session, the object is a member of the OBJS data set,
+     * and the operation is a member of the OPS data set. The session's subject has the permission
+     * to perform the operation on that object if and only if that permission is assigned to (at least)
+     * one of the session's active roles. This implementation will verify the roles or userId correspond
+     * to the subject's active roles are registered in the object's access control list.
+     *
+     * @param session    This object must be instantiated by calling {@link AccessMgrImpl#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param permission object contains obj attribute which is a String and contains the name of the object user is trying to access;
+     *                   perm object contains operation attribute which is also a String and contains the operation name for the object.
+     * @return True of user has access, false otherwise.
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    final boolean checkPermission( Session session, Permission permission ) throws SecurityException
+    {
+        return pDao.checkPermission( session, permission );
+    }
+
+
+    /**
+     * Takes a Permission entity that contains full or partial object name and/or full or partial operation name for search.
+     *
+     * @param permission contains all or partial object name and/or all or partial operation name.
+     * @return List of type Permission containing fully populated matching Permission entities.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<Permission> search( Permission permission ) throws SecurityException
+    {
+        return pDao.findPermissions( permission );
+    }
+
+
+    /**
+     * Takes a Permission object entity that contains full or partial object name for search Permission Objects in directory..
+     *
+     * @param permObj contains all or partial object name.
+     * @return List of type Permission Objects containing fully populated matching entities.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<PermObj> search( PermObj permObj ) throws SecurityException
+    {
+        return pDao.findPermissions( permObj );
+    }
+
+
+    /**
+     * Takes an OrgUnit entity that contains full or partial orgUnitId for search Permission Objects in directory..
+     *
+     * @param ou contains all or OrgUnitId.
+     * @param limitSize contains max number of entries to return.
+     * @return List of type Permission Objects containing fully populated matching entities.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<PermObj> search( OrgUnit ou, boolean limitSize ) throws SecurityException
+    {
+        return pDao.findPermissions( ou, limitSize );
+    }
+
+
+    /**
+     * Search will return a list of matching permissions that are assigned to a given RBAC or Admin role name.  The
+     * DAO class will search the Admin perms if the "isAdmin" boolean flag is "true", otherwise it will search RBAC perm tree.
+     *
+     * @param role contains the RBAC or Admin Role name targeted for search.
+     * @return List of type Permission containing fully populated matching Permission entities.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<Permission> search( Role role ) throws SecurityException
+    {
+        return pDao.findPermissions( role );
+    }
+
+
+    /**
+     * Search will return a list of matching permissions that are assigned to a given User.  This method searches
+     * the RBAC perms only.
+     *
+     * @param user contains the userId targeted for search.
+     * @return List of type Permission containing fully populated matching Permission entities.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<Permission> search( User user ) throws SecurityException
+    {
+        return pDao.findPermissions( user );
+    }
+
+
+    /**
+     * Remove the User assignment attribute from all RBAC permssions.  This method is called by AdminMgrImpl
+     * when the User is being deleted.
+     *
+     * @param user contains the userId targeted for attribute removal.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final void remove( User user ) throws SecurityException
+    {
+        List<Permission> list;
+        try
+        {
+            list = pDao.findUserPermissions( user );
+            for ( Permission perm : list )
+            {
+                revoke( perm, user );
+            }
+        }
+        catch ( FinderException fe )
+        {
+            String error = "remove userId [" + user.getUserId() + "] caught FinderException=" + fe;
+            throw new SecurityException( GlobalErrIds.PERM_BULK_USER_REVOKE_FAILED, error, fe );
+        }
+    }
+
+
+    /**
+     * Remove the RBAC Role assignment attribute from all RBAC permssions.  This method is called by AdminMgrImpl
+     * when the RBAC Role is being deleted.
+     *
+     * @param role contains the name of Role targeted for attribute removal.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final void remove( Role role ) throws SecurityException
+    {
+        List<Permission> list;
+        try
+        {
+            list = pDao.findPermissions( role );
+            for ( Permission perm : list )
+            {
+                revoke( perm, role );
+            }
+        }
+        catch ( FinderException fe )
+        {
+            String error = "remove role [" + role.getName() + "] caught FinderException=" + fe;
+            throw new SecurityException( GlobalErrIds.PERM_BULK_ROLE_REVOKE_FAILED, error, fe );
+        }
+    }
+
+
+    /**
+     * Remove the Admin Role assignment attribute from all Admin permssions.  This method is called by DelAdminMgrImpl
+     * when the AdminRole is being deleted.
+     *
+     * @param role contains the name of AdminRole targeted for attribute removal.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final void remove( AdminRole role ) throws SecurityException
+    {
+        List<Permission> list;
+        try
+        {
+            list = pDao.findPermissions( role );
+            for ( Permission perm : list )
+            {
+                perm.setAdmin( true );
+                revoke( perm, role );
+            }
+        }
+        catch ( FinderException fe )
+        {
+            String error = "remove admin role [" + role.getName() + "] caught FinderException=" + fe;
+            throw new SecurityException( GlobalErrIds.PERM_BULK_ADMINROLE_REVOKE_FAILED, error, fe );
+        }
+    }
+
+
+    /**
+     * This function returns the permissions of the session, i.e., the permissions assigned
+     * to its authorized roles. The function is valid if and only if the session is a valid Fortress session.
+     *
+     * @param session This object must be instantiated by calling {@link AccessMgrImpl#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return List<Permission> containing permissions (op, obj) active for user's session.
+     * @throws SecurityException is thrown if runtime error occurs with system.
+     */
+    final List<Permission> search( Session session ) throws SecurityException
+    {
+        return search(session, false);
+    }
+
+
+    /**
+     * This function returns the permissions of the session, i.e., the permissions assigned
+     * to its authorized roles. The function is valid if and only if the session is a valid Fortress session.
+     *
+     * @param session This object must be instantiated by calling {@link AccessMgrImpl#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return List<Permission> containing permissions (op, obj) active for user's session.
+     * @throws org.apache.directory.fortress.core.SecurityException is thrown if runtime error occurs with system.
+     */
+    final List<Permission> search(Session session, boolean isAdmin)
+        throws SecurityException
+    {
+        return pDao.findPermissions(session, isAdmin);
+    }
+
+
+    /**
+     * Return the matching Permission entity.  This method will throw SecurityException if not found.
+     *
+     * @param permission contains the full permission object and operation name.
+     * @return Permission containing fully populated matching object.
+     * @throws SecurityException is thrown if permission not found or runtime error occurs with system.
+     */
+    final Permission read( Permission permission ) throws SecurityException
+    {
+        return pDao.getPerm( permission );
+    }
+
+
+    /**
+     * Return the matching Permission object entity.  This method will throw SecurityException if not found.
+     *
+     * @param permObj contains the full permission object name.
+     * @return PermObj containing fully populated matching object.
+     * @throws SecurityException is thrown if perm object not found or runtime error occurs with system.
+     */
+    final PermObj read( PermObj permObj ) throws SecurityException
+    {
+        return pDao.getPerm( permObj );
+    }
+
+
+    /**
+     * Adds a new Permission Object entity to directory.  The Permission Object entity input will be validated to ensure that:
+     * object name is present, orgUnitId is valid, reasonability checks on all of the
+     * other populated values.
+     *
+     * @param entity Permission object entity contains data targeted for insertion.
+     * @return Permission 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 PermObj add( PermObj entity ) throws SecurityException
+    {
+        validate( entity, false );
+        return pDao.createObject( entity );
+    }
+
+
+    /**
+     * Adds a new Permission operation entity to directory.  The Permission operation entity input will be validated to ensure that:
+     * operation name is present, roles (optional) are valid, reasonability checks on all of the
+     * other populated values.
+     *
+     * @param entity Permission operation entity contains data targeted for insertion.
+     * @return Permission operation 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 Permission add( Permission entity ) throws SecurityException
+    {
+        validate( entity, false );
+        return pDao.createOperation( entity );
+    }
+
+
+    /**
+     * Update existing Permission Object attributes with the input entity.  Null or empty attributes will be ignored.
+     * The Permission Object entity input will be validated to ensure that:
+     * object name is present, orgUnitId is valid, reasonability checks on all of the other populated values.
+     *
+     * @param entity Permission object entity contains data targeted for updating.
+     * @return Permission entity copy of input + additional attributes (internalId) that were updated by op.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final PermObj update( PermObj entity ) throws SecurityException
+    {
+        update( entity, true );
+        return entity;
+    }
+
+
+    /**
+     * Update existing Permission Object attributes with the input entity.  Null or empty attributes will be ignored.
+     * The Permission Object entity input will be validated to ensure that:
+     * object name is present, orgUnitId is valid, reasonability checks on all of the other populated values.
+     *
+     * @param entity   Permission object entity contains data targeted for updating.
+     * @param validate if false will skip the validations described above.
+     * @return Permission entity copy of input + additional attributes (internalId) that were updated by op.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    private PermObj update( PermObj entity, boolean validate )
+        throws SecurityException
+    {
+        if ( validate )
+        {
+            validate( entity, true );
+        }
+        return pDao.updateObj( entity );
+    }
+
+
+    /**
+     * Update existing Permission Operation Object attributes with the input entity.  Null or empty attributes will be ignored.
+     * The Permission Operation Object entity input will be validated to ensure that:
+     * object name is present, orgUnitId is valid, reasonability checks on all of the other populated values.
+     *
+     * @param entity Permission operation object entity contains data targeted for updating.
+     * @return Permission entity copy of input + additional attributes (internalId) that were updated by op.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final Permission update( Permission entity ) throws SecurityException
+    {
+        update( entity, true );
+        return entity;
+    }
+
+
+    /**
+     * Update existing Permission Operation Object attributes with the input entity.  Null or empty attributes will be ignored.
+     * The Permission Operation Object entity input will be validated to ensure that:
+     * object name is present, orgUnitId is valid, reasonability checks on all of the other populated values.
+     *
+     * @param entity   Permission operation object entity contains data targeted for updating.
+     * @param validate if false will skip the validations described above.
+     * @return Permission entity copy of input + additional attributes (internalId) that were updated by op.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    private Permission update( Permission entity, boolean validate )
+        throws SecurityException
+    {
+        if ( validate )
+        {
+            validate( entity, true );
+        }
+        return pDao.updateOperation( entity );
+    }
+
+
+    /**
+     * This method performs a "hard" delete.  It completely removes all data associated with this Permission Object from the directory
+     * including the Permission operations..
+     * Permission Object entity must exist in directory prior to making this call else exception will be thrown.
+     *
+     * @param entity Contains the Permission Object name targeted for deletion.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final void delete( PermObj entity ) throws SecurityException
+    {
+        pDao.deleteObj( entity );
+    }
+
+
+    /**
+     * This method performs a "hard" delete.  It completely removes all data associated with this Permission Operation from the directory
+     * Permission Operation entity must exist in directory prior to making this call else exception will be thrown.
+     *
+     * @param entity Contains the Permission Operation name targeted for deletion.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final void delete( Permission entity ) throws SecurityException
+    {
+        pDao.deleteOperation( entity );
+    }
+
+
+    /**
+     * This command grants a role the permission to perform an operation on an object to a role.
+     * The command is implemented by granting permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * and the role is a member of the ROLES data set.
+     *
+     * @param pOp  contains object and operation name for resource.
+     * @param role contains the role name
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    final void grant( Permission pOp, Role role ) throws SecurityException
+    {
+        // Now assign it to the perm op:
+        pDao.grant( pOp, role );
+    }
+
+
+    /**
+     * This command revokes the permission to perform an operation on an object from the set
+     * of permissions assigned to a role. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * the role is a member of the ROLES data set, and the permission is assigned to that role.
+     *
+     * @param pOp  contains object and operation name for resource.
+     * @param role contains role name
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    final void revoke( Permission pOp, Role role ) throws SecurityException
+    {
+        pDao.revoke( pOp, role );
+    }
+
+
+    /**
+     * Method grants a permission directly to a User entity.
+     *
+     * @param pOp  contains object and operation name for resource.
+     * @param user contains userid of User entity.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    final void grant( Permission pOp, User user ) throws SecurityException
+    {
+        // call dao to grant userId access to the perm op:
+        pDao.grant( pOp, user );
+    }
+
+
+    /**
+     * Method revokes a permission directly from a User entity.
+     *
+     * @param pOp  contains object and operation name for resource.
+     * @param user contains userid of User entity.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    final void revoke( Permission pOp, User user ) throws SecurityException
+    {
+        pDao.revoke( pOp, user );
+    }
+
+
+    /**
+     * Method will perform various validations to ensure the integrity of the Permission Object entity targeted for insertion
+     * or updating in directory.  Data reasonability checks will be performed on all non-null attributes.
+     *
+     * @param pObj     Permission Object entity contains data targeted for insertion or update.
+     * @param isUpdate if true update operation is being performed which specifies a different set of targeted attributes.
+     * @throws org.apache.directory.fortress.core.ValidationException in the event of data validation error.
+     */
+    final void validate( PermObj pObj, boolean isUpdate ) throws ValidationException
+    {
+        if ( !isUpdate )
+        {
+            // Validate length
+            VUtil.orgUnit( pObj.getOu() );
+            // ensure ou exists in the OS-P pool:
+            OrgUnit ou = new OrgUnit( pObj.getOu(), OrgUnit.Type.PERM );
+            ou.setContextId( pObj.getContextId() );
+            if ( !orgUnitP.isValid( ou ) )
+            {
+                String error = "validate detected invalid orgUnit name [" + pObj.getOu() + "] for object name ["
+                    + pObj.getObjName() + "]";
+                //log.warn(error);
+                throw new ValidationException( GlobalErrIds.PERM_OU_INVALID, error );
+            }
+            if ( VUtil.isNotNullOrEmpty( pObj.getObjName() ) )
+            {
+                VUtil.description( pObj.getObjName() );
+            }
+            if ( VUtil.isNotNullOrEmpty( pObj.getOu() ) )
+            {
+                VUtil.orgUnit( pObj.getOu() );
+            }
+            if ( VUtil.isNotNullOrEmpty( pObj.getDescription() ) )
+            {
+                VUtil.description( pObj.getDescription() );
+            }
+        }
+        else
+        {
+            if ( VUtil.isNotNullOrEmpty( pObj.getOu() ) )
+            {
+                VUtil.orgUnit( pObj.getOu() );
+                // ensure ou exists in the OS-P pool:
+                OrgUnit ou = new OrgUnit( pObj.getOu(), OrgUnit.Type.PERM );
+                ou.setContextId( pObj.getContextId() );
+                if ( !orgUnitP.isValid( ou ) )
+                {
+                    String error = "validate detected invalid orgUnit name [" + pObj.getOu() + "] for object name ["
+                        + pObj.getObjName() + "]";
+                    throw new ValidationException( GlobalErrIds.PERM_OU_INVALID, error );
+                }
+            }
+            if ( VUtil.isNotNullOrEmpty( pObj.getDescription() ) )
+            {
+                VUtil.description( pObj.getDescription() );
+            }
+        }
+    }
+
+
+    /**
+     * Method will perform various validations to ensure the integrity of the Permission Operation entity targeted for insertion
+     * or updating in directory.  Data reasonability checks will be performed on all non-null attributes.
+     *
+     * @param pOp      Permission Operation entity contains data targeted for insertion or update.
+     * @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.
+     */
+    private void validate( Permission pOp, boolean isUpdate )
+        throws SecurityException
+    {
+        if ( !isUpdate )
+        {
+            //operation
+            if ( pOp.getOpName() != null && pOp.getOpName().length() > 0 )
+            {
+                VUtil.description( pOp.getOpName() );
+            }
+        }
+        if ( VUtil.isNotNullOrEmpty( pOp.getType() ) )
+        {
+            VUtil.description( pOp.getType() );
+        }
+        if ( VUtil.isNotNullOrEmpty( pOp.getDescription() ) )
+        {
+            VUtil.description( pOp.getDescription() );
+        }
+        // Validate Role Grants:
+        if ( VUtil.isNotNullOrEmpty( pOp.getRoles() ) )
+        {
+            Set<String> roles = pOp.getRoles();
+            if(pOp.isAdmin())
+            {
+                AdminRoleP arp = new AdminRoleP();
+                for (String roleNm : roles)
+                {
+                    AdminRole adminRole = new AdminRole(roleNm);
+                    adminRole.setContextId(pOp.getContextId());
+                    arp.read(adminRole);
+                }
+            }
+            else
+            {
+                RoleP rp = new RoleP();
+                for (String roleNm : roles)
+                {
+                    Role role = new Role(roleNm);
+                    role.setContextId(pOp.getContextId());
+                    rp.read(role);
+                }
+            }
+        }
+        // Validate User Grants:
+        if ( VUtil.isNotNullOrEmpty( pOp.getUsers() ) )
+        {
+            Set<String> users = pOp.getUsers();
+            UserP up = new UserP();
+            for ( String userId : users )
+            {
+                User user = new User( userId );
+                user.setContextId( pOp.getContextId() );
+                up.read( user, false );
+            }
+        }
+    }
+}
\ No newline at end of file


[34/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/container/OrganizationalUnitDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/container/OrganizationalUnitDAO.java b/src/main/java/org/apache/directory/fortress/core/ldap/container/OrganizationalUnitDAO.java
new file mode 100755
index 0000000..f2e05cd
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/container/OrganizationalUnitDAO.java
@@ -0,0 +1,162 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.container;
+
+
+import org.apache.directory.api.ldap.model.cursor.CursorException;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+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.util.attr.VUtil;
+
+
+/**
+ * This class provides data access for the standard ldap object class Organizational Unit.  This
+ * entity is used to provide containers in DIT for organization of related nodes..
+ * A container node is used to group other related nodes, i.e. 'ou=People' or 'ou'Roles'.
+ * <br />The organizational unit object class is 'organizationalUnit' <br />
+ * <p/>
+ * The OrganizationalUnitDAO maintains the following structural object class:
+ * <p/>
+ * organizationalUnit Structural Object Class is used to store basic attributes like ou and description.
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 2.5.6.5 NAME 'organizationalUnit'</code>
+ * <li> <code>DESC 'RFC2256: an organizational unit'</code>
+ * <li> <code>SUP top STRUCTURAL</code>
+ * <li> <code>MUST ou</code>
+ * <li> <code>MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $</code>
+ * <li> <code>x121Address $ registeredAddress $ destinationIndicator $</code>
+ * <li> <code>preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $</code>
+ * <li> <code>telephoneNumber $ internationaliSDNNumber $</code>
+ * <li> <code>facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $</code>
+ * <li> <code>postalAddress $ physicalDeliveryOfficeName $ st $ l $ description ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+final class OrganizationalUnitDAO extends ApacheDsDataProvider
+{
+    private static final String CLS_NM = OrganizationalUnitDAO.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final String ORGUNIT_CLASS = "organizationalunit";
+    private static final String[] ORGUNIT_OBJ_CLASS =
+        {
+            ORGUNIT_CLASS
+    };
+
+
+    /**
+     * Package private default constructor.
+     */
+    OrganizationalUnitDAO()
+    {
+    }
+
+
+    private String getSdRoot( String contextId )
+    {
+        return getRootDn( contextId, GlobalIds.SUFFIX );
+    }
+
+
+    /**
+     * @param oe
+     * @throws org.apache.directory.fortress.core.CreateException
+     */
+    final void create( OrganizationalUnit oe )
+        throws CreateException
+    {
+        LdapConnection ld = null;
+        String nodeDn = GlobalIds.OU + "=" + oe.getName() + ",";
+        if ( VUtil.isNotNullOrEmpty( oe.getParent() ) )
+            nodeDn += GlobalIds.OU + "=" + oe.getParent() + ",";
+        nodeDn += getRootDn( oe.getContextId() );
+        try
+        {
+            LOG.info( "create container dn [" + nodeDn + "]" );
+            Entry myEntry = new DefaultEntry( nodeDn );
+            myEntry.add( GlobalIds.OBJECT_CLASS, ORGUNIT_OBJ_CLASS );
+            myEntry.add( GlobalIds.OU, oe.getName() );
+            myEntry.add( GlobalIds.DESC, oe.getDescription() );
+            ld = getAdminConnection();
+            add( ld, myEntry );
+        }
+        catch ( LdapException e )
+        {
+            String error = "create container node dn [" + nodeDn + "] caught LDAPException="
+                + e.getMessage();
+            throw new CreateException( GlobalErrIds.CNTR_CREATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param oe
+     * @throws org.apache.directory.fortress.core.RemoveException
+     */
+    final void remove( OrganizationalUnit oe )
+        throws RemoveException
+    {
+        LdapConnection ld = null;
+        String nodeDn = GlobalIds.OU + "=" + oe.getName() + ",";
+        if ( VUtil.isNotNullOrEmpty( oe.getParent() ) )
+            nodeDn += GlobalIds.OU + "=" + oe.getParent() + ",";
+        nodeDn += getRootDn( oe.getContextId(), GlobalIds.SUFFIX );
+
+        LOG.info( "remove container dn [" + nodeDn + "]" );
+        try
+        {
+            ld = getAdminConnection();
+            deleteRecursive( ld, nodeDn );
+        }
+        catch ( CursorException e )
+        {
+            String error = "remove container node dn [" + nodeDn + "] caught CursorException="
+                + e.getMessage();
+            throw new RemoveException( GlobalErrIds.CNTR_DELETE_FAILED, error, e );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove container node dn [" + nodeDn + "] caught LDAPException="
+                + e.getMessage();
+            throw new RemoveException( GlobalErrIds.CNTR_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+}
\ 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/ldap/container/OrganizationalUnitP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/container/OrganizationalUnitP.java b/src/main/java/org/apache/directory/fortress/core/ldap/container/OrganizationalUnitP.java
new file mode 100755
index 0000000..7ce72d8
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/container/OrganizationalUnitP.java
@@ -0,0 +1,147 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.container;
+
+
+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.SecurityException;
+import org.apache.directory.fortress.core.ValidationException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * Process module for the container node used for grouping  related nodes within Fortress directory structure. The organizational unit represents
+ * the middle nodes that act as containers for other nodes, i.e. ou=People container which groups Users.
+ * The organizational unit data is passed using {@link OrganizationalUnit} class.  This class does perform simple data validations.
+ * The {@link org.apache.directory.fortress.core.ant.FortressAntTask#addContainers()} method calls the {@link #add} from this class during initial base loads.
+ * Removal {@link org.apache.directory.fortress.core.ant.FortressAntTask#deleteContainers()} is performed during regression tests and should never
+ * be executed targeting enabled production directory system datasets.<BR>
+ * This class will accept {@link OrganizationalUnit}, and forward on to it's corresponding DAO class {@link OrganizationalUnitDAO} for add/delete of container.
+ * <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.CreateException},,{@link org.apache.directory.fortress.core.RemoveException}),
+ *  or {@link org.apache.directory.fortress.core.ValidationException} as {@link org.apache.directory.fortress.core.SecurityException}s with appropriate
+ *  error id from {@link org.apache.directory.fortress.core.GlobalErrIds}.
+ * <p>
+ * <font size="3" color="red">
+ * The {@link #delete} method in this class is destructive as it will remove all nodes below the container using recursive delete function.<BR>
+ * Extreme care should be taken during execution to ensure target dn is correct and permanent removal of data is intended.  There is no
+ * 'undo' for this operation.
+ * </font>
+ * <p/>
+ * Simple error mapping is performed in {@link #validate} class.
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+public class OrganizationalUnitP
+{
+    private static final String CLS_NM = OrganizationalUnitP.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+
+    /**
+     * Add a new container to the Directory Information Tree (DIT).  After added the
+     * node will be inserted after suffix, i.e. ou=NewContainerName, dc=companyName, dc=com.
+     *
+     * @param orgUnit contains the ou name and description for target node.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event node already present, {@link GlobalErrIds#CNTR_CREATE_FAILED}, validation, {@link GlobalErrIds#CNTR_NAME_NULL}, {@link org.apache.directory.fortress.core.GlobalErrIds#CNTR_NAME_INVLD} or system error.
+     */
+    public final void add( OrganizationalUnit orgUnit )
+        throws SecurityException
+    {
+        OrganizationalUnitDAO oDao = new OrganizationalUnitDAO();
+        oDao.create( orgUnit );
+    }
+
+
+    /**
+     * Remove a container from the Directory Information Tree (DIT).  After this operation the
+     * node will be removed after suffix.
+     *
+     * <p>
+     * <font size="4" color="red">
+     * The {@link #delete} method in this class is destructive as it will remove all nodes below the container using recursive delete function.<BR>
+     * Extreme care should be taken during execution to ensure target dn is correct and permanent removal of data is intended.  There is no
+     * 'undo' for this operation.
+     * </font>
+     * <p/>
+     *
+     * @param orgUnit contains the ou name of container targeted for removal.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event node not present, {@link org.apache.directory.fortress.core.GlobalErrIds#CNTR_DELETE_FAILED}, validation, {@link org.apache.directory.fortress.core.GlobalErrIds#CNTR_NAME_NULL}, {@link org.apache.directory.fortress.core.GlobalErrIds#CNTR_NAME_INVLD} or system error.
+     */
+    public final void delete( OrganizationalUnit orgUnit )
+        throws SecurityException
+    {
+        OrganizationalUnitDAO oDao = new OrganizationalUnitDAO();
+        oDao.remove( orgUnit );
+    }
+
+
+    /**
+     * Method will perform simple validations to ensure the integrity of the {@link OrganizationalUnit} entity targeted for insertion
+     * or deletion in directory.
+     *
+     * @param entity contains the enum type to validate
+     * @throws SecurityException thrown in the event the attribute is null.
+     */
+    private void validate( OrganizationalUnit entity )
+        throws SecurityException
+    {
+        if ( entity.getName().length() > GlobalIds.OU_LEN )
+        {
+            String name = entity.getName();
+            String error = "validate name [" + name + "] invalid length [" + entity.getName().length() + "]";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.CNTR_NAME_INVLD, error );
+        }
+        if ( !VUtil.isNotNullOrEmpty( entity.getName() ) )
+        {
+            String error = "validate name validation failed, null or empty value";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.CNTR_NAME_NULL, error );
+        }
+        if ( entity.getParent().length() > GlobalIds.OU_LEN )
+        {
+            String name = entity.getName();
+            String error = "validate parent [" + name + "] invalid length [" + entity.getName().length()
+                + "]";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.CNTR_PARENT_INVLD, error );
+        }
+        if ( !VUtil.isNotNullOrEmpty( entity.getParent() ) )
+        {
+            String error = "validate parent validation failed, null or empty value";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.CNTR_PARENT_NULL, error );
+        }
+        VUtil.safeText( entity.getDescription(), GlobalIds.DESC_LEN );
+        if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+        {
+            VUtil.description( entity.getDescription() );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/container/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/container/package.html b/src/main/java/org/apache/directory/fortress/core/ldap/container/package.html
new file mode 100755
index 0000000..3f386af
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/container/package.html
@@ -0,0 +1,36 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.ldap.container</title>
+   </head>
+   <body>
+      <p>
+         This package contains APIs to perform CRUD on fortress container objects in ldap.
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress.ldap.container</b> package provides apis to add and
+          remove ldap <b>OrganizationalUnit</b> entries.  These entries are called 'containers'
+          and are used to organize related fortress nodes.  An example container is <b>ou=People</b> which will be placed as a
+          child node of the directory's ldap suffix, i.e. <b>dc=example,dc=com</b>.  The container is used to store subentries, i.e. <b>inetOrgPerson</b>.
+          These container APIs are used by buildup/teardown processes.
+      </p>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/group/Group.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/group/Group.java b/src/main/java/org/apache/directory/fortress/core/ldap/group/Group.java
new file mode 100755
index 0000000..2488205
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/group/Group.java
@@ -0,0 +1,421 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.group;
+
+
+import org.apache.directory.fortress.core.rbac.FortEntity;
+import org.apache.directory.fortress.core.rbac.Props;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+@XmlRootElement(name = "fortGroup")
+@XmlAccessorType( XmlAccessType.FIELD)
+@XmlType(name = "group", propOrder =
+    {
+        "name",
+        "description",
+        "protocol",
+        "members",
+        "props",
+    })
+public class Group extends FortEntity implements Serializable
+{
+    private String name;
+    private String description;
+    private String protocol;
+    private List<String> members;
+    private Props props = new Props();
+    boolean memberDn;
+
+    /**
+     * Default constructor used by {@link org.apache.directory.fortress.core.ant.FortressAntTask}
+     */
+    public Group()
+    {
+    }
+
+    /**
+     * Generate instance of group to be loaded as ldap object.
+     *
+     * @param name        maps to 'cn' attribute in group object class.
+     */
+    public Group( String name )
+    {
+        this.name = name;
+    }
+
+    /**
+     * Generate instance of group to be loaded as ldap object.
+     *
+     * @param name        maps to 'cn' attribute in group object class.
+     * @param description maps to 'description' attribute in group object class.
+     */
+    public Group( String name, String description )
+    {
+        this.name = name;
+        this.description = description;
+    }
+
+    /**
+     * Get the second level qualifier on the domain component.  This attribute is required.
+     *
+     * @return name maps to 'dcObject' object class.
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * Set the second level qualifier on the domain component.  This attribute is required.
+     *
+     * @param name maps to 'dcObject' object class.
+     */
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    /**
+     * Get the description for the domain component.  This value is not required or constrained
+     * but is validated on reasonability.
+     *
+     * @return field maps to 'o' attribute on 'dcObject'.
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+    /**
+     * Set the description for the domain component.  This value is not required or constrained
+     * but is validated on reasonability.
+     *
+     * @param description maps to 'o' attribute on 'dcObject'.
+     */
+    public void setDescription(String description)
+    {
+        this.description = description;
+    }
+
+    /**
+     * Get protocol qualifier for this entity.
+     *
+     * @return protocol.
+     */
+    public String getProtocol()
+    {
+        return protocol;
+    }
+
+    /**
+     * Set the protocol qualifier for this entity.
+     *
+     * @param protocol contains protocol qualifier for this entity.
+     */
+    public void setProtocol( String protocol )
+    {
+        this.protocol = protocol;
+    }
+
+    /**
+     * Add a single userId as member of this entity.
+     *
+     * @param userId
+     */
+    public void setMember( String userId )
+    {
+        if ( members == null )
+        {
+            members = new ArrayList<>();
+        }
+        members.add( userId );
+    }
+
+    /**
+     * Return the members
+     *
+     * @return List of type String containing userIds.
+     */
+    public List<String> getMembers()
+    {
+        return members;
+    }
+
+    /**
+     * Set a member on this entity using a comma delimited String.
+     *
+     * @param members String contains one or more userids in comma delimited format.
+     */
+    public void setMembers( String members )
+    {
+        if (members != null)
+        {
+            StringTokenizer tkn = new StringTokenizer(members, ",");
+            if (tkn.countTokens() > 0)
+            {
+                while (tkn.hasMoreTokens())
+                {
+                    String member = tkn.nextToken();
+                    setMember( member );
+                }
+            }
+        }
+    }
+
+    /**
+     * Set members onto this entity using a List of userIds.
+     *
+     * @param members List of type String contains userIds to be associated as members of this group.
+     */
+    public void setMembers( List<String> members )
+    {
+        this.members = members;
+    }
+
+    /**
+     * Add name/value pair to list of properties associated with PermObj.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param key   contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     * @param value
+     */
+    public void addProperty( String key, String value )
+    {
+        Props.Entry entry = new Props.Entry();
+        entry.setKey( key );
+        entry.setValue( value );
+        this.props.getEntry().add( entry );
+    }
+
+    /**
+     * Get a name/value pair attribute from list of properties associated with PermObj.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param key contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     * @return value containing name/value pair that maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public String getProperty( String key )
+    {
+        List<Props.Entry> props = this.props.getEntry();
+        Props.Entry keyObj = new Props.Entry();
+        keyObj.setKey( key );
+
+        String value = null;
+        int indx = props.indexOf( keyObj );
+        if ( indx != -1 )
+        {
+            Props.Entry entry = props.get( props.indexOf( keyObj ) );
+            value = entry.getValue();
+        }
+
+        return value;
+    }
+
+    /**
+     * Replace teh collection of name/value pairs to attributes associated with Group entity.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param properties contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public void setProperties( Properties properties )
+    {
+        if ( properties != null )
+        {
+            // reset the existing properties stored in this entity.
+            props = new Props();
+            for ( Enumeration e = properties.propertyNames(); e.hasMoreElements(); )
+            {
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                String key = ( String ) e.nextElement();
+                String val = properties.getProperty( key );
+                addProperty( key, val );
+            }
+        }
+    }
+
+    /**
+     * Add new collection of name=value pairs to attributes associated with Group.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param properties contains name=value pairs that are comma delmited.
+     */
+    public void setProperties( String properties )
+    {
+        setProperties( AttrHelper.getProperties( properties, '=', "," ) );
+    }
+
+    /**
+     * Return the collection of name/value pairs to attributes associated with PermObj.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @return Properties contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public Properties getProperties()
+    {
+        Properties properties = null;
+        List<Props.Entry> props = this.props.getEntry();
+        if ( props.size() > 0 )
+        {
+            properties = new Properties();
+            //int size = props.size();
+            for ( Props.Entry entry : props )
+            {
+                String key = entry.getKey();
+                String val = entry.getValue();
+                properties.setProperty( key, val );
+            }
+        }
+        return properties;
+    }
+
+    public List<String> getPropList()
+    {
+        List<Props.Entry> props = this.props.getEntry();
+        List<String> propList = null;
+        if ( props.size() > 0 )
+        {
+            propList = new ArrayList<>(  );
+            for ( Props.Entry entry : props )
+            {
+                String key = entry.getKey();
+                String val = entry.getValue();
+                String prop = key + "=" + val;
+                propList.add( prop );
+            }
+        }
+        return propList;
+    }
+
+    /**
+     * Gets the value of the Props property.  This method is used by Fortress and En Masse and should not be called by external programs.
+     *
+     * @return {@link Props }
+     *
+     */
+    public Props getProps()
+    {
+        return props;
+    }
+
+    /**
+     * Sets the value of the Props property.  This method is used by Fortress and En Masse and should not be called by external programs.
+     *
+     * @param props
+     *     allowed object is
+     *     {@link Props }
+     *
+     */
+    public void setProps( Props props )
+    {
+        this.props = props;
+    }
+
+    /**
+     * Set if userDn's are loaded in dn format.
+     *
+     * @return true indicates members are in dn format.
+     */
+    public boolean isMemberDn()
+    {
+        return memberDn;
+    }
+
+    /**
+     * Set to 'true' if members are in dn format.
+     *
+     * @param memberDn boolean value, set to 'true' if distinguished name (dn) format, 'false' if relative distinguished name (rdn) format.
+     */
+    public void setMemberDn( boolean memberDn )
+    {
+        this.memberDn = memberDn;
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o )
+        {
+            return true;
+        }
+        if ( o == null || getClass() != o.getClass() )
+        {
+            return false;
+        }
+
+        Group group = ( Group ) o;
+
+/*
+        if ( description != null ? !description.equals( group.description ) : group.description != null )
+        {
+            return false;
+        }
+        if ( members != null ? !members.equals( group.members ) : group.members != null )
+        {
+            return false;
+        }
+*/
+        if(name == null)
+            return false;
+
+        if ( !name.equals( group.name ) )
+        {
+            return false;
+        }
+/*
+        if ( protocol != null ? !protocol.equals( group.protocol ) : group.protocol != null )
+        {
+            return false;
+        }
+*/
+
+        return true;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int result = name.hashCode();
+        result = 31 * result + ( description != null ? description.hashCode() : 0 );
+        result = 31 * result + ( protocol != null ? protocol.hashCode() : 0 );
+        result = 31 * result + ( members != null ? members.hashCode() : 0 );
+        result = 31 * result + ( props != null ? props.hashCode() : 0 );
+        return result;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Group{" +
+            "name='" + name + '\'' +
+            ", description='" + description + '\'' +
+            '}';
+    }
+}
\ 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/ldap/group/GroupDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupDAO.java b/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupDAO.java
new file mode 100755
index 0000000..fc906ee
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupDAO.java
@@ -0,0 +1,463 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.group;
+
+
+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.FinderException;
+import org.apache.directory.fortress.core.ObjectFactory;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Contains the Group node for LDAP Directory Information Tree.
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+final class GroupDAO extends ApacheDsDataProvider
+{
+    private static final String CLS_NM = GroupDAO.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final String GROUP_OBJECT_CLASS = "group.objectclass";
+    private static final String GROUP_OBJECT_CLASS_IMPL = Config.getProperty( GROUP_OBJECT_CLASS );
+    private static final String GROUP_PROTOCOL_ATTR = "group.protocol";
+    private static final String GROUP_PROTOCOL_ATTR_IMPL = Config.getProperty( GROUP_PROTOCOL_ATTR );
+    private static final String GROUP_PROPERTY_ATTR = "group.properties";
+    private static final String GROUP_PROPERTY_ATTR_IMPL = Config.getProperty( GROUP_PROPERTY_ATTR );
+    private static final String GROUP_OBJ_CLASS[] = {GlobalIds.TOP, GROUP_OBJECT_CLASS_IMPL};
+    private static final String MEMBER = "member";
+    private static final String[] GROUP_ATRS = {GlobalIds.CN, GlobalIds.DESC, GROUP_PROTOCOL_ATTR_IMPL, GROUP_PROPERTY_ATTR_IMPL, MEMBER};
+
+    /**
+     * Package private default constructor.
+     */
+    GroupDAO()
+    {
+    }
+
+    /**
+     * @param group
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    final Group create( Group group ) throws CreateException
+    {
+        LdapConnection ld = null;
+        String nodeDn = getDn( group.getName(), group.getContextId() );
+        try
+        {
+            LOG.debug( "create group dn {[]}", nodeDn );
+            Entry myEntry = new DefaultEntry( nodeDn );
+            myEntry.add( GlobalIds.OBJECT_CLASS, GROUP_OBJ_CLASS );
+            myEntry.add( GlobalIds.CN , group.getName() );
+            myEntry.add( GROUP_PROTOCOL_ATTR_IMPL, group.getProtocol() );
+            loadAttrs( group.getMembers(), myEntry, MEMBER );
+            loadProperties( group.getProperties(), myEntry, GROUP_PROPERTY_ATTR_IMPL, '=' );
+            if ( VUtil.isNotNullOrEmpty( group.getDescription() ) )
+            {
+                myEntry.add( GlobalIds.DESC, group.getDescription() );
+            }
+            ld = getAdminConnection();
+            add( ld, myEntry );
+        }
+        catch ( LdapException e )
+        {
+            String error = "create group node dn [" + nodeDn + "] caught LDAPException=" + e.getMessage();
+            throw new CreateException( GlobalErrIds.GROUP_ADD_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return group;
+    }
+
+    /**
+     * @param group
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    final Group update( Group group ) throws FinderException, UpdateException
+    {
+        LdapConnection ld = null;
+        String nodeDn = getDn( group.getName(), group.getContextId() );
+        try
+        {
+            LOG.debug( "update group dn {[]}", nodeDn );
+            List<Modification> mods = new ArrayList<Modification>();
+            if ( VUtil.isNotNullOrEmpty( group.getDescription() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.DESC, group.getDescription() ) );
+            }
+            if ( VUtil.isNotNullOrEmpty( group.getProtocol() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GROUP_PROTOCOL_ATTR_IMPL, group.getProtocol() ) );
+            }
+            loadAttrs( group.getMembers(), mods, MEMBER );
+            loadProperties( group.getProperties(), mods, GROUP_PROPERTY_ATTR_IMPL, true, '=' );
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, nodeDn, mods, group );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "update group node dn [" + nodeDn + "] caught LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.GROUP_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return get( group );
+    }
+
+    final Group add( Group group, String key, String value ) throws FinderException, CreateException
+    {
+        LdapConnection ld = null;
+        String nodeDn = getDn( group.getName(), group.getContextId() );
+        try
+        {
+            LOG.debug( "add group property dn {[]}, key {[]}, value {[]}", nodeDn, key, value );
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification(
+                ModificationOperation.ADD_ATTRIBUTE, GROUP_PROPERTY_ATTR_IMPL, key + "=" + value ) );
+            ld = getAdminConnection();
+            modify( ld, nodeDn, mods, group );
+        }
+        catch ( LdapException e )
+        {
+            String error = "update group property node dn [" + nodeDn + "] caught LDAPException=" + e.getMessage();
+            throw new CreateException( GlobalErrIds.GROUP_ADD_PROPERTY_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return get( group );
+    }
+
+    final Group delete( Group group, String key, String value ) throws FinderException, RemoveException
+    {
+        LdapConnection ld = null;
+        String nodeDn = getDn( group.getName(), group.getContextId() );
+        try
+        {
+            LOG.debug( "delete group property dn {[]}, key {[]}, value {[]}", nodeDn, key, value );
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification(
+                ModificationOperation.REMOVE_ATTRIBUTE, GROUP_PROPERTY_ATTR_IMPL, key + "=" + value ) );
+            ld = getAdminConnection();
+            modify( ld, nodeDn, mods, group );
+        }
+        catch ( LdapException e )
+        {
+            String error = "delete group property node dn [" + nodeDn + "] caught LDAPException=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.GROUP_DELETE_PROPERTY_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return get( group );
+    }
+
+    /**
+     * This method will remove group node from diretory.
+     *
+     * @param group
+     * @throws org.apache.directory.fortress.core.RemoveException
+     *
+     */
+    final Group remove( Group group ) throws RemoveException
+    {
+        LdapConnection ld = null;
+        String nodeDn = getDn( group.getName(), group.getContextId() );
+        LOG.debug( "remove group dn {[]}", nodeDn );
+        try
+        {
+            ld = getAdminConnection();
+            deleteRecursive( ld, nodeDn );
+        }
+        catch ( CursorException e )
+        {
+            String error = "remove group node dn [" + nodeDn + "] caught CursorException="
+                + e.getMessage();
+            throw new RemoveException( GlobalErrIds.GROUP_DELETE_FAILED, error, e );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove group node dn [" + nodeDn + "] caught LDAPException=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.GROUP_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return group;
+    }
+
+    /**
+     * @param entity
+     * @param userDn
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    final Group assign( Group entity, String userDn ) throws FinderException, UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+        LOG.debug( "assign group property dn {[]}, member dn {[]}", dn, userDn );
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification(
+                ModificationOperation.ADD_ATTRIBUTE, MEMBER, userDn ) );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "assign group name [" + entity.getName() + "] user dn [" + userDn + "] caught " +
+                "LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.GROUP_USER_ASSIGN_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return get( entity );
+    }
+
+    /**
+     * @param entity
+     * @param userDn
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    final Group deassign( Group entity, String userDn ) throws FinderException, UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+        LOG.debug( "deassign group property dn {[]}, member dn {[]}", dn, userDn );
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification(
+                ModificationOperation.REMOVE_ATTRIBUTE, MEMBER, userDn ) );
+
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "deassign group name [" + entity.getName() + "] user dn [" + userDn + "] caught " +
+                "LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.GROUP_USER_DEASSIGN_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return get( entity );
+    }
+
+    /**
+     * @param group
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    final Group get( Group group ) throws FinderException
+    {
+        Group entity = null;
+        LdapConnection ld = null;
+        String dn = getDn( group.getName(), group.getContextId() );
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, dn, GROUP_ATRS );
+            entity = unloadLdapEntry( findEntry, 0 );
+            if ( entity == null )
+            {
+                String warning = "read no entry found dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.GROUP_NOT_FOUND, warning );
+            }
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "read Obj COULD NOT FIND ENTRY for dn [" + dn + "]";
+            throw new FinderException( GlobalErrIds.GROUP_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "read dn [" + dn + "] LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.GROUP_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+    /**
+     * @param group
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    final List<Group> find( Group group ) throws FinderException
+    {
+        List<Group> groupList = new ArrayList<>();
+        LdapConnection ld = null;
+        SearchCursor searchResults;
+        String groupRoot = getRootDn( group.getContextId(), GlobalIds.GROUP_ROOT );
+        String filter = null;
+        try
+        {
+            String searchVal = encodeSafeText( group.getName(), GlobalIds.ROLE_LEN );
+            filter = GlobalIds.FILTER_PREFIX + GROUP_OBJECT_CLASS_IMPL + ")(" + GlobalIds.CN + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            searchResults = search( ld, groupRoot, SearchScope.ONELEVEL, filter, GROUP_ATRS, false,
+                GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.next() )
+            {
+                groupList.add( unloadLdapEntry( searchResults.getEntry(), sequence++ ) );
+            }
+        }
+        catch ( CursorException e )
+        {
+            String error = "find filter [" + filter + "] caught CursorException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.GROUP_SEARCH_FAILED, error, e );
+        }
+        catch ( LdapException e )
+        {
+            String error = "find filter [" + filter + "] caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.GROUP_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return groupList;
+    }
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    final List<Group> find( User user ) throws FinderException
+    {
+        List<Group> groupList = new ArrayList<>();
+        LdapConnection ld = null;
+        SearchCursor searchResults;
+        String groupRoot = getRootDn( user.getContextId(), GlobalIds.GROUP_ROOT );
+        String filter = null;
+        try
+        {
+            String searchVal = encodeSafeText( user.getUserId(), GlobalIds.USERID_LEN );
+            filter = GlobalIds.FILTER_PREFIX + GROUP_OBJECT_CLASS_IMPL + ")(" + MEMBER + "=" + user.getDn() + "))";
+            ld = getAdminConnection();
+            searchResults = search( ld, groupRoot, SearchScope.ONELEVEL, filter, GROUP_ATRS, false,
+                GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.next() )
+            {
+                groupList.add( unloadLdapEntry( searchResults.getEntry(), sequence++ ) );
+            }
+        }
+        catch ( CursorException e )
+        {
+            String error = "find filter [" + filter + "] caught CursorException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.GROUP_SEARCH_FAILED, error, e );
+        }
+        catch ( LdapException e )
+        {
+            String error = "find filter [" + filter + "] caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.GROUP_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return groupList;
+    }
+
+    /**
+     * @param le
+     * @param sequence
+     * @return
+     * @throws LdapException
+     */
+    private Group unloadLdapEntry( Entry le, long sequence )
+        throws LdapInvalidAttributeValueException
+    {
+        Group entity = new ObjectFactory().createGroup();
+        entity.setName( getAttribute( le, GlobalIds.CN ) );
+        entity.setDescription( getAttribute( le, GlobalIds.DESC ) );
+        entity.setProtocol( getAttribute( le, GROUP_PROTOCOL_ATTR_IMPL ) );
+        entity.setMembers( getAttributes( le, MEMBER ) );
+        entity.setMemberDn( true );
+        entity.setProperties( AttrHelper.getProperties( getAttributes( le, GROUP_PROPERTY_ATTR_IMPL ), '=' ) );
+        entity.setSequenceId( sequence );
+        return entity;
+    }
+
+    private String getDn( String name, String contextId )
+    {
+        return GlobalIds.CN + "=" + name + "," + getRootDn( contextId, GlobalIds.GROUP_ROOT );
+    }
+}
\ 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/ldap/group/GroupMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupMgr.java b/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupMgr.java
new file mode 100755
index 0000000..2316de9
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupMgr.java
@@ -0,0 +1,135 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.group;
+
+import org.apache.directory.fortress.core.*;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.User;
+
+import java.util.List;
+
+/**
+ * This interface prescribes CRUD methods used to manage groups stored within the ldap directory.
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public interface GroupMgr extends Manageable
+{
+    /**
+     * Create a new group node.,
+     *
+     * @param group contains {@link Group}.
+     * @return {@link Group} containing entity just added.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    public Group add( Group group ) throws org.apache.directory.fortress.core.SecurityException;
+
+    /**
+     * Modify existing group node.  The name is required.  Does not update members or properties.
+     * Use {@link GroupMgr#add( Group group, String key, String value )}, {@link GroupMgr#delete( Group group, String key, String value )},
+     * {@link GroupMgr#assign( Group group, String member) }, or {@link GroupMgr#deassign( Group group, String member) } for multi-occurring attributes.
+     *
+     * @param group contains {@link Group}.
+     * @return {@link Group} containing entity just modified.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    public Group update( Group group ) throws SecurityException;
+
+    /**
+     * Delete existing group node.  The name is required.
+     *
+     * @param group contains {@link Group}.
+     * @return {@link Group} containing entity just removed.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    public Group delete( Group group ) throws SecurityException;
+
+    /**
+     * Add a property to an existing group node. Must have a name and at least one member.
+     *
+     * @param group contains {@link Group}.
+     * @param key contains the property key.
+     * @param value contains contains the property value.
+     * @return {@link Group} containing entity just modified.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    public Group add( Group group, String key, String value ) throws SecurityException;
+
+    /**
+     * Delete existing group node.  The name is required.
+     *
+     * @param group contains {@link Group}.
+     * @param key contains the property key.
+     * @param value contains contains the property value.
+     * @return {@link Group} containing entity just modified.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    public Group delete( Group group, String key, String value ) throws SecurityException;
+
+    /**
+     * Read an existing group node.  The name is required.
+     *
+     * @param group contains {@link Group} with name field set with an existing group name.
+     * @return {@link Group} containing entity found.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    public Group read( Group group ) throws SecurityException;
+
+    /**
+     * Search using a full or partial group node.  The name is required.
+     *
+     * @param group contains {@link Group}.
+     * @return List of type {@link Group} containing entities found.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    public List<Group> find( Group group ) throws SecurityException;
+
+    /**
+     * Search for groups by userId.  Member (maps to userId) and is required.
+     *
+     * @param user contains userId that maps to Group member attribute.
+     * @return {@link Group} containing entity just added.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    public List<Group> find( User user ) throws SecurityException;
+
+    /**
+     * Assign a user to an existing group node.  The group name and member are required.
+     *
+     * @param group contains {@link Group}.
+     * @param member is the relative distinguished name (rdn) of an existing user in ldap.
+     * @return {@link Group} containing entity to assign.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry already present or other system error.
+     */
+    public Group assign( Group group, String member ) throws SecurityException;
+
+    /**
+     * Deassign a member from an existing group node. The group name and member are required.
+     *
+     * @param group contains {@link Group}.
+     * @param member is the relative distinguished name (rdn) of an existing user in ldap.
+     * @return {@link Group} containing entity to deassign
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry already present or other system error.
+     */
+    public Group deassign( Group group, String member ) throws SecurityException;
+}
\ 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/ldap/group/GroupMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupMgrFactory.java
new file mode 100755
index 0000000..102587c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupMgrFactory.java
@@ -0,0 +1,107 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.group;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Creates an instance of the ConfigMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link GroupMgrImpl} but can be overridden by
+ * adding the {@link org.apache.directory.fortress.core.GlobalIds#GROUP_IMPLEMENTATION} config property.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class GroupMgrFactory
+{
+    private static String groupClassName = Config.getProperty( GlobalIds.GROUP_IMPLEMENTATION );
+    private static final String CLS_NM = GroupMgrFactory.class.getName();
+
+    /**
+     * Create and return a reference to {@link GroupMgr} object using HOME context.
+     *
+     * @return instance of {@link org.apache.directory.fortress.core.AdminMgr}.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event of failure during instantiation.
+     */
+    public static GroupMgr createInstance()
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME );
+    }
+
+    /**
+     * Create and return a reference to {@link GroupMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return instance of {@link GroupMgr}.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event of failure during instantiation.
+     */
+    public static GroupMgr createInstance(String contextId)
+        throws SecurityException
+    {
+        VUtil.assertNotNull( contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance" );
+        if (!VUtil.isNotNullOrEmpty(groupClassName))
+        {
+            groupClassName = GroupMgrImpl.class.getName();
+        }
+
+        GroupMgr groupMgr = (GroupMgr) ClassUtil.createInstance(groupClassName);
+        groupMgr.setContextId(contextId);
+        return groupMgr;
+    }
+
+
+    /**
+     * Create and return a reference to {@link GroupMgr} object using HOME context.
+     *
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link org.apache.directory.fortress.core.AdminMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static GroupMgr createInstance(Session adminSess)
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME, adminSess );
+    }
+
+    /**
+     * Create and return a reference to {@link GroupMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link org.apache.directory.fortress.core.AdminMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static GroupMgr createInstance(String contextId, Session adminSess)
+        throws SecurityException
+    {
+        GroupMgr groupMgr = createInstance(contextId);
+        groupMgr.setAdmin(adminSess);
+        return groupMgr;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupMgrImpl.java
new file mode 100755
index 0000000..8c5722a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupMgrImpl.java
@@ -0,0 +1,244 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.group;
+
+import org.apache.directory.fortress.core.*;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.Manageable;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * This Manager impl supplies CRUD methods used to manage groups stored within the ldap directory.
+ * LDAP group nodes are used for utility and security functions within various systems and apps.
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class GroupMgrImpl extends Manageable implements GroupMgr
+{
+    private static final String CLS_NM = GroupMgrImpl.class.getName();
+    private static final GroupP groupP = new GroupP();
+
+    /**
+     * Create a new group node.  Must have a name and at least one member.
+     *
+     * @param group contains {@link Group}.
+     * @return {@link Group} containing entity just added.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    @Override
+    public Group add( Group group ) throws org.apache.directory.fortress.core.SecurityException
+    {
+        String methodName = "add";
+        assertContext(CLS_NM, methodName, group, GlobalErrIds.GROUP_NULL);
+        checkAccess(CLS_NM, methodName);
+        if(!group.isMemberDn())
+        {
+            loadUserDns( group );
+        }
+
+        return groupP.add( group );
+    }
+
+    /**
+     * Modify existing group node.  The name is required.  Does not update members or properties.
+     * Use {@link GroupMgr#add( Group group, String key, String value )}, {@link GroupMgr#delete( Group group, String key, String value )},
+     * {@link GroupMgr#assign( Group group, String member) }, or {@link GroupMgr#deassign( Group group, String member) } for multi-occurring attributes.
+     *
+     * @param group contains {@link Group}.
+     * @return {@link Group} containing entity just modified.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    @Override
+    public Group update( Group group ) throws SecurityException
+    {
+        String methodName = "update";
+        assertContext(CLS_NM, methodName, group, GlobalErrIds.GROUP_NULL);
+        checkAccess(CLS_NM, methodName);
+        return groupP.update( group );
+    }
+
+    /**
+     * Delete existing group node.  The name is required.
+     *
+     * @param group contains {@link Group}.
+     * @return {@link Group} containing entity just removed.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    @Override
+    public Group delete( Group group ) throws SecurityException
+    {
+        String methodName = "delete";
+        assertContext(CLS_NM, methodName, group, GlobalErrIds.GROUP_NULL);
+        checkAccess(CLS_NM, methodName);
+        return groupP.delete( group );
+    }
+
+    /**
+     * Add a property to an existing group node.  The name is required.
+     *
+     * @param group contains {@link Group}.
+     * @param key contains the property key.
+     * @param value contains contains the property value.
+     * @return {@link Group} containing entity just modified.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    public Group add( Group group, String key, String value ) throws SecurityException
+    {
+        String methodName = "addProperty";
+        assertContext(CLS_NM, methodName, group, GlobalErrIds.GROUP_NULL);
+        checkAccess(CLS_NM, methodName);
+        return groupP.add( group, key, value );
+    }
+
+    /**
+     * Delete existing group node.  The name is required.
+     *
+     * @param group contains {@link Group}.
+     * @param key contains the property key.
+     * @param value contains contains the property value.
+     * @return {@link Group} containing entity just modified.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    public Group delete( Group group, String key, String value ) throws SecurityException
+    {
+        String methodName = "deleteProperty";
+        assertContext(CLS_NM, methodName, group, GlobalErrIds.GROUP_NULL);
+        checkAccess(CLS_NM, methodName);
+        return groupP.delete( group, key, value );
+    }
+
+    /**
+     * Read an existing group node.  The name is required.
+     *
+     * @param group contains {@link Group} with name field set with an existing group name.
+     * @return {@link Group} containing entity found.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    @Override
+    public Group read( Group group ) throws SecurityException
+    {
+        String methodName = "read";
+        assertContext(CLS_NM, methodName, group, GlobalErrIds.GROUP_NULL);
+        checkAccess(CLS_NM, methodName);
+        return groupP.read( group );
+    }
+
+    /**
+     * Search using a full or partial group node.  The name is required.
+     *
+     * @param group contains {@link Group}.
+     * @return List of type {@link Group} containing entities found.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    @Override
+    public List<Group> find( Group group ) throws SecurityException
+    {
+        String methodName = "find";
+        assertContext(CLS_NM, methodName, group, GlobalErrIds.GROUP_NULL);
+        checkAccess(CLS_NM, methodName);
+        return groupP.search( group );
+    }
+
+    /**
+     * Search for groups by userId.  Member (maps to userId) and is required.
+     *
+     * @param user contains userId that maps to Group member attribute.
+     * @return {@link Group} containing entity just added.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event system error.
+     */
+    public List<Group> find( User user ) throws SecurityException
+    {
+        String methodName = "findWithUsers";
+        assertContext(CLS_NM, methodName, user, GlobalErrIds.USER_NULL);
+        checkAccess(CLS_NM, methodName);
+        loadUserDn( user );
+        return groupP.search( user );
+    }
+
+    /**
+     * Assign a user to an existing group node.  The name is required and userDn are required.
+     *
+     * @param group contains {@link Group}.
+     * @param member is the relative distinguished name (rdn) of an existing user in ldap.
+     * @return {@link Group} containing entity to assign.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry already present or other system error.
+     */
+    @Override
+    public Group assign( Group group, String member ) throws SecurityException
+    {
+        String methodName = "assign";
+        assertContext(CLS_NM, methodName, group, GlobalErrIds.GROUP_NULL);
+        checkAccess(CLS_NM, methodName);
+        ReviewMgr reviewMgr = ReviewMgrFactory.createInstance();
+        User user = reviewMgr.readUser( new User( member ) );
+        return groupP.assign( group, user.getDn() );
+    }
+
+    /**
+     * Deassign a user from an existing group node.  The name is required and userDn are required.
+     *
+     * @param group contains {@link Group}.
+     * @param member is the relative distinguished name (rdn) of an existing user in ldap.
+     * @return {@link Group} containing entity to deassign
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry already present or other system error.
+     */
+    @Override
+    public Group deassign( Group group, String member ) throws SecurityException
+    {
+        String methodName = "deassign";
+        assertContext(CLS_NM, methodName, group, GlobalErrIds.GROUP_NULL);
+        checkAccess(CLS_NM, methodName);
+        ReviewMgr reviewMgr = ReviewMgrFactory.createInstance();
+        User user = reviewMgr.readUser( new User( member ) );
+        return groupP.deassign( group, user.getDn() );
+    }
+
+    private void loadUserDns( Group group ) throws SecurityException
+    {
+        if( VUtil.isNotNullOrEmpty( group.getMembers() ))
+        {
+            ReviewMgr reviewMgr = ReviewMgrFactory.createInstance();
+            List<String> userDns = new ArrayList<>();
+            for( String member : group.getMembers() )
+            {
+                User user = reviewMgr.readUser( new User( member ) );
+                userDns.add( user.getDn() );
+            }
+            group.setMembers( userDns );
+        }
+    }
+
+    private void loadUserDn( User inUser ) throws SecurityException
+    {
+        ReviewMgr reviewMgr = ReviewMgrFactory.createInstance();
+        String userDns;
+        User outUser = reviewMgr.readUser( inUser );
+        inUser.setDn( outUser.getDn() );
+    }
+}
\ 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/ldap/group/GroupP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupP.java b/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupP.java
new file mode 100755
index 0000000..c311443
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/group/GroupP.java
@@ -0,0 +1,213 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.group;
+
+
+import org.apache.directory.fortress.core.ValidationException;
+import org.apache.directory.fortress.core.rbac.User;
+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.SecurityException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.List;
+
+
+/**
+ * Process module for the group node of Fortress directory structure.
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+final class GroupP
+{
+    private static final String CLS_NM = GroupP.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static GroupDAO gDao = new GroupDAO();
+
+    /**
+     * Add a group node to the Directory Information Tree (DIT).
+     *
+     * @param group contains the group entity for target node.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in event of validation or system error.
+     */
+    final Group add( Group group ) throws SecurityException
+    {
+        validate( group );
+        return gDao.create( group );
+    }
+
+    /**
+     * Modify a group node within the Directory Information Tree (DIT).
+     *
+     * @param group contains the group entity for target node.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in event of validation or system error.
+     */
+    final Group update( Group group ) throws SecurityException
+    {
+        validate( group );
+        return gDao.update( group );
+    }
+
+    /**
+     * Remove the group node.
+     *
+     * @param group contains the group entity for target node.
+     * @throws SecurityException in event of validation or system error.
+     */
+    final Group delete( Group group ) throws SecurityException
+    {
+        return gDao.remove( group );
+    }
+
+    /**
+     * Add a new property to an existing Group
+     *
+     * @param group
+     * @param key
+     * @param value
+     * @return
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *
+     */
+    final Group add( Group group, String key, String value ) throws SecurityException
+    {
+        return gDao.add( group, key, value );
+    }
+
+    /**
+     * Remove an existing property value from an existing Group
+     *
+     * @param group
+     * @param key
+     * @param value
+     * @return
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *
+     */
+    final Group delete( Group group, String key, String value ) throws SecurityException
+    {
+        return gDao.delete( group, key, value );
+    }
+
+    /**
+     * Method will add the "member" attribute on LDAP entry which represents a Group assignment.
+     *
+     * @param entity contains the group name targeted.
+     * @param userDn String contains the dn for the user entry that is being assigned the RBAC Role.
+     * @return Group containing copy of input data.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final Group assign( Group entity, String userDn ) throws SecurityException
+    {
+        return gDao.assign( entity, userDn );
+    }
+
+    /**
+     * Method will remove the "member" attribute on LDAP entry which represents a Group assignment.
+     *
+     * @param entity contains the role name targeted.
+     * @param userDn String contains the dn for the user entry that is being assigned the RBAC Role.
+     * @return Role containing copy of input data.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final Group deassign( Group entity, String userDn ) throws SecurityException
+    {
+        return gDao.deassign( entity, userDn );
+    }
+
+    /**
+     * Return a fully populated Group entity for a given name.  If matching record not found a
+     * SecurityException will be thrown.
+     *
+     * @param group contains full group name for entry in directory.
+     * @return Group entity containing all attributes associated.
+     * @throws SecurityException in the event not found or DAO search error.
+     */
+    final Group read( Group group ) throws SecurityException
+    {
+        return gDao.get( group );
+    }
+
+    /**
+     * Takes a search string that contains full or partial Group name in directory.
+     *
+     * @param group contains full or partial name.
+     * @return List of type Group containing fully populated matching entities.  If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<Group> search( Group group ) throws SecurityException
+    {
+        return gDao.find( group );
+    }
+
+    /**
+     * Takes a search string that contains full or partial Group name in directory.
+     *
+     * @param user contains full dn for existing user.
+     * @return List of type Group containing fully populated matching entities.  If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<Group> search( User user ) throws SecurityException
+    {
+        return gDao.find( user );
+    }
+
+    /**
+     * Method will perform simple validations to ensure the integrity of the {@link Group} entity targeted for insertion
+     * or deletion in directory.
+     *
+     * @param entity contains the enum type to validate
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event the attribute is null.
+     */
+    private void validate( Group entity ) throws SecurityException
+    {
+        if ( !VUtil.isNotNullOrEmpty( entity.getName() ) )
+        {
+            String error = "validate name validation failed, null or empty value";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.GROUP_NAME_NULL, error );
+        }
+        if ( entity.getName().length() > GlobalIds.OU_LEN )
+        {
+            String name = entity.getName();
+            String error = "validate name [" + name + "] invalid length [" + entity.getName().length() + "]";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.GROUP_NAME_INVLD, error );
+        }
+        if ( entity.getProtocol().length() > GlobalIds.OU_LEN )
+        {
+            String error = "validate protocol [" + entity.getProtocol() + "] invalid length [" + entity.getProtocol()
+                .length() + "]";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.GROUP_PROTOCOL_INVLD, error );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+        {
+            VUtil.description( entity.getDescription() );
+        }
+    }
+}
\ 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/ldap/group/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/group/package.html b/src/main/java/org/apache/directory/fortress/core/ldap/group/package.html
new file mode 100755
index 0000000..28db54b
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/group/package.html
@@ -0,0 +1,33 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.ldap.group</title>
+   </head>
+   <body>
+      <p>
+         This package contains APIs to perform create and teardown the ldap group node.
+      </p>
+      <p>
+          The <b>org.apache.directory.fortress.ldap.group</b> package provides apis to add and remove group node, <b>dcObject</b>.
+          The group node is common throughout ldap operartions and is commonly used to define sets of users or other data types.
+      </p>
+   </body>
+</html>


[41/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java b/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java
new file mode 100755
index 0000000..1938d22
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/FortressAntTask.java
@@ -0,0 +1,2435 @@
+/*
+ *   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.ant;
+
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.input.InputRequest;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.ldap.group.Group;
+import org.apache.directory.fortress.core.ldap.group.GroupMgr;
+import org.apache.directory.fortress.core.ldap.group.GroupMgrFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.AdminMgr;
+import org.apache.directory.fortress.core.AdminMgrFactory;
+import org.apache.directory.fortress.core.CfgException;
+import org.apache.directory.fortress.core.DelAdminMgr;
+import org.apache.directory.fortress.core.DelAdminMgrFactory;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.PwPolicyMgr;
+import org.apache.directory.fortress.core.PwPolicyMgrFactory;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.cfg.ConfigMgr;
+import org.apache.directory.fortress.core.cfg.ConfigMgrFactory;
+import org.apache.directory.fortress.core.ldap.container.OrganizationalUnit;
+import org.apache.directory.fortress.core.ldap.container.OrganizationalUnitP;
+import org.apache.directory.fortress.core.ldap.suffix.Suffix;
+import org.apache.directory.fortress.core.ldap.suffix.SuffixP;
+
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.rbac.Context;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.OrgUnitAnt;
+import org.apache.directory.fortress.core.rbac.PermGrant;
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.PwPolicy;
+import org.apache.directory.fortress.core.rbac.Relationship;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.SDSet;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+import org.apache.directory.fortress.core.rbac.UserRole;
+import org.apache.directory.fortress.core.util.Testable;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * This class implements Apache Ant custom task and is used to drive the Fortress Administrative APIs using XML files
+ * .  The
+ * methods in this class are not intended to be callable by outside programs.  The following APIs are supported:
+ * <p/>
+ * <ol>
+ * <li>{@link org.apache.directory.fortress.core.AdminMgr}</li>
+ * <li>{@link org.apache.directory.fortress.core.DelAdminMgr}</li>
+ * <li>{@link org.apache.directory.fortress.core.PwPolicyMgr}</li>
+ * <li>{@link ConfigMgr}</li>
+ * </ol>
+ * <p/>
+ * using the custom Ant task that is implemented in this class.  The format of the XML is flat and consists of entity
+ * names
+ * along with their attributes.
+ * <h3>
+ * This class will process xml formatted requests with the following tags:
+ * </h3>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *          <adduser> ...</adduser>
+ *          <deluser> ...</deluser>
+ *          <adduserrole> ...</adduserrole>
+ *          <deluserrole> ...</deluserrole>
+ *          <addrole> ...</addrole>*
+ *          <delrole> ...</delrole>
+ *          <addroleinheritance>...</addroleinheritance>
+ *          <delroleinheritance>...</delroleinheritance>
+ *          <addsdset>STATIC or DYNAMIC</addsdset>
+ *          <delsdset>STATIC or DYNAMIC</delsdset>
+ *          <delpwpolicy> ...</delpwpolicy>
+ *          <addpwpolicy> ...</addpwpolicy>
+ *          <addpermobj> RBAC or ARBAC permission objects</addpermobj>
+ *          <delpermobj> RBAC or ARBAC permission objects</delpermobj>
+ *          <addpermop> RBAC or ARBAC permission operations</addpermop>
+ *          <delpermop> RBAC or ARBAC permission operations</delpermop>
+ *          <addpermgrant> RBAC or ARBAC permission grants </addpermgrant>
+ *          <delpermgrant> RBAC or ARBAC permission revokes </delpermgrant>
+ *          <addorgunit> User OUs or Perm OUs </addorgunit>
+ *          <delorgunit> User OUs or Perm OUs </delorgunit>
+ *          <adduserorgunitinheritance> ...</adduserorgunitinheritance>
+ *          <deluserorgunitinheritance> ...</deluserorgunitinheritance>
+ *          <addpermorgunitinheritance> ...</addpermorgunitinheritance>
+ *          <delpermorgunitinheritance> ...</delpermorgunitinheritance>
+ *          <adduser> ... </adduser>
+ *          <deluser> ...</deluser>
+ *          <addadminrole>  ... </addadminrole>
+ *          <deladminrole>  ... </deladminrole>
+ *          <addadminroleinheritance>...</addadminroleinheritance>
+ *          <deladminroleinheritance>...</deladminroleinheritance>
+ *          <adduseradminrole> ... </adduseradminrole>
+ *          <deluseradminrole>  ... </deluseradminrole>
+ *      </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ * <h3>Order of Precedence</h3>
+ * The order of operations in the XML does not effect the order or precedence which has been "hard-wired" by the
+ * processing order within this class.
+ * <ol>
+ * <li>Delete User Role Assignments {@link org.apache.directory.fortress.core.AdminMgr#deassignUser(org.apache.directory.fortress.core.rbac.UserRole)}</li>
+ * <li>Delete User AdminRole Assignments {@link DelAdminMgr#deassignUser(UserAdminRole)}</li>
+ * <li>Revoke Permission Assignments Delete{@link AdminMgr#revokePermission(org.apache.directory.fortress.core.rbac.Permission,
+ * org.apache.directory.fortress.core.rbac.Role)}</li>
+ * <li>Delete Users {@link org.apache.directory.fortress.core.AdminMgr#disableUser(org.apache.directory.fortress.core.rbac.User)}</li>
+ * <li>Delete Password Policies {@link org.apache.directory.fortress.core.PwPolicyMgr#delete(org.apache.directory.fortress.core.rbac.PwPolicy)}</li>
+ *
+ * <li>Delete Permission Operations {@link org.apache.directory.fortress.core.AdminMgr#deletePermission(org.apache.directory.fortress.core.rbac.Permission)
+ * }</li>
+ * <li>Delete Permission Objects {@link org.apache.directory.fortress.core.AdminMgr#deletePermObj(org.apache.directory.fortress.core.rbac.PermObj)}</li>
+ *
+ * <li>Delete SSD and DSD Sets {@link org.apache.directory.fortress.core.AdminMgr#deleteDsdSet(org.apache.directory.fortress.core.rbac.SDSet)} and {@link
+ * org.apache.directory.fortress.core.AdminMgr#deleteSsdSet(org.apache.directory.fortress.core.rbac.SDSet)}</li>
+ * <li>Delete RBAC Roles Inheritances {@link org.apache.directory.fortress.core.AdminMgr#deleteInheritance(org.apache.directory.fortress.core.rbac.Role,
+ * org.apache.directory.fortress.core.rbac.Role)}</li>
+ * <li>Delete RBAC Roles {@link org.apache.directory.fortress.core.AdminMgr#deleteRole(org.apache.directory.fortress.core.rbac.Role)}</li>
+ * <li>Delete ARBAC Role Inheritances {@link DelAdminMgr#deleteInheritance(org.apache.directory.fortress.core.rbac.AdminRole,
+ * org.apache.directory.fortress.core.rbac.AdminRole)}</li>
+ * <li>Delete ARBAC Roles {@link org.apache.directory.fortress.core.DelAdminMgr#deleteRole(org.apache.directory.fortress.core.rbac.AdminRole)}</li>
+ * <li>Delete User and Perm OU Inheritances {@link DelAdminMgr#deleteInheritance(org.apache.directory.fortress.core.rbac.OrgUnit,
+ * org.apache.directory.fortress.core.rbac.OrgUnit)} USER and PERM</li>
+ * <li>Delete User and Perm OUs {@link org.apache.directory.fortress.core.DelAdminMgr#delete(org.apache.directory.fortress.core.rbac.OrgUnit)} USER and
+ * PERM</li>
+ * <li>Delete Configuration Entries {@link org.apache.directory.fortress.cfg.ConfigMgr#delete(String, java.util.Properties)}</li>
+ * <li>Delete Containers {@link OrganizationalUnitP#delete(OrganizationalUnit)}</li>
+ * <li>Delete Suffix {@link org.apache.directory.fortress.core.ldap.suffix.SuffixP#delete(org.apache.directory.fortress.core.ldap.suffix.Suffix)}}</li>
+ * <li>Add Suffix {@link SuffixP#add(Suffix)}}</li>
+ * <li>Add Containers {@link OrganizationalUnitP#add(OrganizationalUnit)}</li>
+ * <li>Add Configuration Parameters {@link ConfigMgr#add(String, java.util.Properties)}</li>
+ * <li>Add User and Perm OUs {@link org.apache.directory.fortress.core.DelAdminMgr#add(org.apache.directory.fortress.core.rbac.OrgUnit)} USER and PERM</li>
+ * <li>Add User and Perm OU Inheritances {@link DelAdminMgr#addInheritance(org.apache.directory.fortress.core.rbac.OrgUnit,
+ * org.apache.directory.fortress.core.rbac.OrgUnit)} USER and PERM</li>
+ * <li>Add ARBAC Roles {@link org.apache.directory.fortress.core.DelAdminMgr#addRole(org.apache.directory.fortress.core.rbac.AdminRole)}</li>
+ * <li>Add ARBAC Role Inheritances {@link org.apache.directory.fortress.core.DelAdminMgr#addInheritance(org.apache.directory.fortress.core.rbac.AdminRole,
+ * org.apache.directory.fortress.core.rbac.AdminRole)}</li>
+ * <li>Add RBAC Roles {@link org.apache.directory.fortress.core.AdminMgr#addRole(org.apache.directory.fortress.core.rbac.Role)}</li>
+ * <li>Add RBAC Role Inheritances {@link org.apache.directory.fortress.core.AdminMgr#addInheritance(org.apache.directory.fortress.core.rbac.Role,
+ * org.apache.directory.fortress.core.rbac.Role)}</li>
+ * <li>Add DSD and SSD Sets {@link org.apache.directory.fortress.core.AdminMgr#createDsdSet(org.apache.directory.fortress.core.rbac.SDSet)} and {@link org.apache.directory.fortress.core.AdminMgr#createSsdSet(org.apache.directory.fortress.core.rbac.SDSet)}</li>
+ * <li>Add Permission Objects {@link org.apache.directory.fortress.core.AdminMgr#addPermObj(org.apache.directory.fortress.core.rbac.PermObj)}</li>
+ * <li>Add Permission Operations {@link org.apache.directory.fortress.core.AdminMgr#addPermission(org.apache.directory.fortress.core.rbac.Permission)}</li>
+ * <li>Add Password Policies {@link org.apache.directory.fortress.core.PwPolicyMgr#add(org.apache.directory.fortress.core.rbac.PwPolicy)}</li>
+ * <li>Add Users {@link org.apache.directory.fortress.core.AdminMgr#addUser(org.apache.directory.fortress.core.rbac.User)}</li>
+ * <li>Grant RBAC Permissions {@link org.apache.directory.fortress.core.AdminMgr#grantPermission(org.apache.directory.fortress.core.rbac.Permission,
+ * org.apache.directory.fortress.core.rbac.Role)}</li>
+ * <li>Assign ARBAC Roles {@link org.apache.directory.fortress.core.DelAdminMgr#assignUser(org.apache.directory.fortress.core.rbac.UserAdminRole)}</li>
+ * <li>Assign RBAC Roles {@link org.apache.directory.fortress.core.AdminMgr#assignUser(org.apache.directory.fortress.core.rbac.UserRole)}</li>
+ * </li>
+ * </ol>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class FortressAntTask extends Task implements InputHandler
+{
+    public static final boolean DEBUG = ( ( System.getProperty( "debug.admin" ) != null ) && ( System.getProperty(
+        "debug.admin" ).equalsIgnoreCase( "true" ) ) );
+    private static final String SEMICOLON = ";";
+    final private List<Addconfig> addconfig = new ArrayList<>();
+    final private List<Delconfig> delconfig = new ArrayList<>();
+    final private List<Adduser> addusers = new ArrayList<>();
+    final private List<Deluser> delusers = new ArrayList<>();
+    final private List<Adduserrole> adduserroles = new ArrayList<>();
+    final private List<Deluserrole> deluserroles = new ArrayList<>();
+    final private List<Addrole> addroles = new ArrayList<>();
+    final private List<Delrole> delroles = new ArrayList<>();
+    final private List<Addsdset> addsdsets = new ArrayList<>();
+    final private List<Addroleinheritance> addroleinheritances = new ArrayList<>();
+    final private List<Delroleinheritance> delroleinheritances = new ArrayList<>();
+    final private List<Delsdset> delsdsets = new ArrayList<>();
+    final private List<AddpermOp> addpermOps = new ArrayList<>();
+    final private List<DelpermOp> delpermOps = new ArrayList<>();
+    final private List<AddpermObj> addpermObjs = new ArrayList<>();
+    final private List<DelpermObj> delpermObjs = new ArrayList<>();
+    final private List<AddpermGrant> addpermGrants = new ArrayList<>();
+    final private List<DelpermGrant> delpermGrants = new ArrayList<>();
+    final private List<Addpwpolicy> addpolicies = new ArrayList<>();
+    final private List<Delpwpolicy> delpolicies = new ArrayList<>();
+    final private List<Addcontainer> addcontainers = new ArrayList<>();
+    final private List<Delcontainer> delcontainers = new ArrayList<>();
+    final private List<Addsuffix> addsuffixes = new ArrayList<>();
+    final private List<Delsuffix> delsuffixes = new ArrayList<>();
+    final private List<Addorgunit> addorgunits = new ArrayList<>();
+    final private List<Delorgunit> delorgunits = new ArrayList<>();
+    final private List<Adduserorgunitinheritance> adduserorgunitinheritances = new ArrayList<>();
+    final private List<Deluserorgunitinheritance> deluserorgunitinheritances = new ArrayList<>();
+    final private List<Addpermorgunitinheritance> addpermorgunitinheritances = new ArrayList<>();
+    final private List<Delpermorgunitinheritance> delpermorgunitinheritances = new ArrayList<>();
+    final private List<Addadminrole> addadminroles = new ArrayList<>();
+    final private List<Deladminrole> deladminroles = new ArrayList<>();
+    final private List<Adduseradminrole> adduseradminroles = new ArrayList<>();
+    final private List<Addadminroleinheritance> addadminroleinheritances = new ArrayList<>();
+    final private List<Deladminroleinheritance> deladminroleinheritances = new ArrayList<>();
+    final private List<Deluseradminrole> deluseradminroles = new ArrayList<>();
+    final private List<Addcontext> addcontexts = new ArrayList<>();
+    final protected List<Addgroup> addgroups = new ArrayList<>();
+    final protected List<Delgroup> delgroups = new ArrayList<>();
+    final protected List<Addgroupmember> addgroupmembers = new ArrayList<>();
+    final protected List<Delgroupmember> delgroupmembers = new ArrayList<>();
+    final protected List<Addgroupproperty> addgroupproperties = new ArrayList<>();
+    final protected List<Delgroupproperty> delgroupproperties = new ArrayList<>();
+
+    protected ConfigMgr cfgMgr = null;
+    protected AdminMgr adminMgr = null;
+    protected DelAdminMgr dAdminMgr = null;
+    protected PwPolicyMgr policyMgr = null;
+    protected GroupMgr groupMgr = null;
+    private static final String CLS_NM = FortressAntTask.class.getName();
+    protected static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    protected Context context;
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addcontext contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddcontext( Addcontext addcontext )
+    {
+        this.addcontexts.add( addcontext );
+    }
+
+
+    public void setContext( Context context )
+    {
+        System.out.println( CLS_NM + ".setContext name: " + context.getName() );
+        this.context = context;
+        try
+        {
+            adminMgr = AdminMgrFactory.createInstance( context.getName() );
+            dAdminMgr = DelAdminMgrFactory.createInstance( context.getName() );
+            policyMgr = PwPolicyMgrFactory.createInstance( context.getName() );
+            groupMgr = GroupMgrFactory.createInstance( context.getName() );
+        }
+        catch ( SecurityException se )
+        {
+            LOG.warn( " FortressAntTask setContext caught SecurityException=" + se );
+        }
+    }
+
+
+    /**
+     * Default constructor initializes he Manager APIs.
+     */
+    public FortressAntTask()
+    {
+        try
+        {
+            cfgMgr = ConfigMgrFactory.createInstance();
+            adminMgr = AdminMgrFactory.createInstance( GlobalIds.HOME );
+            dAdminMgr = DelAdminMgrFactory.createInstance( GlobalIds.HOME );
+            policyMgr = PwPolicyMgrFactory.createInstance( GlobalIds.HOME );
+            groupMgr = GroupMgrFactory.createInstance( GlobalIds.HOME );
+        }
+        catch ( SecurityException se )
+        {
+            LOG.warn( " FortressAntTask constructor caught SecurityException=" + se );
+        }
+    }
+
+
+    /**
+     * Used by Apache Ant to load data from xml into entities.
+     *
+     * @param request
+     */
+    public void handleInput( InputRequest request )
+    {
+        LOG.info( "handleInput request=" + request );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addcfg contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddconfig( Addconfig addcfg )
+    {
+        this.addconfig.add( addcfg );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delcfg contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelconfig( Delconfig delcfg )
+    {
+        this.delconfig.add( delcfg );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param adduser contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAdduser( Adduser adduser )
+    {
+        this.addusers.add( adduser );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param deluser contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDeluser( Deluser deluser )
+    {
+        this.delusers.add( deluser );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param adduserrole contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAdduserrole( Adduserrole adduserrole )
+    {
+        this.adduserroles.add( adduserrole );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param deluserrole contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDeluserrole( Deluserrole deluserrole )
+    {
+        this.deluserroles.add( deluserrole );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addrole contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddrole( Addrole addrole )
+    {
+        this.addroles.add( addrole );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delrole contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelrole( Delrole delrole )
+    {
+        this.delroles.add( delrole );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addroleinheritance contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddroleinheritance( Addroleinheritance addroleinheritance )
+    {
+        this.addroleinheritances.add( addroleinheritance );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delroleinheritance contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelroleinheritance( Delroleinheritance delroleinheritance )
+    {
+        this.delroleinheritances.add( delroleinheritance );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addsd contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddsdset( Addsdset addsd )
+    {
+        this.addsdsets.add( addsd );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delsd contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelsdset( Delsdset delsd )
+    {
+        this.delsdsets.add( delsd );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addpermOp contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddpermOp( AddpermOp addpermOp )
+    {
+        this.addpermOps.add( addpermOp );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delpermOp contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelpermOp( DelpermOp delpermOp )
+    {
+        this.delpermOps.add( delpermOp );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addpermObj contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddpermObj( AddpermObj addpermObj )
+    {
+        this.addpermObjs.add( addpermObj );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delpermObj contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelpermObj( DelpermObj delpermObj )
+    {
+        this.delpermObjs.add( delpermObj );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addpermGrant contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddpermGrant( AddpermGrant addpermGrant )
+    {
+        this.addpermGrants.add( addpermGrant );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delpermGrant contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelpermGrant( DelpermGrant delpermGrant )
+    {
+        this.delpermGrants.add( delpermGrant );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addpwpolicy contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddpwpolicy( Addpwpolicy addpwpolicy )
+    {
+        this.addpolicies.add( addpwpolicy );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delpwpolicy contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelpwpolicy( Delpwpolicy delpwpolicy )
+    {
+        this.delpolicies.add( delpwpolicy );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addcontainer contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddcontainer( Addcontainer addcontainer )
+    {
+        this.addcontainers.add( addcontainer );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delcontainer contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelcontainer( Delcontainer delcontainer )
+    {
+        this.delcontainers.add( delcontainer );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addsuffix contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddsuffix( Addsuffix addsuffix )
+    {
+        this.addsuffixes.add( addsuffix );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delsuffix contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelsuffix( Delsuffix delsuffix )
+    {
+        this.delsuffixes.add( delsuffix );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addorgunit contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddorgunit( Addorgunit addorgunit )
+    {
+        this.addorgunits.add( addorgunit );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delorgunit contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelorgunit( Delorgunit delorgunit )
+    {
+        this.delorgunits.add( delorgunit );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addinheritance contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAdduserorgunitinheritance( Adduserorgunitinheritance addinheritance )
+    {
+        this.adduserorgunitinheritances.add( addinheritance );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delinheritance contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDeluserorgunitinheritance( Deluserorgunitinheritance delinheritance )
+    {
+        this.deluserorgunitinheritances.add( delinheritance );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addinheritance contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddpermorgunitinheritance( Addpermorgunitinheritance addinheritance )
+    {
+        this.addpermorgunitinheritances.add( addinheritance );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delinheritance contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelpermorgunitinheritance( Delpermorgunitinheritance delinheritance )
+    {
+        this.delpermorgunitinheritances.add( delinheritance );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addrole contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddadminrole( Addadminrole addrole )
+    {
+        this.addadminroles.add( addrole );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delrole contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDeladminrole( Deladminrole delrole )
+    {
+        this.deladminroles.add( delrole );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addadminroleinheritance contains the ant initialized data entities to be handed off for further
+     *                                processing.
+     */
+    public void addAddadminroleinheritance( Addadminroleinheritance addadminroleinheritance )
+    {
+        this.addadminroleinheritances.add( addadminroleinheritance );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param deladminroleinheritance contains the ant initialized data entities to be handed off for further
+     *                                processing.
+     */
+    public void addDeladminroleinheritance( Deladminroleinheritance deladminroleinheritance )
+    {
+        this.deladminroleinheritances.add( deladminroleinheritance );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param adduserrole contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAdduseradminrole( Adduseradminrole adduserrole )
+    {
+        this.adduseradminroles.add( adduserrole );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param deluserrole contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDeluseradminrole( Deluseradminrole deluserrole )
+    {
+        this.deluseradminroles.add( deluserrole );
+    }
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addgroup contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddgroup( Addgroup addgroup )
+    {
+        this.addgroups.add( addgroup );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delgroup contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelgroup( Delgroup delgroup )
+    {
+        this.delgroups.add( delgroup );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addgroupmember contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddgroupmember( Addgroupmember addgroupmember )
+    {
+        this.addgroupmembers.add( addgroupmember );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delgroupmember contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelgroupmember( Delgroupmember delgroupmember )
+    {
+        this.delgroupmembers.add( delgroupmember );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param addgroupproperty contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addAddgroupproperty( Addgroupproperty addgroupproperty )
+    {
+        this.addgroupproperties.add( addgroupproperty );
+    }
+
+
+    /**
+     * Load the entity with data.
+     *
+     * @param delgroupproperty contains the ant initialized data entities to be handed off for further processing.
+     */
+    public void addDelgroupproperty( Delgroupproperty delgroupproperty )
+    {
+        this.delgroupproperties.add( delgroupproperty );
+    }
+
+
+    /**
+     * @param list
+     * @return boolean
+     */
+    private boolean isListNotNull( List list )
+    {
+        return ( list != null && list.size() > 0 );
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    public void execute() throws BuildException
+    {
+        LOG.info( "FORTRESS ANT TASK NAME : " + getTaskName() );
+        if ( isListNotNull( addcontexts ) )
+        {
+            setContext( addcontexts.get( 0 ).getContexts().get( 0 ) );
+        }
+
+        if ( isListNotNull( deluserroles ) )
+        {
+            delUserRoles();
+        }
+
+        if ( isListNotNull( deluseradminroles ) )
+        {
+            delUserAdminRoles();
+        }
+
+        if ( isListNotNull( delpermGrants ) )
+        {
+            deletePermGrants();
+        }
+
+        if ( isListNotNull( delgroupproperties ) )
+        {
+            deleteGroupProperties();
+        }
+
+        if ( isListNotNull( delgroupmembers ) )
+        {
+            deleteGroupMembers();
+        }
+
+        if ( isListNotNull( delgroups ) )
+        {
+            deleteGroups();
+        }
+
+        if ( isListNotNull( delusers ) )
+        {
+            deleteUsers();
+        }
+
+        if ( isListNotNull( delpolicies ) )
+        {
+            deletePolicies();
+        }
+
+        if ( isListNotNull( delpermOps ) )
+        {
+            deletePermOps();
+        }
+
+        if ( isListNotNull( delpermObjs ) )
+        {
+            deletePermObjs();
+        }
+
+        if ( isListNotNull( delsdsets ) )
+        {
+            deleteSdsets();
+        }
+
+        if ( isListNotNull( delroleinheritances ) )
+        {
+            deleteRoleInheritances();
+        }
+
+        if ( isListNotNull( delroles ) )
+        {
+            deleteRoles();
+        }
+
+        if ( isListNotNull( deladminroleinheritances ) )
+        {
+            deleteAdminRoleInheritances();
+        }
+
+        if ( isListNotNull( deladminroles ) )
+        {
+            deleteAdminRoles();
+        }
+
+        if ( isListNotNull( deluserorgunitinheritances ) )
+        {
+            deleteUserOrgunitInheritances();
+        }
+
+        if ( isListNotNull( delpermorgunitinheritances ) )
+        {
+            deletePermOrgunitInheritances();
+        }
+
+        if ( isListNotNull( delorgunits ) )
+        {
+            delOrgunits();
+        }
+
+        if ( isListNotNull( delconfig ) )
+        {
+            deleteConfig();
+        }
+
+        if ( isListNotNull( delcontainers ) )
+        {
+            deleteContainers();
+        }
+
+        if ( isListNotNull( delsuffixes ) )
+        {
+            deleteSuffixes();
+        }
+
+        if ( isListNotNull( addsuffixes ) )
+        {
+            addSuffixes();
+        }
+
+        if ( isListNotNull( addcontainers ) )
+        {
+            addContainers();
+        }
+
+        if ( isListNotNull( addconfig ) )
+        {
+            addConfig();
+        }
+
+        if ( isListNotNull( addorgunits ) )
+        {
+            addOrgunits();
+        }
+
+        if ( isListNotNull( adduserorgunitinheritances ) )
+        {
+            addUserOrgunitInheritances();
+        }
+
+        if ( isListNotNull( addpermorgunitinheritances ) )
+        {
+            addPermOrgunitInheritances();
+        }
+
+        if ( isListNotNull( addadminroles ) )
+        {
+            addAdminRoles();
+        }
+
+        if ( isListNotNull( addadminroleinheritances ) )
+        {
+            addAdminRoleInheritances();
+        }
+
+        if ( isListNotNull( addroles ) )
+        {
+            addRoles();
+        }
+
+        if ( isListNotNull( addroleinheritances ) )
+        {
+            addRoleInheritances();
+        }
+
+        if ( isListNotNull( addsdsets ) )
+        {
+            addSdsets();
+        }
+
+        if ( isListNotNull( addpermObjs ) )
+        {
+            addPermObjs();
+        }
+
+        if ( isListNotNull( addpermOps ) )
+        {
+            addPermOps();
+        }
+
+        if ( isListNotNull( addpolicies ) )
+        {
+            addPolicies();
+        }
+
+        if ( isListNotNull( addusers ) )
+        {
+            addUsers();
+        }
+
+        if ( isListNotNull( addgroups ) )
+        {
+            addGroups();
+        }
+
+        if ( isListNotNull( addgroupmembers ) )
+        {
+            addGroupMembers();
+        }
+
+        if ( isListNotNull( addgroupproperties ) )
+        {
+            addGroupProperties();
+        }
+
+        if ( isListNotNull( addpermGrants ) )
+        {
+            addPermGrants();
+        }
+
+        if ( isListNotNull( adduseradminroles ) )
+        {
+            addUserAdminRoles();
+        }
+
+        if ( isListNotNull( adduserroles ) )
+        {
+            addUserRoles();
+        }
+
+        // Test the results?
+        if ( DEBUG )
+        {
+            // Verify the input XML file against what made it into the target LDAP directory:
+            LOG.info( "DEBUG MODE" );
+            try
+            {
+                String testClassName = Config.getProperty( getTaskName() );
+                if(!VUtil.isNotNullOrEmpty( testClassName ))
+                {
+                    testClassName = "org.apache.directory.fortress.core.rbac.FortressAntLoadTest";
+                }
+                // Use reflexion to avoid core dependency on test classes located under FORTRESS_HOME/src/main/test
+                Testable tester = ( Testable ) ClassUtil.createInstance( testClassName );
+                tester.execute( this );
+            }
+            catch ( CfgException ce )
+            {
+                String error = "Error executing tests, errCode=" + ce.getErrorId() + " msg=" + ce;
+                LOG.warn( error );
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addUsers() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Adduser adduser : addusers )
+        {
+            List<UserAnt> users = adduser.getUsers();
+
+            for ( UserAnt user : users )
+            {
+                LOG.info( "addUsers userid=" + user.getUserId() + " description=" + user.getDescription() + " " +
+                    "orgUnit=" + user.getOu() );
+                try
+                {
+                    try
+                    {
+                        adminMgr.addUser( user );
+                        if ( VUtil.isNotNullOrEmpty( user.getRoles() ) )
+                        {
+                            for ( UserRole uRole : user.getRoles() )
+                            {
+                                adminMgr.assignUser( uRole );
+                            }
+                        }
+                        if ( VUtil.isNotNullOrEmpty( user.getAdminRoles() ) )
+                        {
+                            for ( UserAdminRole uAdminRoleRole : user.getAdminRoles() )
+                            {
+                                dAdminMgr.assignUser( uAdminRoleRole );
+                            }
+                        }
+                    }
+                    catch ( SecurityException se )
+                    {
+                        // If User entity already there then call the udpate method.
+                        if ( se.getErrorId() == GlobalErrIds.USER_ID_DUPLICATE )
+                        {
+                            adminMgr.updateUser( user );
+                            if ( VUtil.isNotNullOrEmpty( user.getRoles() ) )
+                            {
+                                for ( UserRole uRole : user.getRoles() )
+                                {
+                                    adminMgr.assignUser( uRole );
+                                }
+                            }
+                            if ( VUtil.isNotNullOrEmpty( user.getAdminRoles() ) )
+                            {
+                                for ( UserAdminRole uAdminRoleRole : user.getAdminRoles() )
+                                {
+                                    dAdminMgr.assignUser( uAdminRoleRole );
+                                }
+                            }
+                            LOG.info( "addUsers - Update entity - userId=" + user.getUserId() );
+                        }
+                        else
+                        {
+                            throw se;
+                        }
+                    }
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addUsers userId [" + user.getUserId() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteUsers() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Deluser deluser : delusers )
+        {
+            List<UserAnt> users = deluser.getUsers();
+            for ( UserAnt user : users )
+            {
+                LOG.info( "deleteUsers userid=" + user.getUserId() );
+                try
+                {
+                    adminMgr.deleteUser( user );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deleteUsers userId [" + user.getUserId() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+    /**
+     * @throws BuildException
+     */
+    private void addGroups() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addgroup addgroup : addgroups )
+        {
+            List<Group> groups = addgroup.getGroups();
+
+            for ( Group group : groups )
+            {
+                LOG.info( "addGroups name=" + group.getName() + " description=" + group.getDescription());
+                try
+                {
+                    groupMgr.add( group );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addGroups name [" + group.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteGroups() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Delgroup delgroup : delgroups )
+        {
+            List<Group> groups = delgroup.getGroups();
+            for ( Group group : groups )
+            {
+                LOG.info( "deleteGroups name=" + group.getName() );
+                try
+                {
+                    groupMgr.delete( group );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deleteGroups name [" + group.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+    /**
+     * @throws BuildException
+     */
+    private void addGroupMembers() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addgroupmember addgroupmember : addgroupmembers )
+        {
+            List<Group> groups = addgroupmember.getGroups();
+
+            for ( Group group : groups )
+            {
+                List<String> members = group.getMembers();
+                if(VUtil.isNotNullOrEmpty( members ))
+                {
+                    for( String member : members )
+                    {
+                        LOG.info( "addGroupMembers name=" + group.getName() + ", member=" + member );
+                        try
+                        {
+                            groupMgr.assign( group, member );
+                        }
+                        catch ( SecurityException se )
+                        {
+                            LOG.warn( "addGroupMembers name [" + group.getName() + "], member [" + member + "] caught SecurityException=" + se );
+                        }
+                    }
+                }
+                else
+                {
+                    LOG.info( "addGroupMembers name=" + group.getName() + ", no member found" );
+                }
+            }
+        }
+    }
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteGroupMembers() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Delgroupmember delgroupmember : delgroupmembers )
+        {
+            List<Group> groups = delgroupmember.getGroups();
+            for ( Group group : groups )
+            {
+                if(VUtil.isNotNullOrEmpty( group.getMembers() ))
+                {
+                    for(String member : group.getMembers())
+                    {
+                        LOG.info( "deleteGroupmembers name=" + group.getName() + ", member=" + member );
+                        try
+                        {
+                            groupMgr.deassign( group, member );
+                        }
+                        catch ( SecurityException se )
+                        {
+                            LOG.warn( "deleteGroupmembers name [" + group.getName() + "], member [" + member + "] caught SecurityException=" + se );
+                        }
+                    }
+                }
+                else
+                {
+                    LOG.info( "deleteGroupmembers name=" + group.getName() + ", no member found" );
+                }
+            }
+        }
+    }
+
+    /**
+     * @throws BuildException
+     */
+    private void addGroupProperties() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addgroupproperty addgroupproperty : addgroupproperties )
+        {
+            List<Group> groups = addgroupproperty.getGroups();
+            for ( Group group : groups )
+            {
+                if(VUtil.isNotNullOrEmpty( group.getProperties() ))
+                {
+                    for ( Enumeration e = group.getProperties().propertyNames(); e.hasMoreElements(); )
+                    {
+                        // This LDAP attr is stored as a name-value pair separated by a ':'.
+                        String key = ( String ) e.nextElement();
+                        String val = group.getProperties().getProperty( key );
+                        try
+                        {
+                            groupMgr.add( group, key, val );
+                        }
+                        catch ( SecurityException se )
+                        {
+                            LOG.warn( "addGroupProperties name [" + group.getName() + "], key [" + key + "], value [" + val + "] caught SecurityException=" + se );
+                        }
+                    }
+                }
+                else
+                {
+                    LOG.info( "addGroupProperties name=" + group.getName() + ", no properties found" );
+                }
+            }
+        }
+    }
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteGroupProperties() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Delgroupproperty delgroupproperty : delgroupproperties )
+        {
+            List<Group> groups = delgroupproperty.getGroups();
+            for ( Group group : groups )
+            {
+                if(VUtil.isNotNullOrEmpty( group.getProperties() ))
+                {
+                    for ( Enumeration e = group.getProperties().propertyNames(); e.hasMoreElements(); )
+                    {
+                        // This LDAP attr is stored as a name-value pair separated by a ':'.
+                        String key = ( String ) e.nextElement();
+                        String val = group.getProperties().getProperty( key );
+                        try
+                        {
+                            groupMgr.delete( group, key, val );
+                        }
+                        catch ( SecurityException se )
+                        {
+                            LOG.warn( "deleteGroupProperties name [" + group.getName() + "], key [" + key + "], value [" + val + "] caught SecurityException=" + se );
+                        }
+                    }
+                }
+                else
+                {
+                    LOG.info( "deleteGroupProperties name=" + group.getName() + ", no properties found" );
+                }
+            }
+        }
+    }
+
+    /**
+     * @throws BuildException
+     */
+    private void addUserRoles() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Adduserrole adduserrole : adduserroles )
+        {
+            List<UserRole> userroles = adduserrole.getUserRoles();
+            for ( UserRole userRole : userroles )
+            {
+                LOG.info( "addUserRoles userid=" + userRole.getUserId() + " role name=" + userRole.getName() );
+
+                /*
+                System.out.println("userrole data:");
+                System.out.println("    userId:" + userRole.getUserId());
+                System.out.println("    name:" + userRole.getName());
+                System.out.println("    bdate:" + userRole.getBeginDate());
+                System.out.println("    edate:" + userRole.getEndDate());
+                System.out.println("    blckdate:" + userRole.getBeginLockDate());
+                System.out.println("    elckdate:" + userRole.getEndLockDate());
+                System.out.println("    btime:" + userRole.getBeginTime());
+                System.out.println("    etime:" + userRole.getEndTime());
+                System.out.println("    day:" + userRole.getDayMask());
+                System.out.println("    raw:" + ((UserRole)userRole).getRawData());
+                System.out.println("    to:" + userRole.getTimeout());
+                */
+
+                try
+                {
+                    //Role role = new Role(userRole);
+                    adminMgr.assignUser( userRole );
+                }
+                catch ( SecurityException se )
+                {
+                    String warning = "addUserRoles userId [" + userRole.getUserId() + "] role name [" + userRole
+                        .getName() + "] caught SecurityException=" + se;
+                    LOG.warn( warning );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void delUserRoles() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Deluserrole deluserrole : deluserroles )
+        {
+            List<UserRole> userroles = deluserrole.getUserRoles();
+            for ( UserRole userRole : userroles )
+            {
+                LOG.info( "delUserRoles userid=" + userRole.getUserId() + " role name=" + userRole.getName() );
+                try
+                {
+                    adminMgr.deassignUser( userRole );
+                }
+                catch ( SecurityException se )
+                {
+                    String warning = "delUserRoles userId [" + userRole.getUserId() + "] role name [" + userRole
+                        .getName() + "] caught SecurityException=" + se;
+                    LOG.warn( warning );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addRoles() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addrole addrole : addroles )
+        {
+            List<Role> roles = addrole.getRoles();
+            for ( Role role : roles )
+            {
+                LOG.info( "addRoles name=" + role.getName() + " description=" + role.getDescription() );
+                try
+                {
+                    adminMgr.addRole( role );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addRoles name [" + role.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteRoles() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Delrole delrole : delroles )
+        {
+            List<Role> roles = delrole.getRoles();
+            for ( Role role : roles )
+            {
+                LOG.info( "deleteRoles name=" + role.getName() );
+                try
+                {
+                    adminMgr.deleteRole( role );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deleteRoles name [" + role.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addRoleInheritances() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addroleinheritance addroleinheritance : addroleinheritances )
+        {
+            List<Relationship> roles = addroleinheritance.getRelationships();
+            for ( Relationship relationship : roles )
+            {
+                LOG.info( "addRoleInheritances parent=" + relationship.getParent() + " child=" + relationship
+                    .getChild() );
+                try
+                {
+                    adminMgr.addInheritance( new Role( relationship.getParent() ), new Role( relationship.getChild()
+                    ) );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addRoleInheritances parent [" + relationship.getParent() + "] child [" + relationship
+                        .getChild() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteRoleInheritances() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Delroleinheritance delroleinheritance : delroleinheritances )
+        {
+            List<Relationship> roles = delroleinheritance.getRelationships();
+            for ( Relationship relationship : roles )
+            {
+                LOG.info( "deleteRoleInheritances parent=" + relationship.getParent() + " child=" + relationship
+                    .getChild() );
+                try
+                {
+                    adminMgr.deleteInheritance( new Role( relationship.getParent() ),
+                        new Role( relationship.getChild() ) );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deleteRoleInheritances parent [" + relationship.getParent() + "] child [" +
+                        relationship.getChild() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addSdsets() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addsdset addsdset : addsdsets )
+        {
+            List<SDSetAnt> sds = addsdset.getSdset();
+            for ( SDSetAnt sd : sds )
+            {
+                LOG.info( "addSdsets name=" + sd.getName() + " description=" + sd.getDescription() );
+                try
+                {
+                    if ( sd.getType() == SDSet.SDType.STATIC )
+                    {
+                        adminMgr.createSsdSet( sd );
+                    }
+                    else
+                    {
+                        adminMgr.createDsdSet( sd );
+                    }
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addSdsets name [" + sd.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteSdsets() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Delsdset delsdset : delsdsets )
+        {
+            List<SDSetAnt> sds = delsdset.getSdset();
+            for ( SDSetAnt sd : sds )
+            {
+                LOG.info( "deleteSdsets name=" + sd.getName() );
+                try
+                {
+                    if ( sd.getSetType().equals( "STATIC" ) )
+                    {
+                        sd.setType( SDSet.SDType.STATIC );
+                    }
+                    else
+                    {
+                        sd.setType( SDSet.SDType.DYNAMIC );
+                    }
+                    adminMgr.deleteSsdSet( sd );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deleteSdsets name [" + sd.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addPermObjs() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( AddpermObj addpermObj : addpermObjs )
+        {
+            List<PermObj> permObjs = addpermObj.getPermObjs();
+            for ( PermObj permObj : permObjs )
+            {
+                LOG.info( "addPermObjs objName=" + permObj.getObjName() + " description=" + permObj
+                    .getDescription() + " orgUnit=" + permObj.getOu() + " type=" + permObj.getType() );
+                try
+                {
+                    try
+                    {
+                        adminMgr.addPermObj( permObj );
+                    }
+                    catch ( SecurityException se )
+                    {
+                        // If Perm Object entity already there then call the udpate method.
+                        if ( se.getErrorId() == GlobalErrIds.PERM_DUPLICATE )
+                        {
+                            adminMgr.updatePermObj( permObj );
+                            System.out.println( CLS_NM + ".addPermObjs - update entity objName=" + permObj
+                                .getObjName() );
+                        }
+                        else
+                        {
+                            throw se;
+                        }
+                    }
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addPermObjs objName [" + permObj.getObjName() + "] caught SecurityException=" +
+                        se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deletePermObjs() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( DelpermObj delpermObj : delpermObjs )
+        {
+            List<PermObj> permObjs = delpermObj.getObjs();
+            for ( PermObj permObj : permObjs )
+            {
+                LOG.info( "deletePermObjs objName=" + permObj.getObjName() + " description=" + permObj
+                    .getDescription() );
+                try
+                {
+                    adminMgr.deletePermObj( permObj );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deletePermObjs name [" + permObj.getObjName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addPermOps() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( AddpermOp addpermOp : addpermOps )
+        {
+            List<PermAnt> permissions = addpermOp.getPermOps();
+            for ( PermAnt permission : permissions )
+            {
+                LOG.info( "addPermOps name=" + permission.getOpName() + " objName=" + permission.getObjName() );
+                try
+                {
+                    try
+                    {
+                        adminMgr.addPermission( permission );
+                    }
+                    catch ( SecurityException se )
+                    {
+                        // If Perm Object entity already there then call the udpate method.
+                        if ( se.getErrorId() == GlobalErrIds.PERM_DUPLICATE )
+                        {
+                            adminMgr.updatePermission( permission );
+                            LOG.info( "addPermOps - update entity - name=" + permission.getOpName() + " objName="
+                                + permission.getObjName() );
+                        }
+                        else
+                        {
+                            throw se;
+                        }
+                    }
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addPermOps name [" + permission.getOpName() + "] objName [" + permission
+                        .getObjName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deletePermOps() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( DelpermOp delpermOp : delpermOps )
+        {
+            List<PermAnt> permissions = delpermOp.getPermOps();
+            for ( Permission permission : permissions )
+            {
+                LOG.info( "deletePermOps name=" + permission.getOpName() + " objName=" + permission.getObjName() );
+                try
+                {
+                    adminMgr.deletePermission( permission );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deletePermOps name [" + permission.getOpName() + "] objName[" + permission
+                        .getObjName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addPermGrants() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( AddpermGrant addpermGrant : addpermGrants )
+        {
+            List<PermGrant> permGrants = addpermGrant.getPermGrants();
+            for ( PermGrant permGrant : permGrants )
+            {
+                String info = "addPermGrants: Add permission grant object name=" + permGrant.getObjName() + " " +
+                    "operation name=" + permGrant.getOpName() + " object id=" + permGrant.getObjId() + " role name="
+                    + permGrant.getRoleNm() + " userId=" + permGrant.getUserId();
+                LOG.info( info );
+                try
+                {
+                    Permission perm = new Permission( permGrant.getObjName(), permGrant.getOpName(),
+                        permGrant.isAdmin() );
+                    perm.setOpName( permGrant.getOpName() );
+                    perm.setObjId( permGrant.getObjId() );
+                    if ( permGrant.getRoleNm() != null && permGrant.getRoleNm().length() > 0 )
+                    {
+                        adminMgr.grantPermission( perm, new Role( permGrant.getRoleNm() ) );
+                    }
+                    else if ( permGrant.getUserId() != null && permGrant.getUserId().length() > 0 )
+                    {
+                        adminMgr.grantPermission( perm, new User( permGrant.getUserId() ) );
+                    }
+                    else
+                    {
+                        String warning = "addPermGrants called without user or role set in xml";
+                        LOG.warn( warning );
+                    }
+                }
+                catch ( SecurityException se )
+                {
+                    String warning = "addPermGrants caught SecurityException=" + se;
+                    LOG.warn( warning );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deletePermGrants() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( DelpermGrant delpermGrant : delpermGrants )
+        {
+            List<PermGrant> permGrants = delpermGrant.getPermGrants();
+            for ( PermGrant permGrant : permGrants )
+            {
+                String info = "deletePermGrants: Delete permission grant object name=" + permGrant.getObjName() + " " +
+                    "operation name=" + permGrant.getOpName() + " role name=" + permGrant.getRoleNm() + " userId=" +
+                    permGrant.getUserId();
+                LOG.info( info );
+                try
+                {
+                    Permission perm = new Permission( permGrant.getObjName(), permGrant.getOpName(),
+                        permGrant.isAdmin() );
+                    perm.setOpName( permGrant.getOpName() );
+                    perm.setObjId( permGrant.getObjId() );
+                    if ( permGrant.getRoleNm() != null && permGrant.getRoleNm().length() > 0 )
+                    {
+                        adminMgr.revokePermission( perm, new Role( permGrant.getRoleNm() ) );
+                    }
+                    else if ( permGrant.getUserId() != null && permGrant.getUserId().length() > 0 )
+                    {
+                        adminMgr.revokePermission( perm, new User( permGrant.getUserId() ) );
+                    }
+                    else
+                    {
+                        String warning = "deletePermGrants called without user or role set in xml";
+                        LOG.warn( warning );
+                    }
+                }
+                catch ( SecurityException se )
+                {
+                    String warning = "deletePermGrants caught SecurityException=" + se;
+                    LOG.warn( warning );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addPolicies() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addpwpolicy addpwpolicy : addpolicies )
+        {
+            List<PwPolicy> policies = addpwpolicy.getPolicies();
+            for ( PwPolicy policy : policies )
+            {
+                LOG.info( "addPolicies name=" + policy.getName() );
+                try
+                {
+                    policyMgr.add( policy );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addPolicies name [" + policy.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deletePolicies() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Delpwpolicy delpwpolicy : delpolicies )
+        {
+            List<PwPolicy> policies = delpwpolicy.getPolicies();
+            for ( PwPolicy policy : policies )
+            {
+                LOG.info( "deletePolicies name=" + policy.getName() );
+                try
+                {
+                    policyMgr.delete( policy );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deletePolicies name [" + policy.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addContainers() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addcontainer addcontainer : addcontainers )
+        {
+            List<OrganizationalUnit> containers = addcontainer.getContainers();
+
+            for ( OrganizationalUnit ou : containers )
+            {
+                LOG.info( "addContainers name=" + ou.getName() + " description=" + ou.getDescription() );
+                try
+                {
+                    OrganizationalUnitP op = new OrganizationalUnitP();
+
+                    if ( this.context != null )
+                    {
+                        ou.setContextId( this.context.getName() );
+                    }
+
+                    op.add( ou );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addContainers name [" + ou.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteContainers() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Delcontainer delcontainer : delcontainers )
+        {
+            List<OrganizationalUnit> containers = delcontainer.getContainers();
+            for ( OrganizationalUnit ou : containers )
+            {
+                LOG.info( "deleteContainers name=" + ou.getName() );
+                try
+                {
+                    OrganizationalUnitP op = new OrganizationalUnitP();
+                    op.delete( ou );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deleteContainers name [" + ou.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addSuffixes() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addsuffix addsuffix : addsuffixes )
+        {
+            List<Suffix> suffixes = addsuffix.getSuffixes();
+
+            for ( Suffix suffix : suffixes )
+            {
+                LOG.info( "addSuffixes name=" + suffix.getName() + " description=" + suffix.getDescription() );
+                try
+                {
+                    SuffixP sp = new SuffixP();
+                    sp.add( suffix );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addSuffixes name [" + suffix.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteSuffixes() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Delsuffix delsuffix : delsuffixes )
+        {
+            List<Suffix> suffixes = delsuffix.getSuffixes();
+            for ( Suffix suffix : suffixes )
+            {
+                LOG.info( "deleteSuffixes name=" + suffix.getName() );
+                try
+                {
+                    SuffixP sp = new SuffixP();
+                    sp.delete( suffix );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deleteSuffixes name [" + suffix.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addOrgunits() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addorgunit addorgunit : addorgunits )
+        {
+            List<OrgUnitAnt> ous = addorgunit.getOrgUnits();
+            for ( OrgUnitAnt ou : ous )
+            {
+                LOG.info( "addOrgunits name=" + ou.getName() + " typeName=" + ou.getTypeName() + " description=" + ou
+                    .getDescription() );
+                try
+                {
+                    dAdminMgr.add( ou );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addOrgunits name [" + ou.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void delOrgunits() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Delorgunit delorgunit : delorgunits )
+        {
+            List<OrgUnitAnt> ous = delorgunit.getOrgUnits();
+            for ( OrgUnitAnt ou : ous )
+            {
+                LOG.info( "deleteOrgunits name=" + ou.getName() + " typeName=" + ou.getTypeName() );
+                try
+                {
+                    dAdminMgr.delete( ou );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deleteOrgunits name [" + ou.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addUserOrgunitInheritances() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Adduserorgunitinheritance adduserorgunitinheritance : adduserorgunitinheritances )
+        {
+            List<Relationship> orgs = adduserorgunitinheritance.getRelationships();
+            for ( Relationship relationship : orgs )
+            {
+                LOG.info( "addUserOrgunitInheritances parent=" + relationship.getParent() + " child=" + relationship
+                    .getChild() );
+                try
+                {
+                    dAdminMgr.addInheritance( new OrgUnit( relationship.getParent(), OrgUnit.Type.USER ),
+                        new OrgUnit( relationship.getChild(), OrgUnit.Type.USER ) );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addUserOrgunitInheritances parent [" + relationship.getParent() + "] child [" +
+                        relationship.getChild() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteUserOrgunitInheritances() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Deluserorgunitinheritance deluserorgunitinheritance : deluserorgunitinheritances )
+        {
+            List<Relationship> orgs = deluserorgunitinheritance.getRelationships();
+            for ( Relationship relationship : orgs )
+            {
+                LOG.info( "deleteUserOrgunitInheritances parent=" + relationship.getParent() + " child=" +
+                    relationship.getChild() );
+                try
+                {
+                    dAdminMgr.deleteInheritance( new OrgUnit( relationship.getParent(), OrgUnit.Type.USER ),
+                        new OrgUnit( relationship.getChild(), OrgUnit.Type.USER ) );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deleteUserOrgunitInheritances parent [" + relationship.getParent() + "] child [" +
+                        relationship.getChild() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addPermOrgunitInheritances() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addpermorgunitinheritance addpermorgunitinheritance : addpermorgunitinheritances )
+        {
+            List<Relationship> orgs = addpermorgunitinheritance.getRelationships();
+            for ( Relationship relationship : orgs )
+            {
+                LOG.info( "addPermOrgunitInheritances parent=" + relationship.getParent() + " child=" + relationship
+                    .getChild() );
+                try
+                {
+                    dAdminMgr.addInheritance( new OrgUnit( relationship.getParent(), OrgUnit.Type.PERM ),
+                        new OrgUnit( relationship.getChild(), OrgUnit.Type.PERM ) );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addPermOrgunitInheritances parent [" + relationship.getParent() + "] child [" +
+                        relationship.getChild() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deletePermOrgunitInheritances() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Delpermorgunitinheritance delpermorgunitinheritance : delpermorgunitinheritances )
+        {
+            List<Relationship> orgs = delpermorgunitinheritance.getRelationships();
+            for ( Relationship relationship : orgs )
+            {
+                LOG.info( "deletePermOrgunitInheritances parent=" + relationship.getParent() + " child=" +
+                    relationship.getChild() );
+                try
+                {
+                    dAdminMgr.deleteInheritance( new OrgUnit( relationship.getParent(), OrgUnit.Type.PERM ),
+                        new OrgUnit( relationship.getChild(), OrgUnit.Type.PERM ) );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deletePermOrgunitInheritances parent [" + relationship.getParent() + "] child [" +
+                        relationship.getChild() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addAdminRoles() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addadminrole addrole : addadminroles )
+        {
+            List<AdminRoleAnt> roles = addrole.getRoles();
+            for ( AdminRoleAnt role : roles )
+            {
+                LOG.info( "addAdminRoles name=" + role.getName() + " description=" + role.getDescription() );
+                try
+                {
+                    dAdminMgr.addRole( role );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addAdminRoles name [" + role.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteAdminRoles() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Deladminrole delrole : deladminroles )
+        {
+            List<AdminRoleAnt> roles = delrole.getRoles();
+            for ( AdminRoleAnt role : roles )
+            {
+                LOG.info( "deleteAdminRoles name=" + role.getName() );
+                try
+                {
+                    dAdminMgr.deleteRole( role );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deleteAdminRoles name [" + role.getName() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addAdminRoleInheritances() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Addadminroleinheritance addadminroleinheritance : addadminroleinheritances )
+        {
+            List<Relationship> roles = addadminroleinheritance.getRelationships();
+            for ( Relationship relationship : roles )
+            {
+                LOG.info( "addAdminRoleInheritances parent=" + relationship.getParent() + " child=" + relationship
+                    .getChild() );
+                try
+                {
+                    dAdminMgr.addInheritance( new AdminRole( relationship.getParent() ),
+                        new AdminRole( relationship.getChild() ) );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "addAdminRoleInheritances parent [" + relationship.getParent() + "] child [" +
+                        relationship.getChild() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteAdminRoleInheritances() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Deladminroleinheritance deladminroleinheritance : deladminroleinheritances )
+        {
+            List<Relationship> roles = deladminroleinheritance.getRelationships();
+            for ( Relationship relationship : roles )
+            {
+                LOG.info( "deleteAdminRoleInheritances parent=" + relationship.getParent() + " child=" + relationship
+                    .getChild() );
+                try
+                {
+                    dAdminMgr.deleteInheritance( new AdminRole( relationship.getParent() ),
+                        new AdminRole( relationship.getChild() ) );
+                }
+                catch ( SecurityException se )
+                {
+                    LOG.warn( "deleteAdminRoleInheritances parent [" + relationship.getParent() + "] child [" +
+                        relationship.getChild() + "] caught SecurityException=" + se );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addUserAdminRoles() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Adduseradminrole adduserrole : adduseradminroles )
+        {
+            List<UserAdminRole> userroles = adduserrole.getUserRoles();
+            for ( UserAdminRole userRole : userroles )
+            {
+                LOG.info( "addUserAdminRoles userid=" + userRole.getUserId() + " role name=" + userRole.getName() );
+                try
+                {
+                    //AdminRole role = new AdminRole(userRole);
+                    dAdminMgr.assignUser( userRole );
+                }
+                catch ( SecurityException se )
+                {
+                    String warning = "addUserAdminRoles userId [" + userRole.getUserId() + "] role name [" + userRole
+                        .getName() + "] caught SecurityException=" + se;
+                    LOG.warn( warning );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void delUserAdminRoles() throws BuildException
+    {
+        // Loop through the entityclass elements
+        for ( Deluseradminrole deluserrole : deluseradminroles )
+        {
+            List<UserAdminRole> userroles = deluserrole.getUserRoles();
+            for ( UserAdminRole userRole : userroles )
+            {
+                LOG.info( "delUserAdminRoles userid=" + userRole.getUserId() + " role name=" + userRole.getName() );
+                try
+                {
+                    dAdminMgr.deassignUser( userRole );
+                }
+                catch ( SecurityException se )
+                {
+                    String warning = "delUserAdminRoles userId [" + userRole.getUserId() + "] role name [" + userRole
+                        .getName() + "] caught SecurityException=" + se;
+                    LOG.warn( warning );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void addConfig() throws BuildException
+    {
+        Properties props = new Properties();
+        String configNodeName = "";
+        // Loop through the entityclass elements
+        for ( Addconfig addcfg : addconfig )
+        {
+            try
+            {
+                List<ConfigAnt> cfgs = addcfg.getConfig();
+                for ( ConfigAnt cfg : cfgs )
+                {
+                    LOG.info( "addConfig" );
+                    String val = cfg.getProps();
+                    int indx = val.indexOf( GlobalIds.PROP_SEP );
+                    if ( indx >= 1 )
+                    {
+                        String name = val.substring( 0, indx );
+                        String value = val.substring( indx + 1 );
+                        props.setProperty( name, value );
+                    }
+                }
+                configNodeName = props.getProperty( GlobalIds.CONFIG_REALM );
+                LOG.info( "addConfig realm name [" + configNodeName + "]" );
+                cfgMgr.add( configNodeName, props );
+            }
+            catch ( SecurityException se )
+            {
+                String msgHdr = "addConfig realm name [" + configNodeName + "]";
+                if ( se.getErrorId() == GlobalErrIds.FT_CONFIG_ALREADY_EXISTS )
+                {
+                    try
+                    {
+                        String warning = msgHdr + " entry already exists, attempt to update";
+                        LOG.info( warning );
+                        cfgMgr.update( configNodeName, props );
+                        LOG.info( msgHdr + " update [" + configNodeName + "] successful" );
+                    }
+                    catch ( SecurityException se2 )
+                    {
+                        String warning = msgHdr + " update failed SecurityException=" + se2;
+                        LOG.warn( warning );
+                    }
+                }
+                else
+                {
+                    String warning = msgHdr + " failed SecurityException=" + se;
+                    LOG.warn( warning );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @throws BuildException
+     */
+    private void deleteConfig() throws BuildException
+    {
+        Properties props = new Properties();
+        String configNodeName = "";
+        // Loop through the entityclass elements
+        for ( Delconfig delcfg : delconfig )
+        {
+            try
+            {
+                List<ConfigAnt> cfgs = delcfg.getConfig();
+                for ( ConfigAnt cfg : cfgs )
+                {
+                    String val = cfg.getProps();
+                    int indx = val.indexOf( GlobalIds.PROP_SEP );
+                    if ( indx >= 1 )
+                    {
+                        String name = val.substring( 0, indx );
+                        String value = val.substring( indx + 1 );
+                        props.setProperty( name, value );
+                    }
+                }
+                configNodeName = props.getProperty( GlobalIds.CONFIG_REALM );
+                LOG.info( "delConfig realm name [" + configNodeName + "]" );
+                props.remove( GlobalIds.CONFIG_REALM );
+                cfgMgr.delete( configNodeName, props );
+            }
+            catch ( SecurityException se )
+            {
+                String warning = "deleteConfig [" + configNodeName + "] caught SecurityException=" + se;
+                LOG.warn( warning );
+            }
+        }
+    }
+
+
+    public static Properties getProperties( String inputString )
+    {
+        Properties props = new Properties();
+        if ( inputString != null && inputString.length() > 0 )
+        {
+            StringTokenizer maxTkn = new StringTokenizer( inputString, SEMICOLON );
+            if ( maxTkn.countTokens() > 0 )
+            {
+                while ( maxTkn.hasMoreTokens() )
+                {
+                    String val = maxTkn.nextToken();
+                    int indx = val.indexOf( GlobalIds.PROP_SEP );
+                    if ( indx >= 1 )
+                    {
+                        String name = val.substring( 0, indx );
+                        String value = val.substring( indx + 1 );
+                        props.setProperty( name, value );
+                    }
+                }
+            }
+        }
+        return props;
+    }
+
+    public List<AddpermOp> getAddpermOps()
+    {
+        return addpermOps;
+    }
+
+    public List<AddpermObj> getAddpermObjs()
+    {
+        return addpermObjs;
+    }
+
+    public List<Adduser> getAddusers()
+    {
+        return addusers;
+    }
+
+    public List<Adduserrole> getAdduserroles()
+    {
+        return adduserroles;
+    }
+
+    public List<Addrole> getAddroles()
+    {
+        return addroles;
+    }
+
+    public List<Addsdset> getAddsdsets()
+    {
+        return addsdsets;
+    }
+
+    public List<Addroleinheritance> getAddroleinheritances()
+    {
+        return addroleinheritances;
+    }
+
+    public List<AddpermGrant> getAddpermGrants()
+    {
+        return addpermGrants;
+    }
+
+    public List<Addgroup> getAddgroups()
+    {
+        return addgroups;
+    }
+}
\ No newline at end of file


[47/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/CfgException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/CfgException.java b/src/main/java/org/apache/directory/fortress/core/CfgException.java
new file mode 100755
index 0000000..3f45dc3
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/CfgException.java
@@ -0,0 +1,53 @@
+/*
+ *   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;
+
+
+/**
+ * This exception extends {@link SecurityException} and is thrown when Fortress cannot find correct cfg for a particular entity.
+ * See the {@link GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+public class CfgException extends SecurityException
+{
+
+    /**
+     * Create an exception with an error code that maps to {@link GlobalErrIds} and message text.
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     */
+    public CfgException(int errorId, String msg)
+    {
+        super(errorId, msg);
+    }
+
+    /**
+     * Create exception with error id, message and related exception.
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     * @param previousException contains reference to related exception which usually is system related, i.e. ldap.
+     */
+    public CfgException(int errorId, String msg, Exception previousException)
+    {
+        super(errorId, msg, previousException);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/CfgRuntimeException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/CfgRuntimeException.java b/src/main/java/org/apache/directory/fortress/core/CfgRuntimeException.java
new file mode 100755
index 0000000..117d413
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/CfgRuntimeException.java
@@ -0,0 +1,66 @@
+/*
+ *   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;
+
+/**
+ * This exception extends {@link BaseRuntimeException} and is thrown when Fortress config startup failed.
+ * This is critical runtime exception and means system is inoperable due to a cfg error.
+ * See the {@link GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+public class CfgRuntimeException extends BaseRuntimeException
+{
+    private int subsystem;
+    private Exception exception;
+    private Object moreInfo;
+
+    /**
+     * Create exception with error id, message and related exception.
+     * @param errorId contains error code that is contained within {@link GlobalErrIds}
+     * @param newMsgText contains text related to the exception.
+     * @param newException contains related exception.
+     */
+    public CfgRuntimeException(int errorId, String newMsgText, Exception newException)
+    {
+        super(errorId, newMsgText, newException);
+        this.exception = newException;
+    }
+
+    /**
+     * Create exception with error id and message.
+     * @param errorId contains error code that is contained within {@link GlobalErrIds}
+     * @param newMsgText contains text related to the exception.
+     */
+    public CfgRuntimeException(int errorId, String newMsgText)
+    {
+        super(errorId, newMsgText);
+    }
+
+    /**
+     * Get the exception object.
+     *
+     * @return reference to Exception.
+     */
+    public Exception getException()
+    {
+        return exception;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/CreateException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/CreateException.java b/src/main/java/org/apache/directory/fortress/core/CreateException.java
new file mode 100755
index 0000000..3a8cadf
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/CreateException.java
@@ -0,0 +1,52 @@
+/*
+ *   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;
+
+
+/**
+ * This exception extends {@link SecurityException} and is thrown when DAO cannot create entity.
+ * See the {@link GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+public class CreateException extends SecurityException
+{
+    /**
+     * Create an exception with an error code that maps to {@link GlobalErrIds} and message text.
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     */
+    public CreateException(int errorId, String msg)
+    {
+        super(errorId, msg);
+    }
+
+    /**
+     * Create exception with error id, message and related exception.
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     * @param previousException contains reference to related exception which usually is system related, i.e. ldap.
+     */
+    public CreateException(int errorId, String msg, Exception previousException)
+    {
+        super(errorId, msg, previousException);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/DelAccessMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/DelAccessMgr.java b/src/main/java/org/apache/directory/fortress/core/DelAccessMgr.java
new file mode 100755
index 0000000..66910ba
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/DelAccessMgr.java
@@ -0,0 +1,192 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rbac.User;
+
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ * This interface prescribes the API for performing runtime delegated access control operations on objects that are provisioned Fortress ARBAC entities
+ * that reside in LDAP directory.
+ * These APIs map directly to similar named APIs specified by ARBAC02 functions.  The ARBAC Functional specification describes delegated administrative
+ * operations for the creation and maintenance of ARBAC element sets and relations.  Delegated administrative review functions for performing administrative queries
+ * and system functions for creating and managing ARBAC attributes on user sessions and making delegated administrative access control decisions.
+ * <h3>Administrative Role Based Access Control (ARBAC)</h3>
+ * <img src="./doc-files/ARbac.png">
+ * <p/>
+ * Fortress fully supports the Oh/Sandhu/Zhang ARBAC02 model for delegated administration.  ARBAC provides large enterprises the capability to delegate administrative authority to users that reside outside of the security admin group.
+ * Decentralizing administration helps because it provides security provisioning capability to work groups without sacrificing regulations for accountability or traceability.
+ * <p/>
+ * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.apache.directory.fortress.core.rbac.Session)}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public interface DelAccessMgr extends Manageable
+{
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized assignment control over
+     * User-Role Assignment (URA).  This adheres to the ARBAC02 functional specification for can-assign URA.
+     *
+     * @param session This object must be instantiated by calling {@link AccessMgr#createSession(org.apache.directory.fortress.core.rbac.User, boolean)} before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param user    Instantiated User entity requires only valid userId attribute set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws SecurityException
+     *          In the event of data validation error (i.e. invalid userId or role name) or system error.
+     */
+    public boolean canAssign(Session session, User user, Role role)
+        throws SecurityException;
+
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized revoke control over
+     * User-Role Assignment (URA).  This adheres to the ARBAC02 functional specification for can-revoke URA.
+     *
+     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.     * @param user    Instantiated User entity requires only valid userId attribute set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws SecurityException
+     *          In the event of data validation error (i.e. invalid userId or role name) or system error.
+     */
+    public boolean canDeassign(Session session, User user, Role role)
+        throws SecurityException;
+
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized assignment control over
+     * Permission-Role Assignment (PRA).  This adheres to the ARBAC02 functional specification for can-assign-p PRA.
+     *
+     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.     * @param perm    Instantiated Permission entity requires valid object name and operation name attributes set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws SecurityException
+     *          In the event of data validation error (i.e. invalid perm or role name) or system error.
+     */
+    public boolean canGrant(Session session, Role role, Permission perm)
+        throws SecurityException;
+
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized revoke control over
+     * Permission-Role Assignment (PRA).  This adheres to the ARBAC02 functional specification for can-revoke-p PRA.
+     *
+     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.     * @param perm    Instantiated Permission entity requires valid object name and operation name attributes set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws SecurityException In the event of data validation error (i.e. invalid perm or role name) or system error.
+     */
+    public boolean canRevoke(Session session, Role role, Permission perm)
+        throws SecurityException;
+
+    /**
+     * This function returns a Boolean value meaning whether the subject of a given session is
+     * allowed or not to perform a given operation on a given object. The function is valid if and
+     * only if the session is a valid Fortress session, the object is a member of the OBJS data set,
+     * and the operation is a member of the OPS data set. The session's subject has the permission
+     * to perform the operation on that object if and only if that permission is assigned to (at least)
+     * one of the session's active roles. This implementation will verify the roles or userId correspond
+     * to the subject's active roles are registered in the object's access control list.
+     *
+     * @param perm    object contains obj attribute which is a String and contains the name of the object user is trying to access;
+     *                perm object contains operation attribute which is also a String and contains the operation name for the object.
+     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return True of user has access, false otherwise.
+     * @throws SecurityException
+     *          is thrown if runtime error occurs with system.
+     */
+    public boolean checkAccess(Session session, Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * This function adds an adminRole as an active role of a session whose owner is a given user.
+     * <p>
+     * The function is valid if and only if:
+     * <ul>
+     * <li> the user is a member of the USERS data set
+     * <li> the role is a member of the ADMIN ROLES data set
+     * <li> the session is a valid Fortress session
+     * <li> the user is authorized to that admin role
+     * <li> the session is owned by that user.
+     * </ul>
+     * </p>
+     *
+     * @param session object contains the user's returned RBAC and ARBAC sessions from the createSession method.
+     * @param role    object contains the adminRole name to be activated into session.
+     * @throws SecurityException
+     *          is thrown if user is not allowed to activate or runtime error occurs with system.
+     */
+    public void addActiveRole(Session session, UserAdminRole role)
+        throws SecurityException;
+
+
+    /**
+     * This function deactivates adminRole from the active adminRole set of a session owned by a given user.
+     * The function is valid if and only if the user is a member of the USERS data set, the
+     * session object contains a valid Fortress session, the session is owned by the user,
+     * and the adminRole is an active adminRole of that session.
+     *
+     * @param session object contains the user's returned RBAC and ARBAC sessions from the createSession method.
+     * @param role    object contains the adminRole name to be deactivated.
+     * @throws SecurityException is thrown if user is not allowed to deactivate or runtime error occurs with system.
+     */
+    public void dropActiveRole(Session session, UserAdminRole role)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the active admin roles associated with a session. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned ARBAC session from the createSession method.
+     * @return List<UserAdminRole> containing all adminRoles active in user's session.  This will NOT contain inherited roles.
+     * @throws SecurityException
+     *          is thrown if session invalid or system. error.
+     */
+    public List<UserAdminRole> sessionAdminRoles(Session session)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the authorized admin roles associated with a session based on hierarchical relationships. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned ARBAC session from the createSession method.
+     * @return Set<String> containing all adminRoles authorized in user's session.  This will contain inherited roles.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    public Set<String> authorizedAdminRoles(Session session)
+        throws SecurityException;
+
+    /**
+     * This function returns the ARBAC (administrative) permissions of the session, i.e., the permissions assigned
+     * to its authorized admin roles. The function is valid if and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned ARBAC session from the createSession method.
+     * @return List<Permission> containing admin permissions (op, obj) active for user's session.
+     * @throws SecurityException in the event runtime error occurs with system.
+     */
+    public List<Permission> sessionPermissions(Session session)
+        throws SecurityException;
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/DelAccessMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/DelAccessMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/DelAccessMgrFactory.java
new file mode 100755
index 0000000..e355a67
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/DelAccessMgrFactory.java
@@ -0,0 +1,114 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.rbac.DelAccessMgrImpl;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rest.DelAccessMgrRestImpl;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Creates an instance of the DelAccessMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link DelAccessMgrImpl} but can be overridden by
+ * adding the {@link GlobalIds#DELEGATED_ACCESS_IMPLEMENTATION} config property.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class DelAccessMgrFactory
+{
+    private static String accessClassName = Config.getProperty(GlobalIds.DELEGATED_ACCESS_IMPLEMENTATION);
+    private static final String CLS_NM = DelAccessMgrFactory.class.getName();
+
+    /**
+     * Create and return a reference to {@link DelAccessMgr} object using HOME context.
+     *
+     * @return instance of {@link DelAccessMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelAccessMgr createInstance()
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME );
+    }
+
+
+    /**
+     * Create and return a reference to {@link DelAccessMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return instance of {@link DelAccessMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelAccessMgr createInstance(String contextId)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance");
+        if (!VUtil.isNotNullOrEmpty(accessClassName))
+        {
+            if(GlobalIds.IS_REST)
+            {
+                accessClassName = DelAccessMgrRestImpl.class.getName();
+            }
+            else
+            {
+                accessClassName = DelAccessMgrImpl.class.getName();
+            }
+        }
+
+        DelAccessMgr accessMgr = (DelAccessMgr) ClassUtil.createInstance(accessClassName);
+        accessMgr.setContextId(contextId);
+        return accessMgr;
+    }
+
+
+    /**
+     * Create and return a reference to {@link DelAccessMgr} object using HOME context.
+     *
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link DelAccessMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelAccessMgr createInstance(Session adminSess)
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME, adminSess );
+    }
+
+
+    /**
+     * Create and return a reference to {@link DelAccessMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link DelAccessMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelAccessMgr createInstance(String contextId, Session adminSess)
+        throws SecurityException
+    {
+        DelAccessMgr accessMgr = createInstance(contextId);
+        accessMgr.setAdmin(adminSess);
+        return accessMgr;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/DelAdminMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/DelAdminMgr.java b/src/main/java/org/apache/directory/fortress/core/DelAdminMgr.java
new file mode 100755
index 0000000..c236479
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/DelAdminMgr.java
@@ -0,0 +1,697 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.User;
+
+/**
+ * This class prescribes the ARBAC02 DelAdminMgr interface for performing policy administration of Fortress ARBAC entities
+ * that reside in LDAP directory.
+ * These APIs map directly to similar named APIs specified by ARBAC02 functions.  The ARBAC Functional specification describes delegated administrative
+ * operations for the creation and maintenance of ARBAC element sets and relations.  Delegated administrative review functions for performing administrative queries
+ * and system functions for creating and managing ARBAC attributes on user sessions and making delegated administrative access control decisions.
+ * <p/>
+ * <h3>Administrative Role Based Access Control (ARBAC)</h3>
+ * <img src="./doc-files/ARbac.png">
+ * <p/>
+ * Fortress fully supports the Oh/Sandhu/Zhang ARBAC02 model for delegated administration.  ARBAC provides large enterprises the capability to delegate administrative authority to users that reside outside of the security admin group.
+ * Decentralizing administration helps because it provides security provisioning capability to work groups without sacrificing regulations for accountability or traceability.
+ * <p/>
+ * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.apache.directory.fortress.core.rbac.Session)}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public interface DelAdminMgr extends Manageable
+{
+    /**
+     * This command creates a new admin role. The command is valid if and only if the new admin role is not
+     * already a member of the ADMIN ROLES data set. The ADMIN ROLES data set is updated.
+     * Initially, no user or permission is assigned to the new role.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains the name of the new AdminRole being targeted for addition to LDAP</li>
+     * </ul>
+     * <p/>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#description} - contains any safe text</li>
+     * <li>{@link AdminRole#osPs} * - multi-occurring attribute used to set associations to existing PERMS OrgUnits</li>
+     * <li>{@link AdminRole#osUs} * - multi-occurring attribute used to set associations to existing USERS OrgUnits</li>
+     * <li>{@link AdminRole#beginRange} - contains the name of an existing RBAC Role that represents the lowest role in hierarchy that administrator (whoever has this AdminRole activated) controls</li>
+     * <li>{@link AdminRole#endRange} - contains the name of an existing RBAC Role that represents that highest role in hierarchy that administrator may control</li>
+     * <li>{@link AdminRole#beginInclusive} - if 'true' the RBAC Role specified in beginRange is also controlled by the posessor of this AdminRole</li>
+     * <li>{@link AdminRole#endInclusive} - if 'true' the RBAC Role specified in endRange is also controlled by the administratrator</li>
+     * <li>{@link AdminRole#beginTime} - HHMM - determines begin hour adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link AdminRole#endTime} - HHMM - determines end hour adminRole may be activated into user's ARBAC session.</li>
+     * <li>{@link AdminRole#beginDate} - YYYYMMDD - determines date when adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link AdminRole#endDate} - YYYYMMDD - indicates latest date adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's ARBAC session</li>
+     * </ul>
+     *
+     * @param role Contains role name and description.
+     * @return AdminRole contains reference to entity added.
+     * @throws SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    public AdminRole addRole(AdminRole role)
+        throws SecurityException;
+
+
+    /**
+     * This command deletes an existing admin role from the ARBAC database. The command is valid
+     * if and only if the role to be deleted is a member of the ADMIN ROLES data set.  This command will
+     * also deassign role from all users.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains the name of the new AdminRole being targeted for removal</li>
+     * </ul>
+     * <p/>
+     *
+     * @param role Contains role name.
+     * @throws SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    public void deleteRole(AdminRole role)
+        throws SecurityException;
+
+
+    /**
+     * Method will update an AdminRole entity in the directory.  The role must exist in directory prior to this call.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains the name of the new AdminRole being targeted for updating</li>
+     * </ul>
+     * <p/>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#description} - contains any safe text</li>
+     * <li>{@link AdminRole#osPs} * - multi-occurring attribute used to set associations to existing PERMS OrgUnits</li>
+     * <li>{@link AdminRole#osUs} * - multi-occurring attribute used to set associations to existing USERS OrgUnits</li>
+     * <li>{@link AdminRole#beginRange} - contains the name of an existing RBAC Role that represents the lowest role in hierarchy that administrator (whoever has this AdminRole activated) controls</li>
+     * <li>{@link AdminRole#endRange} - contains the name of an existing RBAC Role that represents that highest role in hierarchy that administrator may control</li>
+     * <li>{@link AdminRole#beginInclusive} - if 'true' the RBAC Role specified in beginRange is also controlled by the posessor of this AdminRole</li>
+     * <li>{@link AdminRole#endInclusive} - if 'true' the RBAC Role specified in endRange is also controlled by the administratrator</li>
+     * <li>{@link AdminRole#beginTime} - HHMM - determines begin hour adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link AdminRole#endTime} - HHMM - determines end hour adminRole may be activated into user's ARBAC session.</li>
+     * <li>{@link AdminRole#beginDate} - YYYYMMDD - determines date when adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link AdminRole#endDate} - YYYYMMDD - indicates latest date adminRole may be activated into user's ARBAC session</li>
+     * <li>{@link AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's ARBAC session</li>
+     * </ul>
+     *
+     * @param role Contains role name and new description.
+     * @return AdminRole contains reference to entity operated on.
+     * @throws SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    public AdminRole updateRole(AdminRole role)
+        throws SecurityException;
+
+
+    /**
+     * 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>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserAdminRole#name} - contains the name for already existing AdminRole to be assigned</li>
+     * <li>{@link UserAdminRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAdminRole#beginTime} - HHMM - determines begin hour AdminRole may be activated into user's RBAC session</li>
+     * <li>{@link UserAdminRole#endTime} - HHMM - determines end hour AdminRole may be activated into user's RBAC session.</li>
+     * <li>{@link UserAdminRole#beginDate} - YYYYMMDD - determines date when AdminRole may be activated into user's RBAC session</li>
+     * <li>{@link UserAdminRole#endDate} - YYYYMMDD - indicates latest date AdminRole may be activated into user's RBAC session</li>
+     * <li>{@link UserAdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link UserAdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link UserAdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's ARBAC session</li>
+     * </ul>
+     *
+     * @param uAdminRole entity contains {@link org.apache.directory.fortress.core.rbac.User#userId} and {@link org.apache.directory.fortress.core.rbac.AdminRole#name} and optional {@code Constraints}..
+     * @throws SecurityException
+     *          in the event data error in user or role objects or system error.
+     */
+    public void assignUser(UserAdminRole uAdminRole)
+        throws SecurityException;
+
+
+    /**
+     * 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.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#name} - contains the name for already existing AdminRole to be deassigned</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     *
+     * @param uAdminRole entity contains {@link org.apache.directory.fortress.core.rbac.User#userId} and {@link org.apache.directory.fortress.core.rbac.AdminRole#name}.
+     * @throws SecurityException - in the event data error in user or role objects or system error.
+     */
+    public void deassignUser(UserAdminRole uAdminRole)
+        throws SecurityException;
+
+    /**
+     * Commands adds a new OrgUnit entity to OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new USERS or PERMS OrgUnit to be added</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit contains reference to entity added.
+     * @throws SecurityException
+     *          in the event of data validation or system error.
+     */
+    public OrgUnit add(OrgUnit entity)
+        throws SecurityException;
+
+    /**
+     * Commands updates existing OrgUnit entity to OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new USERS or PERMS OrgUnit to be updated</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit contains reference to entity operated on.
+     * @throws SecurityException
+     *          in the event of data validation or system error.
+     */
+    public OrgUnit update(OrgUnit entity)
+        throws SecurityException;
+
+    /**
+     * Commands deletes existing OrgUnit entity to OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new USERS or PERMS OrgUnit to be removed</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit contains reference to entity operated on.
+     * @throws SecurityException
+     *          in the event of data validation or system error.
+     */
+    public OrgUnit delete(OrgUnit entity)
+        throws SecurityException;
+
+
+    /**
+     * This command creates a new orgunit child, and inserts it in the orgunit hierarchy as an immediate descendant of
+     * the existing orgunit parent.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The child orgunit is not a member of the ORGUNITS data set.
+     * <li> The parent orgunit is a member of the ORGUNITS data set.
+     * </ul>
+     * </p>
+     * <p> This method:
+     * <ul>
+     * <li> Adds new orgunit.
+     * <li> Assigns orgunit relationship between new child and pre-existing parent.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new OrgUnit to be child</li>
+     * </ul>
+     * <h4>optional parameters child</h4>
+     * <ul>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.OrgUnit#description} - maps to description attribute on organizationalUnit object class for new child</li>
+     * </ul>
+     *
+     * @param parent This entity must be present in ORGUNIT data set.  Success will add rel with child.
+     * @param child  This entity must not be present in ORGUNIT data set.  Success will add the new entity to ORGUNIT data set.
+     * @throws SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    public void addDescendant(OrgUnit parent, OrgUnit child)
+        throws SecurityException;
+
+
+    /**
+     * This command creates a new orgunit parent, and inserts it in the orgunit hierarchy as an immediate ascendant of
+     * the existing child orgunit.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The parent is not a member of the ORGUNITS data set.
+     * <li> The child is a member of the ORGUNITS data set.
+     * </ul>
+     * </p>
+     * <p> This method:
+     * <ul>
+     * <li> Adds new orgunit.
+     * <li> Assigns orgunit relationship between new parent and pre-existing child.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>child - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be parent</li>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of new OrgUnit to be child</li>
+     * </ul>
+     * <h4>optional parameters child</h4>
+     * <ul>
+     * <li>parent - {@link OrgUnit#description} - maps to description attribute on organizationalUnit object class for new child</li>
+     * </ul>
+     *
+     * @param parent completion of op assigns new child relationship with child orgunit.
+     * @param child  completion of op assigns new parent relationship with parent orgunit.
+     * @throws SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    public void addAscendant(OrgUnit child, OrgUnit parent)
+        throws SecurityException;
+
+
+    /**
+     * This command establishes a new immediate inheritance relationship with parent orgunit <<-- child orgunit
+     * <p/>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The parent and child are members of the ORGUNITS data set.
+     * <li> The parent is not an immediate ascendant of child.
+     * <li> The child does not properly inherit parent (in order to avoid cycle creation).
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be parent</li>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>child - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to be child</li>
+     * </ul>
+     *
+     * @param parent completion of op deassigns child relationship with child orgunit.
+     * @param child  completion of op deassigns parent relationship with parent orgunit.
+     * @throws SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    public void addInheritance(OrgUnit parent, OrgUnit child)
+        throws SecurityException;
+
+
+    /**
+     * This command deletes an existing immediate inheritance relationship parent <<-- child.
+     * <p/>
+     * The command is valid if and only if:
+     * <ul>
+     * <li> The orgunits parent and child are members of the ORGUNITS data set.
+     * <li> The parent is an immediate ascendant of child.
+     * <li> The new inheritance relation is computed as the reflexive-transitive closure of the immediate inheritance
+     * relation resulted after deleting the relationship parent <<-- child.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to remove as parent</li>
+     * <li>parent - {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OrgUnit targeted: {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>child - {@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name of existing OrgUnit to remove as child</li>
+     * </ul>
+     *
+     * @param parent completion of op removes child relationship with childRole.
+     * @param child  completion of op removes parent relationship with parentRole.
+     * @throws SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    public void deleteInheritance(OrgUnit parent, OrgUnit child)
+        throws SecurityException;
+
+
+    /**
+     * This command creates a new role childRole, and inserts it in the role hierarchy as an immediate descendant of
+     * the existing role parentRole. The command is valid if and only if childRole is not a member of the ADMINROLES data set,
+     * and parentRole is a member of the ADMINROLES data set.
+     * <p/>
+     * This method:
+     * 1 - Adds new role.
+     * 2 - Assigns role relationship between new childRole and pre-existing parentRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing Role to be parent</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of new Role to be child</li>
+     * </ul>
+     * <h4>optional parameters childRole</h4>
+     * <ul>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#description} - maps to description attribute on organizationalRole object class for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginTime} - HHMM - determines begin hour role may be activated into user's session for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endTime} - HHMM - determines end hour role may be activated into user's session for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginDate} - YYYYMMDD - determines date when role may be activated into user's session for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endDate} - YYYYMMDD - indicates latest date role may be activated into user's session for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new child</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's session for new child</li>
+     * </ul>
+     *
+     * @param parentRole This entity must be present in ADMINROLES data set.  Success will add role rel with childRole.
+     * @param childRole  This entity must not be present in ADMINROLES data set.  Success will add the new role entity to ADMINROLES data set.
+     * @throws SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    public void addDescendant(AdminRole parentRole, AdminRole childRole)
+        throws SecurityException;
+
+    /**
+     * This command creates a new role parentRole, and inserts it in the role hierarchy as an immediate ascendant of
+     * the existing role childRole. The command is valid if and only if parentRole is not a member of the ADMINROLES data set,
+     * and childRole is a member of the ADMINROLES data set.
+     * This method:
+     * 1 - Adds new role.
+     * 2 - Assigns role relationship between new parentRole and pre-existing childRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing Role to be child</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of new Role to be added as parent</li>
+     * </ul>
+     * <h4>optional parameters parentRole</h4>
+     * <ul>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#description} - maps to description attribute on organizationalRole object class for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginTime} - HHMM - determines begin hour role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endTime} - HHMM - determines end hour role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginDate} - YYYYMMDD - determines date when role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endDate} - YYYYMMDD - indicates latest date role may be activated into user's session for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new parent</li>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's session for new parent</li>
+     * </ul>
+     *
+     * @param parentRole completion of op assigns new child relationship with childRole.
+     * @param childRole  completion of op assigns new parent relationship with parentRole.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    public void addAscendant(AdminRole childRole, AdminRole parentRole)
+        throws SecurityException;
+
+    /**
+     * This command establishes a new immediate inheritance relationship parentRole <<-- childRole between existing
+     * roles parentRole, childRole. The command is valid if and only if parentRole and childRole are members of the ADMINROLES data
+     * set, parentRole is not an immediate ascendant of childRole, and childRole does not properly inherit parentRole (in order to
+     * avoid cycle creation).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing AdminRole to be parent</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing AdminRole to be child</li>
+     * </ul>
+     *
+     * @param parentRole completion of op deassigns child relationship with childRole.
+     * @param childRole  completion of op deassigns parent relationship with parentRole.
+     * @throws SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    public void addInheritance(AdminRole parentRole, AdminRole childRole)
+        throws SecurityException;
+
+    /**
+     * This command deletes an existing immediate inheritance relationship parentRole <<-- childRole. The command is
+     * valid if and only if the roles parentRole and childRole are members of the ADMINROLES data set, and parentRole is an
+     * immediate ascendant of childRole. The new inheritance relation is computed as the reflexive-transitive
+     * closure of the immediate inheritance relation resulted after deleting the relationship parentRole <<-- childRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing AdminRole to remove as parent</li>
+     * <li>childRole - {@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the name of existing AdminRole to remove as child</li>
+     * </ul>
+     *
+     * @param parentRole completion of op removes child relationship with childRole.
+     * @param childRole  completion of op removes parent relationship with parentRole.
+     * @throws SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    public void deleteInheritance(AdminRole parentRole, AdminRole childRole)
+        throws SecurityException;
+
+
+    /**
+     * This method will add an administrative permission operation to an existing permission object which resides under {@code ou=AdminPerms,ou=ARBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may have {@link org.apache.directory.fortress.core.rbac.AdminRole} or {@link org.apache.directory.fortress.core.rbac.User} associations.  The target {@link org.apache.directory.fortress.core.rbac.Permission} must not exist prior to calling.
+     * A Fortress Permission instance exists in a hierarchical, one-many relationship between its parent and itself as stored in ldap tree: ({@link org.apache.directory.fortress.core.rbac.PermObj}*->{@link org.apache.directory.fortress.core.rbac.Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the name of existing object being targeted for the permission add</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the name of new permission operation being added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
+     * <li>{@link Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
+     * <li>{@link Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link Permission#opName}, that identifies target along with optional other attributes..
+     * @return copy of Permission entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    public Permission addPermission(Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * This method will update administrative permission operation pre-existing in target directory under {@code ou=AdminPerms,ou=ARBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may also contain {@link org.apache.directory.fortress.core.rbac.AdminRole} or {@link org.apache.directory.fortress.core.rbac.User} associations to add or remove using this function.
+     * The perm operation must exist before making this call.  Only non-null attributes will be updated.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the name of existing object being targeted for the permission update</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the name of existing permission operation being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target and any optional data to update.  Null or empty attributes will be ignored.
+     * @return copy of Permission entity.
+     * @throws SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    public Permission updatePermission(Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * This method will remove administrative permission operation entity from permission object. A Fortress permission is (object->operation).
+     * The perm operation must exist before making this call.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the name of existing object being targeted for the permission delete</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the name of existing permission operation being removed</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target.
+     * @throws SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    public void deletePermission(Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * This method will add administrative permission object to admin perms container in directory. The perm object must not exist before making this call.
+     * A {@link org.apache.directory.fortress.core.rbac.PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link org.apache.directory.fortress.core.rbac.PermObj}*->{@link org.apache.directory.fortress.core.rbac.Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#objName} - contains the name of new object being added</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#description} - any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#type} - contains any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link org.apache.directory.fortress.core.rbac.PermObj#objName} and {@link org.apache.directory.fortress.core.rbac.PermObj#ou}.  The other attributes are optional.
+     * @return copy of PermObj entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    public PermObj addPermObj(PermObj pObj)
+        throws SecurityException;
+
+
+    /**
+     * This method will update administrative permission object in perms container in directory.  The perm object must exist before making this call.
+     * A {@link org.apache.directory.fortress.core.rbac.PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link org.apache.directory.fortress.core.rbac.PermObj}*->{@link org.apache.directory.fortress.core.rbac.Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#objName} - contains the name of existing object being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#description} - any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#type} - contains any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link org.apache.directory.fortress.core.rbac.PermObj#objName}. Only non-null attributes will be updated.
+     * @return copy of newly updated PermObj entity.
+     * @throws SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    public PermObj updatePermObj(PermObj pObj)
+        throws SecurityException;
+
+
+    /**
+     * This method will remove administrative permission object from perms container in directory.  This method will also remove
+     * in associated permission objects that are attached to this object.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#objName} - contains the name of existing object targeted for removal</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link org.apache.directory.fortress.core.rbac.PermObj#objName} of object targeted for removal.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    public void deletePermObj(PermObj pObj)
+        throws SecurityException;
+
+
+    /**
+     * This command grants an AdminRole the administrative permission to perform an operation on an object to a role.
+     * The command is implemented by granting administrative permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * and the adminRole is a member of the ADMIN_ROLES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the object name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the operation name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the adminRole name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target.
+     * @param role must contains {@link org.apache.directory.fortress.core.rbac.AdminRole#name}.
+     * @throws SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    public void grantPermission(Permission perm, AdminRole role)
+        throws SecurityException;
+
+
+    /**
+     * This command revokes the administrative permission to perform an operation on an object from the set
+     * of permissions assigned to an AdminRole. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * the role is a member of the ADMIN_ROLES data set, and the permission is assigned to that AdminRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the object name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the operation name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole#name} - contains the adminRole name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target.
+     * @param role must contains {@link org.apache.directory.fortress.core.rbac.AdminRole#name}.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    public void revokePermission(Permission perm, AdminRole role)
+        throws SecurityException;
+
+
+    /**
+     * This command grants a user the administrative permission to perform an operation on an object to a user.
+     * The command is implemented by granting administrative permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents an administrative permission,
+     * and the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the object name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the operation name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target.
+     * @param user must contain {@link org.apache.directory.fortress.core.rbac.User#userId} of target User entity.
+     * @throws SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    public void grantPermission(Permission perm, User user)
+        throws SecurityException;
+
+
+    /**
+     * This command revokes the administrative permission to perform an operation on an object from the set
+     * of permissions assigned to a user. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents an administrative permission,
+     * the user is a member of the USERS data set, and the permission is assigned to that user.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the object name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the operation name</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target.
+     * @param user must contain {@link org.apache.directory.fortress.core.rbac.User#userId} of target User entity.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    public void revokePermission(Permission perm, User user)
+        throws SecurityException;
+
+}
\ 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/DelAdminMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/DelAdminMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/DelAdminMgrFactory.java
new file mode 100755
index 0000000..649cc47
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/DelAdminMgrFactory.java
@@ -0,0 +1,112 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.rbac.DelAdminMgrImpl;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rest.DelAdminMgrRestImpl;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Creates an instance of the DelAdminMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link DelAdminMgrImpl} but can be overridden by
+ * adding the {@link GlobalIds#DELEGATED_ADMIN_IMPLEMENTATION} config property.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class DelAdminMgrFactory
+{
+    private static String dAdminClassName = Config.getProperty(GlobalIds.DELEGATED_ADMIN_IMPLEMENTATION);
+    private static final String CLS_NM = DelAdminMgrFactory.class.getName();
+
+    /**
+     * Create and return a reference to {@link DelAdminMgr} object using HOME context.
+     *
+     * @return instance of {@link DelAdminMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelAdminMgr createInstance()
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME );
+    }
+
+    /**
+     * Create and return a reference to {@link DelAdminMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return instance of {@link DelAdminMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelAdminMgr createInstance(String contextId)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance");
+        if (!VUtil.isNotNullOrEmpty(dAdminClassName))
+        {
+            if(GlobalIds.IS_REST)
+            {
+                dAdminClassName = DelAdminMgrRestImpl.class.getName();
+            }
+            else
+            {
+                dAdminClassName = DelAdminMgrImpl.class.getName();
+            }
+        }
+
+        DelAdminMgr delAdminMgr = (DelAdminMgr) ClassUtil.createInstance(dAdminClassName);
+        delAdminMgr.setContextId(contextId);
+        return delAdminMgr;
+    }
+
+    /**
+     * Create and return a reference to {@link DelAdminMgr} object using HOME context.
+     *
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link DelAdminMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelAdminMgr createInstance(Session adminSess)
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME, adminSess );
+    }
+
+    /**
+     * Create and return a reference to {@link DelAdminMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link DelAdminMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelAdminMgr createInstance(String contextId, Session adminSess)
+        throws SecurityException
+    {
+        DelAdminMgr delAdminMgr = createInstance(contextId);
+        delAdminMgr.setAdmin(adminSess);
+        return delAdminMgr;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/DelReviewMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/DelReviewMgr.java b/src/main/java/org/apache/directory/fortress/core/DelReviewMgr.java
new file mode 100755
index 0000000..153917f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/DelReviewMgr.java
@@ -0,0 +1,146 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+import org.apache.directory.fortress.core.rbac.User;
+
+import java.util.List;
+
+/**
+ * This class prescribes the ARBAC02 DelReviewMgr interface for performing policy interrogation of provisioned Fortress ARBAC entities
+ * that reside in LDAP directory.
+ * These APIs map directly to similar named APIs specified by ARBAC02 functions.  The ARBAC Functional specification describes delegated administrative
+ * operations for the creation and maintenance of ARBAC element sets and relations.  Delegated administrative review functions for performing administrative queries
+ * and system functions for creating and managing ARBAC attributes on user sessions and making delegated administrative access control decisions.
+ * <h3>Administrative Role Based Access Control (ARBAC)</h3>
+ * <img src="./doc-files/ARbac.png">
+ * <p/>
+ * Fortress fully supports the Oh/Sandhu/Zhang ARBAC02 model for delegated administration.  ARBAC provides large enterprises the capability to delegate administrative authority to users that reside outside of the security admin group.
+ * Decentralizing administration helps because it provides security provisioning capability to work groups without sacrificing regulations for accountability or traceability.
+ * <p/>
+ * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.apache.directory.fortress.core.rbac.Session)}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public interface DelReviewMgr extends Manageable
+{
+    /**
+     * Method reads Admin Role entity from the admin role container in directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains the name of the AdminRole being targeted for read</li>
+     * </ul>
+     *
+     * @param role contains role name to be read.
+     * @return AdminRole entity that corresponds with role name.
+     * @throws SecurityException
+     *          will be thrown if role not found or system error occurs.
+     */
+    public AdminRole readRole(AdminRole role)
+        throws SecurityException;
+
+
+    /**
+     * Method will return a list of type Admin Role.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains all or some chars in the name of AdminRole(s) targeted for search</li>
+     * </ul>
+     *
+     * @param searchVal contains the all or some of the chars corresponding to admin role entities stored in directory.
+     * @return List of type AdminRole containing role entities that match the search criteria.
+     * @throws SecurityException
+     *          in the event of system error.
+     */
+    public List<AdminRole> findRoles(String searchVal)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the set of admin roles assigned to a given user. The function is valid if and
+     * only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains userId matching user entity stored in the directory.
+     * @return List of type UserAdminRole containing the user admin role data.
+     * @throws SecurityException
+     *          If user not found or system error occurs.
+     */
+    public List<UserAdminRole> assignedRoles(User user)
+        throws SecurityException;
+
+    /**
+     * This method returns the data set of all users who are assigned the given admin role.  This searches the User data set for
+     * AdminRole relationship.  This method does NOT search for hierarchical Admin Roles relationships.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link AdminRole#name} - contains the name of AdminRole targeted for search</li>
+     * </ul>
+     *
+     * @param role contains the role name used to search the User data set.
+     * @return List of type User containing the users assigned data.
+     * @throws SecurityException
+     *          If system error occurs.
+     */
+    public List<User> assignedUsers(AdminRole role)
+        throws SecurityException;
+
+
+    /**
+     * Commands reads existing OrgUnit entity from OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type attribute.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains the name associated with the OrgUnit object targeted for search.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * </ul>
+     *
+     * @param entity contains OrgUnit name and type.
+     * @return OrgUnit entity that corresponds with ou name and type.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public OrgUnit read(OrgUnit entity)
+        throws SecurityException;
+
+    /**
+     * Commands searches existing OrgUnit entities from OrgUnit dataset.  The OrgUnit can be either User or Perm and is
+     * set by setting type parameter on API.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#type} - contains the type of OU:  {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} or {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}</li>
+     * <li>searchVal - contains some or all of the chars associated with the OrgUnit objects targeted for search.</li>
+     * </ul>
+     *
+     * @param type      either PERM or USER
+     * @param searchVal contains the leading chars that map to {@link OrgUnit#name} on existing OrgUnit(s) targeted for search.
+     * @return List of type OrgUnit containing the OrgUnit data.
+     * @throws SecurityException
+     *
+     */
+    public List<OrgUnit> search(OrgUnit.Type type, String searchVal)
+        throws SecurityException;
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/DelReviewMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/DelReviewMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/DelReviewMgrFactory.java
new file mode 100755
index 0000000..b751a90
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/DelReviewMgrFactory.java
@@ -0,0 +1,112 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.rbac.DelReviewMgrImpl;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rest.DelReviewMgrRestImpl;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Creates an instance of the DelReviewMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link DelReviewMgrImpl} but can be overridden by
+ * adding the {@link GlobalIds#DELEGATED_REVIEW_IMPLEMENTATION} config property.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class DelReviewMgrFactory
+{
+    private static String dReviewClassName = Config.getProperty(GlobalIds.DELEGATED_REVIEW_IMPLEMENTATION);
+    private static final String CLS_NM = DelReviewMgrFactory.class.getName();
+
+    /**
+     * Create and return a reference to {@link DelReviewMgr} object using HOME context.
+     *
+     * @return instance of {@link DelReviewMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelReviewMgr createInstance()
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME );
+    }
+
+    /**
+     * Create and return a reference to {@link DelReviewMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return instance of {@link DelReviewMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelReviewMgr createInstance(String contextId)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance");
+        if (!VUtil.isNotNullOrEmpty(dReviewClassName))
+        {
+            if(GlobalIds.IS_REST)
+            {
+                dReviewClassName = DelReviewMgrRestImpl.class.getName();
+            }
+            else
+            {
+                dReviewClassName = DelReviewMgrImpl.class.getName();
+            }
+        }
+
+        DelReviewMgr delReviewMgr = (DelReviewMgr) ClassUtil.createInstance(dReviewClassName);
+        delReviewMgr.setContextId(contextId);
+        return delReviewMgr;
+    }
+
+    /**
+     * Create and return a reference to {@link DelReviewMgr} object using HOME context.
+     *
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link DelReviewMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelReviewMgr createInstance(Session adminSess)
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME, adminSess );
+    }
+
+    /**
+     * Create and return a reference to {@link DelReviewMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link DelReviewMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static DelReviewMgr createInstance(String contextId, Session adminSess)
+        throws SecurityException
+    {
+        DelReviewMgr delReviewMgr = createInstance(contextId);
+        delReviewMgr.setAdmin(adminSess);
+        return delReviewMgr;
+    }
+}
+


[15/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/RoleDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/RoleDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/RoleDAO.java
new file mode 100755
index 0000000..6aa4900
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/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.dao.apache;
+
+
+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
+ */
+public final class RoleDAO extends ApacheDsDataProvider implements org.apache.directory.fortress.core.rbac.dao.RoleDAO
+{
+    /*
+      *  *************************************************************************
+      *  **  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
+     */
+    public 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
+     *
+     */
+    public 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
+     */
+    public 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
+     *
+     */
+    public 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
+     *
+     */
+    public 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
+     */
+    public 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
+     *
+     */
+    public 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
+     *
+     */
+    public 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
+     *
+     */
+    public 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
+     */
+    public 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
+     */
+    public 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/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/SdDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/SdDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/SdDAO.java
new file mode 100755
index 0000000..f4d25b6
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/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.dao.apache;
+
+
+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
+ */
+public final class SdDAO extends ApacheDsDataProvider implements org.apache.directory.fortress.core.rbac.dao.SdDAO
+{
+    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
+     */
+    public 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
+     */
+    public 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
+     */
+    public 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
+     */
+    public 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
+     */
+    public 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
+     */
+    public 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
+     */
+    public 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 );
+    }
+}


[05/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rest/FortResponse.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/FortResponse.java b/src/main/java/org/apache/directory/fortress/core/rest/FortResponse.java
new file mode 100755
index 0000000..2acc385
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/FortResponse.java
@@ -0,0 +1,146 @@
+/*
+ *   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.rest;
+
+import org.apache.directory.fortress.core.rbac.FortEntity;
+import org.apache.directory.fortress.core.rbac.Session;
+
+import javax.xml.bind.annotation.*;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is used to return response data from En Masse server.
+ * </p>
+ * This class is not thread safe.
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "FortResponse")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "fortResponse", propOrder =
+{
+    "errorCode",
+    "errorMessage",
+    "entity",
+    "entities",
+    "values",
+    "valueSet",
+    "isAuthorized",
+    "session"
+})
+public class FortResponse
+{
+    private int errorCode;
+    @XmlElement(nillable = true)
+    private Boolean isAuthorized;
+    private String errorMessage;
+    @XmlElement(nillable = true)
+    private FortEntity entity;
+    @XmlElement(nillable = true)
+    private List<FortEntity> entities;
+    @XmlElement(nillable = true)
+    private List<String> values;
+    @XmlElement(nillable = true)
+    private Set<String> valueSet;
+    @XmlElement(nillable = true)
+    private Session session;
+
+    public FortEntity getEntity()
+    {
+        return entity;
+    }
+
+    public void setEntity(FortEntity entity)
+    {
+        this.entity = entity;
+    }
+
+    public String getErrorMessage()
+    {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage)
+    {
+        this.errorMessage = errorMessage;
+    }
+
+    public int getErrorCode()
+    {
+        return errorCode;
+    }
+
+    public Boolean getAuthorized()
+    {
+        return isAuthorized;
+    }
+
+    public void setAuthorized(Boolean authorized)
+    {
+        isAuthorized = authorized;
+    }
+
+    public void setErrorCode(int errorCode)
+    {
+        this.errorCode = errorCode;
+    }
+
+    public <T extends FortEntity> List<T> getEntities()
+    {
+        return (List<T>)entities;
+    }
+
+    public <T extends FortEntity> void setEntities(List<T> entities)
+    {
+        this.entities = (List<FortEntity>)entities;
+    }
+
+    public List<String> getValues()
+    {
+        return values;
+    }
+
+    public void setValues(List<String> values)
+    {
+        this.values = values;
+    }
+
+    public Set<String> getValueSet()
+    {
+        return valueSet;
+    }
+
+    public void setValueSet(Set<String> valueSet)
+    {
+        this.valueSet = valueSet;
+    }
+
+    public Session getSession()
+    {
+        return session;
+    }
+
+    public void setSession(Session session)
+    {
+        this.session = session;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rest/HttpIds.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/HttpIds.java b/src/main/java/org/apache/directory/fortress/core/rest/HttpIds.java
new file mode 100644
index 0000000..97a4c99
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/HttpIds.java
@@ -0,0 +1,156 @@
+/*
+ *   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.rest;
+
+/**
+ * Contains global HttpIds that map to the Fortress REST server EnMasse.
+ *
+ * @author Shawn McKinney
+ */
+public class HttpIds
+{
+    public static final String RBAC_AUTHN = "rbacAuthN";
+    public static final String RBAC_CREATE = "rbacCreate";
+    public static final String RBAC_CREATE_TRUSTED = "rbacCreateT";
+    public static final String RBAC_AUTHZ = "rbacAuthZ";
+    public static final String RBAC_PERMS = "rbacPerms";
+    public static final String RBAC_ROLES = "rbacRoles";
+    public static final String RBAC_AUTHZ_ROLES = "rbacAuthzRoles";
+    public static final String RBAC_ADD = "rbacAdd";
+    public static final String RBAC_DROP = "rbacDrop";
+    public static final String RBAC_USERID = "rbacUserId";
+    public static final String RBAC_USER = "rbacUser";
+    public static final String USER_READ = "userRead";
+    public static final String USER_UPDATE = "userUpdate";
+    public static final String USER_CHGPW = "userChange";
+    public static final String USER_LOCK = "userLock";
+    public static final String USER_UNLOCK = "userUnlock";
+    public static final String USER_RESET = "userReset";
+    public static final String USER_ADD = "userAdd";
+    public static final String USER_DELETE = "userDelete";
+    public static final String USER_DISABLE = "userDisable";
+    public static final String USER_SEARCH = "userSearch";
+    public static final String USER_PERMS = "userPerms";
+    public static final String USER_GRANT = "userGrant";
+    public static final String USER_REVOKE = "userRevoke";
+    public static final String USER_ASGNED = "userAsigned";
+    public static final String USER_AUTHZED = "userAuthzed";
+    public static final String USER_ASGNED_ADMIN = "userAsignedAdmin";
+    public static final String ROLE_READ = "roleRead";
+    public static final String ROLE_UPDATE = "roleUpdate";
+    public static final String ROLE_ADD = "roleAdd";
+    public static final String ROLE_DELETE = "roleDelete";
+    public static final String ROLE_SEARCH = "roleSearch";
+    public static final String ROLE_ASGN = "roleAsgn";
+    public static final String ROLE_DEASGN = "roleDeasgn";
+    public static final String ROLE_GRANT = "roleGrant";
+    public static final String ROLE_REVOKE = "roleRevoke";
+    public static final String ROLE_PERMS = "rolePerms";
+    public static final String ROLE_DESC = "roleDescendant";
+    public static final String ROLE_ASC = "roleAscendent";
+    public static final String ROLE_ADDINHERIT = "roleAddinherit";
+    public static final String ROLE_DELINHERIT = "roleDelinherit";
+    public static final String ROLE_ASGNED = "roleAsigned";
+    public static final String ROLE_AUTHZED = "roleAuthzed";
+    public static final String OBJ_READ = "objRead";
+    public static final String OBJ_UPDATE = "objUpdate";
+    public static final String OBJ_ADD = "objAdd";
+    public static final String OBJ_DELETE = "objDelete";
+    public static final String OBJ_SEARCH = "objSearch";
+    public static final String PERM_READ = "permRead";
+    public static final String PERM_UPDATE = "permUpdate";
+    public static final String PERM_ADD = "permAdd";
+    public static final String PERM_DELETE = "permDelete";
+    public static final String PERM_SEARCH = "permSearch";
+    public static final String PERM_ROLES = "permRoles";
+    public static final String PERM_USERS = "permUsers";
+    public static final String PERM_ROLES_AUTHZED = "permRolesAuthzed";
+    public static final String PERM_USERS_AUTHZED = "permUsersAuthzed";
+    public static final String ORG_READ = "orgRead";
+    public static final String ORG_UPDATE = "orgUpdate";
+    public static final String ORG_ADD = "orgAdd";
+    public static final String ORG_DELETE = "orgDelete";
+    public static final String ORG_DESC = "orgDescendant";
+    public static final String ORG_ASC = "orgAscendent";
+    public static final String ORG_ADDINHERIT = "orgAddinherit";
+    public static final String ORG_DELINHERIT = "orgDelinherit";
+    public static final String ORG_SEARCH = "orgSearch";
+    public static final String SSD_ROLE_SETS = "ssdRoleSets";
+    public static final String SSD_SETS = "ssdSets";
+    public static final String SSD_READ = "ssdRead";
+    public static final String SSD_ROLES = "ssdRoles";
+    public static final String SSD_CARD = "ssdCard";
+    public static final String SSD_ADD = "ssdAdd";
+    public static final String SSD_UPDATE = "ssdUpdate";
+    public static final String SSD_DELETE = "ssdDelete";
+    public static final String SSD_ADD_MEMBER = "ssdAddMember";
+    public static final String SSD_DEL_MEMBER = "ssdDelMember";
+    public static final String SSD_CARD_UPDATE = "ssdCardUpdate";
+    public static final String DSD_ROLE_SETS = "dsdRoleSets";
+    public static final String DSD_SETS = "dsdSets";
+    public static final String DSD_READ = "dsdRead";
+    public static final String DSD_ROLES = "dsdRoles";
+    public static final String DSD_CARD = "dsdCard";
+    public static final String DSD_ADD = "dsdAdd";
+    public static final String DSD_UPDATE = "dsdUpdate";
+    public static final String DSD_DELETE = "dsdDelete";
+    public static final String DSD_ADD_MEMBER = "dsdAddMember";
+    public static final String DSD_DEL_MEMBER = "dsdDelMember";
+    public static final String DSD_CARD_UPDATE = "dsdCardUpdate";
+    public static final String ADMIN_AUTHZ = "adminAuthZ";
+    public static final String ADMIN_ROLES = "adminRoles";
+    public static final String ADMIN_PERMS = "adminPerms";
+    public static final String ADMIN_AUTHZ_ROLES = "adminAuthzRoles";
+    public static final String ADMIN_ADD = "adminAdd";
+    public static final String ADMIN_DROP = "adminDrop";
+    public static final String ADMIN_ASSIGN = "adminAssign";
+    public static final String ADMIN_DEASSIGN = "adminDeassign";
+    public static final String ADMIN_GRANT = "adminGrant";
+    public static final String ADMIN_REVOKE = "adminRevoke";
+    public static final String ARLE_READ = "arleRead";
+    public static final String ARLE_UPDATE = "arleUpdate";
+    public static final String ARLE_ADD = "arleAdd";
+    public static final String ARLE_DELETE = "arleDelete";
+    public static final String ARLE_SEARCH = "arleSearch";
+    public static final String ARLE_DESC = "arleDescendant";
+    public static final String ARLE_ASC = "arleAscendent";
+    public static final String ARLE_ADDINHERIT = "arleAddinherit";
+    public static final String ARLE_DELINHERIT = "arleDelinherit";
+    public static final String ARLE_ASGN = "arleAsgn";
+    public static final String ARLE_DEASGN = "arleDeasgn";
+    public static final String ARLE_ASGNED = "arleAsigned";
+    public static final String PSWD_READ = "pswdRead";
+    public static final String PSWD_UPDATE = "pswdUpdate";
+    public static final String PSWD_ADD = "pswdAdd";
+    public static final String PSWD_DELETE = "pswdDelete";
+    public static final String PSWD_SEARCH = "pswdSearch";
+    public static final String PSWD_USER_ADD = "pswdUserAdd";
+    public static final String PSWD_USER_DELETE = "pswdUserDelete";
+    public static final String AUDIT_BINDS = "auditBinds";
+    public static final String AUDIT_AUTHZS = "auditAuthzs";
+    public static final String AUDIT_UAUTHZS = "auditUserAuthzs";
+    public static final String AUDIT_SESSIONS = "auditSessions";
+    public static final String AUDIT_MODS = "auditMods";
+    public static final String AUDIT_INVLD = "auditInvld";
+    public static final String CFG_ADD = "cfgAdd";
+    public static final String CFG_UPDATE = "cfgUpdate";
+    public static final String CFG_DELETE = "cfgDelete";
+    public static final String CFG_READ = "cfgRead";
+}
\ 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/rest/JAXBCachedEntry.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/JAXBCachedEntry.java b/src/main/java/org/apache/directory/fortress/core/rest/JAXBCachedEntry.java
new file mode 100644
index 0000000..faccd06
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/JAXBCachedEntry.java
@@ -0,0 +1,68 @@
+/*
+ *   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.rest;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+
+/**
+ * This class wraps JAXBContext and is used for simple caching mechanism during Fortress XML processing.
+ * The intent is to leave future extension point in case schema validation is needed which prevents handling in cache itself.
+ *
+ * @author Shawn McKinney
+ */
+@SuppressWarnings( "rawtypes" )
+public class JAXBCachedEntry
+{
+    private final Class cachedClass;
+    private final JAXBContext context;
+
+    /**
+     * Public constructor requires the entity class to be passed.
+     *
+     * @param type contains reference to object of type class.
+     * @throws JAXBException thrown in the event new instance cannot be created.
+     */
+    public JAXBCachedEntry( Class type ) throws JAXBException
+    {
+        context = JAXBContext.newInstance( type );
+        cachedClass = type;
+    }
+
+    /**
+     * Return the class that is associated with this cached JAXBContext.
+     *
+     * @return class associated with JAXContext
+     */
+    public Class getCachedClass()
+    {
+        return cachedClass;
+    }
+
+    /**
+     * Return the JAXBContext object associated with this wrapper class.
+     *
+     * @return handle to JAXBContext object.
+     */
+    public JAXBContext getContext()
+    {
+        return context;
+    }
+}
\ 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/rest/PwPolicyMgrRestImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/PwPolicyMgrRestImpl.java b/src/main/java/org/apache/directory/fortress/core/rest/PwPolicyMgrRestImpl.java
new file mode 100644
index 0000000..8a1cfb9
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/PwPolicyMgrRestImpl.java
@@ -0,0 +1,453 @@
+/*
+ *   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.rest;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.PwPolicyMgr;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.Manageable;
+import org.apache.directory.fortress.core.rbac.PwPolicy;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.rbac.User;
+
+import java.util.List;
+
+/**
+ * This class is used to perform administrative and review functions on the PWPOLICIES and USERS data sets using HTTP access to En Masse REST server.
+ * <p/>
+ * <h4>Password Policies</h4>
+ * <a href="http://www.openldap.org/">OpenLDAP</a> supports the IETF draft <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10/">Password Policies for LDAP directories</a></li>.  Policies may be applied at the user, group or global level.
+ * <p/>
+ * <img src="../doc-files/PasswordPolicy.png">
+ * <p/>
+ * Password enforcement options include:
+ * <ol>
+ * <li>A configurable limit on failed authentication attempts.</li>
+ * <li>A counter to track the number of failed authentication attempts.</li>
+ * <li>A time frame in which the limit of consecutive failed authentication attempts must happen before action is taken.</li>
+ * <li>The action to be taken when the limit is reached. The action will either be nothing, or the account will be locked.</li>
+ * <li>An amount of time the account is locked (if it is to be locked) This can be indefinite.</li>
+ * <li>Password expiration.</li>
+ * <li>Expiration warning</li>
+ * <li>Grace authentications</li>
+ * <li>Password history</li>
+ * <li>Password minimum age</li>
+ * <li>Password minimum length</li>
+ * <li>Password Change after Reset</li>
+ * <li>Safe Modification of Password</li>
+ * </ol>
+ * <p/>
+ * This class is NOT thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class PwPolicyMgrRestImpl extends Manageable implements PwPolicyMgr
+{
+    private static final String CLS_NM = PwPolicyMgrRestImpl.class.getName();
+
+    /**
+     * This method will add a new policy entry to the POLICIES data set.  This command is valid
+     * if and only if the policy entry is not already present in the POLICIES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#name} - Maps to name attribute of pwdPolicy object class being added.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#minAge} - This attribute holds the number of seconds that must elapse between
+     * modifications to the password.  If this attribute is not present, 0
+     * seconds is assumed.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#maxAge} - This attribute holds the number of seconds after which a modified
+     * password will expire. If this attribute is not present, or if the value is 0 the password
+     * does not expire.  If not 0, the value must be greater than or equal
+     * to the value of the pwdMinAge.
+     * </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#inHistory} - This attribute specifies the maximum number of used passwords stored
+     * in the pwdHistory attribute. If this attribute is not present, or if the value is 0, used
+     * passwords are not stored in the pwdHistory attribute and thus may be reused.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#minLength} - When quality checking is enabled, this attribute holds the minimum
+     * number of characters that must be used in a password.  If this
+     * attribute is not present, no minimum password length will be
+     * enforced.  If the server is unable to check the length (due to a
+     * hashed password or otherwise), the server will, depending on the
+     * value of the pwdCheckQuality attribute, either accept the password
+     * without checking it ('0' or '1') or refuse it ('2').</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#expireWarning} - This attribute specifies the maximum number of seconds before a
+     * password is due to expire that expiration warning messages will be
+     * returned to an authenticating user.  If this attribute is not present, or if the value is 0 no warnings
+     * will be returned.  If not 0, the value must be smaller than the value
+     * of the pwdMaxAge attribute.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#graceLoginLimit} - This attribute specifies the number of times an expired password can
+     * be used to authenticate.  If this attribute is not present or if the
+     * value is 0, authentication will fail. </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#lockout} - This attribute indicates, when its value is "TRUE", that the password
+     * may not be used to authenticate after a specified number of
+     * consecutive failed bind attempts.  The maximum number of consecutive
+     * failed bind attempts is specified in pwdMaxFailure.  If this attribute is not present, or if the
+     * value is "FALSE", the password may be used to authenticate when the number of failed bind
+     * attempts has been reached.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#lockoutDuration} - This attribute holds the number of seconds that the password cannot
+     * be used to authenticate due to too many failed bind attempts.  If
+     * this attribute is not present, or if the value is 0 the password
+     * cannot be used to authenticate until reset by a password
+     * administrator.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#maxFailure} - This attribute specifies the number of consecutive failed bind
+     * attempts after which the password may not be used to authenticate.
+     * If this attribute is not present, or if the value is 0, this policy
+     * is not checked, and the value of pwdLockout will be ignored.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#failureCountInterval} - This attribute holds the number of seconds after which the password
+     * failures are purged from the failure counter, even though no
+     * successful authentication occurred.  If this attribute is not present, or if its value is 0, the failure
+     * counter is only reset by a successful authentication.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#mustChange} - This attribute specifies with a value of "TRUE" that users must
+     * change their passwords when they first bind to the directory after a
+     * password is set or reset by a password administrator.  If this
+     * attribute is not presen        request.setContextId(this.contextId);t, or if the value is "FALSE", users are not
+     * required to change their password upon binding after the password
+     * administrator sets or resets the password.  This attribute is not set
+     * due to any actions specified by this document, it is typically set by
+     * a password administrator after resetting a user's password.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#allowUserChange} - This attribute indicates whether users can change their own
+     * passwords, although the change operation is still subject to access
+     * control.  If this attribute is not present, a value of "TRUE" is
+     * assumed.  This attribute is intended to be used in the absence of an access control mechanism.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#safeModify} - This attribute specifies whether or not the existing password must be
+     * sent along with the new password when being changed.  If this
+     * attribute is not present, a "FALSE" value is assumed.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#checkQuality} - This attribute indicates how the password quality will be verified
+     * while being modified or added.  If this attribute is not present, or
+     * if the value is '0', quality checking will not be enforced.  A value
+     * of '1' indicates that the server will check the quality, and if the
+     * server is unable to check it (due to a hashed password or other
+     * reasons) it will be accepted.  A value of '2' indicates that the
+     * server will check the quality, and if the server is unable to verify
+     * it, it will return an error refusing the password. </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#attribute} - This holds the name of the attribute to which the password policy is
+     * applied.  For example, the password policy may be applied to the
+     * userPassword attribute </li>
+     * </ul>
+     *
+     * @param policy Object must contain {@link org.apache.directory.fortress.core.rbac.PwPolicy#name} and optionally other attributes.
+     * @throws SecurityException In the event of data validation or system error.
+     */
+    @Override
+    public void add(PwPolicy policy)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(policy, GlobalErrIds.PSWD_PLCY_NULL, CLS_NM + ".add");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(policy);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PSWD_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+
+    /**
+     * This method will update an exiting policy entry to the POLICIES data set.  This command is valid
+     * if and only if the policy entry is already present in the POLICIES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#name} - Maps to name attribute of pwdPolicy object class being updated.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#minAge} - This attribute holds the number of seconds that must elapse between
+     * modifications to the password.  If this attribute is not present, 0
+     * seconds is assumed.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#maxAge} - This attribute holds the number of seconds after which a modified
+     * password will expire. If this attribute is not present, or if the value is 0 the password
+     * does not expire.  If not 0, the value must be greater than or equal
+     * to the value of the pwdMinAge.
+     * </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#inHistory} - This attribute specifies the maximum number of used passwords stored
+     * in the pwdHistory attribute. If this attribute is not present, or if the value is 0, used
+     * passwords are not stored in the pwdHistory attribute and thus may be reused.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#minLength} - When quality checking is enabled, this attribute holds the minimum
+     * number of characters that must be used in a password.  If this
+     * attribute is not present, no minimum password length will be
+     * enforced.  If the server is unable to check the length (due to a
+     * hashed password or otherwise), the server will, depending on the
+     * value of the pwdCheckQuality attribute, either accept the password
+     * without checking it ('0' or '1') or refuse it ('2').</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#expireWarning} - This attribute specifies the maximum number of seconds before a
+     * password is due to expire that expiration warning messages will be
+     * returned to an authenticating user.  If this attribute is not present, or if the value is 0 no warnings
+     * will be returned.  If not 0, the value must be smaller than the value
+     * of the pwdMaxAge attribute.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#graceLoginLimit} - This attribute specifies the number of times an expired password can
+     * be used to authenticate.  If this attribute is not present or if the
+     * value is 0, authentication will fail. </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#lockout} - This attribute indicates, when its value is "TRUE", that the password
+     * may not be used to authenticate after a specified number of
+     * consecutive failed bind attempts.  The maximum number of consecutive
+     * failed bind attempts is specified in pwdMaxFailure.  If this attribute is not present, or if the
+     * value is "FALSE", the password may be used to authenticate when the number of failed bind
+     * attempts has been reached.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#lockoutDuration} - This attribute holds the number of seconds that the password cannot
+     * be used to authenticate due to too many failed bind attempts.  If
+     * this attribute is not present, or if the value is 0 the password
+     * cannot be used to authenticate until reset by a password
+     * administrator.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#maxFailure} - This attribute specifies the number of consecutive failed bind
+     * attempts after which the password may not be used to authenticate.
+     * If this attribute is not present, or if the value is 0, this policy
+     * is not checked, and the value of pwdLockout will be ignored.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#failureCountInterval} - This attribute holds the number of seconds after which the password
+     * failures are purged from the failure counter, even though no
+     * successful authentication occurred.  If this attribute is not present, or if its value is 0, the failure
+     * counter is only reset by a successful authentication.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#mustChange} - This attribute specifies with a value of "TRUE" that users must
+     * change their passwords when they first bind to the directory after a
+     * password is set or reset by a password administrator.  If this
+     * attribute is not present, or if the value is "FALSE", users are not
+     * required to change their password upon binding after the password
+     * administrator sets or resets the password.  This attribute is not set
+     * due to any actions specified by this document, it is typically set by
+     * a password administrator after resetting a user's password.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#allowUserChange} - This attribute indicates whether users can change their own
+     * passwords, although the change operation is still subject to access
+     * control.  If this attribute is not present, a value of "TRUE" is
+     * assumed.  This attribute is intended to be used in the absence of an access control mechanism.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#safeModify} - This attribute specifies whether or not the existing password must be
+     * sent along with the new password when being changed.  If this
+     * attribute is not present, a "FALSE" value is assumed.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#checkQuality} - This attribute indicates how the password quality will be verified
+     * while being modified or added.  If this attribute is not present, or
+     * if the value is '0', quality checking will not be enforced.  A value
+     * of '1' indicates that the server will check the quality, and if the
+     * server is unable to check it (due to a hashed password or other
+     * reasons) it will be accepted.  A value of '2' indicates that the
+     * server will check the quality, and if the server is unable to verify
+     * it, it will return an error refusing the password. </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#attribute} - This holds the name of the attribute to which the password policy is
+     * applied.  For example, the password policy may be applied to the
+     * userPassword attribute </li>
+     * </ul>
+     *
+     * @param policy Object must contain {@link org.apache.directory.fortress.core.rbac.PwPolicy#name} and optionally all non-null attributes will be updated.  null attributes will be ignored.
+     * @throws SecurityException In the event policy not found , data validation or system error.
+     */
+    @Override
+    public void update(PwPolicy policy)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(policy, GlobalErrIds.PSWD_PLCY_NULL, CLS_NM + ".update");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(policy);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PSWD_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+
+    /**
+     * This method will delete exiting policy entry from the POLICIES data set.  This command is valid
+     * if and only if the policy entry is already present in the POLICIES data set.  Existing users that
+     * are assigned this policy will be removed from association.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#name} - Maps to name attribute of pwdPolicy object class being removed.</li>
+     * </ul>
+     *
+     * @param policy Object must contain {@link org.apache.directory.fortress.core.rbac.PwPolicy#name} of the policy entity to remove.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          In the event policy entity not found or system error.
+     */
+    @Override
+    public void delete(PwPolicy policy)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(policy, GlobalErrIds.PSWD_NAME_NULL, CLS_NM + ".delete");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(policy);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PSWD_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+
+    /**
+     * This method will return the password policy entity to the caller.  This command is valid
+     * if and only if the policy entry is present in the POLICIES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#name} - Maps to name attribute of pwdPolicy object class being read.</li>
+     * </ul>
+     *
+     * @return PswdPolicy entity returns fully populated with attributes.
+     * @throws SecurityException In the event policy entry not found, data validation or system error.
+     */
+    @Override
+    public PwPolicy read(String name)
+        throws SecurityException
+    {
+        VUtil.assertNotNullOrEmpty(name, GlobalErrIds.PSWD_NAME_NULL, CLS_NM + ".read");
+        PwPolicy retPolicy;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(new PwPolicy(name));
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PSWD_READ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPolicy = (PwPolicy) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPolicy;
+    }
+
+
+    /**
+     * This method will return a list of all password policy entities that match a particular search string.
+     * This command will return an empty list of no matching entries are found.
+     *
+     * @param searchVal String contains the leading chars of a policy entity.  This search is not case sensitive.
+     * @return List<PswdPolicy> contains all matching password policy entities. If no records found this will be empty.
+     * @throws SecurityException In the event of data validation or system error.
+     */
+    @Override
+    public List<PwPolicy> search(String searchVal)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(searchVal, GlobalErrIds.PSWD_NAME_NULL, CLS_NM + ".search");
+        List<PwPolicy> retPolicies;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(new PwPolicy(searchVal));
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PSWD_SEARCH);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPolicies = response.getEntities();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPolicies;
+    }
+
+
+    /**
+     * This method will associate a user entity with a password policy entity.  This function is valid
+     * if and only if the user is a member of the USERS data set and the policyName refers to a
+     * policy that is a member of the PWPOLICIES data set.
+     *
+     * @param userId Contains {@link org.apache.directory.fortress.core.rbac.User#userId} of a User entity in USERS data set.
+     * @param name   String contains the {@link org.apache.directory.fortress.core.rbac.PwPolicy#name} of a pw policy entity contained within the PWPOLICIES data set.
+     * @throws SecurityException thrown in the event either user or policy not valid or system error.
+     */
+    @Override
+    public void updateUserPolicy(String userId, String name)
+        throws SecurityException
+    {
+        String methodName = "updateUserPolicy";
+        VUtil.assertNotNullOrEmpty(userId, GlobalErrIds.USER_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNullOrEmpty(name, GlobalErrIds.PSWD_NAME_NULL, CLS_NM + "." + methodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(new PwPolicy(name));
+        request.setValue(userId);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PSWD_USER_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+
+    /**
+     * This method will remove the pw policy assignment from a user entity.  This function is valid
+     * if and only if the user is a member of the USERS data set and the policy attribute is assigned.
+     * Removal of pw policy assignment will revert the user's policy to use the global default for OpenLDAP
+     * instance that contains user.
+     *
+     * @param userId Contains {@link User#userId} of a User entity in USERS data set.
+     * @throws SecurityException Thrown in the event either user not valid or system error.
+     */
+    @Override
+    public void deletePasswordPolicy(String userId)
+        throws SecurityException
+    {
+        VUtil.assertNotNullOrEmpty(userId, GlobalErrIds.USER_NULL, CLS_NM + ".deletePasswordPolicy");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setValue(userId);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PSWD_USER_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rest/RestUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/RestUtils.java b/src/main/java/org/apache/directory/fortress/core/rest/RestUtils.java
new file mode 100644
index 0000000..3797bd1
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/RestUtils.java
@@ -0,0 +1,483 @@
+/*
+ *   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.rest;
+
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.PutMethod;
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.helpers.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.ObjectFactory;
+import org.apache.directory.fortress.core.RestException;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.Props;
+import org.apache.directory.fortress.core.util.crypto.EncryptUtil;
+
+
+/**
+ * This utility class provides methods that wrap Apache's HTTP Client APIs.  This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+public class RestUtils
+{
+    private static final String CLS_NM = RestUtils.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private final static String HTTP_UID = Config.getProperty( "http.user" );
+    private final static String HTTP_PW_PARAM = "http.pw";
+    private final static String HTTP_PW = ( ( EncryptUtil.isEnabled() ) ? EncryptUtil.decrypt( Config
+        .getProperty( HTTP_PW_PARAM ) ) : Config.getProperty( HTTP_PW_PARAM ) );
+    private final static String HTTP_HOST = Config.getProperty( "http.host" );
+    private final static String HTTP_PORT = Config.getProperty( "http.port" );
+    private final static String HTTP_PROTOCOL = Config.getProperty( "http.protocol", "http" );
+    private static final String VERSION = System.getProperty( "version" );
+    private static final String SERVICE = "enmasse-" + VERSION;
+    // TODO: add SSL capability here:
+    private static final String URI = HTTP_PROTOCOL + "://" + HTTP_HOST + ":" + HTTP_PORT + "/" + SERVICE + "/";
+    private static final int HTTP_OK = 200;
+    private static final int HTTP_401_UNAUTHORIZED = 401;
+    private static final int HTTP_403_FORBIDDEN = 403;
+    private static final int HTTP_404_NOT_FOUND = 404;
+    private static CachedJaxbContext cachedJaxbContext = new CachedJaxbContext();
+
+    /**
+     * Used to manage trust store properties.  If enabled, create SSL connection.
+     *
+     */
+    private static final String TRUST_STORE = Config.getProperty( "trust.store" );
+    private static final String TRUST_STORE_PW = Config.getProperty( "trust.store.password" );
+    private static final String SET_TRUST_STORE_PROP = "trust.store.set.prop";
+    private static final boolean IS_SET_TRUST_STORE_PROP = (
+            Config.getProperty( SET_TRUST_STORE_PROP ) != null   &&
+            Config.getProperty( SET_TRUST_STORE_PROP ).equalsIgnoreCase( "true" ));
+
+    static
+    {
+        if(IS_SET_TRUST_STORE_PROP)
+        {
+            LOG.info( "Set JSSE truststore properties:");
+            LOG.info( "javax.net.ssl.trustStore: " + TRUST_STORE );
+            System.setProperty( "javax.net.ssl.trustStore", TRUST_STORE );
+            System.setProperty( "javax.net.ssl.trustStorePassword", TRUST_STORE_PW );
+        }
+    }
+
+
+
+
+    /**
+     * Marshall the request into an XML String.
+     *
+     * @param request
+     * @return String containing xml request
+     * @throws RestException
+     */
+    public static String marshal( FortRequest request ) throws RestException
+    {
+        String szRetValue;
+        try
+        {
+            // Create a JAXB context passing in the class of the object we want to marshal/unmarshal
+            final JAXBContext context = cachedJaxbContext.getJaxbContext( FortRequest.class );
+            // =============================================================================================================
+            // Marshalling OBJECT to XML
+            // =============================================================================================================
+            // Create the marshaller, that will transform the object into XML
+            final Marshaller marshaller = context.createMarshaller();
+            // Create a stringWriter to hold the XML
+            final StringWriter stringWriter = new StringWriter();
+            // Marshal the javaObject and write the XML to the stringWriter
+            marshaller.marshal( request, stringWriter );
+            szRetValue = stringWriter.toString();
+        }
+        catch ( JAXBException je )
+        {
+            String error = "marshal caught JAXBException=" + je;
+            throw new RestException( GlobalErrIds.REST_MARSHALL_ERR, error, je );
+        }
+        return szRetValue;
+    }
+
+
+    /**
+     * Unmarshall the XML response into its associated Java objects.
+     *
+     * @param szResponse
+     * @return FortResponse
+     * @throws RestException
+     */
+    public static FortResponse unmarshall( String szResponse ) throws RestException
+    {
+        FortResponse response;
+        try
+        {
+            // Create a JAXB context passing in the class of the object we want to marshal/unmarshal
+            final JAXBContext context = cachedJaxbContext.getJaxbContext( FortResponse.class );
+
+            // Create the unmarshaller, that will transform the XML back into an object
+            final Unmarshaller unmarshaller = context.createUnmarshaller();
+            response = ( FortResponse ) unmarshaller.unmarshal( new StringReader( szResponse ) );
+        }
+        catch ( JAXBException je )
+        {
+            String error = "unmarshall caught JAXBException=" + je;
+            throw new RestException( GlobalErrIds.REST_UNMARSHALL_ERR, error, je );
+        }
+        return response;
+    }
+
+
+    /**
+     * Perform HTTP Get REST request.
+     *
+     * @param userId
+     * @param password
+     * @param id
+     * @param id2
+     * @param id3
+     * @param function
+     * @return String containing response
+     * @throws RestException
+     */
+    public static String get( String userId, String password, String id, String id2, String id3, String function )
+        throws RestException
+    {
+        String url = URI + function + "/" + id;
+        if ( id2 != null )
+        {
+            url += "/" + id2;
+        }
+        if ( id3 != null )
+        {
+            url += "/" + id3;
+        }
+        LOG.debug( "get function1:{}, id1:{}, id2:{}, id3:{}, url:{}", function, id, id2, id3, url );
+        GetMethod get = new GetMethod( url );
+        setMethodHeaders( get, userId, password );
+        return handleHttpMethod( get );
+    }
+
+
+    /**
+     * Perform HTTP Get REST request.
+     *
+     * @param id
+     * @param id2
+     * @param id3
+     * @param function
+     * @return String containing response
+     * @throws RestException
+     */
+    public static String get( String id, String id2, String id3, String function ) throws RestException
+    {
+        String url = URI + function + "/" + id;
+        if ( id2 != null )
+        {
+            url += "/" + id2;
+        }
+        if ( id3 != null )
+        {
+            url += "/" + id3;
+        }
+        LOG.debug( "get function2:{}, id1:{}, id2:{}, id3:{}, url:{}", function, id, id2, id3, url );
+        GetMethod get = new GetMethod( url );
+        setMethodHeaders( get, HTTP_UID, HTTP_PW );
+        return handleHttpMethod( get );
+    }
+
+
+    /**
+     * Perform an HTTP Post REST operation.
+     *
+     * @param userId
+     * @param password
+     * @param szInput
+     * @param function
+     * @return String containing response
+     * @throws RestException
+     */
+    public static String post( String userId, String password, String szInput, String function ) throws RestException
+    {
+        LOG.debug( "post URI=[" + URI + "], function=[" + function + "], request=" + szInput );
+        String szResponse = null;
+        PostMethod post = new PostMethod( URI + function );
+        post.addRequestHeader( "Accept", "text/xml" );
+        setMethodHeaders( post, userId, password );
+        try
+        {
+            RequestEntity entity = new StringRequestEntity( szInput, "text/xml; charset=ISO-8859-1", null );
+            post.setRequestEntity( entity );
+            HttpClient httpclient = new HttpClient();
+            int result = httpclient.executeMethod( post );
+            szResponse = IOUtils.toString( post.getResponseBodyAsStream(), "UTF-8" );
+            LOG.debug( "post URI=[{}], function=[{}], response=[{}], result=[{}]", URI, function, szResponse, result );
+        }
+        catch ( IOException ioe )
+        {
+            String error = "post URI=[" + URI + "], [" + function + "] caught IOException=" + ioe;
+            LOG.error( error );
+            throw new RestException( GlobalErrIds.REST_IO_ERR, error, ioe );
+        }
+        catch ( WebApplicationException we )
+        {
+            String error = "post URI=[" + URI + "], function=[" + function
+                + "] caught WebApplicationException=" + we;
+            LOG.error( error );
+            throw new RestException( GlobalErrIds.REST_WEB_ERR, error, we );
+        }
+        finally
+        {
+            // Release current connection to the connection pool.
+            post.releaseConnection();
+        }
+        return szResponse;
+    }
+
+
+    /**
+     * Perform an HTTP Post REST operation.
+     *
+     * @param szInput
+     * @param function
+     * @return String containing response
+     * @throws RestException
+     */
+    public static String post( String szInput, String function ) throws RestException
+    {
+        LOG.debug( "post URI=[{}], function=[{}], request=[{}]", URI, function, szInput );
+        String szResponse = null;
+        PostMethod post = new PostMethod( URI + function );
+        post.addRequestHeader( "Accept", "text/xml" );
+        setMethodHeaders( post, HTTP_UID, HTTP_PW );
+        try
+        {
+            RequestEntity entity = new StringRequestEntity( szInput, "text/xml; charset=ISO-8859-1", null );
+            post.setRequestEntity( entity );
+            HttpClient httpclient = new HttpClient();
+            int result = httpclient.executeMethod( post );
+            if ( result == HTTP_OK )
+            {
+                szResponse = IOUtils.toString( post.getResponseBodyAsStream(), "UTF-8" );
+                LOG.debug( "post URI=[{}], function=[{}], response=[{}]", URI, function, szResponse );
+            }
+            else if ( result == HTTP_401_UNAUTHORIZED )
+            {
+                String error = "post URI=[" + URI + "], function=[" + function
+                    + "], 401 function unauthorized on host";
+                LOG.error( error );
+                throw new RestException( GlobalErrIds.REST_UNAUTHORIZED_ERR, error );
+            }
+            else if ( result == HTTP_403_FORBIDDEN )
+            {
+                String error = "post URI=[" + URI + "], function=[" + function
+                    + "], 403 function forbidden on host";
+                LOG.error( error );
+                throw new RestException( GlobalErrIds.REST_FORBIDDEN_ERR, error );
+            }
+            else if ( result == HTTP_404_NOT_FOUND )
+            {
+                String error = "post URI=[" + URI + "], function=[" + function + "], 404 not found from host";
+                LOG.error( error );
+                throw new RestException( GlobalErrIds.REST_NOT_FOUND_ERR, error );
+            }
+            else
+            {
+                String error = "post URI=[" + URI + "], function=[" + function
+                    + "], error received from host: " + result;
+                LOG.error( error );
+                throw new RestException( GlobalErrIds.REST_UNKNOWN_ERR, error );
+            }
+        }
+        catch ( IOException ioe )
+        {
+            String error = "post URI=[" + URI + "], function=[" + function + "] caught IOException=" + ioe;
+            LOG.error( error );
+            throw new RestException( GlobalErrIds.REST_IO_ERR, error, ioe );
+        }
+        catch ( WebApplicationException we )
+        {
+            String error = "post URI=[" + URI + "], function=[" + function
+                + "] caught WebApplicationException=" + we;
+            LOG.error( error );
+            throw new RestException( GlobalErrIds.REST_WEB_ERR, error, we );
+        }
+        finally
+        {
+            // Release current connection to the connection pool.
+            post.releaseConnection();
+        }
+        return szResponse;
+    }
+
+
+    /**
+     * Set these params into their associated HTTP header vars.
+     *
+     * @param httpMethod
+     * @param name
+     * @param password
+     */
+    private static void setMethodHeaders( HttpMethod httpMethod, String name, String password )
+    {
+        if ( httpMethod instanceof PostMethod || httpMethod instanceof PutMethod )
+        {
+            httpMethod.setRequestHeader( "Content-Type", "application/xml" );
+            httpMethod.setRequestHeader( "Accept", "application/xml" );
+        }
+        //httpMethod.setDoAuthentication(false);
+        httpMethod.setDoAuthentication( true );
+        httpMethod.setRequestHeader( "Authorization",
+            "Basic " + base64Encode( name + ":" + password ) );
+    }
+
+
+    /**
+     * Convert from non-Base64 to Base64 encoded.
+     *
+     * @param value
+     * @return String contains encoded data
+     */
+    private static String base64Encode( String value )
+    {
+        return Base64Utility.encode( value.getBytes() );
+    }
+
+
+    /**
+     * Process the HTTP method request.
+     *
+     * @param httpMethod
+     * @return String containing response
+     * @throws Exception
+     */
+    private static String handleHttpMethod( HttpMethod httpMethod ) throws RestException
+    {
+        HttpClient client = new HttpClient();
+        String szResponse = null;
+        try
+        {
+            int statusCode = client.executeMethod( httpMethod );
+            LOG.debug( "handleHttpMethod Response status : {}", statusCode );
+
+            Response.Status status = Response.Status.fromStatusCode( statusCode );
+
+            if ( status == Response.Status.OK )
+            {
+                szResponse = httpMethod.getResponseBodyAsString();
+                LOG.debug( szResponse );
+            }
+            else if ( status == Response.Status.FORBIDDEN )
+            {
+                LOG.debug( "handleHttpMethod Authorization failure" );
+            }
+            else if ( status == Response.Status.UNAUTHORIZED )
+            {
+                LOG.debug( "handleHttpMethod Authentication failure" );
+            }
+            else
+            {
+                LOG.debug( "handleHttpMethod Unknown error" );
+            }
+        }
+        catch ( IOException ioe )
+        {
+            String error = "handleHttpMethod caught IOException=" + ioe;
+            LOG.error( error );
+            throw new RestException( GlobalErrIds.REST_IO_ERR, error, ioe );
+        }
+        finally
+        {
+            // Release current connection to the connection pool.
+            httpMethod.releaseConnection();
+        }
+        return szResponse;
+    }
+
+
+    /**
+     * @param inProps
+     * @return Properties
+     */
+    public static Properties getProperties( Props inProps )
+    {
+        Properties properties = null;
+        List<Props.Entry> props = inProps.getEntry();
+        if ( props.size() > 0 )
+        {
+            properties = new Properties();
+            //int size = props.size();
+            for ( Props.Entry entry : props )
+            {
+                String key = entry.getKey();
+                String val = entry.getValue();
+                properties.setProperty( key, val );
+            }
+        }
+        return properties;
+    }
+
+
+    /**
+     *
+     * @param properties
+     * @return Prop contains name value pairs.
+     */
+    public static Props getProps( Properties properties )
+    {
+        Props props = null;
+        if ( properties != null )
+        {
+            props = new ObjectFactory().createProps();
+            for ( Enumeration e = properties.propertyNames(); e.hasMoreElements(); )
+            {
+                String key = ( String ) e.nextElement();
+                String val = properties.getProperty( key );
+                Props.Entry entry = new Props.Entry();
+                entry.setKey( key );
+                entry.setValue( val );
+                props.getEntry().add( entry );
+            }
+        }
+        return props;
+    }
+}
\ No newline at end of file


[20/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/SetAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/SetAdapter.java b/src/main/java/org/apache/directory/fortress/core/rbac/SetAdapter.java
new file mode 100755
index 0000000..f2e797f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/SetAdapter.java
@@ -0,0 +1,77 @@
+/*
+ *   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.adapters.XmlAdapter;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Shawn McKinney
+ * Date: 1/21/12
+ * Time: 7:59 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class SetAdapter extends XmlAdapter<ArrayList<String>, Set<String>>
+{
+    public Set<String> unmarshal(ArrayList<String> val) throws Exception
+    {
+        Set<String> members = null;
+        if(val != null)
+        {
+            members = new TreeSet<>();
+            for(String member : val)
+            {
+                members.add(member);
+            }
+        }
+        return members;
+    }
+
+    public ArrayList<String> marshal(Set<String> val) throws Exception
+    {
+        ArrayList<String> members = null;
+        if(val != null)
+        {
+            members = new ArrayList<>();
+            for(String member : val)
+            {
+                members.add(member);
+            }
+        }
+        return members;
+    }
+}
+
+
+/*
+    public char[] unmarshal(String val) throws Exception
+    {
+        return val.toCharArray();
+    }
+
+    public String marshal(char[] val) throws Exception
+    {
+        return val.toString();
+    }
+
+ */

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/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
new file mode 100755
index 0000000..907063e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/User.java
@@ -0,0 +1,1547 @@
+/*
+ *   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.io.Serializable;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.UUID;
+
+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.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;
+
+
+/**
+ * All entities ({@link User}, {@link org.apache.directory.fortress.core.rbac.Role}, {@link Permission},
+ * {@link PwPolicy} {@link SDSet} etc...) are used to carry data between three Fortress
+ * layers.starting with the (1) Manager layer down thru middle (2) Process layer and it's processing rules into
+ * (3) DAO layer where persistence with the OpenLDAP server occurs.
+ * <p/>
+ * <h4>Fortress Processing Layers</h4>
+ * <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 org.apache.directory.fortress.core.rbac.dao.RoleDAO}, {@link org.apache.directory.fortress.core.rbac.dao.PermDAO},...</li>
+ * </ol>
+ * Fortress clients must first instantiate the data entity before invoking one of the Manager APIs.  The caller must first
+ * provide enough information to uniquely identity target record for the particular ldap operation performed.<br />
+ * For example the User entity requires the {@link User#setUserId} attribute to be set before calling a Manager API.
+ * The unique key to locate a User entity in the Fortress DIT is simply the userId field.<br />
+ * Other ldap operations on User may require additional attributes to be set.
+ * <p/>
+ * <h4>User entity attribute usages include</h4>
+ * <ul>
+ * <li>{@link #setPassword(char[])} must be set before calling {@link AccessMgrImpl#authenticate} and {@link AccessMgrImpl#createSession(User, boolean)} (unless trusted).
+ * <li>{@link #setOu} is required before calling {@link AdminMgrImpl#addUser(User)} to add a new user to ldap.
+ * <li>{@link #setRoles} will be set for {@link AccessMgrImpl#createSession(User, boolean)} when selective RBAC Role activation is required.
+ * <li>{@link #setAdminRoles} will be set for {@link AccessMgrImpl#createSession(User, boolean)} when selective Administrative Role activation is required.
+ * <li>{@link #setPwPolicy} may be set for {@link AdminMgrImpl#updateUser(User)} to assign User to a policy {@link PwPolicy}.
+ * <li>{@link #password} is the only case sensitive attribute on this entity.
+ * </ul>
+ * <p/>
+ * Example to create new Fortress User:
+ * <pre>
+ * try
+ * {
+ *  // Instantiate the AdminMgr first
+ *  AdminMgr adminMgr = AdminMgrFactory.createInstance();
+ *
+ *  User myUser = new User("myUserId", "myPassword".toCharArray(), myRoleName", "myOU");
+ *  adminMgr.addUser(myUser);
+ * }
+ * catch (SecurityException ex)
+ * {
+ *  // log or throw
+ * }</pre>
+ * The above code will persist to LDAP a User object that has a userId of "myUserId", a password of "myPassword", a role assignment to "myRoleName", and assigned to organzational unit named "myOU".
+ * This User can be used as a target for subsequent User-Role assignments, User-Permission grants, authentication, authorization and more.
+ *
+ * This entity aggregates one standard LDAP structural object class, {@code inetOrgPerson} see <a href="http://www.ietf.org/rfc/rfc2798.txt">RFC 2798</a>,
+ * along with three auxiliary object extensions supplied by Fortress:  {@code ftUserAttrs}, {@code ftProperties}, {@code ftMods}.
+ * The combination of the standard and custom object classes form a single entry within the directory and is represented in this entity class.
+ *
+ * <h4>Fortress User Schema</h4>
+ *
+ * 1. InetOrgPerson Structural Object Class. <br />
+ * <code># The inetOrgPerson represents people who are associated with an</code><br />
+ * <code># organization in some way.  It is a structural class and is derived</code><br />
+ * <code># from the organizationalPerson which is defined in X.521 [X521].</code><br />
+ * <pre>
+ * ------------------------------------------
+ * objectclass ( 2.16.840.1.113730.3.2.2
+ *  NAME 'inetOrgPerson'
+ *  DESC 'RFC2798: Internet Organizational Person'
+ *  SUP organizationalPerson
+ *  STRUCTURAL
+ *  MAY (
+ *      audio $ businessCategory $ carLicense $ departmentNumber $
+ *      displayName $ employeeNumber $ employeeType $ givenName $
+ *      homePhone $ homePostalAddress $ initials $ jpegPhoto $
+ *      labeledURI $ mail $ manager $ mobile $ o $ pager $ photo $
+ *      roomNumber $ secretary $ uid $ userCertificate $
+ *      x500uniqueIdentifier $ preferredLanguage $
+ *      userSMIMECertificate $ userPKCS12
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ *
+ * 2. organizationalPerson Structural Object Class.
+ * <pre>
+ * ------------------------------------------
+ * objectclass ( 2.5.6.7
+ *  NAME 'organizationalPerson'
+ *  DESC 'RFC2256: an organizational person'
+ *  SUP person
+ *  STRUCTURAL
+ *  MAY (
+ *      title $ x121Address $ registeredAddress $ destinationIndicator $
+ *      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
+ *      telephoneNumber $ internationaliSDNNumber $
+ *      facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $
+ *      postalAddress $ physicalDeliveryOfficeName $ ou $ st $ l
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ *
+ * 3. ftProperties AUXILIARY Object Class is used to store client specific name/value pairs on target entity.<br />
+ * <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 />
+ * <pre>
+ * ------------------------------------------
+ * AC2: Fortress Properties Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.2
+ *  NAME 'ftProperties'
+ *  DESC 'Fortress Properties AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftProps
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ *
+ * 4. ftUserAttrs is used to store user RBAC and Admin role assignment 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>
+ *
+ * 5. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Audit Modification Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.4
+ *  NAME 'ftMods'
+ *  DESC 'Fortress Modifiers AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftModifier $
+ *      ftModCode $
+ *      ftModId
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+
+@XmlRootElement(name = "fortUser")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "user", propOrder =
+    {
+        "userId",
+        "description",
+        "name",
+        "internalId",
+        "ou",
+        "pwPolicy",
+        "sn",
+        "cn",
+        "dn",
+        "displayName",
+        "employeeType",
+        "title",
+        "address",
+        "phones",
+        "mobiles",
+        "emails",
+        "props",
+        "locked",
+        "reset",
+        "system",
+        "beginTime",
+        "endTime",
+        "beginDate",
+        "endDate",
+        "beginLockDate",
+        "endLockDate",
+        "dayMask",
+        "timeout",
+        "roles",
+        "adminRoles",
+        "password",
+        "newPassword"
+/*        "jpegPhoto"*/
+})
+public class User extends FortEntity implements Constraint, Serializable
+{
+    /**
+     * The serialVersionUID needed for Serializable classes
+     */
+    private static final long serialVersionUID = 1L;
+
+    private String userId;
+    @XmlElement(nillable = true)
+    private char[] password;
+    @XmlElement(nillable = true)
+    private char[] newPassword;
+    private String internalId;
+    @XmlElement(nillable = true)
+    private List<UserRole> roles;
+    @XmlElement(nillable = true)
+    private List<UserAdminRole> adminRoles;
+    private String pwPolicy;
+    private String cn;
+    private String sn;
+    private String dn;
+    private String ou;
+    private String displayName;
+    private String description;
+    private String beginTime;
+    private String endTime;
+    private String beginDate;
+    private String endDate;
+    private String beginLockDate;
+    private String endLockDate;
+    private String dayMask;
+    private String name;
+    private String employeeType;
+    private String title;
+    private int timeout;
+    private boolean reset;
+    private boolean locked;
+    private Boolean system;
+    @XmlElement(nillable = true)
+    private Props props = new Props();
+    @XmlElement(nillable = true)
+    private Address address;
+    @XmlElement(nillable = true)
+    private List<String> phones;
+    @XmlElement(nillable = true)
+    private List<String> mobiles;
+    @XmlElement(nillable = true)
+    private List<String> emails;
+    @XmlTransient
+    private byte[] jpegPhoto;
+
+
+    /**
+     * Default constructor not intended for external use and is typically used by internal Fortress classes.
+     * User entity constructed in this manner cannot be used by other until additional attributes (i.e. userId) are set.
+     */
+    public User()
+    {
+    }
+
+
+    /**
+     * Construct User given userId.   Once loaded this entity can be passed to AccessMgr.createSession iff trusted == 'true'..
+     *
+     * @param userId String validated using simple length test and optional regular expression, i.e. safe text.
+     */
+    public User( String userId )
+    {
+        this.userId = userId;
+    }
+
+
+    /**
+     * Construct User given userId and password.  Once loaded this entity can be passed to AccessMgr.createSession.
+     *
+     * @param userId   String validated using simple length test and optional regular expression, i.e. safe text.
+     * @param password validated using simple length test and OpenLDAP password policies.
+     */
+    public User( String userId, char[] password )
+    {
+        this.userId = userId;
+        this.password = password;
+    }
+
+
+    /**
+     * Construct User given userId and password.  Once loaded this entity can be passed to AccessMgr.createSession.
+     *
+     * @param userId   String validated using simple length test and optional regular expression, i.e. safe text.
+     * @param password validated using simple length test and OpenLDAP password policies.
+     * @param roleName contains role that caller is requesting activation.
+     */
+    public User( String userId, char[] password, String roleName )
+    {
+        this.userId = userId;
+        this.password = password;
+        setRole( new UserRole( roleName ) );
+    }
+
+
+    /**
+     * Construct User given userId and password.  Once loaded this entity can be passed to AccessMgr.createSession.
+     *
+     * @param userId   String validated using simple length test and optional regular expression, i.e. safe text.
+     * @param password validated using simple length test and OpenLDAP password policies.
+     * @param roleNames contains array of roleNames that caller is requesting activation.
+     */
+    public User( String userId, char[] password, String[] roleNames )
+    {
+        this.userId = userId;
+        this.password = password;
+
+        if ( roleNames != null )
+        {
+            for ( String name : roleNames )
+            {
+                setRole( new UserRole( name ) );
+            }
+        }
+    }
+
+
+    /**
+     * Construct User given userId and password.  Once loaded this entity can be passed to AccessMgr.createSession.
+     *
+     * @param userId   String validated using simple length test and optional regular expression, i.e. safe text.
+     * @param password validated using simple length test and OpenLDAP password policies.
+     * @param roleName contains role that caller is requesting activation (see {@link org.apache.directory.fortress.core.AccessMgr#createSession(User, boolean)}) or assignment (see {@link org.apache.directory.fortress.core.AdminMgr#addUser(User)}).
+     * @param ou org unit name that caller is requesting assigned to newly created User (see {@link org.apache.directory.fortress.core.AdminMgr#addUser(User)}).
+     */
+    public User( String userId, char[] password, String roleName, String ou )
+    {
+        this.userId = userId;
+        this.password = password;
+        setRole( new UserRole( roleName ) );
+        this.ou = ou;
+    }
+
+    /**
+     * Used to retrieve User's valid userId attribute.  The Fortress userId maps to 'uid' for InetOrgPerson object class.
+     *
+     * @return String containing the userId.
+     */
+    @Override
+    public String toString()
+    {
+        return "User{" +
+            "userId='" + userId + '\'' +
+            ", internalId='" + internalId + '\'' +
+            ", roles=" + roles +
+            ", adminRoles=" + adminRoles +
+            ", pwPolicy='" + pwPolicy + '\'' +
+            ", cn='" + cn + '\'' +
+            ", sn='" + sn + '\'' +
+            ", dn='" + dn + '\'' +
+            ", ou='" + ou + '\'' +
+            ", description='" + description + '\'' +
+            ", beginTime='" + beginTime + '\'' +
+            ", endTime='" + endTime + '\'' +
+            ", beginDate='" + beginDate + '\'' +
+            ", endDate='" + endDate + '\'' +
+            ", beginLockDate='" + beginLockDate + '\'' +
+            ", endLockDate='" + endLockDate + '\'' +
+            ", dayMask='" + dayMask + '\'' +
+            ", name='" + name + '\'' +
+            ", employeeType='" + employeeType + '\'' +
+            ", title='" + title + '\'' +
+            ", timeout=" + timeout +
+            ", reset=" + reset +
+            ", locked=" + locked +
+            ", system=" + system +
+            ", props=" + props +
+            ", address=" + address +
+            ", phones=" + phones +
+            ", mobiles=" + mobiles +
+            ", emails=" + emails +
+            '}';
+    }
+
+    /**
+     * Required by Constraint Interface but not needed for user entity. Not intended for external use.
+     *
+     * @return String containing constraint data ready for ldap.
+     * @throws UnsupportedOperationException
+     */
+    public String getRawData()
+    {
+        throw new UnsupportedOperationException( "not allowed for user" );
+    }
+
+
+    /**
+     * This is used internally by Fortress for Constraint operations.
+     *
+     * @return String contains name attribute used internally for constraint checking.
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+
+    /**
+     * This is used internally by Fortress for Constraint operations.  Values set here by external caller will be ignored.
+     *
+     * @param name contains attribute used internally for constraint checking.
+     */
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * Used to identify the employer to employee relationship.  Typical values used will be "Contractor", "Employee", "Intern", "Temp",
+     * "External", and "Unknown" but any value may be used.
+     *
+     * @return  attribute maps to 'employeeType' attribute in 'inetOrgPerson' object class.
+     */
+    public String getEmployeeType()
+    {
+        return employeeType;
+    }
+
+
+    /**
+     * Used to identify the employer to employee relationship.  Typical values used will be "Contractor", "Employee", "Intern", "Temp",
+     * "External", and "Unknown" but any value may be used.
+     *
+     * @param employeeType maps to 'employeeType' attribute in 'inetOrgPerson' object class.
+     */
+    public void setEmployeeType( String employeeType )
+    {
+        this.employeeType = employeeType;
+    }
+
+
+    /**
+     * The honorific prefix(es) of the User, or "Title" in most Western languages (e.g.  Ms. given the full name Ms.
+     * Barbara Jane Jensen, III.).
+     *
+     * @return maps to 'title' attribute in 'inetOrgPerson' objectclass.
+     */
+    public String getTitle()
+    {
+        return title;
+    }
+
+
+    /**
+     * The honorific prefix(es) of the User, or "Title" in most Western languages (e.g.  Ms. given the full name Ms.
+     * Barbara Jane Jensen, III.).
+     *
+     * @param title maps to 'title' attribute in 'inetOrgPerson' objectclass.
+     */
+    public void setTitle( String title )
+    {
+        this.title = title;
+    }
+
+
+    /**
+     * Return the name of the OpenLDAP password policy that is set for this user.  This attribute may be null.
+     * The attribute maps to 'pwdPolicySubentry' attribute from pwpolicy ldap object class.
+     *
+     * @return name maps to name of OpenLDAP policy in effect for User.
+     */
+    public String getPwPolicy()
+    {
+        return pwPolicy;
+    }
+
+
+    /**
+     * Sets the OpenLDAP password policy name to enable for User.  This attribute is optional but if set, will be validated to ensure
+     * contains actual OpenLDAP password policy name.
+     *
+     * @param pwPolicy parameter must contain valid OpenLDAP policy name.
+     */
+    public void setPwPolicy( String pwPolicy )
+    {
+        this.pwPolicy = pwPolicy;
+    }
+
+
+    /**
+     * Return a list of User's RBAC Roles.
+     *
+     * @return List containing User's RBAC roles.  This list may be empty if User not assigned RBAC.
+     */
+    public List<UserRole> getRoles()
+    {
+        // do not return a null List to caller:
+        if ( roles == null )
+        {
+            roles = new ArrayList<>();
+        }
+
+        return roles;
+    }
+
+
+    /**
+     * Add a list of RBAC Roles to this entity be considered for later processing:
+     * AccessMgr (user-role activation) or AdminMgr (user-role assignment).
+     *
+     * @param roles List of type UserRole that contains at minimum UserId and Role name.
+     */
+    public void setRoles( List<UserRole> roles )
+    {
+        this.roles = roles;
+    }
+
+
+    /**
+     * Add a single user-role object to the list of UserRoles for User.
+     *
+     * @param role UserRole contains {@link UserRole#name} to target for activation into {@link Session}.
+     */
+    public void setRole( UserRole role )
+    {
+        if ( roles == null )
+        {
+            roles = new ArrayList<>();
+        }
+
+        roles.add( role );
+    }
+
+
+    /**
+     * Add a single user-role object to the list of UserRoles for User.
+     *
+     * @param roleName contains role name to target for activation into {@link Session}.
+     */
+    public void setRole( String roleName )
+    {
+        if ( roles == null )
+        {
+            roles = new ArrayList<>();
+        }
+
+        roles.add( new UserRole( roleName ) );
+    }
+
+
+    /**
+     * Removes a user-role object from the list of UserRoles.
+     *
+     * @param role UserRole must contain userId and role name.
+     */
+    public void delRole( UserRole role )
+    {
+        if ( roles != null )
+        {
+            roles.remove( role );
+        }
+    }
+
+
+    /**
+     * Return a list of User's Admin Roles.
+     *
+     * @return List containing User's Admin roles.  This list may be empty if User not assigned Administrative role.
+     */
+    public List<UserAdminRole> getAdminRoles()
+    {
+        // do not return a null List to caller:
+        if ( adminRoles == null )
+        {
+            adminRoles = new ArrayList<>();
+        }
+
+        return adminRoles;
+    }
+
+
+    /**
+     * Add a single user-adminRole object to the list of UserAdminRoles for User.
+     *
+     * @param roles UserAdminRole contains at least userId and admin role name (activation) and additional constraints (assignment)
+     */
+    public void setAdminRoles( List<UserAdminRole> roles )
+    {
+        this.adminRoles = roles;
+    }
+
+
+    /**
+     * Add a single user-adminRole object to the list of UserAdminRoles for User.
+     *
+     * @param role UserAdminRole contains at least userId and adminRole name (activation) and additional constraints (assignment)
+     */
+    public void setAdminRole( UserAdminRole role )
+    {
+        if ( adminRoles == null )
+        {
+            adminRoles = new ArrayList<>();
+        }
+
+        adminRoles.add( role );
+    }
+
+
+    /**
+     * Add a single user-adminRole object to the list of UserAdminRoles for User.
+     *
+     * @param roleName contrains adminRole name.
+     */
+    public void setAdminRole( String roleName )
+    {
+        if ( adminRoles == null )
+        {
+            adminRoles = new ArrayList<>();
+        }
+
+        adminRoles.add( new UserAdminRole( userId, roleName ) );
+    }
+
+
+    /**
+     * Removes a user-adminRole object from the list of UserAdminRoles.
+     *
+     * @param adminRole UserAdminRole must contain userId and adminRole name.
+     */
+    public void delAdminRole( UserAdminRole adminRole )
+    {
+        if ( adminRoles != null )
+        {
+            adminRoles.remove( adminRole );
+        }
+    }
+
+
+    /**
+     * Return the userId that is associated with User.  UserId is required attribute and must be set on add, update, delete, createSession, authenticate, etc..
+     *
+     * @return attribute maps to 'uid' in 'inetOrgPerson' object class.
+     */
+    public String getUserId()
+    {
+        return userId;
+    }
+
+
+    /**
+     * Set the userId that is associated with User.  UserId is required attribute and must be set on add, update, delete, createSession, authenticate, etc..
+     *
+     * @param userId maps to 'uid' attribute in 'inNetOrgPerson' object class.
+     */
+    public void setUserId( String userId )
+    {
+        this.userId = userId;
+    }
+
+
+    /**
+     * Return the internal userId that is associated with User.  This attribute is generated automatically
+     * by Fortress when new User is added to directory and is not known or changeable by external client.
+     *
+     * @return attribute maps to 'ftId' in 'ftUserAttrs' object class.
+     */
+    public String getInternalId()
+    {
+        return internalId;
+    }
+
+
+    /**
+     * Set the internal userId that is associated with User.  This method is used by DAO class and
+     * is generated automatically by Fortress.  Attribute stored in LDAP cannot be changed by external caller.
+     * This method can be used by client for search purposes only.
+     *
+     * @param internalId maps to 'ftId' in 'ftUserAttrs' object class.
+     */
+    public void setInternalId( String internalId )
+    {
+        this.internalId = internalId;
+    }
+
+
+    /**
+     * Generate an internal userId that is associated with User.  This method is used by DAO class and
+     * is not available to outside classes.   The generated attribute maps to 'ftId' in 'ftUserAttrs' object class.
+     */
+    public void setInternalId()
+    {
+        UUID uuid = UUID.randomUUID();
+        internalId = uuid.toString();
+    }
+
+
+    /**
+     * Returns optional description that is associated with User.  This attribute is validated but not constrained by Fortress.
+     *
+     * @return value that is mapped to 'description' in 'inetOrgPerson' object class.
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+
+    /**
+     * Sets the optional description that is associated with User.  This attribute is validated but not constrained by Fortress.
+     *
+     * @param description that is mapped to same name in 'inetOrgPerson' object class.
+     */
+    public void setDescription( String description )
+    {
+        this.description = description;
+    }
+
+
+    /**
+     * Return the optional password attribute for User.  Note this will only return values that were set by client
+     * as the Fortress User DAO class does not return the value of stored password to caller.
+     *
+     * @return attribute containing User password.
+     */
+    public char[] getPassword()
+    {
+        return password;
+    }
+
+
+    /**
+     * Set the optional password attribute associated for a User.  Note, this value is required before User will pass Fortress
+     * authentication in {@link AccessMgrImpl#createSession(User, boolean)}.
+     * Even though password is char[] format here it will be stored on the ldap server (using server-side controls) in configurable and standard hashed formats.
+     *
+     * @param password maps to 'userPassword' attribute in 'inetOrgPerson' object class.
+     */
+    public void setPassword( char[] password )
+    {
+        this.password = password;
+    }
+
+
+    public char[] getNewPassword()
+    {
+        return newPassword;
+    }
+
+
+    public void setNewPassword( char[] newPassword )
+    {
+        this.newPassword = newPassword;
+    }
+
+
+    /**
+     * Returns common name associated with User.  This attribute is validated but not constrained by Fortress.
+     * cn is not required but if not supplied by caller on create, will default to same value as {@link #userId} attribute.
+     *
+     * @return value that is mapped to 'cn' in 'inetOrgPerson' object class.
+     */
+    public String getCn()
+    {
+        return cn;
+    }
+
+
+    /**
+     * Set the common name associated with User.  This attribute is validated but not constrained by Fortress.
+     * cn is not required but if not supplied by caller on create, will default to same value as {@link #userId} attribute.
+     *
+     * @param cn mapped to same name in 'inetOrgPerson' object class.
+     */
+    public void setCn( String cn )
+    {
+        this.cn = cn;
+    }
+
+
+    /**
+     * Returns surname associated with User.  This attribute is validated but not constrained by Fortress.
+     * sn is not required but if not supplied by caller on create, will default to same value as {@link #userId} attribute.
+     *
+     * @return value that is mapped to 'sn' in 'inetOrgPerson' object class.
+     */
+    public String getSn()
+    {
+        return sn;
+    }
+
+
+    /**
+     * Set the surname associated with User.  This attribute is validated but not constrained by Fortress.
+     * sn is not required but if not supplied by caller on create, will default to same value as {@link #userId} attribute.
+     *
+     * @param sn mapped to same name in 'inetOrgPerson' object class.
+     */
+    public void setSn( String sn )
+    {
+        this.sn = sn;
+    }
+
+
+    /**
+     * Returns distinguished name associated with User.  This attribute is generated by DAO and is not allowed for outside classes to modify.
+     * This attribute is for internal user only and need not be processed by external clients.
+     *
+     * @return value that is mapped to 'dn' in 'inetOrgPerson' object class.
+     */
+    public String getDn()
+    {
+        return dn;
+    }
+
+
+    /**
+     * Set distinguished name associated with User.  This attribute is used by DAO and is not allowed for outside classes.
+     * This attribute cannot be set by external callers.
+     *
+     * @param dn that is mapped to same name in 'inetOrgPerson' object class.
+     */
+    public void setDn( String dn )
+    {
+        this.dn = dn;
+    }
+
+
+    /**
+     * Returns orgUnit name for User.  This attribute is validated and constrained by Fortress and must contain name of existing User OU.
+     * This attribute is required on {@link AdminMgrImpl#addUser(User)} but not on {@link ReviewMgrImpl#readUser(User)}.
+     *
+     * @return value that is mapped to 'ou' in 'inetOrgPerson' object class.
+     */
+    public String getOu()
+    {
+        return ou;
+    }
+
+
+    /**
+     * Set the orgUnit name associated with User.  This attribute is validated and constrained by Fortress and must contain name of existing User OU.
+     * This attribute is required on {@link AdminMgrImpl#addUser(User)} but not on {@link ReviewMgrImpl#readUser(User)}.
+     *
+     * @param ou mapped to same name in 'inetOrgPerson' object class.
+     */
+    public void setOu( String ou )
+    {
+        this.ou = ou;
+    }
+
+
+    /**
+     * Optional attribute maps to 'displayName' attribute on inetOrgPerson object class.
+     *
+     * @return value that is mapped to 'displayName' in 'inetOrgPerson' object class.
+     */
+    public String getDisplayName()
+    {
+        return displayName;
+    }
+
+    /**
+     * Optional attribute maps to 'displayName' attribute on inetOrgPerson object class.
+     *
+     * @param displayName maps to attribute of same name in 'inetOrgPerson' object class.
+     */
+    public void setDisplayName( String displayName )
+    {
+        this.displayName = displayName;
+    }
+
+    /**
+     * temporal boolean flag is used by internal Fortress components.
+     *
+     * @return boolean indicating if temporal constraints are placed on user.
+     */
+    @Override
+    public boolean isTemporalSet()
+    {
+        //return (beginTime != null && endTime != null && beginDate != null && endDate != null && beginLockDate != null && endLockDate != null && dayMask != null);
+        return ( beginTime != null || endTime != null || beginDate != null || endDate != null || beginLockDate != null
+            || endLockDate != null || dayMask != null );
+    }
+
+
+    /**
+     * Contains the begin time of day user is allowed to signon to 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 attribute maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getBeginTime()
+    {
+        return beginTime;
+    }
+
+
+    /**
+     * Set the begin time of day user is allowed to signon to 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 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setBeginTime( String beginTime )
+    {
+        this.beginTime = beginTime;
+    }
+
+
+    /**
+     * Contains the end time of day user is allowed to occupy 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 attribute maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getEndTime()
+    {
+        return endTime;
+    }
+
+
+    /**
+     * Set the end time of day user is allowed to signon to 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 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setEndTime( String endTime )
+    {
+        this.endTime = endTime;
+    }
+
+
+    /**
+     * Contains the begin date when user is allowed to signon to system.  The format is - YYYYMMDD, i.e. 20100101 (January 1. 2010).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return attribute maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getBeginDate()
+    {
+        return beginDate;
+    }
+
+
+    /**
+     * Set the beginDate when user is allowed to signon to system.  The format is - YYYYMMDD, i.e. 20100101 (January 1. 2010).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param beginDate maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setBeginDate( String beginDate )
+    {
+        this.beginDate = beginDate;
+    }
+
+
+    /**
+     * Contains the end date when user is allowed to signon to system.  The format is - YYYYMMDD, i.e. 20101231 (December 31, 2010).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return attribute maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getEndDate()
+    {
+        return endDate;
+    }
+
+
+    /**
+     * Set the end date when user is not allowed to signon to 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 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setEndDate( String endDate )
+    {
+        this.endDate = endDate;
+    }
+
+
+    /**
+     * Contains the begin lock date when user is temporarily not allowed to signon to system.  The format is - YYYYMMDD, i.e. 20100101 (January 1. 2010).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return attribute maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getBeginLockDate()
+    {
+        return beginLockDate;
+    }
+
+
+    /**
+     * Set the begin lock date when user is temporarily not allowed to signon to system.  The format is - YYYYMMDD, i.e. 20100101 (January 1. 2010).
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param beginLockDate maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setBeginLockDate( String beginLockDate )
+    {
+        this.beginLockDate = beginLockDate;
+    }
+
+
+    /**
+     * Contains the end lock date when user is allowed to signon to 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 attribute maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getEndLockDate()
+    {
+        return endLockDate;
+    }
+
+
+    /**
+     * Set the end lock date when user is allowed to signon to 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 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setEndLockDate( String endLockDate )
+    {
+        this.endLockDate = endLockDate;
+    }
+
+
+    /**
+     * Get the daymask that indicates what days of week user is allowed to signon to 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 attribute maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public String getDayMask()
+    {
+        return dayMask;
+    }
+
+
+    /**
+     * Set the daymask that specifies what days of week user is allowed to signon to 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 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setDayMask( String dayMask )
+    {
+        this.dayMask = dayMask;
+    }
+
+
+    /**
+     * Return the integer timeout that contains total time (in seconds) that User's session may remain inactive.
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return attribute maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public Integer getTimeout()
+    {
+        return timeout;
+    }
+
+
+    /**
+     * Set the integer timeout that contains max time (in seconds) that User's session may remain inactive.
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param timeout maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    @Override
+    public void setTimeout( Integer timeout )
+    {
+        this.timeout = timeout;
+    }
+
+
+    /**
+     * If set to true User's password has been reset by administrator.
+     * This attribute will be ignored if set by external callers.
+     *
+     * @return boolean value maps to 'pwdResetTime' in OpenLDAP's pwpolicy object class.
+     */
+    public boolean isReset()
+    {
+        return reset;
+    }
+
+
+    /**
+     * If set to true User's password has been reset by administrator.
+     * This attribute will be ignored if set by external callers.
+     *
+     * @param reset contains boolean value which maps to 'pwdResetTime' in OpenLDAP's pwpolicy object class.
+     */
+    public void setReset( boolean reset )
+    {
+        this.reset = reset;
+    }
+
+
+    /**
+     * If set to true User's password has been locked by administrator or directory itself due to password policy violations.
+     * This attribute will be ignored if set by external callers.
+     *
+     * @return boolean value maps to 'pwdLockedTime' in OpenLDAP's pwpolicy object class.
+     */
+    public boolean isLocked()
+    {
+        return locked;
+    }
+
+
+    /**
+     * If set to true User's password has been locked by administrator or directory itself due to password policy violations.
+     * This attribute will be ignored if set by external callers.
+     *
+     * @param locked contains boolean value which maps to 'pwdResetTime' in OpenLDAP's pwpolicy object class.
+     */
+    public void setLocked( boolean locked )
+    {
+        this.locked = locked;
+    }
+
+
+    /**
+     * Gets the value of the Props property.  This method is used by Fortress and En Masse and should not be called by external programs.
+     *
+     * @return
+     *     possible object is
+     *     {@link Props }
+     *
+     */
+    public Props getProps()
+    {
+        return props;
+    }
+
+
+    /**
+     * Sets the value of the Props property.  This method is used by Fortress and En Masse and should not be called by external programs.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link Props }
+     *
+     */
+    public void setProps( Props value )
+    {
+        this.props = value;
+    }
+
+
+    /**
+     * Add name/value pair to list of properties associated with User.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param key   contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     * @param value
+     */
+    public void addProperty( String key, String value )
+    {
+        Props.Entry entry = new Props.Entry();
+        entry.setKey( key );
+        entry.setValue( value );
+        props.getEntry().add( entry );
+    }
+
+
+    /**
+     * Get a name/value pair attribute from list of properties associated with User.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param key contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     * @return value containing name/value pair that maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public String getProperty( String key )
+    {
+        List<Props.Entry> props = this.props.getEntry();
+        Props.Entry keyObj = new Props.Entry();
+        keyObj.setKey( key );
+
+        String value = null;
+        int indx = props.indexOf( keyObj );
+
+        if ( indx != -1 )
+        {
+            Props.Entry entry = props.get( props.indexOf( keyObj ) );
+            value = entry.getValue();
+        }
+
+        return value;
+    }
+
+
+    /**
+     * Add new collection of name/value pairs to attributes associated with User.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param props contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public void addProperties( Properties props )
+    {
+        if ( props != null )
+        {
+            for ( Enumeration<?> e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+                addProperty( key, val );
+            }
+        }
+    }
+
+
+    /**
+     * Return the collection of name/value pairs to attributes associated with User.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @return Properties contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public Properties getProperties()
+    {
+        Properties properties = null;
+        List<Props.Entry> props = this.props.getEntry();
+
+        if ( props.size() > 0 )
+        {
+            properties = new Properties();
+
+            for ( Props.Entry entry : props )
+            {
+                String key = entry.getKey();
+                String val = entry.getValue();
+                properties.setProperty( key, val );
+            }
+        }
+
+        return properties;
+    }
+
+
+    /**
+     * Get address data from entity that was persisted in directory as attributes defined by RFC 2798's LDAP inetOrgPerson Object Class:
+     *
+     * <ul>
+     * <li>  ------------------------------------------
+     * <li> <code>postalAddress</code>
+     * <li> <code>st</code>
+     * <li> <code>postalCode</code>
+     * <li> <code>postOfficeBox</code>
+     * <li>  ------------------------------------------
+     * </ul>
+     *
+     * @return {@link Address}
+     */
+    public Address getAddress()
+    {
+        if ( address == null )
+        {
+            address = new Address();
+        }
+
+        return address;
+    }
+
+
+    /**
+     * Set address data onto entity that stored in directory as attributes defined by RFC 2798's LDAP inetOrgPerson Object Class:
+     *
+     * <ul>
+     * <li>  ------------------------------------------
+     * <li> <code>postalAddress</code>
+     * <li> <code>st</code>
+     * <li> <code>postalCode</code>
+     * <li> <code>postOfficeBox</code>
+     * <li>  ------------------------------------------
+     * </ul>
+     *
+     * @param address
+     */
+    public void setAddress( Address address )
+    {
+        this.address = address;
+    }
+
+
+    /**
+     * Retrieve multi-occurring {@code telephoneNumber} associated with {@code organizationalPerson} object class.
+     *
+     * @return List of type String that contains zero or more phone numbers associated with the user.
+     */
+    public List<String> getPhones()
+    {
+        if ( phones == null )
+        {
+            phones = new ArrayList<>();
+        }
+
+        return phones;
+    }
+
+
+    /**
+     * Set multi-occurring {@code telephoneNumber} number to associated with {@code organizationalPerson} object class.
+     *
+     * @param phones contains an ArrayList of type String with zero or more phone numbers associated with the user.
+     */
+    public void setPhones( List<String> phones )
+    {
+        this.phones = phones;
+    }
+
+
+    /**
+     * Set phone number to stored in rfc822Mailbox format and associated with {@code inetOrgPerson} object class.
+     *
+     * @param phone contains String bound to {@code telephoneNumber} attribute on {@code organizationalPerson} object class.
+     */
+    public void setPhone( String phone )
+    {
+        if ( phones == null )
+        {
+            phones = new ArrayList<>();
+        }
+
+        phones.add( phone );
+    }
+
+
+    /**
+     * Retrieve multi-occurring {@code mobile} associated with {@code inetOrgPerson} object class.
+     *
+     * @return List of type String that contains zero or more mobile phone numbers associated with the user.
+     */
+    public List<String> getMobiles()
+    {
+        if ( mobiles == null )
+        {
+            mobiles = new ArrayList<>();
+        }
+
+        return mobiles;
+    }
+
+
+    /**
+     * Set multi-occurring {@code mobile} associated with {@code inetOrgPerson} object class.
+     *
+     * @param mobiles contains an ArrayList of type String with zero or more mobile phone numbers associated with the user.
+     */
+    public void setMobiles( List<String> mobiles )
+    {
+        this.mobiles = mobiles;
+    }
+
+
+    /**
+     * Set a single {@code mobile} associated with {@code inetOrgPerson} object class.
+     *
+     * @param mobile contains a String containing mobile phone numbers associated with the user.
+     */
+    public void setMobile( String mobile )
+    {
+        if ( mobiles == null )
+        {
+            mobiles = new ArrayList<>();
+        }
+
+        mobiles.add( mobile );
+    }
+
+
+    /**
+     * Retrieve multi-occurring email address stored in rfc822Mailbox format associated with {@code inetOrgPerson} object class.
+     *
+     * @return List of type String that contains zero or more email addresses associated with the user.
+     */
+    public List<String> getEmails()
+    {
+        if ( emails == null )
+        {
+            emails = new ArrayList<>();
+        }
+
+        return emails;
+    }
+
+
+    /**
+     * Set multi-occurring email address to stored in rfc822Mailbox format and associated with {@code inetOrgPerson} object class.
+     *
+     * @param emails contains an ArrayList of type String with zero or more email addresses associated with the user.
+     */
+    public void setEmails( List<String> emails )
+    {
+        this.emails = emails;
+    }
+
+
+    /**
+     * Set a single email address in rfc822Mailbox format to be assoicated with {@code inetOrgPerson} object class.
+     *
+     * @param email contains a String to be stored as email address on user.
+     */
+    public void setEmail( String email )
+    {
+        if ( emails == null )
+        {
+            emails = new ArrayList<>();
+        }
+
+        emails.add( email );
+    }
+
+
+    public Boolean isSystem()
+    {
+        return system;
+    }
+
+
+    public void setSystem( Boolean system )
+    {
+        this.system = system;
+    }
+
+
+    /**
+     * Get one image of a person using the JPEG File Interchange Format [JFIF].
+     * ( 0.9.2342.19200300.100.1.60
+     * NAME 'jpegPhoto'
+     * DESC 'a JPEG image'
+     * SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 )
+     *
+     * return byte array containing the jpeg image.
+     */
+    public byte[] getJpegPhoto()
+    {
+        return jpegPhoto;
+    }
+
+
+    /**
+     * Set one image of a person using the JPEG File Interchange Format [JFIF].
+     * ( 0.9.2342.19200300.100.1.60
+     * NAME 'jpegPhoto'
+     * DESC 'a JPEG image'
+     * SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 )
+     *
+     * @param jpegPhoto contains the jpeg image stored as byte array.
+     */
+    public void setJpegPhoto( byte[] jpegPhoto )
+    {
+        this.jpegPhoto = jpegPhoto;
+    }
+
+
+    /**
+     * Override hashcode so User compare operations work in case insensitive manner in collection classes.
+     *
+     * @return int
+     */
+    public int hashCode()
+    {
+        return userId.toUpperCase().hashCode();
+    }
+
+
+    /**
+     * Matches the userId from two User entities.
+     *
+     * @param thatObj contains a User entity.
+     * @return boolean indicating both objects contain matching userIds.
+     */
+    public boolean equals( Object thatObj )
+    {
+        if ( this == thatObj )
+        {
+            return true;
+        }
+
+        if ( userId == null )
+        {
+            return false;
+        }
+
+        if ( !( thatObj instanceof User ) )
+        {
+            return false;
+        }
+
+        User thatUser = ( User ) thatObj;
+
+        if ( thatUser.getUserId() == null )
+        {
+            return false;
+        }
+
+        return thatUser.getUserId().equalsIgnoreCase( userId );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/UserAdminRole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/UserAdminRole.java b/src/main/java/org/apache/directory/fortress/core/rbac/UserAdminRole.java
new file mode 100755
index 0000000..d6719e4
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/UserAdminRole.java
@@ -0,0 +1,613 @@
+/*
+ *   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 java.util.TreeSet;
+
+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.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 UserAdminRole entity extends the UserRole and is used to store ARBAC User to AdminRole assignment along with temporal and
+ * ARBAC contraint values.
+ * The contents of the UserAdminRole entity will be stored on the User entity in the 'ftARA' (AdminRole name) and 'ftARC' (Temporal and ARBAC Constraints) attributes on the 'ftUserAttrs' object class.
+ * The UserAdminRole 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.AdminRole} entity.  Thus the UserAdminRole can override Constraint attributes from it's corresponding AdminRole if required by caller.
+ * <p/>
+ * <h4>UserAdminRole 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
+ */
+/*
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "userAdminRole", propOrder = {
+    "beginInclusive",
+    "beginRange",
+    "endInclusive",
+    "endRange",
+    "osP",
+    "osU",
+    "roleRangeRaw"
+})
+*/
+@XmlRootElement(name = "fortUserAdminRole")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "userAdminRole", propOrder =
+    {
+        "osPs",
+        "osUs",
+        "beginInclusive",
+        "beginRange",
+        "endInclusive",
+        "endRange",
+        "parents"
+})
+public class UserAdminRole extends UserRole implements Administrator
+{
+    @XmlElement(nillable = true)
+    private Set<String> osPs;
+    @XmlElement(nillable = true)
+    private Set<String> osUs;
+    private String beginRange;
+    private String endRange;
+    private boolean beginInclusive;
+    private boolean endInclusive;
+    @XmlElement(nillable = true)
+    private Set<String> parents;
+
+    // Used for formatting raw data:
+    private static String P = "P";
+    private static String U = "U";
+    private static String R = "R";
+    private static String LEFT_PAREN = "(";
+    private static String RIGHT_PAREN = ")";
+    private static String LEFT_BRACKET = "[";
+    private static String RIGHT_BRACKET = "]";
+
+
+    /**
+     * Default constructor is used by internal Fortress classes.
+     */
+    public UserAdminRole()
+    {
+    }
+
+
+    /**
+     * 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 name   maps to the 'ftARA' attribute on the 'ftUserAttrs' object class.
+     */
+    public UserAdminRole( String userId, String name )
+    {
+        this.userId = userId;
+        this.name = name;
+    }
+
+
+    /**
+     * Construct an ARBAC 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 'ftARC' attribute in 'ftUserAttrs' object class.
+     */
+    public UserAdminRole( String userId, Constraint con )
+    {
+        this.userId = userId;
+        CUtil.copy( con, this );
+    }
+
+
+    /**
+     * This method loads UserAdminRole entity temporal and ARBAC constraint instance variables with data that was retrieved from the
+     * 'ftARC' attribute on the 'ftUserAttrs' object class.  This is the raw format that Fortress uses to condense the temporal and ARBAC 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 'ftARC' 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:
+                            this.setTimeout( Integer.parseInt( tokens[i] ) );
+                            break;
+
+                        case 2:
+                            this.setBeginTime( tokens[i] );
+                            break;
+
+                        case 3:
+                            this.setEndTime( tokens[i] );
+                            break;
+
+                        case 4:
+                            this.setBeginDate( tokens[i] );
+                            break;
+
+                        case 5:
+                            this.setEndDate( tokens[i] );
+                            break;
+
+                        case 6:
+                            this.setBeginLockDate( tokens[i] );
+                            break;
+
+                        case 7:
+                            this.setEndLockDate( tokens[i] );
+                            break;
+
+                        case 8:
+                            this.setDayMask( tokens[i] );
+                            break;
+
+                        default:
+                            String szValue = tokens[i];
+                            int indx = szValue.indexOf( P + GlobalIds.PROP_SEP );
+                            if ( indx >= 0 )
+                            {
+                                String szOsP = szValue.substring( indx + 2 );
+                                this.setOsP( szOsP );
+                            }
+                            indx = szValue.indexOf( U + GlobalIds.PROP_SEP );
+                            if ( indx >= 0 )
+                            {
+                                String szOsU = szValue.substring( indx + 2 );
+                                this.setOsU( szOsU );
+                            }
+                            indx = szValue.indexOf( R + GlobalIds.PROP_SEP );
+                            if ( indx >= 0 )
+                            {
+                                String szRangeRaw = szValue.substring( indx + 2 );
+                                this.setRoleRangeRaw( szRangeRaw );
+                            }
+                            break;
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * This method creates raw data format that represents UserAdminRole temporal and ARBAC constraints using instance variables inside entity.
+     * The raw data is eventually stored in the 'ftARC' attribute on the 'ftUserAttrs' object class.
+     * This is the raw format that Fortress uses to condense the temporal and ARBAC data into a compact String for efficient storage and retrieval
+     * and is not intended to be called by external programs.
+     *
+     * @return String contains a raw formatted String that maps to 'ftARC' attribute on 'ftUserAttrs' object class
+     */
+    @Override
+    public String getRawData()
+    {
+        String szRole;
+        StringBuilder sb = new StringBuilder();
+        sb.append( name );
+        sb.append( GlobalIds.DELIMITER );
+        sb.append( this.getTimeout() );
+        sb.append( GlobalIds.DELIMITER );
+        if ( this.getBeginTime() != null )
+            sb.append( this.getBeginTime() );
+        sb.append( GlobalIds.DELIMITER );
+        if ( this.getEndTime() != null )
+            sb.append( this.getEndTime() );
+        sb.append( GlobalIds.DELIMITER );
+        if ( this.getBeginDate() != null )
+            sb.append( this.getBeginDate() );
+        sb.append( GlobalIds.DELIMITER );
+        if ( this.getEndDate() != null )
+            sb.append( this.getEndDate() );
+        sb.append( GlobalIds.DELIMITER );
+        if ( this.getBeginLockDate() != null )
+            sb.append( this.getBeginLockDate() );
+        sb.append( GlobalIds.DELIMITER );
+        if ( this.getEndLockDate() != null )
+            sb.append( this.getEndLockDate() );
+        sb.append( GlobalIds.DELIMITER );
+        if ( this.getDayMask() != null )
+            sb.append( this.getDayMask() );
+        if ( this.getOsU() != null )
+        {
+            for ( String org : this.getOsU() )
+            {
+                sb.append( GlobalIds.DELIMITER );
+                sb.append( U );
+                sb.append( GlobalIds.PROP_SEP );
+                sb.append( org );
+            }
+        }
+        if ( this.getOsP() != null )
+        {
+            for ( String org : this.getOsP() )
+            {
+                sb.append( GlobalIds.DELIMITER );
+                sb.append( P );
+                sb.append( GlobalIds.PROP_SEP );
+                sb.append( org );
+            }
+        }
+        if ( VUtil.isNotNullOrEmpty( this.getRoleRangeRaw() ) )
+        {
+            sb.append( GlobalIds.DELIMITER );
+            sb.append( R );
+            sb.append( GlobalIds.PROP_SEP );
+            sb.append( this.getRoleRangeRaw() );
+        }
+
+        szRole = sb.toString();
+        return szRole;
+    }
+
+
+    /**
+     * This method loads UserAdminRole entity Role range ARBAC constraint instance variables with data that was retrieved from the
+     * 'ftARC' attribute on the 'ftUserAttrs' object class.  This is the raw format that Fortress uses to condense the ARBAC data into
+     * a compact String for efficient storage and retrieval and is not intended to be called by external programs.
+     *
+     * @param szRaw contains a raw formatted String that maps to 'ftARC' attribute on 'ftUserAttrs' object class
+     */
+    @Override
+    public void setRoleRangeRaw( String szRaw )
+    {
+        if ( VUtil.isNotNullOrEmpty( szRaw ) )
+        {
+            int bindx = szRaw.indexOf( LEFT_PAREN );
+            if ( bindx > -1 )
+            {
+                this.setBeginInclusive( false );
+            }
+            else
+            {
+                bindx = szRaw.indexOf( LEFT_BRACKET );
+                this.setBeginInclusive( true );
+            }
+            int eindx = szRaw.indexOf( RIGHT_PAREN );
+            if ( eindx > -1 )
+            {
+                this.setEndInclusive( false );
+            }
+            else
+            {
+                eindx = szRaw.indexOf( RIGHT_BRACKET );
+                this.setEndInclusive( true );
+            }
+            int cindx = szRaw.indexOf( GlobalIds.PROP_SEP );
+            if ( cindx > -1 )
+            {
+                String szBeginRange = szRaw.substring( bindx + 1, cindx );
+                String szEndRange = szRaw.substring( cindx + 1, eindx );
+                this.setBeginRange( szBeginRange );
+                this.setEndRange( szEndRange );
+            }
+        }
+    }
+
+
+    /**
+     * This method retrieves UserAdminRole instance variables and formats into raw data for ARBAC constraint storage for the
+     * 'ftARC' attribute on the 'ftUserAttrs' object class.  This is the raw format that Fortress uses to condense the ARBAC data into
+     * a compact String for efficient storage and retrieval and is not intended to be called by external programs.
+     *
+     * @return String contains a raw formatted String that maps to 'ftARC' attribute on 'ftUserAttrs' object class
+     */
+    @Override
+    public String getRoleRangeRaw()
+    {
+        String szRaw = "";
+        if ( this.beginRange != null )
+        {
+            if ( this.isBeginInclusive() )
+                szRaw += LEFT_BRACKET;
+            else
+                szRaw += LEFT_PAREN;
+            szRaw += this.getBeginRange();
+            szRaw += GlobalIds.PROP_SEP;
+            szRaw += this.getEndRange();
+            if ( this.isEndInclusive() )
+                szRaw += RIGHT_BRACKET;
+            else
+                szRaw += RIGHT_PAREN;
+        }
+        return szRaw;
+    }
+
+
+    /**
+     * Get a collection of optional Perm OU attributes that were stored on the AdminRole entity.
+     *
+     * @return List of type String containing Perm OU.  This maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public Set<String> getOsP()
+    {
+        return osPs;
+    }
+
+
+    /**
+     * Set a collection of optional Perm OU attributes to be stored on the AdminRole entity.
+     *
+     * @param osPs is a List of type String containing Perm OU.  This maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public void setOsP( Set<String> osPs )
+    {
+        this.osPs = osPs;
+    }
+
+
+    /**
+     * Set a Perm OU attribute to be stored on the AdminRole entity.
+     *
+     * @param osP is a Perm OU that maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public void setOsP( String osP )
+    {
+        if ( this.osPs == null )
+        {
+            // create Set with case insensitive comparator:
+            osPs = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        }
+        osPs.add( osP );
+    }
+
+
+    /**
+     * Get a collection of optional User OU attributes that were stored on the AdminRole entity.
+     *
+     * @return List of type String containing User OU.  This maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public Set<String> getOsU()
+    {
+        return osUs;
+    }
+
+
+    /**
+     * Set a collection of optional User OU attributes to be stored on the AdminRole entity.
+     *
+     * @param osUs is a List of type String containing User OU.  This maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public void setOsU( Set<String> osUs )
+    {
+        this.osUs = osUs;
+    }
+
+
+    /**
+     * Set a User OU attribute to be stored on the AdminRole entity.
+     *
+     * @param osU is a User OU that maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public void setOsU( String osU )
+    {
+        if ( this.osUs == null )
+        {
+            // create Set with case insensitive comparator:
+            osUs = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        }
+        osUs.add( osU );
+    }
+
+
+    /**
+     * Return the begin Role range attribute for AdminRole entity.
+     *
+     * @return String that maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public String getBeginRange()
+    {
+        return beginRange;
+    }
+
+
+    /**
+     * Set the begin Role range attribute for AdminRole entity.
+     *
+     * @param beginRange maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public void setBeginRange( String beginRange )
+    {
+        this.beginRange = beginRange;
+    }
+
+
+    /**
+     * Return the end Role range attribute for AdminRole entity.
+     *
+     * @return String that maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public String getEndRange()
+    {
+        return endRange;
+    }
+
+
+    /**
+     * Set the end Role range attribute for AdminRole entity.
+     *
+     * @param endRange maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public void setEndRange( String endRange )
+    {
+        this.endRange = endRange;
+    }
+
+
+    /**
+     * Set the begin inclusive which specifies if role range includes or excludes the 'beginRange' attribute.
+     *
+     * @return String that maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public boolean isBeginInclusive()
+    {
+        return beginInclusive;
+    }
+
+
+    /**
+     * Get the begin inclusive which specifies if role range includes or excludes the 'beginRange' attribute.
+     *
+     * @param beginInclusive maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public void setBeginInclusive( boolean beginInclusive )
+    {
+        this.beginInclusive = beginInclusive;
+    }
+
+
+    /**
+     * Set the end inclusive which specifies if role range includes or excludes the 'endRange' attribute.
+     *
+     * @return String that maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public boolean isEndInclusive()
+    {
+        return endInclusive;
+    }
+
+
+    /**
+     * Get the end inclusive which specifies if role range includes or excludes the 'endRange' attribute.
+     *
+     * @param endInclusive maps to 'ftARC' attribute on 'ftUserAttrs' aux object class.
+     */
+    @Override
+    public void setEndInclusive( boolean endInclusive )
+    {
+        this.endInclusive = endInclusive;
+    }
+
+
+    /**
+     * Get the names of admin roles that are parents (direct ascendants) of this admin role.
+     * @return Set of parent admin role names assigned to this admin role.
+     */
+    @Override
+    public Set<String> getParents()
+    {
+        return parents;
+    }
+
+
+    /**
+     * Set the names of parent admin roles.
+     * @param parents Set of admin role names.
+     */
+    @Override
+    public void setParents( Set<String> parents )
+    {
+        this.parents = parents;
+    }
+
+
+    /**
+     * Matches the userId and admin role name from two UserAdminRole entities.
+     *
+     * @param thatObj contains a UserAdminRole entity.
+     * @return boolean indicating both objects contain matching userId and Admin Role names.
+     */
+    public boolean equals( Object thatObj )
+    {
+        if ( this == thatObj )
+        {
+            return true;
+        }
+
+        if ( this.getName() == null )
+        {
+            return false;
+        }
+
+        if ( !( thatObj instanceof UserAdminRole ) )
+        {
+            return false;
+        }
+
+        UserAdminRole thatRole = ( UserAdminRole ) thatObj;
+
+        if ( thatRole.getName() == null )
+        {
+            return false;
+        }
+
+        return ( ( thatRole.getName().equalsIgnoreCase( this.getName() ) ) && ( thatRole.getUserId()
+            .equalsIgnoreCase( this.getUserId() ) ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/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
new file mode 100755
index 0000000..dc98611
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/UserAudit.java
@@ -0,0 +1,289 @@
+/*
+ *   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.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;
+
+/**
+ * This entity is used to pass search criteria into the {@link org.apache.directory.fortress.core.AuditMgr} APIs, down through the
+ * {@link org.apache.directory.fortress.core.rbac.AuditP} process layer and finally into the {@link AuditDAO} data access layer.  Once the data has been
+ * retrieved from the directory it will be passed back to the caller using one of audit output entities.
+ * <p/>
+ * All audit data is returned to user using one of the following:
+ * <ul>
+ * <li> Authorization events: {@link org.apache.directory.fortress.core.rbac.AuthZ}
+ * <li> Authentication events: {@link org.apache.directory.fortress.core.rbac.Bind}
+ * <li> Modification events: {@link org.apache.directory.fortress.core.rbac.Mod}
+ * </ul>
+ * <p/>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortUserAudit")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "userAudit", propOrder = {
+    "name",
+    "description",
+    "failedOnly",
+    "objName",
+    "objId",
+    "opName",
+    "userId",
+    "internalUserId",
+    "beginDate",
+    "endDate",
+    "dn",
+    "admin"
+})
+public class UserAudit extends FortEntity implements java.io.Serializable
+{
+    private String name;
+    private String description;
+    private boolean failedOnly;
+    private String objName;
+    private String objId;
+    private String opName;
+    private String userId;
+    private String internalUserId;
+    @XmlElement(nillable = true)
+    private Date beginDate;
+    @XmlElement(nillable = true)
+    private Date endDate;
+    private String dn;
+    private boolean admin = false;
+
+    /**
+     * Get the optional objName attribute which limits set by {@link Permission#objName}.
+     * For modification search, this attr maps to {@link AuditDAO#REQMOD}.  For authorization search, it will map to {@link AuditDAO#REQDN}.
+     * The object name is derived from another class name which represents targets for Fortress authorizations. For example {@link AdminMgrImpl} or 'CustomerCheckOutPage'.
+     *
+     * @return the name of the object which maps to 'reqDn' for 'auditSearch' target, or 'reqMod' for 'auditMod' search.
+     */
+    public String getObjName()
+    {
+        return objName;
+    }
+
+    /**
+     * Set the optional objName attribute which limits set by {@link Permission#objName}.
+     * For modification search, this attr maps to {@link AuditDAO#REQMOD}.  For authorization search, it will map to {@link AuditDAO#REQDN}.
+     * The object name is derived from another class name which represents targets for Fortress authorizations. For example {@link AdminMgrImpl} or 'CustomerCheckOutPage'.
+     *
+     * @param objName maps to 'reqDn' for 'auditSearch' target, or 'reqMod' for 'auditMod' search.
+     */
+    public void setObjName(String objName)
+    {
+        this.objName = objName;
+    }
+
+    /**
+     * The failedOnly flag will limit result set to include only authN or authZ events that have failed.
+     * <p/>
+     * <ul>
+     * <li>{@link AuditMgrImpl#searchInvalidUsers(UserAudit)} maps to ({@link AuditDAO#REQENTRIES} == 0)
+     * <li>{@link AuditMgrImpl#searchAuthZs(UserAudit)} maps to ({@link AuditDAO#REQENTRIES} == 0)
+     * <li>{@link AuditMgrImpl#searchBinds(UserAudit)} maps to ({@link AuditDAO#REQRESULT} >= 1)
+     * </ul>
+     *
+     * @return boolean if true will limit search to failed events.
+     */
+    public boolean isFailedOnly()
+    {
+        return failedOnly;
+    }
+
+    /**
+     * The failedOnly flag will limit result set to include only authN or authZ events that have failed.
+     * <p/>
+     * <ul>
+     * <li>{@link AuditMgrImpl#searchInvalidUsers(UserAudit)} maps to ({@link AuditDAO#REQENTRIES} == 0)
+     * <li>{@link AuditMgrImpl#searchAuthZs(UserAudit)} maps to ({@link AuditDAO#REQENTRIES} == 0)
+     * <li>{@link AuditMgrImpl#searchBinds(UserAudit)} maps to ({@link AuditDAO#REQRESULT} >= 1)
+     * </ul>
+     *
+     * @param failedOnly if boolean true search will limit to failed only.
+     */
+    public void setFailedOnly(boolean failedOnly)
+    {
+        this.failedOnly = failedOnly;
+    }
+
+    /**
+     * Get the optional opName attribute which limits {@link AuditMgrImpl#searchAdminMods(UserAudit)} by {@link AuditDAO#REQMOD}.
+     * The operation name is derived from a method name of a class which represents targets for Fortress authorizations. For example 'read', 'search' or 'add'.
+     *
+     * @return value that maps to 'reqMod' on 'auditMod' object class.
+     */
+    public String getOpName()
+    {
+        return opName;
+    }
+
+    /**
+     * Set the optional opName attribute which limits {@link AuditMgrImpl#searchAdminMods(UserAudit)} by {@link AuditDAO#REQMOD}.
+     * The operation name is derived from a method name of a class which represents targets for Fortress authorizations. For example 'read', 'search' or 'add'.
+     *
+     * @param opName attribute maps to 'reqMod' on 'auditMod' object class.
+     */
+    public void setOpName(String opName)
+    {
+        this.opName = opName;
+    }
+
+    /**
+     * Get the optional userId attribute which limits set by {@link org.apache.directory.fortress.core.rbac.User#userId}.
+     * For authentication searchs, this attr maps to {@link AuditDAO#REQDN}.  For authorization search, it will map to {@link AuditDAO#REQUAUTHZID}.
+     * The userId for this search represents the end user.
+     *
+     * @return the userId which maps to 'reqDn' for authentications or 'reqAuthzID' for authorization events.
+     */
+    public String getUserId()
+    {
+        return userId;
+    }
+
+    /**
+     * Set the optional userId attribute which limits set by {@link org.apache.directory.fortress.core.rbac.User#userId}.
+     * For authentication searchs, this attr maps to {@link AuditDAO#REQDN}.  For authorization search, it will map to {@link AuditDAO#REQUAUTHZID}.
+     * The userId for this search represents the end user.
+     *
+     * @param userId maps to 'reqDn' for authentications or 'reqAuthzID' for authorization events.
+     */
+    public void setUserId(String userId)
+    {
+        this.userId = userId;
+    }
+
+    /**
+     * Get the optional internalUserId attribute which limits set by {@link org.apache.directory.fortress.core.rbac.User#internalId}.
+     * For {@link AuditMgrImpl#searchUserSessions(UserAudit)} this attr maps to {@link AuditDAO#REQMOD}.
+     * The internalUserId for this search represents the end user but is stored as its internal id.
+     *
+     * @return the internalUserId which maps to 'reqMod' for 'auditModify' object class searches.
+     */
+    public String getInternalUserId()
+    {
+        return internalUserId;
+    }
+
+    /**
+     * Set the optional internalUserId attribute which limits set by {@link org.apache.directory.fortress.core.rbac.User#internalId}.
+     * For {@link AuditMgrImpl#searchUserSessions(UserAudit)} this attr maps to {@link AuditDAO#REQMOD}.
+     * The internalUserId for this search represents the end user but is stored as its internal id.
+     *
+     * @param internalUserId maps to 'reqMod' for 'auditModify' object class searches.
+     */
+    public void setInternalUserId(String internalUserId)
+    {
+        this.internalUserId = internalUserId;
+    }
+
+    /**
+     * Get the Date for search to begin.  The earlier the date, the more records will be returned.
+     * This attribute is mapped to 'reqStart' on slapd audit records which provides the start
+     * time of the operation which is also the rDn for the node.
+     *
+     * @return attribute that maps to 'reqStart' in audit object classes.
+     */
+    public Date getBeginDate()
+    {
+        return beginDate;
+    }
+
+    /**
+     * Set the Date for search to begin.  The earlier the date, the more records will be returned.
+     * This attribute is mapped to 'reqStart' on slapd audit records which provides the start
+     * time of the operation which is also the rDn for the node.
+     *
+     * @param beginDate attribute that maps to 'reqStart' in audit object classes.
+     */
+    public void setBeginDate(Date beginDate)
+    {
+        this.beginDate = beginDate;
+    }
+
+    /**
+     *
+     */
+    public Date getEndDate()
+    {
+        return endDate;
+    }
+
+    /**
+     *
+     * @param endDate
+     */
+    public void setEndDate(Date endDate)
+    {
+        this.endDate = endDate;
+    }
+
+    /**
+     * Get the optional dn attribute can be used to constraint {@link AuditMgrImpl#searchUserSessions(UserAudit)}.
+     * The dn for this search may represent any target entry in DIT that has been recently modified or deleted.
+     *
+     * @return the dn which maps to 'reqDn' for 'auditModify' object class searches.
+     */
+    public String getDn()
+    {
+        return dn;
+    }
+
+    /**
+     * Set the optional dn attribute can be used to constraint {@link AuditMgrImpl#searchUserSessions(UserAudit)}.
+     * The dn for this search may represent any target entry in DIT that has been recently modified or deleted.
+     *
+     * @param dn maps to 'reqDn' for 'auditModify' object class searches.
+     */
+    public void setDn(String dn)
+    {
+        this.dn = dn;
+    }
+
+    public String getObjId()
+    {
+        return objId;
+    }
+
+    public void setObjId(String objId)
+    {
+        this.objId = objId;
+    }
+
+    public boolean isAdmin()
+    {
+        return admin;
+    }
+
+    public void setAdmin(boolean admin)
+    {
+        this.admin = admin;
+    }
+}
\ No newline at end of file


[30/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/AdminRole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AdminRole.java b/src/main/java/org/apache/directory/fortress/core/rbac/AdminRole.java
new file mode 100755
index 0000000..88bf87f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AdminRole.java
@@ -0,0 +1,488 @@
+/*
+ *   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 java.util.TreeSet;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.directory.fortress.core.rbac.dao.AdminRoleDAO;
+import org.apache.directory.fortress.core.rbac.dao.OrgUnitDAO;
+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;
+
+
+/**
+ * All entities ({@link AdminRole}, {@link org.apache.directory.fortress.core.rbac.OrgUnit},
+ * {@link org.apache.directory.fortress.core.rbac.SDSet} etc...) are used to carry data between three Fortress
+ * layers.starting with the (1) Manager layer down thru middle (2) Process layer and it's processing rules into
+ * (3) DAO layer where persistence with the OpenLDAP server occurs.
+ * <h4>Fortress Processing Layers</h4>
+ * <ol>
+ * <li>Manager layer: {@link DelAdminMgrImpl}, {@link DelAccessMgrImpl}, {@link DelReviewMgrImpl},...</li>
+ * <li>Process layer: {@link AdminRoleP}, {@link org.apache.directory.fortress.core.rbac.OrgUnitP},...</li>
+ * <li>DAO layer: {@link AdminRoleDAO}, {@link OrgUnitDAO},...</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 />
+ * For example, this entity requires {@link #name} set before passing into {@link DelAdminMgrImpl} or  {@link DelReviewMgrImpl} APIs.
+ * Create methods usually require more attributes (than Read) due to constraints enforced between entities.
+ * <p/>
+ * This entity extends the {@link org.apache.directory.fortress.core.rbac.Role} entity and is used to store the ARBAC AdminRole assignments that comprise the many-to-many relationships between Users and Administrative Permissions.
+ * In addition it is used to store the ARBAC {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM} and {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#USER} OU information that adheres to the AdminRole entity in the ARBAC02 model.
+ * <br />The unique key to locate AdminRole entity (which is subsequently assigned both to Users and administrative Permissions) is {@link AdminRole#name}.<br />
+ * <p/>
+ * There is a many-to-many relationship between User's, Administrative Roles and Administrative Permissions.
+ * <h3>{@link org.apache.directory.fortress.core.rbac.User}*<->*{@link AdminRole}*<->*{@link Permission}</h3>
+ * Example to create new ARBAC AdminRole:
+ * <p/>
+ * <code>AdminRole myRole = new AdminRole("MyRoleName");</code><br />
+ * <code>myRole.setDescription("This is a test admin role");</code><br />
+ * <code>DelAdminMgr delAdminMgr = DelAdminMgrFactory.createInstance();</code><br />
+ * <code>delAdminMgr.addRole(myRole);</code><br />
+ * <p/>
+ * This will create a AdminRole name that can be used as a target for User-AdminRole assignments and AdminRole-AdminPermission grants.
+ * <p/>
+ * <p/>
+ * <h4>Administrative Role Schema</h4>
+ * The Fortress AdminRole entity is a composite of the following other Fortress structural and aux object classes:
+ * <p/>
+ * 1. organizationalRole Structural Object Class is used to store basic attributes like cn and description.
+ * <pre>
+ * ------------------------------------------
+ * objectclass ( 2.5.6.8 NAME 'organizationalRole'
+ *  DESC 'RFC2256: an organizational role'
+ *  SUP top STRUCTURAL
+ *  MUST cn
+ *  MAY (
+ *      x121Address $ registeredAddress $ destinationIndicator $
+ *      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
+ *      telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
+ *      seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $
+ *      postOfficeBox $ postalCode $ postalAddress $
+ *      physicalDeliveryOfficeName $ ou $ st $ l $ description
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 2. ftRls Structural objectclass is used to store the AdminRole information like name, and temporal constraints.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Roles Structural Object Class
+ * objectclass	( 1.3.6.1.4.1.38088.2.1
+ *  NAME 'ftRls'
+ *  DESC 'Fortress Role Structural Object Class'
+ *  SUP organizationalrole
+ *  STRUCTURAL
+ *  MUST (
+ *      ftId $
+ *      ftRoleName
+ *  )
+ *  MAY (
+ *      description $
+ *      ftCstr $
+ *      ftParents
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 3. ftProperties AUXILIARY Object Class is used to store client specific name/value pairs on target entity.<br />
+ * <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 />
+ * <pre>
+ * ------------------------------------------
+ * AC2: Fortress Properties Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.2
+ *  NAME 'ftProperties'
+ *  DESC 'Fortress Properties AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftProps
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 4. ftPools Auxiliary object class store the ARBAC Perm and User OU assignments on AdminRole entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Organizational Pools Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.3
+ *  NAME 'ftPools'
+ *  DESC 'Fortress Pools AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftOSU  $
+ *      ftOSP  $
+ *      ftRange
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 5. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Audit Modification Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.4
+ *  NAME 'ftMods'
+ *  DESC 'Fortress Modifiers AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftModifier $
+ *      ftModCode $
+ *      ftModId
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortAdminRole")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "adminRole", propOrder =
+    {
+        "osPs",
+        "osUs",
+        "beginRange",
+        "endRange",
+        "beginInclusive",
+        "endInclusive"
+})
+public class AdminRole extends Role implements Administrator
+{
+    private Set<String> osPs;
+    private Set<String> osUs;
+    private String beginRange;
+    private String endRange;
+    private boolean beginInclusive;
+    private boolean endInclusive;
+
+
+    /**
+     * Default constructor is used by internal Fortress classes.
+     */
+    public AdminRole()
+    {
+    }
+
+
+    /**
+     * Construct an Admin Role with a given temporal constraint.
+     *
+     * @param con maps to 'OamRC' attribute for 'ftTemporal' aux object classes.
+     */
+    public AdminRole( Constraint con )
+    {
+        CUtil.copy( con, this );
+    }
+
+
+    /**
+     * Construct an AdminRole entity with a given name.
+     *
+     */
+    public AdminRole( String name )
+    {
+        this.setName( name );
+    }
+
+
+    /**
+     * Load the role range attributes given a raw format.  This method is used internal to Fortress and is not intended
+     * to be used by external callers.
+     *
+     * @param szRaw maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public void setRoleRangeRaw( String szRaw )
+    {
+        if ( VUtil.isNotNullOrEmpty( szRaw ) )
+        {
+            int bindx = szRaw.indexOf( "(" );
+            if ( bindx > -1 )
+            {
+                this.setBeginInclusive( false );
+            }
+            else
+            {
+                bindx = szRaw.indexOf( "[" );
+                this.setBeginInclusive( true );
+            }
+            int eindx = szRaw.indexOf( ")" );
+            if ( eindx > -1 )
+            {
+                this.setEndInclusive( false );
+            }
+            else
+            {
+                eindx = szRaw.indexOf( "]" );
+                this.setEndInclusive( true );
+            }
+            int cindx = szRaw.indexOf( ":" );
+            if ( cindx > -1 )
+            {
+                String szBeginRange = szRaw.substring( bindx + 1, cindx );
+                String szEndRange = szRaw.substring( cindx + 1, eindx );
+                this.setBeginRange( szBeginRange );
+                this.setEndRange( szEndRange );
+            }
+        }
+    }
+
+
+    /**
+     *
+     * Get the raw format for role range using current AdminRole entity attributes.  This method is used internal to Fortress and is not intended
+     * to be used by external callers.
+     *
+     * @return String maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public String getRoleRangeRaw()
+    {
+        String szRaw = "";
+        if ( this.beginRange != null )
+        {
+            if ( this.isBeginInclusive() )
+                szRaw += "[";
+            else
+                szRaw += "(";
+            szRaw += this.getBeginRange();
+            szRaw += ":";
+            szRaw += this.getEndRange();
+            if ( this.isEndInclusive() )
+                szRaw += "]";
+            else
+                szRaw += ")";
+        }
+        return szRaw;
+    }
+
+
+    /**
+     * Get a collection of optional Perm OU attributes that were stored on the AdminRole entity.
+     *
+     * @return List of type String containing Perm OU.  This maps to 'ftOSP' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public Set<String> getOsP()
+    {
+        return osPs;
+    }
+
+
+    /**
+     * Set a collection of optional Perm OU attributes to be stored on the AdminRole entity.
+     *
+     * @param osPs is a List of type String containing Perm OU.  This maps to 'ftOSP' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public void setOsP( Set<String> osPs )
+    {
+        this.osPs = osPs;
+    }
+
+
+    /**
+     * Set a Perm OU attribute to be stored on the AdminRole entity.
+     *
+     * @param osP is a Perm OU that maps to 'ftOSP' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public void setOsP( String osP )
+    {
+        if ( this.osPs == null )
+        {
+            // create Set with case insensitive comparator:
+            osPs = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        }
+        osPs.add( osP );
+    }
+
+
+    /**
+     * Get a collection of optional User OU attributes that were stored on the AdminRole entity.
+     *
+     * @return List of type String containing User OU.  This maps to 'ftOSU' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public Set<String> getOsU()
+    {
+        return osUs;
+    }
+
+
+    /**
+     * Set a collection of optional User OU attributes to be stored on the AdminRole entity.
+     *
+     * @param osUs is a List of type String containing User OU.  This maps to 'ftOSU' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public void setOsU( Set<String> osUs )
+    {
+        this.osUs = osUs;
+    }
+
+
+    /**
+     * Set a User OU attribute to be stored on the AdminRole entity.
+     *
+     * @param osU is a User OU that maps to 'ftOSU' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public void setOsU( String osU )
+    {
+        if ( this.osUs == null )
+        {
+            // create Set with case insensitive comparator:
+            osUs = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        }
+        osUs.add( osU );
+    }
+
+
+    /**
+     * Return the begin Role range attribute for AdminRole entity which corresponds to lowest descendant.
+     *
+     * @return String that maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public String getBeginRange()
+    {
+        return beginRange;
+    }
+
+
+    /**
+     * Set the begin Role range attribute for AdminRole entity which corresponds to lowest descendant.
+     *
+     * @param beginRange maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public void setBeginRange( String beginRange )
+    {
+        this.beginRange = beginRange;
+    }
+
+
+    /**
+     * Return the end Role range attribute for AdminRole entity which corresponds to highest ascendant.
+     *
+     * @return String that maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public String getEndRange()
+    {
+        return endRange;
+    }
+
+
+    /**
+     * Set the end Role range attribute for AdminRole entity which corresponds to highest ascendant.
+     *
+     * @param endRange maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public void setEndRange( String endRange )
+    {
+        this.endRange = endRange;
+    }
+
+
+    /**
+     * Get the begin inclusive which specifies if role range includes or excludes the 'beginRange' attribute.
+     *
+     * @return String that maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public boolean isBeginInclusive()
+    {
+        return beginInclusive;
+    }
+
+
+    /**
+     * Set the begin inclusive which specifies if role range includes or excludes the 'beginRange' attribute.
+     *
+     * @param beginInclusive maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public void setBeginInclusive( boolean beginInclusive )
+    {
+        this.beginInclusive = beginInclusive;
+    }
+
+
+    /**
+     * Get the end inclusive which specifies if role range includes or excludes the 'endRange' attribute.
+     *
+     * @return String that maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public boolean isEndInclusive()
+    {
+        return endInclusive;
+    }
+
+
+    /**
+     * Set the end inclusive which specifies if role range includes or excludes the 'endRange' attribute.
+     *
+     * @param endInclusive maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    @Override
+    public void setEndInclusive( boolean endInclusive )
+    {
+        this.endInclusive = endInclusive;
+    }
+
+
+    /**
+     * Matches the name from two AdminRole entities.
+     *
+     * @param thatObj contains an AdminRole entity.
+     * @return boolean indicating both objects contain matching AdminRole names.
+     */
+    public boolean equals( Object thatObj )
+    {
+        if ( this == thatObj )
+            return true;
+        if ( this.getName() == null )
+            return false;
+        if ( !( thatObj instanceof AdminRole ) )
+            return false;
+        Role thatRole = ( Role ) thatObj;
+        if ( thatRole.getName() == null )
+            return false;
+        return thatRole.getName().equalsIgnoreCase( this.getName() );
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleP.java b/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleP.java
new file mode 100755
index 0000000..d589b3c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleP.java
@@ -0,0 +1,403 @@
+/*
+ *   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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.RemoveException;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.dao.AdminRoleDAO;
+import org.apache.directory.fortress.core.rbac.dao.DaoFactory;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * Process module for the AdminRole entity.  This class performs data validations and error mapping.  It is typically called
+ * by internal Fortress delegated manager classes ({@link DelAdminMgrImpl}, {@link DelAccessMgrImpl},
+ * {@link DelReviewMgrImpl}, ...) and not intended for external non-Fortress clients.  This class will accept,
+ * {@link org.apache.directory.fortress.core.rbac.AdminRole}, validate its contents and forward on to it's corresponding DAO class {@link AdminRoleDAO}.
+ * <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 GlobalErrIds}.
+ * <p>
+ * This class is thread safe.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public final class AdminRoleP
+{
+    private static final String CLS_NM = AdminRoleP.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final AdminRoleDAO rDao = DaoFactory.createAdminRoleDAO();
+    private static final OrgUnitP op = new OrgUnitP();
+
+
+    /**
+     * Package private constructor.
+     */
+    AdminRoleP()
+    {
+    }
+
+
+    /**
+     * Return a fully populated Admin Role entity for a given Admin Role name.  If matching record not found a
+     * SecurityException will be thrown.
+     *
+     * @param adminRole contains full Admin Role name.
+     * @return AdminRole entity containing all attributes associated with Administrative Role in directory.
+     * @throws SecurityException in the event AdminRole not found or DAO search error.
+     */
+    final AdminRole read( AdminRole adminRole ) throws SecurityException
+    {
+        return rDao.getRole( adminRole );
+    }
+
+
+    /**
+     * Takes a search string that contains full or partial Admin Role name in directory.
+     *
+     * @param adminRole contains full or partial Admin role name.
+     * @return List of type Role containing fully populated matching Admin Role entities.  If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<AdminRole> search( AdminRole adminRole )
+        throws SecurityException
+    {
+        return rDao.findRoles( adminRole );
+    }
+
+
+    /**
+     * Takes a search string that contains full or partial Admin Role name in directory.
+     *
+     * @param adminRole contains full or partial Admin role name.
+     * @param limit     specify the max number of records to return in result set.
+     * @return List of type String containing Admin Role name 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( AdminRole adminRole, int limit )
+        throws SecurityException
+    {
+        return rDao.findRoles( adminRole, limit );
+    }
+
+
+    /**
+     * Return all AdminRoles that have a parent assignment.  This used for hierarchical processing.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return List of type AdminRole containing {@link AdminRole#name} and {@link AdminRole#parents} populated.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<Graphable> getAllDescendants( String contextId )
+        throws SecurityException
+    {
+        return rDao.getAllDescendants( contextId );
+    }
+
+
+    /**
+     * Adds a new Admin Role entity to directory.  The Role entity input object will be validated to ensure that:
+     * role name is present, and reasonability checks on all of the other populated values.
+     *
+     * @param entity Admin Role entity contains data targeted for insertion.
+     * @return AdminRole 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 AdminRole add( AdminRole entity )
+        throws SecurityException
+    {
+        validate( entity );
+        return rDao.create( entity );
+    }
+
+
+    /**
+     * Updates existing AdminRole entity in directory.  For example the AdminRole description and temporal constraints
+     * updated.
+     *
+     * @param entity Admin Role entity contains data targeted for updating.
+     * @return AdminRole entity contains fully populated updated entity.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final AdminRole update( AdminRole entity ) throws SecurityException
+    {
+        validate( entity );
+        entity = rDao.update( entity );
+        return read( entity );
+    }
+
+
+    /**
+     * Removes parent role assignments from Role entity in directory.
+     * updated.
+     *
+     * @param entity Admin Role entity contains data targeted for updating.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final void deleteParent( AdminRole entity ) throws SecurityException
+    {
+        validate( entity );
+        rDao.deleteParent( entity );
+    }
+
+
+    /**
+     * 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 entity contains userId and admin role name and (optional) role temporal constraints.
+     * @param userDn contains the DN of user being assigned.
+     * @return AdminRole contains copy of input entity and additional data processed by request.
+     * @throws SecurityException in the event data error in user or role objects or system error.
+     */
+    final AdminRole assign( AdminRole entity, String userDn ) throws SecurityException
+    {
+        return rDao.assign( entity, userDn );
+    }
+
+
+    /**
+     * Add the User dn occupant attribute to the OrganizationalRole entity in ldap.  This method is called by AdminMgrImpl
+     * when the User is being added.
+     *
+     * @param uRoles contains a collection of UserAdminRole being targeted for assignment.
+     * @param userDn contains the userId targeted for attribute addition.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    void addOccupant( List<UserAdminRole> uRoles, String userDn, String contextId )
+        throws SecurityException
+    {
+        if ( VUtil.isNotNullOrEmpty( uRoles ) )
+        {
+            for ( UserAdminRole uRole : uRoles )
+            {
+                AdminRole role = new AdminRole( uRole.getName() );
+                role.setContextId( contextId );
+                assign( role, userDn );
+            }
+        }
+    }
+
+
+    /**
+     * Remove the User dn occupant attribute from the OrganizationalRole entity in ldap.  This method is called by AdminMgrImpl
+     * when the User is being deleted.
+     *
+     * @param userDn contains the userId targeted for attribute removal.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final void removeOccupant( String userDn, String contextId )
+        throws SecurityException
+    {
+        List<String> list;
+        try
+        {
+            list = rDao.findAssignedRoles( userDn, contextId );
+            for ( String roleNm : list )
+            {
+                deassign( new AdminRole( roleNm ), userDn );
+            }
+        }
+        catch ( FinderException fe )
+        {
+            String error = "removeOccupant userDn [" + userDn + "] caught FinderException=" + fe;
+            throw new SecurityException( GlobalErrIds.ARLE_REMOVE_OCCUPANT_FAILED, error, fe );
+        }
+    }
+
+
+    /**
+     * 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 entity contains userId and admin role name targeted for removal.
+     * @param userDn contains the userId targeted for attribute removal.
+     * @return AdminRole contains copy of input entity and additional data processed by request.
+     * @throws SecurityException - in the event data error in user or role objects or system error.
+     */
+    final AdminRole deassign( AdminRole entity, String userDn ) throws SecurityException
+    {
+        return rDao.deassign( entity, userDn );
+    }
+
+
+    /**
+     * This method performs a "hard" delete.  It completely the Admin Role node from the ldap directory.
+     * Admin Role entity must exist in directory prior to making this call else exception will be thrown.
+     *
+     * @param entity Contains the name of the Admin Role targeted for deletion.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final void delete( AdminRole entity ) throws SecurityException
+    {
+        try
+        {
+            rDao.remove( entity );
+        }
+        catch ( RemoveException re )
+        {
+            String error = "delete name [" + entity.getName() + "] caught RemoveException=" + re;
+            LOG.error( error );
+            throw new SecurityException( GlobalErrIds.ARLE_DELETE_FAILED, error, re );
+        }
+    }
+
+
+    /**
+     * Method will perform simple validations to ensure the integrity of the Admin Role entity targeted for insertion
+     * or updating in directory.  For example the Admin Role temporal constraints will be validated.  Data reasonability
+     * checks will be performed on all non-null attributes.  Validations will be performed on ARBAC constraints as well.
+     *
+     * @param entity contains data targeted for insertion or update.
+     * @throws SecurityException in the event of data validation error or DAO error on Org validation.
+     */
+    private void validate( AdminRole entity )
+        throws SecurityException
+    {
+        VUtil.safeText( entity.getName(), GlobalIds.ROLE_LEN );
+        if ( VUtil.isNotNullOrEmpty( entity.getBeginRange() ) && VUtil.isNotNullOrEmpty( entity.getEndRange() ) )
+        {
+            VUtil.safeText( entity.getBeginRange(), GlobalIds.ROLE_LEN );
+            VUtil.safeText( entity.getEndRange(), GlobalIds.ROLE_LEN );
+            if ( entity.getBeginRange().equalsIgnoreCase( entity.getEndRange() )
+                && ( !entity.isBeginInclusive() || !entity.isEndInclusive() ) )
+            {
+                String error = "validate invalid range detected for role name [" + entity.getName()
+                    + "] non inclusive endpoint for identical range [" + entity.getBeginRange() + "] begin inclusive ["
+                    + entity.isBeginInclusive() + "] end inclusive [" + entity.isEndInclusive() + "]";
+                LOG.warn( error );
+                throw new SecurityException( GlobalErrIds.ARLE_INVLD_RANGE_INCLUSIVE, error );
+            }
+            else if ( !RoleUtil.isParent( entity.getBeginRange(), entity.getEndRange(), entity.getContextId() )
+                && !entity.getBeginRange().equalsIgnoreCase( entity.getEndRange() ) )
+            //public static boolean isParent(String child, String parent)
+            {
+                String error = "validate invalid range detected for role name [" + entity.getName()
+                    + "] begin range [" + entity.getBeginRange() + "] end range [" + entity.getEndRange() + "]";
+                LOG.warn( error );
+                throw new SecurityException( GlobalErrIds.ARLE_INVLD_RANGE, error );
+            }
+        }
+        else if ( !VUtil.isNotNullOrEmpty( entity.getBeginRange() ) && VUtil.isNotNullOrEmpty( entity.getEndRange() ) )
+        {
+            String error = "validate role name [" + entity.getName() + "] begin range value null or empty.";
+            LOG.warn( error );
+            throw new SecurityException( GlobalErrIds.ARLE_BEGIN_RANGE_NULL, error );
+        }
+        else if ( VUtil.isNotNullOrEmpty( entity.getBeginRange() ) && !VUtil.isNotNullOrEmpty( entity.getEndRange() ) )
+        {
+            String error = "validate role name [" + entity.getName() + "] end range value null or empty.";
+            LOG.warn( error );
+            throw new SecurityException( GlobalErrIds.ARLE_END_RANGE_NULL, error );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+        {
+            VUtil.description( entity.getDescription() );
+        }
+        if ( entity.getTimeout() >= 0 )
+        {
+            VUtil.timeout( entity.getTimeout() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getBeginTime() ) )
+        {
+            VUtil.beginTime( entity.getBeginTime() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getEndTime() ) )
+        {
+            VUtil.endTime( entity.getEndTime() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getBeginDate() ) )
+        {
+            VUtil.beginDate( entity.getBeginDate() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getEndDate() ) )
+        {
+            VUtil.endDate( entity.getEndDate() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getDayMask() ) )
+        {
+            VUtil.dayMask( entity.getDayMask() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getBeginLockDate() ) )
+        {
+            VUtil.beginDate( entity.getBeginDate() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getEndLockDate() ) )
+        {
+            VUtil.endDate( entity.getEndLockDate() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getOsU() ) )
+        {
+            for ( String ou : entity.getOsU() )
+            {
+                OrgUnit inOe = new OrgUnit( ou );
+                inOe.setType( OrgUnit.Type.USER );
+                inOe.setContextId( entity.getContextId() );
+                op.read( inOe );
+            }
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getOsP() ) )
+        {
+            for ( String ou : entity.getOsP() )
+            {
+                OrgUnit inOe = new OrgUnit( ou );
+                inOe.setType( OrgUnit.Type.PERM );
+                inOe.setContextId( entity.getContextId() );
+                op.read( inOe );
+            }
+        }
+    }
+}
\ 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/AdminRoleRelationship.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleRelationship.java b/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleRelationship.java
new file mode 100755
index 0000000..22b90d4
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleRelationship.java
@@ -0,0 +1,63 @@
+/*
+ *   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.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * This entity is used by en masse to communicate parent and child {@link org.apache.directory.fortress.core.rbac.AdminRole} information to the server.
+ * <p/>
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortAdminRoleRelationship")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "adminrelationship", propOrder = {
+    "child",
+    "parent"
+})
+public class AdminRoleRelationship extends FortEntity
+    implements java.io.Serializable
+{
+    private AdminRole parent;
+    private AdminRole child;
+
+    public AdminRole getParent()
+    {
+        return parent;
+    }
+
+    public void setParent(AdminRole parent)
+    {
+        this.parent = parent;
+    }
+
+    public AdminRole getChild()
+    {
+        return child;
+    }
+
+    public void setChild(AdminRole child)
+    {
+        this.child = child;
+    }
+}
\ 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/AdminRoleUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleUtil.java b/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleUtil.java
new file mode 100755
index 0000000..cdcafbc
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleUtil.java
@@ -0,0 +1,290 @@
+/*
+ *   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 org.apache.directory.fortress.core.rbac.HierUtil} methods to provide hierarchical functionality for the {@link org.apache.directory.fortress.core.rbac.AdminRole} data set.
+ * The child to parent relationships are stored within a data cache, {@link #adminRoleCache}, contained within this class.  The parent-child edges are contained in LDAP,
+ * in {@code ftParents} attribute.  The ldap data is retrieved {@link org.apache.directory.fortress.core.rbac.AdminRoleP#getAllDescendants(String)} 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 org.apache.directory.fortress.core.rbac.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 {@link org.apache.directory.fortress.core.rbac.dao.PermDAO}
+ * 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 AdminRoleUtil
+{
+    private static final Cache adminRoleCache;
+    private static final AdminRoleP adminRoleP = new AdminRoleP();
+    private static final String CLS_NM = AdminRoleUtil.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    /**
+     * Initialize the AdminRole 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();
+        adminRoleCache = cacheMgr.getCache( "fortress.admin.roles" );
+    }
+
+
+    /**
+     * Used to determine if one {@link org.apache.directory.fortress.core.rbac.AdminRole} is the parent of another.  This method
+     * will call recursive routine {@link #getAscendants(String, String)} to walk the {@code org.jgrapht.graph.SimpleDirectedGraph} data structure
+     * returning flag indicating if parent-child relationship is valid.
+     *
+     * @param child maps to logical {@link org.apache.directory.fortress.core.rbac.AdminRole#name} on 'ftRls' object class.
+     * @param parent maps to logical {@link org.apache.directory.fortress.core.rbac.AdminRole#name} on 'ftRls' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return boolean result, 'true' indicates parent/child relationship exists.
+     */
+    static boolean isParent( String child, String parent, String contextId )
+    {
+        boolean result = false;
+        Set<String> parents = getAscendants( child, contextId );
+        if ( parents != null && parents.size() > 0 )
+        {
+            result = parents.contains( parent.toUpperCase() );
+        }
+        return result;
+    }
+
+
+    /**
+     * Recursively traverse the {@link org.apache.directory.fortress.core.rbac.AdminRole} graph and return all of the descendants of a given parent {@link org.apache.directory.fortress.core.rbac.AdminRole#name}.
+     * @param roleName {@link org.apache.directory.fortress.core.rbac.AdminRole#name} maps on 'ftRls' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of AdminRole names are children {@link org.apache.directory.fortress.core.rbac.AdminRole}s of given parent.
+     */
+    static Set<String> getDescendants( String roleName, String contextId )
+    {
+        return HierUtil.getDescendants( roleName, getGraph( contextId ) );
+    }
+
+
+    /**
+     * Recursively traverse the hierarchical role graph and return all of the parents of a given child role.
+     * @param roleName maps to logical {@link org.apache.directory.fortress.core.rbac.AdminRole#name} on 'ftRls' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of AdminRole names that are descendants of given node.
+     */
+    public static Set<String> getAscendants( String roleName, String contextId )
+    {
+        return HierUtil.getAscendants( roleName, getGraph( contextId ) );
+    }
+
+
+    /**
+     * Traverse one level of the {@link org.apache.directory.fortress.core.rbac.AdminRole} graph and return all of the parents (direct ascendants) of a given parent {@link org.apache.directory.fortress.core.rbac.AdminRole#name}.
+     * @param roleName {@link org.apache.directory.fortress.core.rbac.AdminRole#name} maps on 'ftRls' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of AdminRole names are parents {@link org.apache.directory.fortress.core.rbac.AdminRole}s of given child.
+     */
+    static Set<String> getParents( String roleName, String contextId )
+    {
+        return HierUtil.getParents( roleName, getGraph( contextId ) );
+    }
+
+
+    /**
+     * Traverse one level of the hierarchical role graph and return all of the children (direct descendants) of a given parent role.
+     * @param roleName maps to logical {@link org.apache.directory.fortress.core.rbac.AdminRole#name} on 'ftRls' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of AdminRole names that are children of given parent.
+     */
+    public static Set<String> getChildren( String roleName, String contextId )
+    {
+        return HierUtil.getChildren( roleName, getGraph( contextId ) );
+    }
+
+
+    /**
+     * Return number of children (direct descendants) a given parent role has.
+     * @param roleName maps to logical {@link org.apache.directory.fortress.core.rbac.AdminRole#name} on 'ftRls' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return int value contains the number of children of a given parent AdminRole.
+     */
+    static int numChildren( String roleName, String contextId )
+    {
+        return HierUtil.numChildren( roleName, getGraph( contextId ) );
+    }
+
+
+    /**
+     * Return Set of {@link org.apache.directory.fortress.core.rbac.AdminRole#name}s ascendants.  Used by {@link org.apache.directory.fortress.core.rbac.dao.PermDAO#checkPermission}
+     * for computing authorized {@link UserAdminRole#name}s.
+     * @param uRoles contains list of adminRoles activated within a {@link org.apache.directory.fortress.core.rbac.User}'s {@link org.apache.directory.fortress.core.rbac.Session}.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return contains Set of all authorized adminRoles for a given User.
+     */
+    public static Set<String> getInheritedRoles( List<UserAdminRole> uRoles, String contextId )
+    {
+        // create Set with case insensitive comparator:
+        Set<String> iRoles = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        if ( VUtil.isNotNullOrEmpty( uRoles ) )
+        {
+            for ( UserAdminRole uRole : uRoles )
+            {
+                String rleName = uRole.getName();
+                iRoles.add( rleName );
+                Set<String> parents = HierUtil.getAscendants( rleName, getGraph( contextId ) );
+                if ( VUtil.isNotNullOrEmpty( parents ) )
+                    iRoles.addAll( parents );
+            }
+        }
+        return iRoles;
+    }
+
+
+    /**
+     * This api is used by {@link DelAdminMgrImpl} to determine parentage for Hierarchical ARBAC processing.
+     * It calls {@link HierUtil#validateRelationship(org.jgrapht.graph.SimpleDirectedGraph, String, String, boolean)} to evaluate three adminRole 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 childRole contains {@link org.apache.directory.fortress.core.rbac.AdminRole#name} of child.
+     * @param parentRole contains {@link org.apache.directory.fortress.core.rbac.AdminRole#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( AdminRole childRole, AdminRole parentRole, boolean mustExist )
+        throws ValidationException
+    {
+        HierUtil.validateRelationship( getGraph( childRole.getContextId() ), childRole.getName(), parentRole.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 ADMIN ROLE context [" + inHier.getContextId() + "]" );
+        List<Graphable> descendants = null;
+        try
+        {
+            descendants = adminRoleP.getAllDescendants( inHier.getContextId() );
+        }
+        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.ARLE ) )
+        {
+            graph = HierUtil.buildGraph( hier );
+        }
+        adminRoleCache.put( getKey( contextId ), graph );
+        return graph;
+    }
+
+
+    /**
+     * 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> getGraph( String contextId )
+    {
+        SimpleDirectedGraph<String, Relationship> graph = ( SimpleDirectedGraph<String, Relationship> ) adminRoleCache
+            .get( getKey( contextId ) );
+        if ( graph == null )
+        {
+            graph = loadGraph( contextId );
+        }
+        return graph;
+    }
+
+
+    /**
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return
+     */
+    private static String getKey( String contextId )
+    {
+        String key = HierUtil.Type.ARLE.toString();
+        if ( VUtil.isNotNullOrEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL ) )
+        {
+            key += ":" + contextId;
+        }
+        return key;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/AdminUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AdminUtil.java b/src/main/java/org/apache/directory/fortress/core/rbac/AdminUtil.java
new file mode 100755
index 0000000..227ea9f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AdminUtil.java
@@ -0,0 +1,207 @@
+/*
+ *   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 org.apache.directory.fortress.core.DelAccessMgr;
+import org.apache.directory.fortress.core.AuthorizationException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.DelAccessMgrFactory;
+
+/**
+ * This class supplies static wrapper utilities to provide ARBAC functionality to Fortress internal Manager APIs.
+ * The utilities within this class are all static and can not be called by code outside of Fortress.
+ * </p>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+final class AdminUtil
+{
+    private static final String CLS_NM = AdminUtil.class.getName();
+
+    /**
+     * Wrapper function to call {@link DelAccessMgrImpl#canAssign(org.apache.directory.fortress.core.rbac.Session, org.apache.directory.fortress.core.rbac.User, org.apache.directory.fortress.core.rbac.Role)}.
+     * This will determine if the user contains an AdminRole that is authorized assignment control over User-Role Assignment (URA).  This adheres to the ARBAC02 functional specification for can-assign URA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param user    Instantiated User entity requires only valid userId attribute set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @throws org.apache.directory.fortress.core.SecurityException In the event of data validation error (i.e. invalid userId or role name) or system error.
+     */
+    static void canAssign(Session session, User user, Role role, String contextId) throws SecurityException
+    {
+        if (session != null)
+        {
+            DelAccessMgr dAccessMgr = DelAccessMgrFactory.createInstance(contextId);
+            boolean result = dAccessMgr.canAssign(session, user, role);
+            if (!result)
+            {
+                String warning = "canAssign Role [" + role.getName() + "] User [" + user.getUserId() + "] Admin [" + session.getUserId() + "] failed check.";
+                throw new SecurityException(GlobalErrIds.URLE_ADMIN_CANNOT_ASSIGN, warning);
+            }
+        }
+    }
+
+    /**
+     * Wrapper function to call {@link DelAccessMgrImpl#canDeassign(org.apache.directory.fortress.core.rbac.Session, org.apache.directory.fortress.core.rbac.User, org.apache.directory.fortress.core.rbac.Role)}.
+     *
+     * This function will determine if the user contains an AdminRole that is authorized revoke control over User-Role Assignment (URA).  This adheres to the ARBAC02 functional specification for can-revoke URA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.     * @param user    Instantiated User entity requires only valid userId attribute set.
+     * @param user    Instantiated User entity requires userId attribute set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @throws org.apache.directory.fortress.core.SecurityException In the event of data validation error (i.e. invalid userId or role name) or system error.
+     */
+    static void canDeassign(Session session, User user, Role role, String contextId) throws SecurityException
+    {
+        if (session != null)
+        {
+            DelAccessMgr dAccessMgr = DelAccessMgrFactory.createInstance(contextId);
+            boolean result = dAccessMgr.canDeassign(session, user, role);
+            if (!result)
+            {
+                String warning = "canDeassign Role [" + role.getName() + "] User [" + user.getUserId() + "] Admin [" + session.getUserId() + "] failed check.";
+                throw new SecurityException(GlobalErrIds.URLE_ADMIN_CANNOT_DEASSIGN, warning);
+
+            }
+        }
+    }
+
+    /**
+     * Wrapper function to call {@link DelAccessMgrImpl#canGrant(org.apache.directory.fortress.core.rbac.Session, org.apache.directory.fortress.core.rbac.Role, Permission)}.
+     * This function will determine if the user contains an AdminRole that is authorized assignment control over
+     * Permission-Role Assignment (PRA).  This adheres to the ARBAC02 functional specification for can-assign-p PRA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.     * @param perm    Instantiated Permission entity requires valid object name and operation name attributes set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @param perm    Instantiated Permission entity requires {@link Permission#objName} and {@link Permission#opName}.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return boolean value true indicates access allowed.
+     * @throws SecurityException In the event of data validation error (i.e. invalid perm or role name) or system error.
+     */
+    static void canGrant(Session session, Role role, Permission perm, String contextId) throws SecurityException
+    {
+        if (session != null)
+        {
+            DelAccessMgr dAccessMgr = DelAccessMgrFactory.createInstance(contextId);
+            boolean result = dAccessMgr.canGrant(session, role, perm);
+            if (!result)
+            {
+                String warning = "canGrant Role [" + role.getName() + "] Perm object [" + perm.getObjName() + "] Perm Operation [" + perm.getOpName() + "] Admin [" + session.getUserId() + "] failed check.";
+                throw new SecurityException(GlobalErrIds.URLE_ADMIN_CANNOT_GRANT, warning);
+            }
+        }
+    }
+
+    /**
+     * Wrapper function to call {@link DelAccessMgrImpl#canRevoke(org.apache.directory.fortress.core.rbac.Session, org.apache.directory.fortress.core.rbac.Role, Permission)}.
+     *
+     * This function will determine if the user contains an AdminRole that is authorized revoke control over
+     * Permission-Role Assignment (PRA).  This adheres to the ARBAC02 functional specification for can-revoke-p PRA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.     * @param perm    Instantiated Permission entity requires valid object name and operation name attributes set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @param perm    Instantiated Permission entity requires {@link Permission#objName} and {@link Permission#opName}.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @throws org.apache.directory.fortress.core.SecurityException In the event of data validation error (i.e. invalid perm or role name) or system error.
+     */
+    static void canRevoke(Session session, Role role, Permission perm, String contextId) throws SecurityException
+    {
+        if (session != null)
+        {
+            DelAccessMgr dAccessMgr = DelAccessMgrFactory.createInstance(contextId);
+            boolean result = dAccessMgr.canRevoke(session, role, perm);
+            if (!result)
+            {
+                String warning = "canRevoke Role [" + role.getName() + "] Perm object [" + perm.getObjName() + "] Perm Operation [" + perm.getOpName() + "] Admin [" + session.getUserId() + "] failed check.";
+                throw new SecurityException(GlobalErrIds.URLE_ADMIN_CANNOT_REVOKE, warning);
+            }
+        }
+    }
+
+    /**
+     * Method is called by Manager APIs to load contextual information on {@link FortEntity} and perform checkAccess on Administrative permission.
+     * </p>
+     * The information is used to
+     * <ol>
+     * <li>Load the administrative User's {@link Session} object into entity.  This is used for checking to ensure administrator has privilege to perform administrative operation.</li>
+     * <li>Load the target operation's permission into the audit context.  This is used for Fortress audit log stored in OpenLDAP</li>
+     * </ol>
+     *
+     * @param session object contains the {@link org.apache.directory.fortress.core.rbac.User}'s RBAC, {@link org.apache.directory.fortress.core.rbac.UserRole}, and Administrative Roles {@link UserAdminRole}.
+     * @param perm    contains the permission object name, {@link Permission#objName}, and operation name, {@link Permission#opName}
+     * @param entity  used to pass contextual information through Fortress layers for administrative security checks and audit.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event of system error.
+     */
+    static void setEntitySession(Session session, Permission perm, FortEntity entity, String contextId) throws SecurityException
+    {
+        if (session != null)
+        {
+            entity.setAdminSession(session);
+            entity.setModCode(getObjName(perm.getObjName()) + "." + perm.getOpName());
+            checkAccess(session, perm, contextId);
+        }
+    }
+
+    /**
+     * Wrapper function to call {@link DelAccessMgrImpl#checkAccess(org.apache.directory.fortress.core.rbac.Session, Permission)}.
+     * Perform user arbac authorization.  This function returns a Boolean value meaning whether the subject of a given session is
+     * allowed or not to perform a given operation on a given object. The function is valid if and
+     * only if the session is a valid Fortress session, the object is a member of the OBJS data set,
+     * and the operation is a member of the OPS data set. The session's subject has the permission
+     * to perform the operation on that object if and only if that permission is assigned to (at least)
+     * one of the session's active roles. This implementation will verify the roles or userId correspond
+     * to the subject's active roles are registered in the object's access control list.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param perm    object contains obj attribute which is a String and contains the name of the object user is trying to access;
+     *                perm object contains operation attribute which is also a String and contains the operation name for the object.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    static void checkAccess(Session session, Permission perm, String contextId) throws SecurityException
+    {
+        if (session != null)
+        {
+            DelAccessMgr dAccessMgr = DelAccessMgrFactory.createInstance(contextId);
+            boolean result = dAccessMgr.checkAccess(session, perm);
+            if (!result)
+            {
+                String info = "checkAccess failed for user [" + session.getUserId() + "] object [" + perm.getObjName() + "] operation [" + perm.getOpName() + "]";
+                throw new AuthorizationException(GlobalErrIds.USER_ADMIN_NOT_AUTHORIZED, info);
+            }
+        }
+    }
+
+    /**
+     * Utility will parse a String containing objName.operationName and return the objName only.
+     *
+     * @param szObj contains raw data format.
+     * @return String containing objName.
+     */
+    static String getObjName(String szObj)
+    {
+        return szObj.substring(szObj.lastIndexOf('.') + 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/Administrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Administrator.java b/src/main/java/org/apache/directory/fortress/core/rbac/Administrator.java
new file mode 100755
index 0000000..2e723b3
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Administrator.java
@@ -0,0 +1,149 @@
+/*
+ *   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;
+
+/**
+ * This interface is used by Fortress admin role processing.  It prescribes the APIs that are necessary for an Administrative
+ * Role entity to fullfill the ARBAC functionality.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public interface Administrator
+{
+
+    /**
+     * Get a collection of optional Perm OU attributes that were stored on the AdminRole entity.
+     *
+     * @return List of type String containing Perm OU.  This maps to 'ftOSP' attribute on 'ftPools' aux object class.
+     */
+    public Set<String> getOsP();
+
+    /**
+     * Set a collection of optional Perm OU attributes to be stored on the AdminRole entity.
+     *
+     * @param osPs is a List of type String containing Perm OU.  This maps to 'ftOSP' attribute on 'ftPools' aux object class.
+     */
+    public void setOsP(Set<String> osPs);
+
+    /**
+     * Set a Perm OU attribute to be stored on the AdminRole entity.
+     *
+     * @param osP is a Perm OU that maps to 'ftOSP' attribute on 'ftPools' aux object class.
+     */
+    public void setOsP(String osP);
+
+    /**
+     * Get a collection of optional User OU attributes that were stored on the AdminRole entity.
+     *
+     * @return List of type String containing User OU.  This maps to 'ftOSU' attribute on 'ftPools' aux object class.
+     */
+    public Set<String> getOsU();
+
+    /**
+     * Set a collection of optional User OU attributes to be stored on the AdminRole entity.
+     *
+     * @param osUs is a List of type String containing User OU.  This maps to 'ftOSU' attribute on 'ftPools' aux object class.
+     */
+    public void setOsU(Set<String> osUs);
+
+    /**
+     * Set a User OU attribute to be stored on the AdminRole entity.
+     *
+     * @param osU is a User OU that maps to 'ftOSU' attribute on 'ftPools' aux object class.
+     */
+    public void setOsU(String osU);
+
+    /**
+     * Load the role range attributes given a raw format.  This method is used internal to Fortress and is not intended
+     * to be used by external callers.
+     *
+     * @param szRaw maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    void setRoleRangeRaw(String szRaw);
+
+    /**
+     * Get the raw format for role range using current AdminRole entity attributes.  This method is used internal to Fortress and is not intended
+     * to be used by external callers.
+     *
+     * @return String maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    public String getRoleRangeRaw();
+
+    /**
+     * Return the begin Role range attribute for AdminRole entity.
+     *
+     * @return String that maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    public String getBeginRange();
+
+    /**
+     * Set the begin Role range attribute for AdminRole entity.
+     *
+     * @param beginRange maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    public void setBeginRange(String beginRange);
+
+    /**
+     * Return the end Role range attribute for AdminRole entity.
+     *
+     * @return String that maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    public String getEndRange();
+
+    /**
+     * Set the end Role range attribute for AdminRole entity.
+     *
+     * @param endRange maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    public void setEndRange(String endRange);
+
+    /**
+     * Set the begin inclusive which specifies if role range includes or excludes the 'beginRange' attribute.
+     *
+     * @return String that maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    public boolean isBeginInclusive();
+
+    /**
+     * Get the begin inclusive which specifies if role range includes or excludes the 'beginRange' attribute.
+     *
+     * @param beginInclusive maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    public void setBeginInclusive(boolean beginInclusive);
+
+    /**
+     * Set the end inclusive which specifies if role range includes or excludes the 'endRange' attribute.
+     *
+     * @return String that maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    public boolean isEndInclusive();
+
+    /**
+     * Get the end inclusive which specifies if role range includes or excludes the 'endRange' attribute.
+     *
+     * @param endInclusive maps to 'ftRange' attribute on 'ftPools' aux object class.
+     */
+    public void setEndInclusive(boolean endInclusive);
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/AuditMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AuditMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/rbac/AuditMgrImpl.java
new file mode 100755
index 0000000..8b06405
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AuditMgrImpl.java
@@ -0,0 +1,259 @@
+/*
+ *   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 org.apache.directory.fortress.core.AuditMgr;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.ReviewMgrFactory;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.ReviewMgr;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.List;
+
+/**
+ * This object performs searches across <a href="http://www.openldap.org/">OpenLDAP</a>'s slapd access log.  The access log events are
+ * persisted in <a href="http://www.oracle.com/technetwork/database/berkeleydb/overview/index.html">BDB</a> and available for inquiry via common LDAP protocols.
+ * Audit entries stored on behalf of Fortress operations correspond to runtime authentication {@link org.apache.directory.fortress.core.rbac.Bind}, authorization {@link org.apache.directory.fortress.core.rbac.AuthZ} and modification {@link org.apache.directory.fortress.core.rbac.Mod}
+ * events as they occur automatically on the server when audit is enabled.
+ * <h4>Audit Interrogator</h4>
+ * Provides an OpenLDAP access log retrieval mechanism that enables security event monitoring.
+ * <ol>
+ * <li>Authentication events:
+ * <li>Session enablement events
+ * <li>Authorization events
+ * <li>Entity mods and deletes
+ * </li>
+ * </ol>
+ * <img src="../doc-files/Audit.png">
+ * <p/>
+ * All events include Fortress context, see {@link org.apache.directory.fortress.core.rbac.FortEntity}.
+ * <p/>
+ * <h4>
+ * The following APIs generate events subsequently stored in this access log:
+ * </h4>
+ * <ul>
+ * <li> {@link org.apache.directory.fortress.core.AccessMgr}
+ * <li> {@link org.apache.directory.fortress.core.AdminMgr}
+ * <li> {@link org.apache.directory.fortress.core.AdminMgr}
+ * <li> {@link org.apache.directory.fortress.core.DelAdminMgr}
+ * <li> {@link org.apache.directory.fortress.core.cfg.ConfigMgr}
+ * <li> {@link org.apache.directory.fortress.core.PwPolicyMgr}
+ * </ul>
+ * <h4>
+ * The following reports are supported using search input: {@link org.apache.directory.fortress.core.rbac.UserAudit}
+ * </h4>
+ * <ul>
+ * <li>User Authentications:     <code>List<{@link org.apache.directory.fortress.core.rbac.Bind}>  {@link org.apache.directory.fortress.core.AuditMgr#searchBinds(org.apache.directory.fortress.core.rbac.UserAudit)}</code>
+ * <li>Invalid Users AuthN:      <code>List<{@link org.apache.directory.fortress.core.rbac.Bind}>  {@link org.apache.directory.fortress.core.AuditMgr#searchInvalidUsers(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>User Authorizations 1:    <code>List<{@link org.apache.directory.fortress.core.rbac.AuthZ}> {@link org.apache.directory.fortress.core.AuditMgr#getUserAuthZs(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>User Authorizations 2:    <code>List<{@link org.apache.directory.fortress.core.rbac.AuthZ}> {@link org.apache.directory.fortress.core.AuditMgr#searchAuthZs(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>User Session Activations: <code>List<{@link org.apache.directory.fortress.core.rbac.Mod}>   {@link org.apache.directory.fortress.core.AuditMgr#searchUserSessions(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>Entity Modifications:     <code>List<{@link org.apache.directory.fortress.core.rbac.Mod}>   {@link org.apache.directory.fortress.core.AuditMgr#searchAdminMods(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * </ul>
+ * <p/>
+ * This class is NOT thread safe if parent instance variables ({@link #contextId} or {@link #adminSess}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public class AuditMgrImpl extends Manageable implements AuditMgr
+{
+    private static final String CLS_NM = AuditMgrImpl.class.getName();
+    private static final AuditP auditP = new AuditP();
+
+    // package private constructor ensures outside classes cannot use:
+    AuditMgrImpl()
+    {}
+
+    /**
+     * This method returns a list of authorization events for a particular user {@link org.apache.directory.fortress.core.rbac.UserAudit#userId}
+     * and given timestamp field {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.<BR>
+     * Method also can discriminate between all events or failed only by setting {@link org.apache.directory.fortress.core.rbac.UserAudit#failedOnly}.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAudit#userId} - contains the target userId</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one authorization event.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if a runtime system error occurs.
+     */
+    @Override
+    public List<AuthZ> getUserAuthZs(UserAudit uAudit)
+        throws SecurityException
+    {
+        String methodName = "getUserAuthZs";
+        assertContext(CLS_NM, methodName, uAudit, GlobalErrIds.AUDT_INPUT_NULL);
+        checkAccess(CLS_NM, methodName);
+        return auditP.getAuthZs(uAudit);
+    }
+
+
+    /**
+     * This method returns a list of authorization events for a particular user {@link UserAudit#userId},
+     * object {@link UserAudit#objName}, and given timestamp field {@link UserAudit#beginDate}.<BR>
+     * Method also can discriminate between all events or failed only by setting flag {@link UserAudit#failedOnly}..
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId<</li>
+     * <li>{@link UserAudit#objName} - contains the object (authorization resource) name</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one authorization event.
+     * @throws SecurityException if a runtime system error occurs.
+     */
+    @Override
+    public List<AuthZ> searchAuthZs(UserAudit uAudit)
+        throws SecurityException
+    {
+        String methodName = "searchAuthZs";
+        assertContext(CLS_NM, methodName, uAudit, GlobalErrIds.AUDT_INPUT_NULL);
+        checkAccess(CLS_NM, methodName);
+        return auditP.searchAuthZs(uAudit);
+    }
+
+
+    /**
+     * This method returns a list of authentication audit events for a particular user {@link UserAudit#userId},
+     * and given timestamp field {@link UserAudit#beginDate}.<BR>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId<</li>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type Bind.  Each Bind object contains one bind event.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if a runtime system error occurs.
+     */
+    @Override
+    public List<Bind> searchBinds(UserAudit uAudit)
+        throws SecurityException
+    {
+        String methodName = "searchBinds";
+        assertContext(CLS_NM, methodName, uAudit, GlobalErrIds.AUDT_INPUT_NULL);
+        checkAccess(CLS_NM, methodName);
+        return auditP.searchBinds(uAudit);
+    }
+
+    /**
+     * This method returns a list of sessions created for a given user {@link UserAudit#userId},
+     * and timestamp {@link UserAudit#beginDate}.<BR>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId<</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type Mod.  Each Mod object in list corresponds to one update or delete event on directory.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if a runtime system error occurs.
+     */
+    @Override
+    public List<Mod> searchUserSessions(UserAudit uAudit)
+        throws SecurityException
+    {
+        String methodName = "searchUserSessions";
+        assertContext(CLS_NM, methodName, uAudit, GlobalErrIds.AUDT_INPUT_NULL);
+        checkAccess(CLS_NM, methodName);
+        return auditP.searchUserMods(uAudit);
+    }
+
+    /**
+     * This method returns a list of admin operations events for a particular entity {@link UserAudit#dn},
+     * object {@link UserAudit#objName} and timestamp {@link UserAudit#beginDate}.  If the internal
+     * userId {@link UserAudit#internalUserId} is set it will limit search by that field.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#dn} - contains the LDAP distinguished name for the updated object.  For example if caller
+     * wants to find out what changes were made to John Doe's user object this would be 'uid=jdoe,ou=People,dc=example,dc=com'</li>
+     * <li>{@link UserAudit#objName} - contains the object (authorization resource) name corresponding to the event.  For example if caller
+     * wants to return events where User object was modified, this would be 'updateUser'</li>
+     * <li>{@link UserAudit#internalUserId} - maps to the internalUserId of user who changed the record in LDAP.  This maps to {@link org.apache.directory.fortress.core.rbac.User#internalId}.</li>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#endDate} - contains the date in which to end search</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type Mod.  Each Mod object in list corresponds to one update or delete event on directory.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if a runtime system error occurs.
+     */
+    @Override
+    public List<Mod> searchAdminMods(UserAudit uAudit)
+        throws SecurityException
+    {
+        String methodName = "searchAdminMods";
+        assertContext(CLS_NM, methodName, uAudit, GlobalErrIds.AUDT_INPUT_NULL);
+        checkAccess(CLS_NM, methodName);
+        if (VUtil.isNotNullOrEmpty(uAudit.getUserId()))
+        {
+            ReviewMgr rMgr = ReviewMgrFactory.createInstance(this.contextId);
+            User user = rMgr.readUser(new User(uAudit.getUserId()));
+            uAudit.setInternalUserId(user.getInternalId());
+        }
+        return auditP.searchAdminMods(uAudit);
+    }
+
+
+    /**
+     * This method returns a list of failed authentication events for a particular invalid user {@link UserAudit#userId},
+     * and given timestamp {@link UserAudit#beginDate}.  If the {@link UserAudit#failedOnly} is true it will
+     * return only authentication attempts made with invalid userId.
+     * </p>
+     * This is possible because Fortress performs read on user before the bind.
+     * </p>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId</li>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one failed authentication event.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if a runtime system error occurs.
+     */
+    @Override
+    public List<AuthZ> searchInvalidUsers(UserAudit uAudit)
+        throws SecurityException
+    {
+        String methodName = "searchInvalidUsers";
+        assertContext(CLS_NM, methodName, uAudit, GlobalErrIds.AUDT_INPUT_NULL);
+        checkAccess(CLS_NM, methodName);
+        return auditP.searchInvalidAuthNs(uAudit);
+    }
+}
\ No newline at end of file


[16/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/PermDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/PermDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/PermDAO.java
new file mode 100755
index 0000000..896ee12
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/PermDAO.java
@@ -0,0 +1,1513 @@
+/*
+ *   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.apache;
+
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+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.DefaultAttribute;
+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.LdapAttributeInUseException;
+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.LdapNoSuchAttributeException;
+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.AdminRole;
+import org.apache.directory.fortress.core.rbac.AdminRoleUtil;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.RoleUtil;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * Permission data access class for LDAP. 
+ * <p/>
+ * This DAO class maintains the PermObj and Permission entities.
+ * <h3>The Fortress PermObj Entity Class is a composite of 3 LDAP Schema object classes</h2>
+ * <h4>PermObj Base - ftObject STRUCTURAL Object Class is used to store object name, id and type variables on target entity.</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass	( 1.3.6.1.4.1.38088.2.2</code>
+ * <li> <code>NAME 'ftObject'</code>
+ * <li> <code>DESC 'Fortress Permission Object Class'</code>
+ * <li> <code>SUP organizationalunit</code>                                              GlobalIds
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST (</code>
+ * <li> <code>ftId $ ftObjNm ) </code>
+ * <li> <code>MAY ( ftType ) )  </code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>PermObj - 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>PermObj - 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>
+ * <h3>The Fortress Permission Entity Class is composite of 3 LDAP Schema object classes</h3>
+ * The Permission entity extends a single OpenLDAP standard structural object class, 'organizationalRole' with
+ * one extension structural class, ftOperation,  and two auxiliary object classes, ftProperties, ftMods.
+ * The following 4 LDAP object classes will be mapped into this entity:
+ * <h4>Permission Base - 'ftOperation' STRUCTURAL Object Class is assigned roles and/or users which grants permissions which can be later checked</h4>
+ * using either 'checkAccess' or 'sessionPermissions APIs both methods that reside in the 'AccessMgrImpl' class.
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass	( 1.3.6.1.4.1.38088.2.3</code>
+ * <li> <code>NAME 'ftOperation'</code>
+ * <li> <code>DESC 'Fortress Permission Operation Object Class'</code>
+ * <li> <code>SUP organizationalrole</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST ( ftId $ ftPermName $</code>
+ * <li> <code>ftObjNm $ ftOpNm )</code>
+ * <li> <code>MAY ( ftRoles $ ftUsers $</code>
+ * <li> <code> ftObjId $ ftType) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>Permission Aux - ftProperties AUXILIARY Object Class is used to store optional client or otherwise custom 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>Permission Aux - 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>
+ * This class is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public final class PermDAO extends ApacheDsDataProvider implements org.apache.directory.fortress.core.rbac.dao.PermDAO
+{
+    /*
+      *  *************************************************************************
+      *  **  OpenAccessMgr PERMISSION STATICS
+      *  ************************************************************************
+      */
+    private static final String TYPE = "ftType";
+    private static final String PERM_OBJ_OBJECT_CLASS_NAME = "ftObject";
+    private static final String PERM_OP_OBJECT_CLASS_NAME = "ftOperation";
+
+    private static final String PERM_OBJ_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP,
+            "organizationalunit",
+            PERM_OBJ_OBJECT_CLASS_NAME,
+            GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME,
+            GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+
+    private static final String PERM_OP_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP,
+            "organizationalrole",
+            PERM_OP_OBJECT_CLASS_NAME,
+            GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME,
+            GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+
+    private static final String PERM_NAME = "ftPermName";
+    private static final String POBJ_ID = "ftObjId";
+    private static final String ROLES = "ftRoles";
+    private static final String USERS = "ftUsers";
+    private static final String[] PERMISSION_OP_ATRS =
+        {
+            GlobalIds.FT_IID, PERM_NAME, GlobalIds.POBJ_NAME, GlobalIds.POP_NAME, GlobalIds.DESC, GlobalIds.OU,
+            POBJ_ID, TYPE, ROLES, USERS, GlobalIds.PROPS
+    };
+
+    private static final String[] PERMISION_OBJ_ATRS =
+        {
+            GlobalIds.FT_IID, GlobalIds.POBJ_NAME, GlobalIds.DESC, GlobalIds.OU, TYPE,
+            GlobalIds.PROPS
+    };
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    public final PermObj createObject( PermObj entity ) throws CreateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity, entity.getContextId() );
+
+        try
+        {
+            Entry entry = new DefaultEntry( dn );
+            entry.add( GlobalIds.OBJECT_CLASS, PERM_OBJ_OBJ_CLASS );
+            entry.add( GlobalIds.POBJ_NAME, entity.getObjName() );
+
+            // this will generatre a new random, unique id on this entity:
+            entity.setInternalId();
+
+            // create the rDN:
+            entry.add( GlobalIds.FT_IID, entity.getInternalId() );
+
+            // ou is required:
+            entry.add( GlobalIds.OU, entity.getOu() );
+
+            // description is optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                entry.add( GlobalIds.DESC, entity.getDescription() );
+            }
+
+            // type is optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getType() ) )
+            {
+                entry.add( TYPE, entity.getType() );
+            }
+
+            // props are optional as well:
+            //if the props is null don't try to load these attributes
+            if ( VUtil.isNotNullOrEmpty( entity.getProperties() ) )
+            {
+                loadProperties( entity.getProperties(), entry, GlobalIds.PROPS );
+            }
+
+            // now add the new entry to directory:
+            ld = getAdminConnection();
+            add( ld, entry, entity );
+            entity.setDn( dn );
+        }
+        catch ( LdapException e )
+        {
+            String error = "createObject perm obj [" + entity.getObjName() + "] caught LdapException="
+                + e.getMessage();
+            throw new CreateException( GlobalErrIds.PERM_ADD_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    public final PermObj updateObj( PermObj entity )
+        throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity, entity.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            if ( VUtil.isNotNullOrEmpty( entity.getOu() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.OU, entity.getOu() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.DESC, entity.getDescription() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getType() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, TYPE, entity.getType() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getProperties() ) )
+            {
+                loadProperties( entity.getProperties(), mods, GlobalIds.PROPS, true );
+            }
+
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods, entity );
+                entity.setDn( dn );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "updateObj objName [" + entity.getObjName() + "] caught LdapException="
+                + e.getMessage();
+            throw new UpdateException( GlobalErrIds.PERM_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.RemoveException
+     *
+     */
+    public final void deleteObj( PermObj entity ) throws RemoveException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity, entity.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            deleteRecursive( ld, dn, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "deleteObj objName [" + entity.getObjName() + "] caught LdapException="
+                + e.getMessage();
+            throw new RemoveException( GlobalErrIds.PERM_DELETE_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "deleteObj objName [" + entity.getObjName() + "] caught LdapException="
+                + e.getMessage();
+            throw new RemoveException( GlobalErrIds.PERM_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    public final Permission createOperation( Permission entity ) throws CreateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity, entity.getContextId() );
+
+        try
+        {
+            Entry entry = new DefaultEntry( dn );
+
+            entry.add( GlobalIds.OBJECT_CLASS, PERM_OP_OBJ_CLASS );
+            entry.add( GlobalIds.POP_NAME, entity.getOpName() );
+            entry.add( GlobalIds.POBJ_NAME, entity.getObjName() );
+            entity.setAbstractName( entity.getObjName() + "." + entity.getOpName() );
+
+            // this will generate a new random, unique id on this entity:
+            entity.setInternalId();
+
+            // create the internal id:
+            entry.add( GlobalIds.FT_IID, entity.getInternalId() );
+
+            // description is optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                entry.add( GlobalIds.DESC, entity.getDescription() );
+            }
+
+            // the abstract name is the human readable identifier:
+            entry.add( PERM_NAME, entity.getAbstractName() );
+
+            // organizational name requires CN attribute:
+            entry.add( GlobalIds.CN, entity.getAbstractName() );
+
+            // objectid is optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getObjId() ) )
+            {
+                entry.add( POBJ_ID, entity.getObjId() );
+            }
+
+            // type is optional:
+            if ( VUtil.isNotNullOrEmpty( entity.getType() ) )
+            {
+                entry.add( TYPE, entity.getType() );
+            }
+
+            // These are multi-valued attributes, use the util function to load:
+            // These items are optional as well.  The utility function will return quietly if no items are loaded into collection:
+            loadAttrs( entity.getRoles(), entry, ROLES );
+            loadAttrs( entity.getUsers(), entry, USERS );
+
+            // props are optional as well:
+            //if the props is null don't try to load these attributes
+            if ( VUtil.isNotNullOrEmpty( entity.getProperties() ) )
+            {
+                loadProperties( entity.getProperties(), entry, GlobalIds.PROPS );
+            }
+
+            // now add the new entry to directory:
+            ld = getAdminConnection();
+            add( ld, entry, entity );
+            entity.setDn( dn );
+        }
+        catch ( LdapException e )
+        {
+            String error = "createOperation objName [" + entity.getObjName() + "] opName ["
+                + entity.getOpName() + "] caught LdapException=" + e.getMessage();
+            throw new CreateException( GlobalErrIds.PERM_ADD_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    public final Permission updateOperation( Permission entity )
+        throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( entity, entity.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            if ( VUtil.isNotNullOrEmpty( entity.getAbstractName() ) )
+            {
+                // the abstract name is the human readable identifier:
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, PERM_NAME, entity.getAbstractName() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.DESC, entity.getDescription() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getType() ) )
+            {
+
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, TYPE, entity.getType() ) );
+            }
+
+            // These are multi-valued attributes, use the util function to load:
+            loadAttrs( entity.getRoles(), mods, ROLES );
+            loadAttrs( entity.getUsers(), mods, USERS );
+            loadProperties( entity.getProperties(), mods, GlobalIds.PROPS, true );
+
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods, entity );
+                entity.setDn( dn );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "updateOperation objName [" + entity.getObjName() + "] opName ["
+                + entity.getOpName() + "] caught LdapException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.PERM_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.RemoveException
+     *
+     */
+    public final void deleteOperation( Permission entity ) throws RemoveException
+    {
+        LdapConnection ld = null;
+        String dn = getOpRdn( entity.getOpName(), entity.getObjId() ) + "," + GlobalIds.POBJ_NAME + "="
+            + entity.getObjName() + "," + getRootDn( entity.isAdmin(), entity.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            deleteRecursive( ld, dn, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "deleteOperation objName [" + entity.getObjName() + "] opName ["
+                + entity.getOpName() + "] caught LdapException=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.PERM_DELETE_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "deleteOperation objName [" + entity.getObjName() + "] opName ["
+                + entity.getOpName() + "] caught LdapException=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.PERM_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param pOp
+     * @param role
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final void grant( Permission pOp, Role role )
+        throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( pOp, pOp.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            mods.add( new DefaultModification(
+                ModificationOperation.ADD_ATTRIBUTE, ROLES, role.getName() ) );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, pOp );
+        }
+        catch ( LdapAttributeInUseException e )
+        {
+            String warning = "grant perm object [" + pOp.getObjName() + "] operation ["
+                + pOp.getOpName() + "] role [" + role.getName() + "] assignment already exists, Fortress rc="
+                + GlobalErrIds.PERM_ROLE_EXIST;
+            throw new UpdateException( GlobalErrIds.PERM_ROLE_EXIST, warning );
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "grant perm object [" + pOp.getObjName() + "] operation ["
+                + pOp.getOpName() + "] role [" + role.getName() + "] perm not found, Fortress rc="
+                + GlobalErrIds.PERM_OP_NOT_FOUND;
+            throw new UpdateException( GlobalErrIds.PERM_OP_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "grant perm object [" + pOp.getObjName() + "] operation ["
+                + pOp.getOpName() + "] name [" + role.getName() + "]  caught LdapException="
+                + e.getMessage();
+            throw new UpdateException( GlobalErrIds.PERM_GRANT_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param pOp
+     * @param role
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final void revoke( Permission pOp, Role role )
+        throws UpdateException, FinderException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( pOp, pOp.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification(
+                ModificationOperation.REMOVE_ATTRIBUTE, ROLES, role.getName() ) );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, pOp );
+        }
+        catch ( LdapNoSuchAttributeException e )
+        {
+            String warning = "revoke perm object [" + pOp.getObjName() + "] operation ["
+                + pOp.getOpName() + "] name [" + role.getName() + "] assignment does not exist.";
+            throw new FinderException( GlobalErrIds.PERM_ROLE_NOT_EXIST, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "revoke perm object [" + pOp.getObjName() + "] operation ["
+                + pOp.getOpName() + "] name [" + role.getName() + "] caught LdapException=" +
+                e.getMessage();
+            throw new UpdateException( GlobalErrIds.PERM_REVOKE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param pOp
+     * @param user
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final void grant( Permission pOp, User user )
+        throws UpdateException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( pOp, pOp.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification(
+                ModificationOperation.ADD_ATTRIBUTE, USERS, user.getUserId() ) );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, pOp );
+        }
+        catch ( LdapAttributeInUseException e )
+        {
+            String warning = "grant perm object [" + pOp.getObjName() + "] operation ["
+                + pOp.getOpName() + "] userId [" + user.getUserId() + "] assignment already exists, Fortress rc="
+                + GlobalErrIds.PERM_USER_EXIST;
+
+            throw new UpdateException( GlobalErrIds.PERM_USER_EXIST, warning );
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "grant perm object [" + pOp.getObjName() + "] operation ["
+                + pOp.getOpName() + "] userId [" + user.getUserId() + "] perm not found, Fortress rc="
+                + GlobalErrIds.PERM_OP_NOT_FOUND;
+            throw new UpdateException( GlobalErrIds.PERM_OP_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "grant perm object [" + pOp.getObjName() + "] operation ["
+                + pOp.getOpName() + "] userId [" + user.getUserId() + "] caught LdapException="
+                + e.getMessage();
+            throw new UpdateException( GlobalErrIds.PERM_GRANT_USER_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param pOp
+     * @param user
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final void revoke( Permission pOp, User user )
+        throws UpdateException, FinderException
+    {
+        LdapConnection ld = null;
+        String dn = getDn( pOp, pOp.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE,
+                USERS, user.getUserId() ) );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, pOp );
+        }
+        catch ( LdapNoSuchAttributeException e )
+        {
+            String warning = "revoke perm object [" + pOp.getObjName() + "] operation ["
+                + pOp.getOpName() + "] userId [" + user.getUserId() + "] assignment does not exist.";
+            throw new FinderException( GlobalErrIds.PERM_USER_NOT_EXIST, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "revoke perm object [" + pOp.getObjName() + "] operation ["
+                + pOp.getOpName() + "] userId [" + user.getUserId() + "] caught LdapException="
+                + e.getMessage();
+            throw new UpdateException( GlobalErrIds.PERM_REVOKE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param permission
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final Permission getPerm( Permission permission )
+        throws FinderException
+    {
+        Permission entity = null;
+        LdapConnection ld = null;
+        String dn = getOpRdn( permission.getOpName(), permission.getObjId() ) + "," + GlobalIds.POBJ_NAME + "="
+            + permission.getObjName() + "," + getRootDn( permission.isAdmin(), permission.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, dn, PERMISSION_OP_ATRS );
+            entity = unloadPopLdapEntry( findEntry, 0, permission.isAdmin() );
+
+            if ( entity == null )
+            {
+                String warning = "getPerm no entry found dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.PERM_OP_NOT_FOUND, warning );
+            }
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getPerm Op COULD NOT FIND ENTRY for dn [" + dn + "]";
+            throw new FinderException( GlobalErrIds.PERM_OP_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getUser [" + dn + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_READ_OP_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param permObj
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final PermObj getPerm( PermObj permObj )
+        throws FinderException
+    {
+        PermObj entity = null;
+        LdapConnection ld = null;
+        String dn = GlobalIds.POBJ_NAME + "=" + permObj.getObjName() + ","
+            + getRootDn( permObj.isAdmin(), permObj.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, dn, PERMISION_OBJ_ATRS );
+            entity = unloadPobjLdapEntry( findEntry, 0,permObj.isAdmin() );
+
+            if ( entity == null )
+            {
+                String warning = "getPerm Obj no entry found dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.PERM_OBJ_NOT_FOUND, warning );
+            }
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getPerm Obj COULD NOT FIND ENTRY for dn [" + dn + "]";
+            throw new FinderException( GlobalErrIds.PERM_OBJ_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getPerm Obj dn [" + dn + "] caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_READ_OBJ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * This method performs fortress authorization using data passed in (session) and stored on ldap server (permission).  It has been recently changed to use ldap compare operations in order to trigger slapd access log updates in directory.
+     * It performs ldap operations:  read and (optionally) compare.  The first is to pull back the permission to see if user has access or not.  The second is to trigger audit
+     * record storage on ldap server but can be disabled.
+     *
+     * @param session contains {@link Session#getUserId()}, for rbac check {@link org.apache.directory.fortress.core.rbac.Session#getRoles()}, for arbac check: {@link org.apache.directory.fortress.core.rbac.Session#getAdminRoles()}.
+     * @param inPerm  must contain required attributes {@link Permission#objName} and {@link Permission#opName}.  {@link Permission#objId} is optional.
+     * @return boolean containing result of check.
+     * @throws org.apache.directory.fortress.core.FinderException
+     *          In the event system error occurs looking up data on ldap server.
+     */
+    public final boolean checkPermission( Session session, Permission inPerm ) throws FinderException
+    {
+        boolean isAuthZd = false;
+        LdapConnection ld = null;
+        String dn = getOpRdn( inPerm.getOpName(), inPerm.getObjId() ) + "," + GlobalIds.POBJ_NAME + "="
+            + inPerm.getObjName() + "," + getRootDn( inPerm.isAdmin(), inPerm.getContextId() );
+
+        try
+        {
+            // Use unauthenticated connection because we want to assert the end user identity onto ldap hop:
+            ld = getUserConnection();
+
+            // LDAP Operation #1: Read the targeted permission from ldap server
+            //LDAPEntry entry = read(ld, dn, PERMISSION_OP_ATRS, session.getUser().getDn());
+            Entry entry = read( ld, dn, PERMISSION_OP_ATRS );
+            if(entry == null)
+            {
+                // if permission not found, cannot continue.
+                String error = "checkPermission DOES NOT EXIST : obj name [" + inPerm.getObjName() + "], obj id [" + inPerm.getObjId() + "], op name [" + inPerm.getOpName() + "], idAdmin [" + inPerm.isAdmin() + "]";
+                throw new FinderException( GlobalErrIds.PERM_NOT_EXIST, error );
+            }
+
+            // load the permission entity with data retrieved from the permission node:
+            Permission outPerm = unloadPopLdapEntry( entry, 0, inPerm.isAdmin() );
+
+            // The admin flag will be set to 'true' if this is an administrative permission:
+            outPerm.setAdmin( inPerm.isAdmin() );
+
+            // Pass the tenant id along:
+            outPerm.setContextId( inPerm.getContextId() );
+
+            // The objective of these next steps is to evaluate the outcome of authorization attempt and trigger a write to slapd access logger containing the result.
+            // The objectClass triggered by slapd access log write for upcoming ldap op is 'auditCompare'.
+            // Set this attribute either with actual operation name that will succeed compare (for authZ success) or bogus value which will fail compare (for authZ failure):
+            String attributeValue;
+
+            // This method determines if the user is authorized for this permission:
+            isAuthZd = isAuthorized( session, outPerm );
+
+            // This is done to leave an audit trail in ldap server log:
+            if ( isAuthZd )
+            {
+                // Yes, set the operation name onto this attribute for storage into audit trail:
+                attributeValue = outPerm.getOpName();
+            }
+            else
+            {
+                // No, set a simple error message onto this attribute for storage into audit trail:
+                attributeValue = "AuthZ Failed";
+            }
+
+            // There is a switch in fortress config to disable audit ops like this one.
+            // But if used the compare method will use OpenLDAP's Proxy Authorization Control to assert identity of end user onto connection.
+            // LDAP Operation #2: Compare.
+            addAuthZAudit( ld, dn, session.getUser().getDn(), attributeValue );
+        }
+        catch ( LdapException e )
+        {
+            if ( !( e instanceof LdapNoSuchObjectException ) )
+            {
+                String error = "checkPermission caught LdapException=" + e.getMessage();
+                throw new FinderException( GlobalErrIds.PERM_READ_OP_FAILED, error, e );
+            }
+
+            // There is a switch in fortress config to disable the audit ops.
+            addAuthZAudit( ld, dn, session.getUser().getDn(), "AuthZ Invalid" );
+        }
+        finally
+        {
+            closeUserConnection( ld );
+        }
+
+        return isAuthZd;
+    }
+
+
+    /**
+     * Perform LDAP compare operation here to associate audit record with user authorization event.
+     *
+     * @param ld this method expects the ldap connection to be good
+     * @param permDn contains distinguished name of the permission object.
+     * @param userDn contains the distinguished name of the user object.
+     * @param attributeValue string value will be associated with the 'audit' record stored in ldap.
+     * @throws FinderException in the event ldap system exception occurs.
+     */
+    private void addAuthZAudit( LdapConnection ld, String permDn, String userDn, String attributeValue )
+        throws FinderException
+    {
+        // Audit can be turned off here with fortress config param: 'enable.audit=false'
+        if ( GlobalIds.IS_AUDIT && GlobalIds.IS_OPENLDAP )
+        {
+            try
+            {
+                // The compare method uses OpenLDAP's Proxy Authorization Control to assert identity of end user onto connection:
+                // LDAP Operation #2: Compare:
+                compareNode( ld, permDn, userDn, new DefaultAttribute( GlobalIds.POP_NAME, attributeValue ) );
+            }
+            catch ( UnsupportedEncodingException ee )
+            {
+                String error = "addAuthZAudit caught UnsupportedEncodingException=" + ee.getMessage();
+                throw new FinderException( GlobalErrIds.PERM_COMPARE_OP_FAILED, error, ee );
+            }
+            catch ( LdapException e )
+            {
+                if ( !( e instanceof LdapNoSuchObjectException ) )
+                {
+                    String error = "addAuthZAudit caught LdapException=" + e.getMessage();
+                    throw new FinderException( GlobalErrIds.PERM_COMPARE_OP_FAILED, error, e );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * This function will first compare the userId from the session object with the list of users attached to permission object.
+     * If match does not occur there, determine if there is a match between the authorized roles of user with roles attached to permission object.
+     * For this use {@link org.apache.directory.fortress.core.rbac.Permission#isAdmin()} to determine if admin permissions or normal permissions have been passed in by caller.
+     *
+     * @param session contains the {@link org.apache.directory.fortress.core.rbac.Session#getUserId()},{@link Session#getRoles()} or {@link org.apache.directory.fortress.core.rbac.Session#getAdminRoles()}.
+     * @param permission contains {@link org.apache.directory.fortress.core.rbac.Permission#getUsers()} and {@link Permission#getRoles()}.
+     * @return binary result.
+     */
+    private boolean isAuthorized( Session session, Permission permission )
+    {
+        boolean result = false;
+        Set<String> userIds = permission.getUsers();
+
+        if ( VUtil.isNotNullOrEmpty( userIds ) && userIds.contains( session.getUserId() ) )
+        {
+            // user is assigned directly to this permission, no need to look further.
+            return true;
+        }
+
+        Set<String> roles = permission.getRoles();
+
+        if ( VUtil.isNotNullOrEmpty( roles ) )
+        {
+            if ( permission.isAdmin() )
+            {
+                // ARBAC Permission check include's User's inherited admin roles:
+                Set<String> activatedRoles = AdminRoleUtil.getInheritedRoles( session.getAdminRoles(),
+                    permission.getContextId() );
+
+                for ( String role : roles )
+                {
+                    // This is case insensitive op determines if user has matching admin role to the admin permission::
+                    if ( activatedRoles.contains( role ) )
+                    {
+                        result = true;
+                        break;
+                    }
+                }
+            }
+            else
+            {
+                // RBAC Permission check include's User's inherited roles:
+                Set<String> activatedRoles = RoleUtil.getInheritedRoles( session.getRoles(), permission.getContextId() );
+
+                for ( String role : roles )
+                {
+                    // This is case insensitive op determines if user has matching role:
+                    if ( activatedRoles.contains( role ) )
+                    {
+                        result = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+        return result;
+    }
+
+
+    /**
+     * @param le
+     * @param sequence
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     * @throws LdapException
+     */
+    private Permission unloadPopLdapEntry( Entry le, long sequence, boolean isAdmin ) throws LdapInvalidAttributeValueException
+    {
+        Permission entity = new ObjectFactory().createPermission();
+        entity.setSequenceId( sequence );
+        entity.setAbstractName( getAttribute( le, PERM_NAME ) );
+        entity.setObjName( getAttribute( le, GlobalIds.POBJ_NAME ) );
+        entity.setObjId( getAttribute( le, POBJ_ID ) );
+        entity.setOpName( getAttribute( le, GlobalIds.POP_NAME ) );
+        entity.setInternalId( getAttribute( le, GlobalIds.FT_IID ) );
+        entity.setRoles( getAttributeSet( le, ROLES ) );
+        entity.setUsers( getAttributeSet( le, USERS ) );
+        entity.setType( getAttribute( le, TYPE ) );
+        entity.setDescription( getAttribute( le, GlobalIds.DESC ) );
+        entity.addProperties( AttrHelper.getProperties( getAttributes( le, GlobalIds.PROPS ) ) );
+        entity.setAdmin( isAdmin );
+
+        // TODO: find out the correct way to do this:
+        if(le != null)
+        {
+            entity.setDn( le.getDn().getNormName() );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param le
+     * @param sequence
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     * @throws LdapException
+     */
+    private PermObj unloadPobjLdapEntry( Entry le, long sequence, boolean isAdmin ) throws LdapInvalidAttributeValueException
+    {
+        PermObj entity = new ObjectFactory().createPermObj();
+        entity.setSequenceId( sequence );
+        entity.setObjName( getAttribute( le, GlobalIds.POBJ_NAME ) );
+        entity.setOu( getAttribute( le, GlobalIds.OU ) );
+        entity.setDn( le.getDn().getName() );
+        entity.setInternalId( getAttribute( le, GlobalIds.FT_IID ) );
+        entity.setType( getAttribute( le, TYPE ) );
+        entity.setDescription( getAttribute( le, GlobalIds.DESC ) );
+        entity.addProperties( AttrHelper.getProperties( getAttributes( le, GlobalIds.PROPS ) ) );
+        entity.setAdmin( isAdmin );
+        return entity;
+    }
+
+
+    /**
+     * @param permission
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Permission> findPermissions( Permission permission )
+        throws FinderException
+    {
+        List<Permission> permList = new ArrayList<>();
+        LdapConnection ld = null;
+        String permRoot = getRootDn( permission.isAdmin(), permission.getContextId() );
+
+        try
+        {
+            String permObjVal = encodeSafeText( permission.getObjName(), GlobalIds.PERM_LEN );
+            String permOpVal = encodeSafeText( permission.getOpName(), GlobalIds.PERM_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OP_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.POBJ_NAME + "=" + permObjVal + "*)("
+                + GlobalIds.POP_NAME + "=" + permOpVal + "*))";
+
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, permRoot,
+                SearchScope.SUBTREE, filter, PERMISSION_OP_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                permList.add( unloadPopLdapEntry( searchResults.getEntry(), sequence++, permission.isAdmin() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findPermissions caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findPermissions caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return permList;
+    }
+
+
+    /**
+     * @param permObj
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<PermObj> findPermissions( PermObj permObj )
+        throws FinderException
+    {
+        List<PermObj> permList = new ArrayList<>();
+        LdapConnection ld = null;
+        String permRoot = getRootDn( permObj.isAdmin(), permObj.getContextId() );
+
+        try
+        {
+            String permObjVal = encodeSafeText( permObj.getObjName(), GlobalIds.PERM_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OBJ_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.POBJ_NAME + "=" + permObjVal + "*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, permRoot,
+                SearchScope.SUBTREE, filter, PERMISION_OBJ_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                permList.add( unloadPobjLdapEntry( searchResults.getEntry(), sequence++, permObj.isAdmin() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findPermissions caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findPermissions caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return permList;
+    }
+
+
+    /**
+     * @param ou
+     * @return
+     * @throws FinderException
+     */
+    public final List<PermObj> findPermissions( OrgUnit ou, boolean limitSize ) throws FinderException
+    {
+        List<PermObj> permList = new ArrayList<>();
+        LdapConnection ld = null;
+        String permRoot = getRootDn( ou.getContextId(), GlobalIds.PERM_ROOT );
+
+        try
+        {
+            String ouVal = encodeSafeText( ou.getName(), GlobalIds.OU_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OBJ_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.OU + "=" + ouVal + "*))";
+            int maxLimit;
+
+            if ( limitSize )
+            {
+                maxLimit = 10;
+            }
+            else
+            {
+                maxLimit = 0;
+            }
+
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, permRoot,
+                SearchScope.SUBTREE, filter, PERMISION_OBJ_ATRS, false, GlobalIds.BATCH_SIZE, maxLimit );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                permList.add( unloadPobjLdapEntry( searchResults.getEntry(), sequence++, false ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findPermissions caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findPermissions caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return permList;
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Permission> findPermissions( Role role ) throws FinderException
+    {
+        List<Permission> permList = new ArrayList<>();
+        LdapConnection ld = null;
+        String permRoot;
+
+        boolean isAdmin = false;
+        if ( role.getClass().equals( AdminRole.class ) )
+        {
+            permRoot = getRootDn( role.getContextId(), GlobalIds.ADMIN_PERM_ROOT );
+            isAdmin = true;
+        }
+        else
+        {
+            permRoot = getRootDn( role.getContextId(), GlobalIds.PERM_ROOT );
+        }
+
+        try
+        {
+            String roleVal = encodeSafeText( role.getName(), GlobalIds.ROLE_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OP_OBJECT_CLASS_NAME + ")(";
+            Set<String> roles;
+
+            if ( role.getClass().equals( AdminRole.class ) )
+            {
+                roles = AdminRoleUtil.getAscendants( role.getName(), role.getContextId() );
+            }
+            else
+            {
+                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, permRoot,
+                SearchScope.SUBTREE, filter, PERMISSION_OP_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                permList.add( unloadPopLdapEntry( searchResults.getEntry(), sequence++, isAdmin ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findPermissions caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_ROLE_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findPermissions caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_ROLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return permList;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Permission> findPermissions( User user ) throws FinderException
+    {
+        List<Permission> permList = new ArrayList<>();
+        LdapConnection ld = null;
+        String permRoot = getRootDn( user.getContextId(), GlobalIds.PERM_ROOT );
+
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OP_OBJECT_CLASS_NAME + ")(|";
+            Set<String> roles = RoleUtil.getInheritedRoles( user.getRoles(), user.getContextId() );
+
+            if ( VUtil.isNotNullOrEmpty( roles ) )
+            {
+                for ( String uRole : roles )
+                {
+                    filter += "(" + ROLES + "=" + uRole + ")";
+                }
+            }
+
+            filter += "(" + USERS + "=" + user.getUserId() + ")))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, permRoot,
+                SearchScope.SUBTREE, filter, PERMISSION_OP_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                permList.add( unloadPopLdapEntry( searchResults.getEntry(), sequence++,false ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findPermissions user [" + user.getUserId()
+                + "] caught LdapException in PermDAO.findPermissions=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_USER_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findPermissions user [" + user.getUserId()
+                + "] caught LdapException in PermDAO.findPermissions=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_USER_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return permList;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Permission> findUserPermissions( User user ) throws FinderException
+    {
+        List<Permission> permList = new ArrayList<>();
+        LdapConnection ld = null;
+        String permRoot = getRootDn( user.getContextId(), GlobalIds.PERM_ROOT );
+
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OP_OBJECT_CLASS_NAME + ")";
+            filter += "(" + USERS + "=" + user.getUserId() + "))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, permRoot,
+                SearchScope.SUBTREE, filter, PERMISSION_OP_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                permList.add( unloadPopLdapEntry( searchResults.getEntry(), sequence++, false ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findUserPermissions user [" + user.getUserId()
+                + "] caught LdapException in PermDAO.findPermissions=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_USER_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findUserPermissions user [" + user.getUserId()
+                + "] caught LdapException in PermDAO.findPermissions=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_USER_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return permList;
+    }
+
+
+    /**
+     * @param session
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Permission> findPermissions( Session session, boolean isAdmin ) throws FinderException
+    {
+        List<Permission> permList = new ArrayList<>();
+        LdapConnection ld = null;
+        String permRoot = getRootDn( isAdmin, session.getContextId() );
+
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + PERM_OP_OBJECT_CLASS_NAME + ")(|";
+            filter += "(" + USERS + "=" + session.getUserId() + ")";
+            Set<String> roles;
+            if(isAdmin)
+            {
+                roles = AdminRoleUtil.getInheritedRoles( session.getAdminRoles(), session.getContextId() );
+            }
+            else
+            {
+                roles = RoleUtil.getInheritedRoles( session.getRoles(), session.getContextId() );
+            }
+            if ( VUtil.isNotNullOrEmpty( roles ) )
+            {
+                for ( String uRole : roles )
+                {
+                    filter += "(" + ROLES + "=" + uRole + ")";
+                }
+            }
+
+            filter += "))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, permRoot,
+                SearchScope.SUBTREE, filter, PERMISSION_OP_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                permList.add( unloadPopLdapEntry( searchResults.getEntry(), sequence++, isAdmin ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findPermissions user [" + session.getUserId()
+                + "] caught LdapException in PermDAO.findPermissions=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SESS_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findPermissions user [" + session.getUserId()
+                + "] caught LdapException in PermDAO.findPermissions=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.PERM_SESS_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return permList;
+    }
+
+
+    /**
+     * @param opName
+     * @param objId
+     * @return
+     */
+    static String getOpRdn( String opName, String objId )
+    {
+        String rDn;
+
+        if ( objId != null && objId.length() > 0 )
+        {
+            rDn = GlobalIds.POP_NAME + "=" + opName + "+" + POBJ_ID + "=" + objId;
+        }
+        else
+        {
+            rDn = GlobalIds.POP_NAME + "=" + opName;
+        }
+
+        return rDn;
+    }
+
+
+    private String getDn( Permission pOp, String contextId )
+    {
+        return getOpRdn( pOp.getOpName(), pOp.getObjId() ) + "," + GlobalIds.POBJ_NAME + "=" + pOp.getObjName()
+            + "," + getRootDn( pOp.isAdmin(), contextId );
+    }
+
+
+    private String getDn( PermObj pObj, String contextId )
+    {
+        return GlobalIds.POBJ_NAME + "=" + pObj.getObjName() + "," + getRootDn( pObj.isAdmin(), contextId );
+    }
+
+
+    private String getRootDn( boolean isAdmin, String contextId )
+    {
+        String dn;
+
+        if ( isAdmin )
+        {
+            dn = getRootDn( contextId, GlobalIds.ADMIN_PERM_ROOT );
+        }
+        else
+        {
+            dn = getRootDn( contextId, GlobalIds.PERM_ROOT );
+        }
+
+        return dn;
+    }
+}
\ 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/apache/PolicyDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/PolicyDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/PolicyDAO.java
new file mode 100755
index 0000000..1fedf7f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/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.dao.apache;
+
+
+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
+ */
+public final class PolicyDAO extends ApacheDsDataProvider implements org.apache.directory.fortress.core.rbac.dao.PolicyDAO
+{
+    /*
+      *  *************************************************************************
+      *  **  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
+     *
+     */
+    public 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
+     *
+     */
+    public 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
+     */
+    public 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
+     *
+     */
+    public 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
+     *
+     */
+    public 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
+     */
+    public 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 );
+    }
+}


[35/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/LdapCounters.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/LdapCounters.java b/src/main/java/org/apache/directory/fortress/core/ldap/LdapCounters.java
new file mode 100644
index 0000000..6f83b4d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/LdapCounters.java
@@ -0,0 +1,122 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap;
+
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+/**
+ *
+ */
+public class LdapCounters
+{
+    AtomicInteger readCtr = new AtomicInteger( 0 );
+    AtomicInteger searchCtr = new AtomicInteger( 0 );
+    AtomicInteger compareCtr = new AtomicInteger( 0 );
+    AtomicInteger addCtr = new AtomicInteger( 0 );
+    AtomicInteger modCtr = new AtomicInteger( 0 );
+    AtomicInteger deleteCtr = new AtomicInteger( 0 );
+    AtomicInteger bindCtr = new AtomicInteger( 0 );
+
+
+    public void incrementSearch()
+    {
+        searchCtr.incrementAndGet();
+    }
+
+
+    public void incrementRead()
+    {
+        readCtr.incrementAndGet();
+    }
+
+
+    public void incrementCompare()
+    {
+        compareCtr.incrementAndGet();
+    }
+
+
+    public void incrementAdd()
+    {
+        addCtr.incrementAndGet();
+    }
+
+
+    public void incrementMod()
+    {
+        modCtr.incrementAndGet();
+    }
+
+
+    public void incrementDelete()
+    {
+        deleteCtr.incrementAndGet();
+    }
+
+
+    public void incrementBind()
+    {
+        bindCtr.incrementAndGet();
+    }
+
+
+    public long getSearch()
+    {
+        return searchCtr.intValue();
+    }
+
+
+    public long getRead()
+    {
+        return readCtr.intValue();
+    }
+
+
+    public long getCompare()
+    {
+        return compareCtr.intValue();
+    }
+
+
+    public long getAdd()
+    {
+        return addCtr.intValue();
+    }
+
+
+    public long getMod()
+    {
+        return modCtr.intValue();
+    }
+
+
+    public long getDelete()
+    {
+        return deleteCtr.intValue();
+    }
+
+
+    public long getBind()
+    {
+        return bindCtr.intValue();
+    }
+}
\ 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/ldap/PoolMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/PoolMgr.java b/src/main/java/org/apache/directory/fortress/core/ldap/PoolMgr.java
new file mode 100755
index 0000000..e960ad3
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/PoolMgr.java
@@ -0,0 +1,619 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap;
+
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.util.crypto.EncryptUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPControl;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConstraints;
+
+/**
+ * This class uses {@link ConnectionPool} to manage pools of {@code com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection}
+ * to supply resource connections to Fortress DAO utilities.  The methods in the class are used by internal Fortress functions
+ * and are not intended for used by external clients.  This class maintains 3 pools of connections.
+ * <ol>
+ * <li>Connections of type, {@link PoolMgr.ConnType#USER}, use {@link #connPoolUser} for user authentication and password change operations.</li>
+ * <li>Connections of type, {@link PoolMgr.ConnType#ADMIN}, use {@link #connPoolAdmin} and are used for maintenance and interrogation of ldap server objects.</li>
+ * <li>Connections of type, {@link PoolMgr.ConnType#LOG}, use {@link #connPoolLog} and used for pulling slapd log data from the server,  </li>
+ * </ol>
+ * <p/>
+ * This class uses <a href="http://www.unboundid.com/products/ldap-sdk/">UnboundID LDAP SDK for Java</a> as client to
+ * process LDAP operations.  The UnboundID SDK is distributed under 3 open source licenses and is free to use and distribute in
+ * other open source or proprietary software packages.  For more info see, <a href="http://www.unboundid.com/products/ldap-sdk/docs/">LDAP SDK for Java</a>
+ * <p/>
+ * The {@link ConnectionPool} class derives source code from the Mozilla Java LDAP SDK.  For more
+ * info on the license this derived code adheres, see: <a href="http://www.mozilla.org/MPL/MPL-1.1.html/">Mozilla Public License Version 1.1</a>
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+class PoolMgr
+{
+    // Property names for ldap connection pools:
+    private static final String LDAP_ADMIN_POOL_UID = "admin.user";
+    private static final String LDAP_ADMIN_POOL_PW = "admin.pw";
+    private static final String LDAP_LOG_POOL_UID = "log.admin.user";
+    private static final String LDAP_LOG_POOL_PW = "log.admin.pw";
+    private static final String LDAP_ADMIN_POOL_MIN = "min.admin.conn";
+    private static final String LDAP_ADMIN_POOL_MAX = "max.admin.conn";
+    private static final String LDAP_USER_POOL_MIN = "min.user.conn";
+    private static final String LDAP_USER_POOL_MAX = "max.user.conn";
+    private static final String LDAP_LOG_POOL_MIN = "min.log.conn";
+    private static final String LDAP_LOG_POOL_MAX = "max.log.conn";
+    private static final String LDAP_VERSION = "ldapVersion";
+    private static final String LDAP_CONNECTION_TIMEOUT = "connTimeout";
+    private static final String LDAP_DEBUG_FLAG = "debug.ldap.pool";
+    private static final String LDAP_HOST = "host";
+    private static final String LDAP_PORT = "port";
+
+    // 3 types of connection pools are managed by ths class:
+    static enum ConnType
+    {
+        /**
+         * Admin connections used for most of the Fortress internal operations.  Internal bind on connection
+         * will be performed using config param found {@link #LDAP_ADMIN_POOL_UID}
+         */
+        ADMIN,
+
+        /**
+         * User connections for non-admin binds and password mods.  Connections will not be bound
+         * to user prior to returning to caller.
+         */
+        USER,
+
+        /**
+         * All slapd log operations use this connection pool.   Internal bind on connection
+         * will be performed using config param found {@link #LDAP_LOG_POOL_UID}
+         */
+        LOG
+    }
+
+    // Used to synch the getConnection method:
+    private static final Object adminSynchLock = new Object();
+    private static final Object userSynchLock = new Object();
+    private static final Object logSynchLock = new Object();
+
+    // Canaries in the coal mine:
+    private static LDAPConnection testAdminConn;
+    private static LDAPConnection testUConn;
+    private static LDAPConnection testLConn;
+
+    // Logging
+    private static final String CLS_NM = PoolMgr.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    // Declare the index for connection pool array:
+    private static final int ADMIN = 0;
+    private static final int USER = 1;
+    private static final int AUDIT = 2;
+
+    // Contains the adminUserId LDAP connections:
+    private static final ConnectionPool connPoolAdmin = null;
+    private static final ConnectionPool connPoolUser = null;
+    private static final ConnectionPool connPoolLog = null;
+    private static final ConnectionPool[] connPool = {connPoolAdmin, connPoolUser, connPoolLog};
+
+    // this modules uses openldap pw policies
+    private static final LDAPControl pwPolicyControl = new LDAPControl(GlobalIds.OPENLDAP_PW_RESPONSE_CONTROL, false, null);
+    private static String adminPw;
+    private static String adminUserId = null;
+    private static final boolean isDebugEnabled = Config.getBoolean(LDAP_DEBUG_FLAG, false);
+    private static int connectionTimeout ;
+    private static int ldapRevision;
+
+    // Load all of the static member variables of this class & initialize the admin connection pools:
+    static
+    {
+        try
+        {
+            adminUserId = Config.getProperty(LDAP_ADMIN_POOL_UID);
+            if(EncryptUtil.isEnabled())
+            {
+                adminPw = EncryptUtil.decrypt(Config.getProperty(LDAP_ADMIN_POOL_PW));
+            }
+            else
+            {
+                adminPw = Config.getProperty(LDAP_ADMIN_POOL_PW);
+            }
+
+            // Default ldap version to v3:
+            ldapRevision = Config.getInt(LDAP_VERSION, 3);
+            // Default 10 seconds for client wait on new connection requests from pool:
+            connectionTimeout = Config.getInt(LDAP_CONNECTION_TIMEOUT, 10000);
+            createAdminPool();
+        }
+
+        // If we can't initialize the connection pools we're dead in the water.
+        catch (com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException le)
+        {
+            String error = " Static Initializer Block caught com.unboundid.ldap.sdk.migrate.ldapjdk.LdapException=" + le;
+            LOG.error( error );
+        }
+        catch (Exception e)
+        {
+            String error = " Static Initializer Block caught java.lang.Exception=" + e;
+            LOG.error( error );
+        }
+    }
+
+
+    /**
+     * Method performs an LDAP bind for a user/password combination.  This function is valid
+     * if and only if the user entity is a member of the USERS data set.  The LDAP directory
+     * will return the OpenLDAP PW Policy control.
+     *
+     * @param ld       connection to ldap server.
+     * @param userId   contains the LDAP dn to the user entry.
+     * @param password contains the password in clear text.
+     * @return boolean value - true if bind successful, false otherwise.
+     * @throws LDAPException in the event of LDAP error.
+     */
+    static boolean bind(LDAPConnection ld, String userId, char[] password)
+        throws LDAPException
+    {
+        return bindUser(userId, password, ld);
+    }
+
+    /**
+     * Close the LDAP connection.
+     *
+     * @param ld   handle to ldap connection object.
+     * @param type specifies the type of connection - ADMIN, USER Or LOG.
+     */
+    static void closeConnection(LDAPConnection ld, ConnType type)
+    {
+        switch (type)
+        {
+            case ADMIN:
+                if (ld != null)
+                {
+                    connPool[ADMIN].close(ld);
+                }
+                break;
+
+            case USER:
+                if (ld != null)
+                {
+                    connPool[USER].close(ld);
+                }
+                break;
+
+            case LOG:
+                if (ld != null)
+                {
+                    connPool[AUDIT].close( ld );
+                }
+                break;
+        }
+    }
+
+    /**
+     * Get a connection to the LDAP server.
+     *
+     * @param type type specifies the type of connection - ADMIN, USER Or LOG.
+     * @return ldap connection.
+     * @throws LDAPException
+     */
+    static LDAPConnection getConnection(ConnType type)
+        throws LDAPException
+    {
+        LDAPConnection ld = null;
+        ConnectionPool cp = null;
+        Object lockObj = null;
+        String szType = null;
+        switch (type)
+        {
+            case ADMIN:
+                cp = connPool[ADMIN];
+                lockObj = adminSynchLock;
+                szType = "ADMIN";
+                break;
+
+            case USER:
+                cp = connPool[USER];
+                lockObj = userSynchLock;
+                szType = "USER";
+                break;
+
+            case LOG:
+                cp = connPool[AUDIT];
+                lockObj = logSynchLock;
+                szType = "LOG";
+                break;
+        }
+        try
+        {
+            synchronized (lockObj)
+            {
+                // check the connection pool reference
+                if (cp == null)
+                {
+                    String info = "getConnection " + szType + " initializing pool";
+                    LOG.info( info );
+                    cp = recoverPool(type);
+                }
+                if (connectionTimeout > 0)
+                {
+                    ld = cp.getConnection(connectionTimeout);
+                }
+                else
+                {
+                    ld = cp.getConnection();
+                }
+                // Did the pool object return a null value?
+                if (ld == null)
+                {
+                    String MSG_HDR = "getConnection " + szType;
+                    String warning = MSG_HDR + " detected null connection";
+                    LOG.warn( warning );
+                    // Is the canary is still alive?
+                    // todo: recheck this sequence, make sure still good.
+                    if (!checkConnection(type))
+                    {
+                        warning += szType + " attempt to recover pool";
+                        LOG.warn( warning );
+                        cp = recoverPool(type);
+                        ld = cp.getConnection();
+                        if (ld == null || !ld.isConnected())
+                        {
+                            // Give up:
+                            String error = MSG_HDR + " could not recover";
+                            LOG.error( error );
+                            throw new LDAPException(error, LDAPException.LDAP_TIMEOUT);
+                        }
+                    }
+                    // todo: think about this scenario some more.  should it attempt recovery of pool here?
+                    else
+                    {
+                        // Cannot establish a good connection, give up:
+                        String error = MSG_HDR + " could not retrieve connection";
+                        LOG.error( error );
+                        throw new LDAPException(error, LDAPException.CONNECT_ERROR);
+                    }
+                }
+                // Did the pool object return a bad connection?
+                else if (!ld.isConnected())
+                {
+                    String MSG_HDR = "getConnection " + szType;
+                    String warning = MSG_HDR + " detected bad connection, retry";
+                    LOG.warn( warning );
+                    // attempt to reconnect:
+                    ld.connect(Config.getProperty(LDAP_HOST, "localhost"), Config.getInt(LDAP_PORT, 389));
+                    // if admin connection type must bind here using stored creds:
+                    if(type.equals(ConnType.ADMIN))
+                    {
+                        ld.bind(ldapRevision, adminUserId, adminPw);
+                    }
+                    // Did the reconnect succeed?
+                    if (!ld.isConnected())
+                    {
+                        warning += szType + " cannot reconnect, attempt pool recovery";
+                        LOG.warn( warning );
+                        // Try one last ditch effort to recover entire pool.
+                        cp = recoverPool(type);
+                        ld = cp.getConnection();
+                        // Still bad?
+                        if (ld == null || !ld.isConnected())
+                        {
+                            // Give up:
+                            String error = MSG_HDR + " recovery failed";
+                            LOG.error( error );
+                            throw new LDAPException(error, LDAPException.SERVER_DOWN);
+                        }
+                    }
+                }
+            }
+        }
+        catch (LDAPException e)
+        {
+            String MSG_HDR = "getConnection " + szType;
+            String warning = MSG_HDR + " detected bad connection, retry caught LDAPException=" + e;
+            LOG.warn( warning );
+            // Todo: Test these scenarios:
+            // Did the pool object return a null value or bad conn?
+            if (ld != null && !ld.isConnected()
+                // Make sure this ldap exception wasn't thrown directly above:
+                && e.getLDAPResultCode() != LDAPException.SERVER_DOWN
+                && e.getLDAPResultCode() != LDAPException.CONNECT_ERROR
+                && e.getLDAPResultCode() != LDAPException.LDAP_TIMEOUT)
+            {
+                warning += " attempt to reconnect";
+                LOG.warn( warning );
+                // attempt reconnect:
+                ld.connect(Config.getProperty(LDAP_HOST, "localhost"), Config.getInt(LDAP_PORT, 389));
+                // if admin connection type must bind here using stored creds:
+                if(type.equals(ConnType.ADMIN))
+                {
+                    ld.bind(ldapRevision, adminUserId, adminPw);
+                }
+                // Did it work?
+                if (!ld.isConnected())
+                {
+                    // Give up:
+                    warning = MSG_HDR + " failed to reconnect";
+                    LOG.error( warning );
+                    throw e;
+                }
+            }
+            else
+            {
+                // Give up
+                warning = MSG_HDR + " failed";
+                LOG.error( warning );
+                throw e;
+            }
+        }
+        return ld;
+    }
+
+
+    /**
+     * Internal function is used to create a new pool of admin connections to ldap server.
+     *
+     * @throws LDAPException
+     */
+    private static void createAdminPool()
+        throws LDAPException
+    {
+        String adminUserId = Config.getProperty(LDAP_ADMIN_POOL_UID);
+        String adminPw;
+        if(EncryptUtil.isEnabled())
+        {
+            adminPw = EncryptUtil.decrypt(Config.getProperty(LDAP_ADMIN_POOL_PW));
+        }
+        else
+        {
+            adminPw = Config.getProperty(LDAP_ADMIN_POOL_PW);
+        }
+
+        String host = Config.getProperty(LDAP_HOST, "localhost");
+        int port = Config.getInt(LDAP_PORT, 389);
+        int min = Config.getInt(LDAP_ADMIN_POOL_MIN, 1);
+        int max = Config.getInt(LDAP_ADMIN_POOL_MAX, 10);
+        LOG.info( "createAdminPool min [" + min + "] max [" + max + "] host [" + host + "] port [" + port
+            + "]" );
+        testAdminConn = new LDAPConnection();
+        connPool[ADMIN] = new ConnectionPool(min, max, host, port, adminUserId, adminPw);
+        if (isDebugEnabled)
+        {
+            connPool[ADMIN].setDebug(true);
+        }
+    }
+
+
+    /**
+     * Internal function is used to create a new pool of user connections to ldap server.
+     *
+     * @throws LDAPException
+     */
+    private static void createUserPool()
+        throws LDAPException
+    {
+        String host = Config.getProperty(LDAP_HOST, "localhost");
+        int port = Config.getInt(LDAP_PORT, 389);
+        int min = Config.getInt(LDAP_USER_POOL_MIN, 1);
+        int max = Config.getInt(LDAP_USER_POOL_MAX, 5);
+        String adminUserId = Config.getProperty(LDAP_ADMIN_POOL_UID);
+        String adminPw;
+        if(EncryptUtil.isEnabled())
+        {
+            adminPw = EncryptUtil.decrypt(Config.getProperty(LDAP_ADMIN_POOL_PW));
+        }
+        else
+        {
+            adminPw = Config.getProperty(LDAP_ADMIN_POOL_PW);
+        }
+
+        LOG.info( "createUserPool min [" + min + "] max [" + max + "] host [" + host + "] port [" + port + "]" );
+        connPool[USER] = new ConnectionPool(min, max, host, port, adminUserId, adminPw);
+        if (isDebugEnabled)
+        {
+            connPool[USER].setDebug(true);
+        }
+    }
+
+    /**
+     * Internal function is used to create a new pool of slapd log connections to ldap server.
+     *
+     * @throws LDAPException
+     */
+    private static void createLogPool()
+        throws LDAPException
+    {
+        String logUserId = Config.getProperty(LDAP_LOG_POOL_UID);
+        String logUserPw;
+        if(EncryptUtil.isEnabled())
+        {
+            logUserPw = EncryptUtil.decrypt(Config.getProperty(LDAP_LOG_POOL_PW));
+        }
+        else
+        {
+            logUserPw = Config.getProperty(LDAP_LOG_POOL_PW);
+        }
+
+        String host = Config.getProperty(LDAP_HOST, "localhost");
+        int port = Config.getInt(LDAP_PORT, 389);
+        int min = Config.getInt(LDAP_LOG_POOL_MIN, 1);
+        int max = Config.getInt(LDAP_LOG_POOL_MAX, 5);
+        LOG.info( "createLogPool min [" + min + "] max [" + max + "] host [" + host + "] port [" + port + "]" );
+        connPool[AUDIT] = new ConnectionPool(min, max, host, port, logUserId, logUserPw);
+        if (isDebugEnabled)
+        {
+            connPool[AUDIT].setDebug( true );
+        }
+    }
+
+    /**
+     * Method is used to perform a bind operation on the given connection object.  Connection will contain the
+     * password policy control.
+     *
+     * @param userId   contains the LDAP dn to the user entry.
+     * @param password contains the password in clear text.
+     * @param ld       contains a valid ldap connection.
+     * @return boolean value - true if bind successful, false otherwise.
+     * @throws LDAPException in the event of LDAP error.
+     */
+    private static boolean bindUser(String userId, char[] password, LDAPConnection ld)
+        throws LDAPException
+    {
+        boolean result;
+        if (ld == null)
+        {
+            String error = "bindUser detected null ldap connection";
+            LOG.error( error );
+            throw new LDAPException(error, LDAPException.CONNECT_ERROR);
+        }
+        if (GlobalIds.IS_OPENLDAP)
+        {
+            LDAPConstraints lCon = new LDAPConstraints();
+            lCon.setServerControls(pwPolicyControl);
+            ld.authenticate(ldapRevision, userId, new String(password), lCon);
+            result = true;
+        }
+        else
+        {
+            ld.authenticate(ldapRevision, userId, new String(password));
+            result = true;
+        }
+        return result;
+    }
+
+    /**
+     * This method will recover a connection pool in the event the connections become stale due to some network
+     * or system issue.
+     *
+     * @param type contains connection type of request.
+     * @return ConnectionPool reference to newly created connection pool.
+     * @throws LDAPException in the event of ldap system error or the routine fails to reestablish the pool successfully.
+     */
+    private static ConnectionPool recoverPool(ConnType type) throws LDAPException
+    {
+        ConnectionPool cp = null;
+        switch (type)
+        {
+            case ADMIN:
+                if (connPool[ADMIN] != null)
+                {
+                    connPool[ADMIN].destroy();
+                }
+                createAdminPool();
+                if (connPool[ADMIN] == null)
+                {
+                    String error = "recoverPool LDAP_ADMIN_POOL_UID failed";
+                    LOG.error(error);
+                    throw new LDAPException(error, LDAPException.CONNECT_ERROR);
+                }
+                cp = connPool[ADMIN];
+                break;
+
+            case USER:
+                if (connPool[USER] != null)
+                {
+                    connPool[USER].destroy();
+                }
+                createUserPool();
+                if (connPool[USER] == null)
+                {
+                    String error = "recoverPool USER failed";
+                    LOG.error(error);
+                    throw new LDAPException(error, LDAPException.CONNECT_ERROR);
+                }
+                cp = connPool[USER];
+                break;
+            case LOG:
+                if (connPool[AUDIT] != null)
+                {
+                    connPool[AUDIT].destroy();
+                }
+                createLogPool();
+                if (connPool[AUDIT] == null)
+                {
+                    String error = "recoverPool LOG failed";
+                    LOG.error(error);
+                    throw new LDAPException(error, LDAPException.CONNECT_ERROR);
+                }
+                cp = connPool[AUDIT];
+                break;
+        }
+        return cp;
+    }
+
+    /**
+     * System health method will determine the integrity of a given connection associated with a specified pool is good.
+     *
+     * @param type specifies the type of connection - ADMIN, USER Or LOG.
+     * @return true if connection is good, false otherwise.
+     * @throws LDAPException in the event of ldap error.
+     */
+    private static boolean checkConnection(ConnType type)
+        throws LDAPException
+    {
+        boolean rc = false;
+        LDAPConnection conn = null;
+        String szType = null;
+        switch (type)
+        {
+            case ADMIN:
+                conn = testAdminConn;
+                szType = "LDAP_ADMIN_POOL_UID";
+                break;
+            case USER:
+                conn = testUConn;
+                szType = "USER";
+                break;
+            case LOG:
+                conn = testLConn;
+                szType = "LOG";
+                break;
+        }
+        String info = "checkConnection is checking " + szType + " Connection";
+        LOG.info( info );
+        if (conn != null)
+        {
+            if (conn.isConnected())
+            {
+                LOG.debug( "checkConnection for type: {}, is good", szType );
+                rc = true;
+            }
+            else
+            {
+                info = "checkConnection -  " + szType + " connection bad";
+                LOG.info( info );
+                conn.reconnect();
+                if (conn.isConnected())
+                {
+                    info = "checkConnection -  " + szType + " connection reestablished";
+                    LOG.info( info );
+                    rc = true;
+                }
+            }
+        }
+        info = "checkConnetion status code=" + rc;
+        LOG.info( info );
+        return rc;
+    }
+}
\ 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/ldap/UnboundIdDataProvider.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/UnboundIdDataProvider.java b/src/main/java/org/apache/directory/fortress/core/ldap/UnboundIdDataProvider.java
new file mode 100644
index 0000000..944dcb0
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/UnboundIdDataProvider.java
@@ -0,0 +1,1277 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap;
+
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.FortEntity;
+import org.apache.directory.fortress.core.rbac.Hier;
+import org.apache.directory.fortress.core.rbac.Relationship;
+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;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttribute;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPControl;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPDN;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModification;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModificationSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPReferralException;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPSearchConstraints;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPSearchResults;
+
+
+/**
+ * Abstract class contains methods to perform low-level entity to ldap persistence.  These methods are called by the
+ * Fortress DAO's, i.e. {@link org.apache.directory.fortress.core.rbac.dao.unboundid.UserDAO}. {@link org.apache.directory.fortress.core.rbac.dao.unboundid.RoleDAO}, {@link org.apache.directory.fortress.core.rbac.dao.unboundid.PermDAO}, ....
+ * These are low-level data utilities, very little if any data validations are performed here.
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public abstract class UnboundIdDataProvider
+{
+    private static final String OPENLDAP_PROXY_CONTROL = "2.16.840.1.113730.3.4.18";
+    private static final int MAX_DEPTH = 100;
+    private static final String CLS_NM = UnboundIdDataProvider.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final LdapCounters counters = new LdapCounters();
+
+
+    /**
+     * Given a contextId and a fortress param name return the LDAP dn.
+     *
+     * @param contextId is to determine what sub-tree to use.
+     * @param root      contains the fortress parameter name that corresponds with a particular LDAP container.
+     * @return String contains the dn to use for operation.
+     */
+    protected String getRootDn( String contextId, String root )
+    {
+        String szDn = Config.getProperty( root );
+        StringBuilder dn = new StringBuilder();
+
+        // The contextId must not be null, or "HOME" or "null"
+        if ( VUtil.isNotNullOrEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL )
+            && !contextId.equals( GlobalIds.HOME ) )
+        {
+            int idx = szDn.indexOf( Config.getProperty( GlobalIds.SUFFIX ) );
+
+            if ( idx != -1 )
+            {
+                // Found. The DN is ,ou=<contextId>,  
+                dn.append( szDn.substring( 0, idx - 1 ) ).append( "," ).append( GlobalIds.OU ).append( "=" )
+                    .append( contextId ).append( "," ).append( szDn.substring( idx ) );
+            }
+        }
+        else
+        {
+            dn.append( szDn );
+        }
+
+        return dn.toString();
+    }
+
+
+    /**
+     * Given a contextId return the LDAP dn that includes the suffix.
+     *
+     * @param contextId is to determine what sub-tree to use.
+     * @return String contains the dn to use for operation.
+     */
+    protected String getRootDn( String contextId )
+    {
+        StringBuilder dn = new StringBuilder();
+        if ( VUtil.isNotNullOrEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL )
+            && !contextId.equals( GlobalIds.HOME ) )
+        {
+            dn.append( GlobalIds.OU ).append( "=" ).append( contextId ).append( "," )
+                .append( Config.getProperty( GlobalIds.SUFFIX ) );
+        }
+        else
+        {
+            dn.append( Config.getProperty( GlobalIds.SUFFIX ) );
+        }
+        return dn.toString();
+    }
+
+
+    /**
+     * Read the ldap record from specified location.
+     *
+     * @param ld   handle to ldap connection.
+     * @param dn   contains ldap distinguished name.
+     * @param atrs array contains array names to pull back.
+     * @return ldap entry.
+     * @throws LDAPException in the event system error occurs.
+     */
+    protected LDAPEntry read( LDAPConnection ld, String dn, String[] atrs )
+        throws LDAPException
+    {
+        counters.incrementRead();
+
+        return ld.read( dn, atrs );
+    }
+
+
+    /**
+     * Read the ldap record from specified location with user assertion.
+     *
+     * @param ld     handle to ldap connection.
+     * @param dn     contains ldap distinguished name.
+     * @param atrs   array contains array names to pull back.                                        , PoolMgr.ConnType.USER
+     * @param userDn string value represents the identity of user on who's behalf the request was initiated.  The value will be stored in openldap auditsearch record AuthZID's attribute.
+     * @return ldap entry.
+     * @throws LDAPException                in the event system error occurs.
+     * @throws UnsupportedEncodingException for search control errors.
+     */
+    protected LDAPEntry read( LDAPConnection ld, String dn, String[] atrs, String userDn )
+        throws LDAPException, UnsupportedEncodingException
+    {
+        counters.incrementRead();
+        LDAPControl proxyCtl = new LDAPControl( OPENLDAP_PROXY_CONTROL, true,
+            ( GlobalIds.DN + ": " + userDn ).getBytes( GlobalIds.UTF8 ) );
+        LDAPSearchConstraints opt = new LDAPSearchConstraints();
+        opt.setServerControls( proxyCtl );
+        return ld.read( dn, atrs, opt );
+    }
+
+
+    /**
+     * Add a new ldap entry to the directory.  Do not add audit context.
+     *
+     * @param ld    handle to ldap connection.
+     * @param entry contains data to add..
+     * @throws LDAPException in the event system error occurs.
+     */
+    protected void add( LDAPConnection ld, LDAPEntry entry )
+        throws LDAPException
+    {
+        counters.incrementAdd();
+        ld.add( entry );
+    }
+
+
+    /**
+     * Add a new ldap entry to the directory.  Add audit context.
+     *
+     * @param ld     handle to ldap connection.
+     * @param entry  contains data to add..
+     * @param entity contains audit context.
+     * @throws LDAPException in the event system error occurs.
+     */
+    protected void add( LDAPConnection ld, LDAPEntry entry, FortEntity entity )
+        throws LDAPException
+    {
+        counters.incrementAdd();
+
+        if ( GlobalIds.IS_AUDIT && entity != null && entity.getAdminSession() != null )
+        {
+            LDAPAttributeSet attrs = entry.getAttributeSet();
+
+            if ( VUtil.isNotNullOrEmpty( entity.getAdminSession().getInternalUserId() ) )
+            {
+                attrs.add( new LDAPAttribute( GlobalIds.FT_MODIFIER, entity.getAdminSession().getInternalUserId() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getModCode() ) )
+            {
+                attrs.add( new LDAPAttribute( GlobalIds.FT_MODIFIER_CODE, entity.getModCode() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getModId() ) )
+            {
+                attrs.add( new LDAPAttribute( GlobalIds.FT_MODIFIER_ID, entity.getModId() ) );
+            }
+        }
+
+        ld.add( entry );
+    }
+
+
+    /**
+     * Update exiting ldap entry to the directory.  Do not add audit context.
+     *
+     * @param ld   handle to ldap connection.
+     * @param dn   contains distinguished node of entry.
+     * @param mods contains data to modify.
+     * @throws LDAPException in the event system error occurs.
+     */
+    protected void modify( LDAPConnection ld, String dn, LDAPModificationSet mods )
+        throws LDAPException
+    {
+        counters.incrementMod();
+        ld.modify( dn, mods );
+    }
+
+
+    /**
+     * Update exiting ldap entry to the directory.  Add audit context.
+     *
+     * @param ld     handle to ldap connection.
+     * @param dn     contains distinguished node of entry.
+     * @param mods   contains data to modify.
+     * @param entity contains audit context.
+     * @throws LDAPException in the event system error occurs.
+     */
+    protected void modify( LDAPConnection ld, String dn, LDAPModificationSet mods, FortEntity entity )
+        throws LDAPException
+    {
+        counters.incrementMod();
+        audit( mods, entity );
+        ld.modify( dn, mods );
+    }
+
+
+    /**
+     * Delete exiting ldap entry from the directory.  Do not add audit context.
+     *
+     * @param ld handle to ldap connection.
+     * @param dn contains distinguished node of entry targeted for removal..
+     * @throws LDAPException in the event system error occurs.
+     */
+    protected void delete( LDAPConnection ld, String dn )
+        throws LDAPException
+    {
+        counters.incrementDelete();
+        ld.delete( dn );
+    }
+
+
+    /**
+     * Delete exiting ldap entry from the directory.  Add audit context.  This method will call modify prior to delete which will
+     * force corresponding audit record to be written to slapd access log.
+     *
+     * @param ld     handle to ldap connection.
+     * @param dn     contains distinguished node of entry targeted for removal..
+     * @param entity contains audit context.
+     * @throws LDAPException in the event system error occurs.
+     */
+    protected void delete( LDAPConnection ld, String dn, FortEntity entity )
+        throws LDAPException
+    {
+        counters.incrementDelete();
+        LDAPModificationSet mods = new LDAPModificationSet();
+        audit( mods, entity );
+        if ( mods.size() > 0 )
+            modify( ld, dn, mods );
+        ld.delete( dn );
+    }
+
+
+    /**
+     * Delete exiting ldap entry and all descendants from the directory.  Do not add audit context.
+     *
+     * @param ld handle to ldap connection.
+     * @param dn contains distinguished node of entry targeted for removal..
+     * @throws LDAPException in the event system error occurs.
+     */
+    protected void deleteRecursive( LDAPConnection ld, String dn )
+        throws LDAPException
+    {
+        int recursiveCount = 0;
+        deleteRecursive( dn, ld, recursiveCount );
+    }
+
+
+    /**
+     * Delete exiting ldap entry and all descendants from the directory.  Add audit context.  This method will call modify prior to delete which will
+     * force corresponding audit record to be written to slapd access log.
+     *
+     * @param ld     handle to ldap connection.
+     * @param dn     contains distinguished node of entry targeted for removal..
+     * @param entity contains audit context.
+     * @throws LDAPException in the event system error occurs.
+     */
+    protected void deleteRecursive( LDAPConnection ld, String dn, FortEntity entity )
+        throws LDAPException
+    {
+        LDAPModificationSet mods = new LDAPModificationSet();
+        audit( mods, entity );
+        if ( mods.size() > 0 )
+            modify( ld, dn, mods );
+        deleteRecursive( ld, dn );
+    }
+
+
+    /**
+     * Used to recursively remove all nodes up to record pointed to by dn attribute.
+     *
+     * @param dn             contains distinguished node of entry targeted for removal..
+     * @param ld             handle to ldap connection.
+     * @param recursiveCount keeps track of how many iterations have been performed.
+     * @throws LDAPException in the event system error occurs.
+     */
+    private void deleteRecursive( String dn, LDAPConnection ld, int recursiveCount )
+        throws LDAPException
+    {
+        String method = "deleteRecursive";
+        // Sanity check - only allow max tree depth of 100
+        if ( recursiveCount++ > MAX_DEPTH )
+        {
+            // too deep inside of a recursive sequence;
+            String error = "." + method + " dn [" + dn + "] depth error in recursive";
+            throw new LDAPException( error, LDAPException.OPERATION_ERROR );
+        }
+
+        String theDN;
+        // Find child nodes
+        LDAPSearchResults res = search( ld, dn, LDAPConnection.SCOPE_ONE, "objectclass=*", GlobalIds.NO_ATRS, false, 0 );
+
+        // Iterate over all entries under this entry
+        while ( res.hasMoreElements() )
+        {
+            try
+            {
+                // Next directory entry
+                LDAPEntry entry = res.next();
+                theDN = entry.getDN();
+                // continue down:
+                deleteRecursive( theDN, ld, recursiveCount );
+                recursiveCount--;
+            }
+            catch ( LDAPReferralException lre )
+            {
+                // cannot continue;
+                String error = "." + method + " dn [" + dn + "] caught LDAPReferralException="
+                    + lre.errorCodeToString() + "=" + lre.getLDAPErrorMessage();
+                throw new LDAPException( error, lre.getLDAPResultCode() );
+            }
+            catch ( LDAPException ldape )
+            {
+                // cannot continue;
+                String error = "." + method + " dn [" + dn + "] caught LDAPException="
+                    + ldape.errorCodeToString() + "=" + ldape.getLDAPErrorMessage();
+                throw new LDAPException( error, ldape.getLDAPResultCode() );
+            }
+        }
+        // delete the node:
+        counters.incrementDelete();
+        delete( ld, dn );
+    }
+
+
+    /**
+     * Add the audit context variables to the modfication set.
+     *
+     * @param mods   used to update ldap attributes.
+     * @param entity contains audit context.
+     * @throws LDAPException in the event of error with ldap client.
+     */
+    private void audit( LDAPModificationSet mods, FortEntity entity )
+    {
+        if ( GlobalIds.IS_AUDIT && entity != null && entity.getAdminSession() != null )
+        {
+            if ( VUtil.isNotNullOrEmpty( entity.getAdminSession().getInternalUserId() ) )
+            {
+                LDAPAttribute modifier = new LDAPAttribute( GlobalIds.FT_MODIFIER, entity.getAdminSession()
+                    .getInternalUserId() );
+                mods.add( LDAPModification.REPLACE, modifier );
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getModCode() ) )
+            {
+                LDAPAttribute modCode = new LDAPAttribute( GlobalIds.FT_MODIFIER_CODE, entity.getModCode() );
+                mods.add( LDAPModification.REPLACE, modCode );
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getModId() ) )
+            {
+                LDAPAttribute modId = new LDAPAttribute( GlobalIds.FT_MODIFIER_ID, entity.getModId() );
+                mods.add( LDAPModification.REPLACE, modId );
+            }
+        }
+    }
+
+
+    /**
+     * Perform normal ldap search accepting default batch size.
+     *
+     * @param ld        is LDAPConnection object used for all communication with host.
+     * @param baseDn    contains address of distinguished name to begin ldap search
+     * @param scope     indicates depth of search starting at basedn.  0 (base dn), 1 (one level down) or 2 (infinite) are valid values.
+     * @param filter    contains the search criteria
+     * @param atrs      is the requested list of attritubutes to return from directory search.
+     * @param attrsOnly if true pull back attribute names only.
+     * @return result set containing ldap entries returned from directory.
+     * @throws LDAPException thrown in the event of error in ldap client or server code.
+     */
+    protected LDAPSearchResults search( LDAPConnection ld,
+        String baseDn,
+        int scope,
+        String filter,
+        String[] atrs,
+        boolean attrsOnly )
+        throws LDAPException
+    {
+        counters.incrementSearch();
+        LDAPSearchResults result;
+        result = ld.search( baseDn, scope, filter, atrs, attrsOnly );
+        return result;
+    }
+
+
+    /**
+     * Perform normal ldap search specifying default batch size.
+     *
+     * @param ld        is LDAPConnection object used for all communication with host.
+     * @param baseDn    contains address of distinguished name to begin ldap search
+     * @param scope     indicates depth of search starting at basedn.  0 (base dn), 1 (one level down) or 2 (infinite) are valid values.
+     * @param filter    contains the search criteria
+     * @param atrs      is the requested list of attritubutes to return from directory search.
+     * @param attrsOnly if true pull back attribute names only.
+     * @param batchSize Will block until this many entries are ready to return from server.  0 indicates to block until all results are ready.
+     * @return result set containing ldap entries returned from directory.
+     * @throws LDAPException thrown in the event of error in ldap client or server code.
+     */
+    protected LDAPSearchResults search( LDAPConnection ld,
+        String baseDn,
+        int scope,
+        String filter,
+        String[] atrs,
+        boolean attrsOnly,
+        int batchSize )
+        throws LDAPException
+    {
+        counters.incrementSearch();
+        LDAPSearchResults result;
+        LDAPSearchConstraints ldCons = new LDAPSearchConstraints();
+        // Returns the maximum number of search results that are to be returned; 0 means there is no limit.
+        ldCons.setMaxResults( 0 );
+        ldCons.setBatchSize( batchSize );
+        result = ld.search( baseDn, scope, filter, atrs, attrsOnly, ldCons );
+        return result;
+    }
+
+
+    /**
+     * Perform normal ldap search specifying default batch size and max entries to return.
+     *
+     * @param ld         is LDAPConnection object used for all communication with host.
+     * @param baseDn     contains address of distinguished name to begin ldap search
+     * @param scope      indicates depth of search starting at basedn.  0 (base dn), 1 (one level down) or 2 (infinite) are valid values.
+     * @param filter     contains the search criteria
+     * @param atrs       is the requested list of attritubutes to return from directory search.
+     * @param attrsOnly  if true pull back attribute names only.
+     * @param batchSize  Will block until this many entries are ready to return from server.  0 indicates to block until all results are ready.
+     * @param maxEntries specifies the maximum number of entries to return in this search query.
+     * @return result set containing ldap entries returned from directory.
+     * @throws LDAPException thrown in the event of error in ldap client or server code.
+     */
+    protected LDAPSearchResults search( LDAPConnection ld,
+        String baseDn,
+        int scope,
+        String filter,
+        String[] atrs,
+        boolean attrsOnly,
+        int batchSize,
+        int maxEntries )
+        throws LDAPException
+    {
+        counters.incrementSearch();
+        LDAPSearchResults result;
+        LDAPSearchConstraints ldCons = new LDAPSearchConstraints();
+        // Returns the maximum number of search results that are to be returned;
+        ldCons.setMaxResults( maxEntries );
+        ldCons.setBatchSize( batchSize );
+        result = ld.search( baseDn, scope, filter, atrs, attrsOnly, ldCons );
+        return result;
+    }
+
+
+    /**
+     * This method will search the directory and return at most one record.  If more than one record is found
+     * an ldap exception will be thrown.
+     *
+     * @param ld        is LDAPConnection object used for all communication with host.
+     * @param baseDn    contains address of distinguished name to begin ldap search
+     * @param scope     indicates depth of search starting at basedn.  0 (base dn), 1 (one level down) or 2 (infinite) are valid values.
+     * @param filter    contains the search criteria
+     * @param atrs      is the requested list of attritubutes to return from directory search.
+     * @param attrsOnly if true pull back attribute names only.
+     * @return entry   containing target ldap node.
+     * @throws LDAPException thrown in the event of error in ldap client or server code.
+     */
+    protected LDAPEntry searchNode( LDAPConnection ld,
+        String baseDn,
+        int scope, String filter,
+        String[] atrs,
+        boolean attrsOnly )
+        throws LDAPException
+    {
+        LDAPSearchResults result = ld.search( baseDn, scope,
+            filter, atrs, attrsOnly );
+        if ( result.getCount() > 1 )
+        {
+            throw new LDAPException( "searchNode failed to return unique record for LDAP search of base DN ["
+                + baseDn + "] filter [" + filter + "]" );
+        }
+        return result.next();
+    }
+
+
+    /**
+     * This search method uses OpenLDAP Proxy Authorization Control to assert arbitrary user identity onto connection.
+     *
+     * @param ld        is LDAPConnection object used for all communication with host.
+     * @param baseDn    contains address of distinguished name to begin ldap search
+     * @param scope     indicates depth of search starting at basedn.  0 (base dn), 1 (one level down) or 2 (infinite) are valid values.
+     * @param filter    contains the search criteria
+     * @param atrs      is the requested list of attritubutes to return from directory search.
+     * @param attrsOnly if true pull back attribute names only.
+     * @param userDn    string value represents the identity of user on who's behalf the request was initiated.  The value will be stored in openldap auditsearch record AuthZID's attribute.
+     * @return entry   containing target ldap node.
+     * @throws LDAPException thrown in the event of error in ldap client or server code.
+     */
+    protected LDAPEntry searchNode( LDAPConnection ld,
+        String baseDn,
+        int scope,
+        String filter,
+        String[] atrs,
+        boolean attrsOnly,
+        String userDn )
+        throws LDAPException, UnsupportedEncodingException
+    {
+        counters.incrementSearch();
+        LDAPControl proxyCtl = new LDAPControl( OPENLDAP_PROXY_CONTROL, true,
+            ( GlobalIds.DN + ": " + userDn ).getBytes( GlobalIds.UTF8 ) );
+        LDAPSearchConstraints opt = new LDAPSearchConstraints();
+        opt.setServerControls( proxyCtl );
+        LDAPSearchResults result = ld.search( baseDn, scope, filter, atrs, attrsOnly, opt );
+        if ( result.getCount() > 1 )
+        {
+            throw new LDAPException( "searchNode failed to return unique record for LDAP search of base DN ["
+                + baseDn + "] filter [" + filter + "]" );
+        }
+        return result.next();
+    }
+
+
+    /**
+     * This method uses the compare ldap func to assert audit record into the directory server's configured audit logger.
+     *
+     * @param ld        is LDAPConnection object used for all communication with host.
+     * @param dn        contains address of distinguished name to begin ldap search
+     * @param userDn    dn for user node
+     * @param attribute attribute used for compare
+     * @return true if compare operation succeeds
+     * @throws LDAPException                thrown in the event of error in ldap client or server code.
+     * @throws UnsupportedEncodingException in the event the server cannot perform the operation.
+     */
+    protected boolean compareNode( LDAPConnection ld,
+        String dn,
+        String userDn,
+        LDAPAttribute attribute )
+        throws LDAPException, UnsupportedEncodingException
+    {
+        counters.incrementCompare();
+        LDAPControl proxyCtl = new LDAPControl( OPENLDAP_PROXY_CONTROL, true,
+            ( GlobalIds.DN + ": " + userDn ).getBytes( GlobalIds.UTF8 ) );
+        LDAPSearchConstraints opt = new LDAPSearchConstraints();
+        opt.setServerControls( proxyCtl );
+        return ld.compare( dn, attribute, opt );
+    }
+
+
+    /**
+     * Method wraps ldap client to return multi-occurring attribute values by name within a given entry and returns as a list of strings.
+     *
+     * @param entry         contains the target ldap entry.
+     * @param attributeName name of ldap attribute to retrieve.
+     * @return List of type string containing attribute values.
+     * @throws LDAPException in the event of ldap client error.
+     */
+    protected List<String> getAttributes( LDAPEntry entry, String attributeName )
+    {
+        List<String> attrValues = new ArrayList<>();
+        LDAPAttribute attr;
+        Enumeration values;
+        attr = entry.getAttribute( attributeName );
+        if ( attr != null )
+        {
+            values = attr.getStringValues();
+        }
+        else
+        {
+            return null;
+        }
+        if ( values != null )
+        {
+            while ( values.hasMoreElements() )
+            {
+                attrValues.add( ( String ) values.nextElement() );
+            }
+        }
+        return attrValues;
+    }
+
+
+    protected byte[] getPhoto( LDAPEntry entry, String attributeName )
+    {
+        byte[] photo = null;
+        LDAPAttribute attr = entry.getAttribute( attributeName );
+        if ( attr != null )
+        {
+            // Get the values as byte arrays
+            Enumeration enumVals =
+                attr.getByteValues();
+            // Get the first value - if there's more
+            // than one
+            if ( enumVals.hasMoreElements() )
+            {
+                photo =
+                    ( byte[] ) enumVals.nextElement();
+            }
+        }
+        return photo;
+    }
+
+
+    /**
+     * Method wraps ldap client to return multi-occurring attribute values by name within a given entry and returns as a set of strings.
+     *
+     * @param entry         contains the target ldap entry.
+     * @param attributeName name of ldap attribute to retrieve.
+     * @return List of type string containing attribute values.
+     * @throws LDAPException in the event of ldap client error.
+     */
+    protected Set<String> getAttributeSet( LDAPEntry entry, String attributeName )
+    {
+        // create Set with case insensitive comparator:
+        Set<String> attrValues = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        LDAPAttribute attr;
+        Enumeration values;
+        attr = entry.getAttribute( attributeName );
+        if ( attr != null )
+        {
+            values = attr.getStringValues();
+        }
+        else
+        {
+            return null;
+        }
+        if ( values != null )
+        {
+            while ( values.hasMoreElements() )
+            {
+                attrValues.add( ( String ) values.nextElement() );
+            }
+        }
+        return attrValues;
+    }
+
+
+    /**
+     * Method wraps ldap client to return multi-occurring attribute values by name within a given entry and return as a list of type {@link org.apache.directory.fortress.core.rbac.Relationship}.
+     *
+     * @param entry         contains the target ldap entry.
+     * @param attributeName name of ldap attribute to retrieve.
+     * @return List of type {@link org.apache.directory.fortress.core.rbac.Relationship} containing parent-child relationships.
+     * @throws LDAPException in the event of ldap client error.
+     */
+    protected List<Relationship> getRelationshipAttributes( LDAPEntry entry, String attributeName )
+    {
+        List<Relationship> attrValues = new ArrayList<>();
+        LDAPAttribute attr;
+        Enumeration values;
+
+        attr = entry.getAttribute( attributeName );
+        if ( attr != null )
+        {
+            values = attr.getStringValues();
+        }
+        else
+        {
+            return null;
+        }
+        if ( values != null )
+        {
+            while ( values.hasMoreElements() )
+            {
+                String edge = ( String ) values.nextElement();
+                int indx = edge.indexOf( GlobalIds.PROP_SEP );
+                if ( indx >= 1 )
+                {
+                    // This LDAP attr is stored as a name-value pair separated by a ':'.
+                    // Separate the parent from the child:
+                    String child = edge.substring( 0, indx );
+                    String parent = edge.substring( indx + 1 );
+
+                    // Load the parent/child relationship values into a helper class:
+                    Relationship rel = new Relationship( child, parent );
+                    attrValues.add( rel );
+                }
+                else
+                {
+                    String warning = "getRelAttributes detected incorrect data in role relationship field: "
+                        + edge;
+                    LOG.warn( warning );
+                }
+            }
+        }
+        return attrValues;
+    }
+
+
+    /**
+     * Method wraps ldap client to return attribute value by name within a given entry and returns as a string.
+     *
+     * @param entry         contains the target ldap entry.
+     * @param attributeName name of ldap attribute to retrieve.
+     * @return value contained in a string variable.
+     * @throws LDAPException in the event of ldap client error.
+     */
+    protected String getAttribute( LDAPEntry entry, String attributeName )
+    {
+        String attrValue = null;
+        LDAPAttribute attr;
+        Enumeration values;
+        attr = entry.getAttribute( attributeName );
+        if ( attr != null )
+        {
+            values = attr.getStringValues();
+        }
+        else
+        {
+            return null;
+        }
+        if ( values != null )
+        {
+            attrValue = ( String ) values.nextElement();
+        }
+        return attrValue;
+    }
+
+
+    /**
+     * Method will retrieve the relative distinguished name from a distinguished name variable.
+     *
+     * @param dn contains ldap distinguished name.
+     * @return rDn as string.
+     * @throws LDAPException in the event of ldap client error.
+     */
+    protected String getRdn( String dn )
+    {
+        String[] dnList;
+        dnList = LDAPDN.explodeDN( dn, true );
+        return dnList[0];
+    }
+
+
+    /**
+     * Create multi-occurring ldap attribute given array of strings and attribute name.
+     *
+     * @param name   contains attribute name to create.
+     * @param values array of string that contains attribute values.
+     * @return LDAPAttribute containing multi-occurring attribute set.
+     * @throws LDAPException in the event of ldap client error.
+     */
+    protected LDAPAttribute createAttributes( String name, String values[] )
+        throws LDAPException
+    {
+        LDAPAttribute attr = new LDAPAttribute( name );
+        for ( String value : values )
+        {
+            encodeSafeText( value, value.length() );
+            attr.addValue( value );
+        }
+        return attr;
+    }
+
+
+    /**
+     * Create ldap attribute given an attribute name and value.
+     *
+     * @param name  contains attribute name to create.
+     * @param value string contains attribute value.
+     * @return LDAPAttribute containing new ldap attribute.
+     * @throws LDAPException in the event of ldap client error.
+     */
+    protected LDAPAttribute createAttribute( String name, String value )
+        throws LDAPException
+    {
+        LDAPAttribute attr = new LDAPAttribute( name );
+        encodeSafeText( value, value.length() );
+        attr.addValue( value );
+        return attr;
+    }
+
+
+    /**
+     * Convert constraint from raw ldap format to application entity.
+     *
+     * @param le         ldap entry containing constraint.
+     * @param ftDateTime reference to {@link org.apache.directory.fortress.util.time.Constraint} containing formatted data.
+     * @throws LDAPException in the event of ldap client error.
+     */
+    protected void unloadTemporal( LDAPEntry le, Constraint ftDateTime )
+    {
+        String szRawData = getAttribute( le, GlobalIds.CONSTRAINT );
+
+        if ( szRawData != null && szRawData.length() > 0 )
+        {
+            CUtil.setConstraint( szRawData, ftDateTime );
+        }
+    }
+
+
+    /**
+     * Given an ldap attribute name and a list of attribute values, construct an ldap attribute set to be added to directory.
+     *
+     * @param list     list of type string containing attribute values to load into attribute set.
+     * @param attrs    contains ldap attribute set targeted for adding.
+     * @param attrName name of ldap attribute being added.
+     */
+    protected void loadAttrs( List<String> list, LDAPAttributeSet attrs, String attrName )
+    {
+        if ( list != null && list.size() > 0 )
+        {
+            LDAPAttribute attr = null;
+            for ( String val : list )
+            {
+                if ( attr == null )
+                {
+                    attr = new LDAPAttribute( attrName, val );
+                }
+                else
+                {
+                    attr.addValue( val );
+                }
+            }
+            if ( attr != null )
+            {
+                attrs.add( attr );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of {@link org.apache.directory.fortress.core.rbac.Relationship}, convert to raw data name-value format and load into ldap attribute set in preparation for ldap add.
+     *
+     * @param list     contains List of type {@link org.apache.directory.fortress.core.rbac.Relationship} targeted for adding to ldap.
+     * @param attrs    collection of ldap attributes containing parent-child relationships in raw ldap format.
+     * @param attrName contains the name of the ldap attribute to be added.
+     */
+    protected void loadRelationshipAttrs( List<Relationship> list, LDAPAttributeSet attrs, String attrName )
+    {
+        if ( list != null )
+        {
+            LDAPAttribute attr = null;
+            for ( Relationship rel : list )
+            {
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                if ( attr == null )
+                {
+                    attr = new LDAPAttribute( attrName, rel.getChild() + GlobalIds.PROP_SEP + rel.getParent() );
+                }
+                else
+                {
+                    attr.addValue( rel.getChild() + GlobalIds.PROP_SEP + rel.getParent() );
+                }
+            }
+            if ( attr != null )
+            {
+                attrs.add( attr );
+            }
+        }
+    }
+
+
+    /**
+     * Given an ldap attribute name and a set of attribute values, construct an ldap attribute set to be added to directory.
+     *
+     * @param values   set of type string containing attribute values to load into attribute set.
+     * @param attrs    contains ldap attribute set targeted for adding.
+     * @param attrName name of ldap attribute being added.
+     */
+    protected void loadAttrs( Set<String> values, LDAPAttributeSet attrs, String attrName )
+    {
+        if ( values != null && values.size() > 0 )
+        {
+            LDAPAttribute attr = null;
+            for ( String value : values )
+            {
+                if ( attr == null )
+                {
+                    attr = new LDAPAttribute( attrName, value );
+                }
+                else
+                {
+                    attr.addValue( value );
+                }
+            }
+            if ( attr != null )
+            {
+                attrs.add( attr );
+            }
+        }
+    }
+
+
+    /**
+     * Given a multi-occurring ldap attribute name and a list of attribute values, construct an ldap modification set to be updated in directory.
+     * This function will replace all existing attributes with new values.
+     *
+     * @param list     list of type string containing attribute values to load into modification set.
+     * @param mods     contains ldap modification set targeted for updating.
+     * @param attrName name of ldap attribute being modified.
+     */
+    protected void loadAttrs( List<String> list, LDAPModificationSet mods, String attrName )
+    {
+        loadAttrs( list, mods, attrName, true );
+    }
+
+    /**
+     * Given a multi-occurring ldap attribute name and a list of attribute values, construct an ldap modification set to be updated in directory.
+     *
+     * @param list     list of type string containing attribute values to load into modification set.
+     * @param mods     contains ldap modification set targeted for updating.
+     * @param attrName name of ldap attribute being modified.
+     * @param replace boolean value if true will replace existing attributes with new..
+     */
+    protected void loadAttrs( List<String> list, LDAPModificationSet mods, String attrName, boolean replace )
+    {
+        if ( list != null && list.size() > 0 )
+        {
+            LDAPAttribute attr = new LDAPAttribute( attrName );
+            if(replace)
+            {
+                mods.add( LDAPModification.REPLACE, attr );
+            }
+
+            for ( String val : list )
+            {
+                attr = new LDAPAttribute( attrName, val );
+                mods.add( LDAPModification.ADD, attr );
+            }
+        }
+    }
+
+    /**
+     * Given a collection of {@link org.apache.directory.fortress.core.rbac.Relationship}s, convert to raw data name-value format and load into ldap modification set in preparation for ldap modify.
+     *
+     * @param list     contains List of type {@link org.apache.directory.fortress.core.rbac.Relationship} targeted for updating in ldap.
+     * @param mods     ldap modification set containing parent-child relationships in raw ldap format.
+     * @param attrName contains the name of the ldap attribute to be updated.
+     * @param op       specifies type of mod: {@link Hier.Op#ADD}, {@link org.apache.directory.fortress.core.rbac.Hier.Op#MOD}, {@link Hier.Op#REM}
+     */
+    protected void loadRelationshipAttrs( List<Relationship> list, LDAPModificationSet mods, String attrName, Hier.Op op )
+    {
+        if ( list != null )
+        {
+            LDAPAttribute attr;
+            for ( Relationship rel : list )
+            {
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                attr = new LDAPAttribute( attrName, rel.getChild() + GlobalIds.PROP_SEP + rel.getParent() );
+                switch ( op )
+                {
+                    case ADD:
+                        mods.add( LDAPModification.ADD, attr );
+                        break;
+                    case MOD:
+                        mods.add( LDAPModification.REPLACE, attr );
+                        break;
+                    case REM:
+                        mods.add( LDAPModification.DELETE, attr );
+                        break;
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Given an ldap attribute name and a set of attribute values, construct an ldap modification set to be updated in directory.
+     *
+     * @param values   set of type string containing attribute values to load into modification set.
+     * @param mods     contains ldap modification set targeted for updating.
+     * @param attrName name of ldap attribute being updated.
+     */
+    protected void loadAttrs( Set<String> values, LDAPModificationSet mods, String attrName )
+    {
+        if ( values != null && values.size() > 0 )
+        {
+            LDAPAttribute attr = new LDAPAttribute( attrName );
+            mods.add( LDAPModification.REPLACE, attr );
+            for ( String value : values )
+            {
+                attr = new LDAPAttribute( attrName, value );
+                mods.add( LDAPModification.ADD, attr );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap modification set in preparation for ldap modify.
+     *
+     * @param props    contains {@link java.util.Properties} targeted for updating in ldap.
+     * @param mods     ldap modification set containing name-value pairs in raw ldap format.
+     * @param attrName contains the name of the ldap attribute to be updated.
+     * @param replace  boolean variable, if set to true use {@link LDAPModification#REPLACE} else {@link LDAPModification#ADD}.
+     */
+    protected void loadProperties( Properties props, LDAPModificationSet mods, String attrName, boolean replace )
+    {
+        loadProperties( props, mods, attrName, GlobalIds.PROP_SEP, replace );
+    }
+
+
+    /**
+     * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap modification set in preparation for ldap modify.
+     *
+     * @param props    contains {@link java.util.Properties} targeted for updating in ldap.
+     * @param mods     ldap modification set containing name-value pairs in raw ldap format.
+     * @param attrName contains the name of the ldap attribute to be updated.
+     * @param separator contains the delimiter for the property.
+     * @param replace  boolean variable, if set to true use {@link LDAPModification#REPLACE} else {@link LDAPModification#ADD}.
+     */
+    protected void loadProperties( Properties props, LDAPModificationSet mods, String attrName, char separator, boolean replace )
+    {
+        if ( props != null && props.size() > 0 )
+        {
+            LDAPAttribute prop = new LDAPAttribute( attrName );
+            if ( replace )
+                mods.add( LDAPModification.REPLACE, prop );
+
+            for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                prop = new LDAPAttribute( attrName, key + separator + val );
+                mods.add( LDAPModification.ADD, prop );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap modification set in preparation for ldap modify.
+     *
+     * @param props    contains {@link java.util.Properties} targeted for removal from ldap.
+     * @param mods     ldap modification set containing name-value pairs in raw ldap format to be removed.
+     * @param attrName contains the name of the ldap attribute to be removed.
+     */
+    protected void removeProperties( Properties props, LDAPModificationSet mods, String attrName )
+    {
+        if ( props != null && props.size() > 0 )
+        {
+            LDAPAttribute prop;
+            for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                prop = new LDAPAttribute( attrName, key + GlobalIds.PROP_SEP + val );
+                mods.add( LDAPModification.DELETE, prop );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap modification set in preparation for ldap add.
+     *
+     * @param props    contains {@link java.util.Properties} targeted for adding to ldap.
+     * @param attrs    ldap attribute set containing name-value pairs in raw ldap format.
+     * @param attrName contains the name of the ldap attribute to be added.
+     */
+    protected void loadProperties( Properties props, LDAPAttributeSet attrs, String attrName )
+    {
+        loadProperties( props, attrs, attrName, ':' );
+    }
+
+
+    /**
+     * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap modification set in preparation for ldap add.
+     *
+     * @param props    contains {@link java.util.Properties} targeted for adding to ldap.
+     * @param attrs    ldap attribute set containing name-value pairs in raw ldap format.
+     * @param attrName contains the name of the ldap attribute to be added.
+     */
+    protected void loadProperties( Properties props, LDAPAttributeSet attrs, String attrName, char separator )
+    {
+        if ( props != null && props.size() > 0 )
+        {
+            LDAPAttribute attr = null;
+            for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+                String prop = key + separator + val;
+                if ( attr == null )
+                {
+                    attr = new LDAPAttribute( attrName, prop );
+                }
+                else
+                {
+                    attr.addValue( prop );
+                }
+            }
+            if ( attr != null )
+            {
+                attrs.add( attr );
+            }
+        }
+    }
+
+
+    /**
+     * @param value
+     * @param validLen
+     * @return String containing encoded data.
+     * @throws LDAPException
+     */
+    protected String encodeSafeText( String value, int validLen )
+        throws LDAPException
+    {
+        if ( VUtil.isNotNullOrEmpty( value ) )
+        {
+            int length = value.length();
+            if ( length > validLen )
+            {
+                String error = "encodeSafeText value [" + value + "] invalid length [" + length + "]";
+                throw new LDAPException( error, LDAPException.PARAM_ERROR );
+            }
+            if ( GlobalIds.LDAP_FILTER_SIZE_FOUND )
+            {
+                value = VUtil.escapeLDAPSearchFilter( value );
+            }
+        }
+        return value;
+    }
+
+
+    /**
+     * Calls the PoolMgr to perform an LDAP bind for a user/password combination.  This function is valid
+     * if and only if the user entity is a member of the USERS data set.  The LDAP directory
+     * will return the OpenLDAP PW Policy control.
+     *
+     * @param ld       connection to ldap server.
+     * @param userId   contains the LDAP dn to the user entry.
+     * @param password contains the password in clear text.
+     * @return boolean value - true if bind successful, false otherwise.
+     * @throws LDAPException in the event of LDAP error.
+     */
+    protected boolean bind( LDAPConnection ld, String userId, char[] password )
+        throws LDAPException
+    {
+        counters.incrementBind();
+        return PoolMgr.bind( ld, userId, password );
+    }
+
+
+    /**
+     * Calls the PoolMgr to close the Admin LDAP connection.
+     *
+     * @param ld handle to ldap connection object.
+     */
+    protected void closeAdminConnection( LDAPConnection ld )
+    {
+        PoolMgr.closeConnection( ld, PoolMgr.ConnType.ADMIN );
+    }
+
+
+    /**
+     * Calls the PoolMgr to close the User LDAP connection.
+     *
+     * @param ld handle to ldap connection object.
+     */
+    protected void closeUserConnection( LDAPConnection ld )
+    {
+        PoolMgr.closeConnection( ld, PoolMgr.ConnType.USER );
+    }
+
+
+    /**
+     * Calls the PoolMgr to close the Log LDAP connection.
+     *
+     * @param ld handle to ldap connection object.
+     */
+    protected void closeLogConnection( LDAPConnection ld )
+    {
+        PoolMgr.closeConnection( ld, PoolMgr.ConnType.LOG );
+    }
+
+
+    /**
+     * Calls the PoolMgr to get a User connection to the LDAP server.
+     *
+     * @return ldap connection.
+     * @throws LDAPException
+     */
+    protected LDAPConnection getUserConnection() throws LDAPException
+    {
+        return PoolMgr.getConnection( PoolMgr.ConnType.USER );
+    }
+
+
+    /**
+     * Calls the PoolMgr to get an Admin connection to the LDAP server.
+     *
+     * @return ldap connection.
+     * @throws LDAPException
+     */
+    protected LDAPConnection getAdminConnection() throws LDAPException
+    {
+        return PoolMgr.getConnection( PoolMgr.ConnType.ADMIN );
+    }
+
+
+    /**
+     * Calls the PoolMgr to get a Log connection to the LDAP server.
+     *
+     * @return ldap connection.
+     * @throws LDAPException
+     */
+    protected LDAPConnection getLogConnection() throws LDAPException
+    {
+        return PoolMgr.getConnection( PoolMgr.ConnType.LOG );
+    }
+
+
+    /**
+     * Return to call reference to dao counter object with running totals for ldap operations add, mod, delete, search, etc.
+     *
+     * @return {@link LdapCounters} contains long values of atomic ldap operations for current running process.
+     */
+    public static LdapCounters getLdapCounters()
+    {
+        return counters;
+    }
+}
\ 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/ldap/container/OrganizationalUnit.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/container/OrganizationalUnit.java b/src/main/java/org/apache/directory/fortress/core/ldap/container/OrganizationalUnit.java
new file mode 100755
index 0000000..d701b34
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/container/OrganizationalUnit.java
@@ -0,0 +1,179 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.container;
+
+
+/**
+ * This class contains the container node for the OpenLDAP Directory Information Tree.  A container node is used to
+ * group other related nodes, i.e. 'ou=People' or 'ou'Roles'.
+ * <br />The organizational unit object class is 'organizationalUnit' <br />
+ * <p/>
+ * organizational unit structural object class is used to organize groups of nodes within the DIT.
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>#Standard object class from RFC2256</code>
+ * <li> <code>objectclass ( 2.5.6.5 NAME 'organizationalUnit'</code>
+ * <li> <code>DESC 'RFC2256: an organizational unit'</code>
+ * <li> <code>SUP top STRUCTURAL</code>
+ * <li> <code>MUST ou</code>
+ * <li> <code>MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $</code>
+ * <li> <code>x121Address $ registeredAddress $ destinationIndicator $</code>
+ * <li> <code>preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $</code>
+ * <li> <code>telephoneNumber $ internationaliSDNNumber $</code>
+ * <li> <code>facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $</code>
+ * <li> <code>postalAddress $ physicalDeliveryOfficeName $ st $ l $ description ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class OrganizationalUnit
+{
+    private String name;
+    private String parent;
+    private String description;
+    private String contextId = "";
+
+
+    public String getContextId()
+    {
+        return this.contextId;
+    }
+
+
+    public void setContextId( String contextId )
+    {
+        this.contextId = contextId;
+    }
+
+
+    /**
+     * Generate instance of organizational unit object to be loaded as container node.
+     *
+     * @param name        required attribute must be unique for rDn level and maps to 'ou' attribute in 'organizationalUnit' object class.
+     * @param description maps optional attribute maps to name in 'organizationalUnit' object class.
+     */
+    public OrganizationalUnit( String name, String description )
+    {
+        this.name = name;
+        this.description = description;
+    }
+
+
+    /**
+     * Default constructor generates instance of organizational unit object to be loaded as container node.
+     * The object cannot be used until 'name' value is set.
+     */
+    public OrganizationalUnit()
+    {
+    }
+
+
+    /**
+     * Get the required name attribute from the entity.  This attribute must be unique for the level of tree it is
+     * set.
+     *
+     * @return required attribute must be unique for rDn level and maps to 'ou' attribute in 'organizationalUnit' object class.
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+
+    /**
+     * Set the required name attribute in the entity.  This attribute must be unique for the level of tree it is
+     * set.
+     *
+     * @param name is required attribute and must be unique for rDn level and maps to 'ou' attribute in 'organizationalUnit' object class.
+     */
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * Get the description for the organizational unit object.  This value is not required or constrained
+     * but is validated on reasonability.
+     *
+     * @return field maps to same name attribute on 'organizationalUnit'.
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+
+    /**
+     * Set the description for the organizational unit object.  This value is not required or constrained
+     * but is validated on reasonability.
+     *
+     * @param description field maps to same name attribute on 'organizationalUnit'.
+     */
+    public void setDescription( String description )
+    {
+        this.description = description;
+    }
+
+
+    /**
+     * Get the optional parent attribute allows nesting of container nodes two levels below suffix.  For example, if parent
+     * node is created it may be used to subdivide collections of related nodes, dn=ou=Roles, ou=RBAC, dc=companyName, dc=com.
+     *
+     * @return attribute that contains name of parent node that is used to construct the dn.
+     */
+    public String getParent()
+    {
+        return parent;
+    }
+
+
+    /**
+     * Set the optional parent attribute allows nesting of container nodes two levels below suffix.  For example, if parent
+     * node is created it may be used to subdivide collections of related nodes, dn=ou=Roles, ou=RBAC, dc=companyName, dc=com.
+     *
+     * @param parent attribute that contains name of parent node that is used to construct the dn.  This maps to 'ou'
+     *               attribute in parent node's 'organizationalUnit' object class.
+     */
+    public void setParent( String parent )
+    {
+        this.parent = parent;
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "OrganizationalUnit[" );
+        sb.append( name ).append( ", " );
+        sb.append( description ).append( ", " );
+        sb.append( parent ).append( ", " );
+        sb.append( contextId ).append( ']' );
+
+        return sb.toString();
+    }
+}


[23/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicy.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicy.java b/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicy.java
new file mode 100755
index 0000000..759661d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicy.java
@@ -0,0 +1,779 @@
+/*
+ *   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.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * This class contains the Password Policy entity which is used to pass directives into and out of ldap.
+ * <br />The unique key to locate a Policy entity (which is subsequently assigned to Users) is {@link #name}.<br />
+ * <p/>
+ * <h4>Password Policies</h4>
+ * <a href="http://www.openldap.org/">OpenLDAP</a> supports the IETF draft <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10/">Password Policies for LDAP directories</a></li>.  Policies may be applied at the user, group or global level.
+ * <p/>
+ * <img src="../doc-files/PasswordPolicy.png">
+ * <p/>
+ * Password enforcement options include:
+ * <ol>
+ * <li>A configurable limit on failed authentication attempts.</li>
+ * <li>A counter to track the number of failed authentication attempts.</li>
+ * <li>A time frame in which the limit of consecutive failed authentication attempts must happen before action is taken.</li>
+ * <li>The action to be taken when the limit is reached. The action will either be nothing, or the account will be locked.</li>
+ * <li>An amount of time the account is locked (if it is to be locked) This can be indefinite.</li>
+ * <li>Password expiration.</li>
+ * <li>Expiration warning</li>
+ * <li>Grace authentications</li>
+ * <li>Password history</li>
+ * <li>Password minimum age</li>
+ * <li>Password minimum length</li>
+ * <li>Password Change after Reset</li>
+ * <li>Safe Modification of Password</li>
+ * </ol>
+ * <p/>
+ * <h4>Schema</h4>
+ * The OpenLDAP Password Policy entity is a composite of the following structural and aux object classes:
+ * <p/>
+ * 1. organizationalRole Structural Object Class is used to store basic attributes like cn and description.
+ * <pre>
+ * ------------------------------------------
+ * objectclass ( 2.5.6.14 NAME 'device'
+ *  DESC 'RFC2256: a device'
+ *  SUP top STRUCTURAL
+ *  MUST cn
+ *  MAY (
+ *      serialNumber $ seeAlso $ owner $ ou $ o $ l $ description
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 2. pwdPolicy AUXILIARY Object Class is used to store OpenLDAP Password Policies.
+ * <pre>
+ * ------------------------------------------
+ * objectclass ( 1.3.6.1.4.1.42.2.27.8.2.1</code>
+ *  NAME 'pwdPolicy'</code>
+ *  SUP top</code>
+ *  AUXILIARY</code>
+ *  MUST (
+ *      pwdAttribute
+ *  )
+ *  MAY (
+ *      pwdMinAge $ pwdMaxAge $ pwdInHistory $ pwdCheckQuality $
+ *      pwdMinLength $ pwdExpireWarning $ pwdGraceAuthNLimit $ pwdLockout $
+ *      pwdLockoutDuration $ pwdMaxFailure $ pwdFailureCountInterval $
+ *      pwdMustChange $ pwdAllowUserChange $ pwdSafeModify
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 3. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Audit Modification Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.4
+ *  NAME 'ftMods'
+ *  DESC 'Fortress Modifiers AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftModifier $
+ *      ftModCode $
+ *      ftModId
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortPolicy")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "pswdpolicy", propOrder = {
+    "name",
+    "attribute",
+    "minAge",
+    "maxAge",
+    "inHistory",
+    "checkQuality",
+    "minLength",
+    "expireWarning",
+    "graceLoginLimit",
+    "lockout",
+    "lockoutDuration",
+    "maxFailure",
+    "failureCountInterval",
+    "mustChange",
+    "allowUserChange",
+    "safeModify"
+})
+public class PwPolicy extends FortEntity
+    implements java.io.Serializable
+{
+    /**
+     * Maps to name attribute of pwdPolicy object class.
+     */
+    private String name;
+
+    /**
+     * 5.2.1  pwdAttribute
+     * <p/>
+     * This holds the name of the attribute to which the password policy is
+     * applied.  For example, the password policy may be applied to the
+     * userPassword attribute.
+     */
+    private String attribute;
+
+    /**
+     * 5.2.2  pwdMinAge
+     * <p/>
+     * This attribute holds the number of seconds that must elapse between
+     * modifications to the password.  If this attribute is not present, 0
+     * seconds is assumed.
+     */
+    @XmlElement(nillable = true)
+    private Integer minAge;
+    //private String minAge;
+
+    /**
+     * 5.2.3  pwdMaxAge
+     * <p/>
+     * This attribute holds the number of seconds after which a modified
+     * password will expire.
+     * <p/>
+     * If this attribute is not present, or if the value is 0 the password
+     * does not expire.  If not 0, the value must be greater than or equal
+     * to the value of the pwdMinAge.
+     */
+    @XmlElement(nillable = true)
+    private Long maxAge;
+
+    /**
+     * 5.2.4  pwdInHistory
+     * <p/>
+     * This attribute specifies the maximum number of used passwords stored
+     * in the pwdHistory attribute.
+     * <p/>
+     * If this attribute is not present, or if the value is 0, used
+     * passwords are not stored in the pwdHistory attribute and thus may be
+     * reused.
+     */
+    @XmlElement(nillable = true)
+    private Short inHistory;
+
+    /**
+     * 5.2.5  pwdCheckQuality
+     * <p/>
+     * This attribute indicates how the password quality will be verified
+     * while being modified or added.  If this attribute is not present, or
+     * if the value is '0', quality checking will not be enforced.  A value
+     * of '1' indicates that the server will check the quality, and if the
+     * server is unable to check it (due to a hashed password or other
+     * reasons) it will be accepted.  A value of '2' indicates that the
+     * server will check the quality, and if the server is unable to verify
+     * it, it will return an error refusing the password.
+     */
+    @XmlElement(nillable = true)
+    private Short checkQuality;
+
+    /**
+     * 5.2.6  pwdMinLength
+     * <p/>
+     * When quality checking is enabled, this attribute holds the minimum
+     * number of characters that must be used in a password.  If this
+     * attribute is not present, no minimum password length will be
+     * enforced.  If the server is unable to check the length (due to a
+     * hashed password or otherwise), the server will, depending on the
+     * value of the pwdCheckQuality attribute, either accept the password
+     * without checking it ('0' or '1') or refuse it ('2').
+     */
+    @XmlElement(nillable = true)
+    private Short minLength;
+
+    /**
+     * 5.2.7  pwdExpireWarning
+     * <p/>
+     * This attribute specifies the maximum number of seconds before a
+     * password is due to expire that expiration warning messages will be
+     * returned to an authenticating user.
+     * <p/>
+     * If this attribute is not present, or if the value is 0 no warnings
+     * will be returned.  If not 0, the value must be smaller than the value
+     * of the pwdMaxAge attribute.
+     */
+    @XmlElement(nillable = true)
+    private Long expireWarning;
+
+    /**
+     * 5.2.8  pwdGraceAuthNLimit
+     * <p/>
+     * This attribute specifies the number of times an expired password can
+     * be used to authenticate.  If this attribute is not present or if the
+     * value is 0, authentication will fail.
+     */
+    @XmlElement(nillable = true)
+    private Short graceLoginLimit;
+
+    /**
+     * 5.2.9  pwdLockout
+     * <p/>
+     * This attribute indicates, when its value is "TRUE", that the password
+     * may not be used to authenticate after a specified number of
+     * consecutive failed bind attempts.  The maximum number of consecutive
+     * failed bind attempts is specified in pwdMaxFailure.
+     * <p/>
+     * If this attribute is not present, or if the value is "FALSE", the
+     * password may be used to authenticate when the number of failed bind
+     * attempts has been reached.
+     */
+    @XmlElement(nillable = true)
+    private Boolean lockout;
+
+    /**
+     * 5.2.10  pwdLockoutDuration
+     * <p/>
+     * This attribute holds the number of seconds that the password cannot
+     * be used to authenticate due to too many failed bind attempts.  If
+     * this attribute is not present, or if the value is 0 the password
+     * cannot be used to authenticate until reset by a password
+     * administrator.
+     */
+    @XmlElement(nillable = true)
+    private Integer lockoutDuration;
+
+    /**
+     * 5.2.11  pwdMaxFailure
+     * <p/>
+     * This attribute specifies the number of consecutive failed bind
+     * attempts after which the password may not be used to authenticate.
+     * If this attribute is not present, or if the value is 0, this policy
+     * is not checked, and the value of pwdLockout will be ignored.
+     */
+    @XmlElement(nillable = true)
+    private Short maxFailure;
+
+    /**
+     * 5.2.12  pwdFailureCountInterval
+     * <p/>
+     * This attribute holds the number of seconds after which the password
+     * failures are purged from the failure counter, even though no
+     * successful authentication occurred.
+     * <p/>
+     * If this attribute is not present, or if its value is 0, the failure
+     * counter is only reset by a successful authentication.
+     */
+    @XmlElement(nillable = true)
+    private Short failureCountInterval;
+
+    /**
+     * 5.2.13  pwdMustChange
+     * <p/>
+     * This attribute specifies with a value of "TRUE" that users must
+     * change their passwords when they first bind to the directory after a
+     * password is set or reset by a password administrator.  If this
+     * attribute is not present, or if the value is "FALSE", users are not
+     * required to change their password upon binding after the password
+     * administrator sets or resets the password.  This attribute is not set
+     * due to any actions specified by this document, it is typically set by
+     * a password administrator after resetting a user's password.
+     */
+    @XmlElement(nillable = true)
+    private Boolean mustChange;
+
+    /**
+     * 5.2.14  pwdAllowUserChange
+     * <p/>
+     * This attribute indicates whether users can change their own
+     * passwords, although the change operation is still subject to access
+     * control.  If this attribute is not present, a value of "TRUE" is
+     * assumed.  This attribute is intended to be used in the absence of an
+     * access control mechanism.
+     */
+    @XmlElement(nillable = true)
+    private Boolean allowUserChange;
+
+    /**
+     * 5.2.15  pwdSafeModify
+     * <p/>
+     * This attribute specifies whether or not the existing password must be
+     * sent along with the new password when being changed.  If this
+     * attribute is not present, a "FALSE" value is assumed.
+     */
+    @XmlElement(nillable = true)
+    private Boolean safeModify;
+
+    /**
+     * Default constructor is used by internal Fortress classes and not intended for external use.
+     */
+    public PwPolicy()
+    {
+    }
+
+    /**
+     * Create instance given a policy name.
+     * @param name
+     */
+    public PwPolicy(String name)
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * Get the policy name associated with this instance.
+     * @return attribute stored as 'cn' in 'pwdPolicy' object class.
+     */
+    public String getName()
+    {
+        return this.name;
+    }
+
+    /**
+     * Set the required attribute policy name on this entity.
+     * @param name stored as 'cn' in 'pwdPolicy' object class.
+     */
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    /**
+     * This optional attribute holds the number of seconds that must elapse between
+     * modifications to the password. If this attribute is not present, 0
+     * seconds is assumed.
+     *
+     * @return attribute stored as 'pwdMinAge' in 'pwdPolicy' object class.
+     */
+    public Integer getMinAge()
+    {
+        return this.minAge;
+    }
+
+    /**
+     * This optional attribute holds the number of seconds that must elapse between
+     * modifications to the password. If this attribute is not present, 0
+     * seconds is assumed.
+     *
+     * @param minAge stored as 'pwdMinAge' in 'pwdPolicy' object class.
+     */
+    public void setMinAge(Integer minAge)
+    {
+        this.minAge = minAge;
+    }
+
+    /**
+     * This optional attribute holds the number of seconds after which a modified
+     * password will expire.
+     * If this attribute is not present, or if the value is 0 the password
+     * does not expire. If not 0, the value must be greater than or equal
+     * to the value of the pwdMinAge.
+     *
+     * @return attribute stored as 'pwdMaxAge' in 'pwdPolicy' object class.
+     */
+    public Long getMaxAge()
+    {
+        return this.maxAge;
+    }
+
+    /**
+     * This optional attribute holds the number of seconds after which a modified
+     * password will expire.
+     * If this attribute is not present, or if the value is 0 the password
+     * does not expire. If not 0, the value must be greater than or equal
+     * to the value of the pwdMinAge.
+     *
+     * @param maxAge attribute stored as 'pwdMaxAge' in 'pwdPolicy' object class.
+     */
+    public void setMaxAge(Long maxAge)
+    {
+        this.maxAge = maxAge;
+    }
+
+    /**
+     * This optional attribute specifies the maximum number of used passwords stored
+     * in the pwdHistory attribute.
+     * If this attribute is not present, or if the value is 0, used
+     * passwords are not stored in the pwdInHistory attribute and thus may be
+     * reused.
+     *
+     * @return attribute stored as 'pwdInHistory' in 'pwdPolicy' object class.
+     */
+    public Short getInHistory()
+    {
+        return this.inHistory;
+    }
+
+    /**
+     * This optional attribute specifies the maximum number of used passwords stored
+     * in the pwdHistory attribute.
+     * If this attribute is not present, or if the value is 0, used
+     * passwords are not stored in the pwdInHistory attribute and thus may be
+     * reused.
+     *
+     * @param inHistory attribute stored as 'pwdInHistory' in 'pwdPolicy' object class.
+     */
+    public void setInHistory(Short inHistory)
+    {
+        this.inHistory = inHistory;
+    }
+
+    /**
+     * This optional attribute is not currently supported by Fortress.
+     * This attribute indicates how the password quality will be verified
+     * while being modified or added. If this attribute is not present, or
+     * if the value is '0', quality checking will not be enforced. A value
+     * of '1' indicates that the server will check the quality, and if the
+     * server is unable to check it (due to a hashed password or other
+     * reasons) it will be accepted. A value of '2' indicates that the
+     * server will check the quality, and if the server is unable to verify
+     * it, it will return an error refusing the password.
+     *
+     * @return attribute stored as 'pwdCheckQuality' in 'pwdPolicy' object class.
+     */
+    public Short getCheckQuality()
+    {
+        return this.checkQuality;
+    }
+
+    /**
+     * This optional attribute is not currently supported by Fortress.
+     * This attribute indicates how the password quality will be verified
+     * while being modified or added. If this attribute is not present, or
+     * if the value is '0', quality checking will not be enforced. A value
+     * of '1' indicates that the server will check the quality, and if the
+     * server is unable to check it (due to a hashed password or other
+     * reasons) it will be accepted. A value of '2' indicates that the
+     * server will check the quality, and if the server is unable to verify
+     * it, it will return an error refusing the password.
+     *
+     * @param checkQuality attribute stored as 'pwdCheckQuality' in 'pwdPolicy' object class.
+     */
+    public void setCheckQuality(Short checkQuality)
+    {
+        this.checkQuality = checkQuality;
+    }
+
+    /**
+     * When quality checking is enabled, this optional attribute holds the minimum
+     * number of characters that must be used in a password. If this
+     * attribute is not present, no minimum password length will be
+     * enforced. If the server is unable to check the length (due to a
+     * hashed password or otherwise), the server will, depending on the
+     * value of the pwdCheckQuality attribute, either accept the password
+     * without checking it ('0' or '1') or refuse it ('2').
+     *
+     * @return attribute stored as 'pwdMinLength' in 'pwdPolicy' object class.
+     */
+    public Short getMinLength()
+    {
+        return this.minLength;
+    }
+
+    /**
+     * When quality checking is enabled, this optional attribute holds the minimum
+     * number of characters that must be used in a password. If this
+     * attribute is not present, no minimum password length will be
+     * enforced. If the server is unable to check the length (due to a
+     * hashed password or otherwise), the server will, depending on the
+     * value of the pwdCheckQuality attribute, either accept the password
+     * without checking it ('0' or '1') or refuse it ('2').
+     *
+     * @param minLength attribute stored as 'pwdMinLength' in 'pwdPolicy' object class.
+     */
+    public void setMinLength(Short minLength)
+    {
+        this.minLength = minLength;
+    }
+
+    /**
+     * This optional attribute specifies the maximum number of seconds before a
+     * password is due to expire that expiration warning messages will be
+     * returned to an authenticating user.
+     * If this attribute is not present, or if the value is 0 no warnings
+     * will be returned. If not 0, the value must be smaller than the value
+     * of the pwdMaxAge attribute.
+     *
+     * @return attribute stored as 'pwdExpireWarning' in 'pwdPolicy' object class.
+     */
+    public Long getExpireWarning()
+    {
+        return this.expireWarning;
+    }
+
+    /**
+     * This optional attribute specifies the maximum number of seconds before a
+     * password is due to expire that expiration warning messages will be
+     * returned to an authenticating user.
+     * If this attribute is not present, or if the value is 0 no warnings
+     * will be returned. If not 0, the value must be smaller than the value
+     * of the pwdMaxAge attribute.
+     *
+     * @param expireWarning attribute stored as 'pwdExpireWarning' in 'pwdPolicy' object class.
+     */
+    public void setExpireWarning(Long expireWarning)
+    {
+        this.expireWarning = expireWarning;
+    }
+
+    /**
+     * This optional attribute specifies the number of times an expired password can
+     * be used to authenticate. If this attribute is not present or if the
+     * value is 0, authentication will fail.
+     *
+     * @return attribute stored as 'pwdGraceAuthNLimit' in 'pwdPolicy' object class.
+     */
+    public Short getGraceLoginLimit()
+    {
+        return this.graceLoginLimit;
+    }
+
+    /**
+     * This optional attribute specifies the number of times an expired password can
+     * be used to authenticate. If this attribute is not present or if the
+     * value is 0, authentication will fail.
+     *
+     * @param graceLoginLimit attribute stored as 'pwdGraceAuthNLimit' in 'pwdPolicy' object class.
+     */
+    public void setGraceLoginLimit(Short graceLoginLimit)
+    {
+        this.graceLoginLimit = graceLoginLimit;
+    }
+
+    /**
+     * This optional attribute indicates, when its value is "TRUE", that the password
+     * may not be used to authenticate after a specified number of
+     * consecutive failed bind attempts. The maximum number of consecutive
+     * failed bind attempts is specified in pwdMaxFailure.
+     * If this attribute is not present, or if the value is "FALSE", the
+     * password may be used to authenticate when the number of failed bind
+     * attempts has been reached.
+     *
+     * @return attribute stored as 'pwdLockout' in 'pwdPolicy' object class.
+     */
+    public Boolean getLockout()
+    {
+        return this.lockout;
+    }
+
+    /**
+     * This optional attribute indicates, when its value is "TRUE", that the password
+     * may not be used to authenticate after a specified number of
+     * consecutive failed bind attempts. The maximum number of consecutive
+     * failed bind attempts is specified in pwdMaxFailure.
+     * If this attribute is not present, or if the value is "FALSE", the
+     * password may be used to authenticate when the number of failed bind
+     * attempts has been reached.
+     *
+     * @param lockout attribute stored as 'pwdLockout' in 'pwdPolicy' object class.
+     */
+    public void setLockout(Boolean lockout)
+    {
+        this.lockout = lockout;
+    }
+
+    /**
+     * This optional attribute holds the number of seconds that the password cannot
+     * be used to authenticate due to too many failed bind attempts. If
+     * this attribute is not present, or if the value is 0 the password
+     * cannot be used to authenticate until reset by a password
+     * administrator.
+     *
+     * @return attribute stored as 'pwdLockoutDuration' in 'pwdPolicy' object class.
+     */
+    public Integer getLockoutDuration()
+    {
+        return this.lockoutDuration;
+    }
+
+    /**
+     * This optional attribute holds the number of seconds that the password cannot
+     * be used to authenticate due to too many failed bind attempts. If
+     * this attribute is not present, or if the value is 0 the password
+     * cannot be used to authenticate until reset by a password
+     * administrator.
+     *
+     * @param lockoutDuration attribute stored as 'pwdLockoutDuration' in 'pwdPolicy' object class.
+     */
+    public void setLockoutDuration(Integer lockoutDuration)
+    {
+        this.lockoutDuration = lockoutDuration;
+    }
+
+    /**
+     * This optional attribute specifies the number of consecutive failed bind
+     * attempts after which the password may not be used to authenticate.
+     * If this attribute is not present, or if the value is 0, this policy
+     * is not checked, and the value of pwdLockout will be ignored.
+     *
+     * @return attribute stored as 'pwdMaxFailure' in 'pwdPolicy' object class.
+     */
+    public Short getMaxFailure()
+    {
+        return this.maxFailure;
+    }
+
+    /**
+     * This optional attribute specifies the number of consecutive failed bind
+     * attempts after which the password may not be used to authenticate.
+     * If this attribute is not present, or if the value is 0, this policy
+     * is not checked, and the value of pwdLockout will be ignored.
+     *
+     * @param maxFailure attribute stored as 'pwdMaxFailure' in 'pwdPolicy' object class.
+     */
+    public void setMaxFailure(Short maxFailure)
+    {
+        this.maxFailure = maxFailure;
+    }
+
+    /**
+     * This optional attribute holds the number of seconds after which the password
+     * failures are purged from the failure counter, even though no
+     * successful authentication occurred.
+     * If this attribute is not present, or if its value is 0, the failure
+     * counter is only reset by a successful authentication.
+     *
+     * @return attribute stored as 'pwdFailureCountInterval' in 'pwdPolicy' object class.
+     */
+    public Short getFailureCountInterval()
+    {
+        return this.failureCountInterval;
+    }
+
+    /**
+     * This optional attribute holds the number of seconds after which the password
+     * failures are purged from the failure counter, even though no
+     * successful authentication occurred.
+     * If this attribute is not present, or if its value is 0, the failure
+     * counter is only reset by a successful authentication.
+     *
+     * @param failureCountInterval attribute stored as 'pwdFailureCountInterval' in 'pwdPolicy' object class.
+     */
+    public void setFailureCountInterval(Short failureCountInterval)
+    {
+        this.failureCountInterval = failureCountInterval;
+    }
+
+    /**
+     * This optional attribute specifies with a value of "TRUE" that users must
+     * change their passwords when they first bind to the directory after a
+     * password is set or reset by a password administrator. If this
+     * attribute is not present, or if the value is "FALSE", users are not
+     * required to change their password upon binding after the password
+     * administrator sets or resets the password. This attribute is not set
+     * due to any actions specified by this document, it is typically set by
+     * a password administrator after resetting a user's password.
+     *
+     * @return attribute stored as 'pwdMustChange' in 'pwdPolicy' object class.
+     */
+    public Boolean getMustChange()
+    {
+        return this.mustChange;
+    }
+
+    /**
+     * This optional attribute specifies with a value of "TRUE" that users must
+     * change their passwords when they first bind to the directory after a
+     * password is set or reset by a password administrator. If this
+     * attribute is not present, or if the value is "FALSE", users are not
+     * required to change their password upon binding after the password
+     * administrator sets or resets the password. This attribute is not set
+     * due to any actions specified by this document, it is typically set by
+     * a password administrator after resetting a user's password.
+     *
+     * @param mustChange attribute stored as 'pwdMustChange' in 'pwdPolicy' object class.
+     */
+    public void setMustChange(Boolean mustChange)
+    {
+        this.mustChange = mustChange;
+    }
+
+    /**
+     * This optional attribute indicates whether users can change their own
+     * passwords, although the change operation is still subject to access
+     * control. If this attribute is not present, a value of "TRUE" is
+     * assumed. This attribute is intended to be used in the absence of an
+     * access control mechanism.
+     *
+     * @return attribute stored as 'pwdAllowUserChange' in 'pwdPolicy' object class.
+     */
+    public Boolean getAllowUserChange()
+    {
+        return this.allowUserChange;
+    }
+
+    /**
+     * This optional attribute indicates whether users can change their own
+     * passwords, although the change operation is still subject to access
+     * control. If this attribute is not present, a value of "TRUE" is
+     * assumed. This attribute is intended to be used in the absence of an
+     * access control mechanism.
+     *
+     * @param allowUserChange attribute stored as 'pwdAllowUserChange' in 'pwdPolicy' object class.
+     */
+    public void setAllowUserChange(Boolean allowUserChange)
+    {
+        this.allowUserChange = allowUserChange;
+    }
+
+    /**
+     * This optional attribute specifies whether or not the existing password must be
+     * sent along with the new password when being changed. If this
+     * attribute is not present, a "FALSE" value is assumed.
+     *
+     * @return attribute stored as 'pwdSafeModify' in 'pwdPolicy' object class.
+     */
+    public Boolean getSafeModify()
+    {
+        return this.safeModify;
+    }
+
+    /**
+     * This optional attribute specifies whether or not the existing password must be
+     * sent along with the new password when being changed. If this
+     * attribute is not present, a "FALSE" value is assumed.
+     *
+     * @param safeModify attribute stored as 'pwdSafeModify' in 'pwdPolicy' object class.
+     */
+    public void setSafeModify(Boolean safeModify)
+    {
+        this.safeModify = safeModify;
+    }
+
+    /**
+     * Matches the name from two PwPolicy entities.
+     *
+     * @param thatObj contains a Role entity.
+     * @return boolean indicating both objects contain matching PwPolicy names.
+     */
+    public boolean equals(Object thatObj)
+    {
+        if (this == thatObj) return true;
+        if (this.getName() == null) return false;
+        if (!(thatObj instanceof PwPolicy)) return false;
+        PwPolicy thatPolicy = (PwPolicy) thatObj;
+        if (thatPolicy.getName() == null) return false;
+        return thatPolicy.getName().equalsIgnoreCase(this.getName());
+    }
+}
\ 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/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
new file mode 100755
index 0000000..8cc7c51
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicyControl.java
@@ -0,0 +1,41 @@
+/*
+ *   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 com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPControl;
+
+
+/**
+ * Interface is used to allow pluggable password policy interrogation.
+ *
+ * @author Shawn McKinney
+ */
+public interface PwPolicyControl
+{
+    /**
+     * Check the password policy controls returned from server and sets the PwMessage with what it finds.
+     *
+     * @param controls ldap controls object.
+     * @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 );
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicyMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicyMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicyMgrImpl.java
new file mode 100755
index 0000000..1a9ca3e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PwPolicyMgrImpl.java
@@ -0,0 +1,375 @@
+/*
+ *   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 org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.PwPolicyMgr;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.List;
+
+/**
+ * This class is used to perform administrative and review functions on the PWPOLICIES and USERS data sets.
+ * <p/>
+ * <h4>Password Policies</h4>
+ * <a href="http://www.openldap.org/">OpenLDAP</a> supports the IETF draft <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10/">Password Policies for LDAP directories</a></li>.  Policies may be applied at the user, group or global level.
+ * <p/>
+ * <img src="../doc-files/PasswordPolicy.png">
+ * <p/>
+ * Password enforcement options include:
+ * <ol>
+ * <li>A configurable limit on failed authentication attempts.</li>
+ * <li>A counter to track the number of failed authentication attempts.</li>
+ * <li>A time frame in which the limit of consecutive failed authentication attempts must happen before action is taken.</li>
+ * <li>The action to be taken when the limit is reached. The action will either be nothing, or the account will be locked.</li>
+ * <li>An amount of time the account is locked (if it is to be locked) This can be indefinite.</li>
+ * <li>Password expiration.</li>
+ * <li>Expiration warning</li>
+ * <li>Grace authentications</li>
+ * <li>Password history</li>
+ * <li>Password minimum age</li>
+ * <li>Password minimum length</li>
+ * <li>Password Change after Reset</li>
+ * <li>Safe Modification of Password</li>
+ * </ol>
+ * <p/>
+ * This class is NOT thread safe if parent instance variables ({@link #contextId} or {@link #adminSess}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public class PwPolicyMgrImpl  extends Manageable implements PwPolicyMgr
+{
+    private static final String CLS_NM = PwPolicyMgrImpl.class.getName();
+    private static final PolicyP policyP = new PolicyP();
+    private static final UserP userP = new UserP();
+
+    // package private constructor ensures outside classes cannot use:
+    PwPolicyMgrImpl()
+    {}
+
+    /**
+     * This method will add a new policy entry to the POLICIES data set.  This command is valid
+     * if and only if the policy entry is not already present in the POLICIES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#name} - Maps to name attribute of pwdPolicy object class being added.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#minAge} - This attribute holds the number of seconds that must elapse between
+     * modifications to the password.  If this attribute is not present, 0
+     * seconds is assumed.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#maxAge} - This attribute holds the number of seconds after which a modified
+     * password will expire. If this attribute is not present, or if the value is 0 the password
+     * does not expire.  If not 0, the value must be greater than or equal
+     * to the value of the pwdMinAge.
+     * </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#inHistory} - This attribute specifies the maximum number of used passwords stored
+     * in the pwdHistory attribute. If this attribute is not present, or if the value is 0, used
+     * passwords are not stored in the pwdHistory attribute and thus may be reused.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#minLength} - When quality checking is enabled, this attribute holds the minimum
+     * number of characters that must be used in a password.  If this
+     * attribute is not present, no minimum password length will be
+     * enforced.  If the server is unable to check the length (due to a
+     * hashed password or otherwise), the server will, depending on the
+     * value of the pwdCheckQuality attribute, either accept the password
+     * without checking it ('0' or '1') or refuse it ('2').</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#expireWarning} - This attribute specifies the maximum number of seconds before a
+     * password is due to expire that expiration warning messages will be
+     * returned to an authenticating user.  If this attribute is not present, or if the value is 0 no warnings
+     * will be returned.  If not 0, the value must be smaller than the value
+     * of the pwdMaxAge attribute.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#graceLoginLimit} - This attribute specifies the number of times an expired password can
+     * be used to authenticate.  If this attribute is not present or if the
+     * value is 0, authentication will fail. </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#lockout} - This attribute indicates, when its value is "TRUE", that the password
+     * may not be used to authenticate after a specified number of
+     * consecutive failed bind attempts.  The maximum number of consecutive
+     * failed bind attempts is specified in pwdMaxFailure.  If this attribute is not present, or if the
+     * value is "FALSE", the password may be used to authenticate when the number of failed bind
+     * attempts has been reached.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#lockoutDuration} - This attribute holds the number of seconds that the password cannot
+     * be used to authenticate due to too many failed bind attempts.  If
+     * this attribute is not present, or if the value is 0 the password
+     * cannot be used to authenticate until reset by a password
+     * administrator.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#maxFailure} - This attribute specifies the number of consecutive failed bind
+     * attempts after which the password may not be used to authenticate.
+     * If this attribute is not present, or if the value is 0, this policy
+     * is not checked, and the value of pwdLockout will be ignored.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#failureCountInterval} - This attribute holds the number of seconds after which the password
+     * failures are purged from the failure counter, even though no
+     * successful authentication occurred.  If this attribute is not present, or if its value is 0, the failure
+     * counter is only reset by a successful authentication.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#mustChange} - This attribute specifies with a value of "TRUE" that users must
+     * change their passwords when they first bind to the directory after a
+     * password is set or reset by a password administrator.  If this
+     * attribute is not present, or if the value is "FALSE", users are not
+     * required to change their password upon binding after the password
+     * administrator sets or resets the password.  This attribute is not set
+     * due to any actions specified by this document, it is typically set by
+     * a password administrator after resetting a user's password.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#allowUserChange} - This attribute indicates whether users can change their own
+     * passwords, although the change operation is still subject to access
+     * control.  If this attribute is not present, a value of "TRUE" is
+     * assumed.  This attribute is intended to be used in the absence of an access control mechanism.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#safeModify} - This attribute specifies whether or not the existing password must be
+     * sent along with the new password when being changed.  If this
+     * attribute is not present, a "FALSE" value is assumed.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#checkQuality} - This attribute indicates how the password quality will be verified
+     * while being modified or added.  If this attribute is not present, or
+     * if the value is '0', quality checking will not be enforced.  A value
+     * of '1' indicates that the server will check the quality, and if the
+     * server is unable to check it (due to a hashed password or other
+     * reasons) it will be accepted.  A value of '2' indicates that the
+     * server will check the quality, and if the server is unable to verify
+     * it, it will return an error refusing the password. </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#attribute} - This holds the name of the attribute to which the password policy is
+     * applied.  For example, the password policy may be applied to the
+     * userPassword attribute </li>
+     * </ul>
+     *
+     * @param policy Object must contain {@link org.apache.directory.fortress.core.rbac.PwPolicy#name} and optionally other attributes.
+     * @throws SecurityException In the event of data validation or system error.
+     */
+    @Override
+    public void add(PwPolicy policy)
+        throws SecurityException
+    {
+        String methodName = "add";
+        assertContext(CLS_NM, methodName, policy, GlobalErrIds.PSWD_PLCY_NULL);
+        setEntitySession(CLS_NM, methodName, policy);
+        policyP.add(policy);
+    }
+
+
+    /**
+     * This method will update an exiting policy entry to the POLICIES data set.  This command is valid
+     * if and only if the policy entry is already present in the POLICIES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PwPolicy#name} - Maps to name attribute of pwdPolicy object class being updated.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link PwPolicy#minAge} - This attribute holds the number of seconds that must elapse between
+     * modifications to the password.  If this attribute is not present, 0
+     * seconds is assumed.</li>
+     * <li>{@link PwPolicy#maxAge} - This attribute holds the number of seconds after which a modified
+     * password will expire. If this attribute is not present, or if the value is 0 the password
+     * does not expire.  If not 0, the value must be greater than or equal
+     * to the value of the pwdMinAge.
+     * </li>
+     * <li>{@link PwPolicy#inHistory} - This attribute specifies the maximum number of used passwords stored
+     * in the pwdHistory attribute. If this attribute is not present, or if the value is 0, used
+     * passwords are not stored in the pwdHistory attribute and thus may be reused.</li>
+     * <li>{@link PwPolicy#minLength} - When quality checking is enabled, this attribute holds the minimum
+     * number of characters that must be used in a password.  If this
+     * attribute is not present, no minimum password length will be
+     * enforced.  If the server is unable to check the length (due to a
+     * hashed password or otherwise), the server will, depending on the
+     * value of the pwdCheckQuality attribute, either accept the password
+     * without checking it ('0' or '1') or refuse it ('2').</li>
+     * <li>{@link PwPolicy#expireWarning} - This attribute specifies the maximum number of seconds before a
+     * password is due to expire that expiration warning messages will be
+     * returned to an authenticating user.  If this attribute is not present, or if the value is 0 no warnings
+     * will be returned.  If not 0, the value must be smaller than the value
+     * of the pwdMaxAge attribute.</li>
+     * <li>{@link PwPolicy#graceLoginLimit} - This attribute specifies the number of times an expired password can
+     * be used to authenticate.  If this attribute is not present or if the
+     * value is 0, authentication will fail. </li>
+     * <li>{@link PwPolicy#lockout} - This attribute indicates, when its value is "TRUE", that the password
+     * may not be used to authenticate after a specified number of
+     * consecutive failed bind attempts.  The maximum number of consecutive
+     * failed bind attempts is specified in pwdMaxFailure.  If this attribute is not present, or if the
+     * value is "FALSE", the password may be used to authenticate when the number of failed bind
+     * attempts has been reached.</li>
+     * <li>{@link PwPolicy#lockoutDuration} - This attribute holds the number of seconds that the password cannot
+     * be used to authenticate due to too many failed bind attempts.  If
+     * this attribute is not present, or if the value is 0 the password
+     * cannot be used to authenticate until reset by a password
+     * administrator.</li>
+     * <li>{@link PwPolicy#maxFailure} - This attribute specifies the number of consecutive failed bind
+     * attempts after which the password may not be used to authenticate.
+     * If this attribute is not present, or if the value is 0, this policy
+     * is not checked, and the value of pwdLockout will be ignored.</li>
+     * <li>{@link PwPolicy#failureCountInterval} - This attribute holds the number of seconds after which the password
+     * failures are purged from the failure counter, even though no
+     * successful authentication occurred.  If this attribute is not present, or if its value is 0, the failure
+     * counter is only reset by a successful authentication.</li>
+     * <li>{@link PwPolicy#mustChange} - This attribute specifies with a value of "TRUE" that users must
+     * change their passwords when they first bind to the directory after a
+     * password is set or reset by a password administrator.  If this
+     * attribute is not present, or if the value is "FALSE", users are not
+     * required to change their password upon binding after the password
+     * administrator sets or resets the password.  This attribute is not set
+     * due to any actions specified by this document, it is typically set by
+     * a password administrator after resetting a user's password.</li>
+     * <li>{@link PwPolicy#allowUserChange} - This attribute indicates whether users can change their own
+     * passwords, although the change operation is still subject to access
+     * control.  If this attribute is not present, a value of "TRUE" is
+     * assumed.  This attribute is intended to be used in the absence of an access control mechanism.</li>
+     * <li>{@link PwPolicy#safeModify} - This attribute specifies whether or not the existing password must be
+     * sent along with the new password when being changed.  If this
+     * attribute is not present, a "FALSE" value is assumed.</li>
+     * <li>{@link PwPolicy#checkQuality} - This attribute indicates how the password quality will be verified
+     * while being modified or added.  If this attribute is not present, or
+     * if the value is '0', quality checking will not be enforced.  A value
+     * of '1' indicates that the server will check the quality, and if the
+     * server is unable to check it (due to a hashed password or other
+     * reasons) it will be accepted.  A value of '2' indicates that the
+     * server will check the quality, and if the server is unable to verify
+     * it, it will return an error refusing the password. </li>
+     * <li>{@link PwPolicy#attribute} - This holds the name of the attribute to which the password policy is
+     * applied.  For example, the password policy may be applied to the
+     * userPassword attribute </li>
+     * </ul>
+     *
+     * @param policy Object must contain {@link PwPolicy#name} and optionally all non-null attributes will be updated.  null attributes will be ignored.
+     * @throws SecurityException In the event policy not found , data validation or system error.
+     */
+    @Override
+    public void update(PwPolicy policy)
+        throws SecurityException
+    {
+        String methodName = "update";
+        assertContext(CLS_NM, methodName, policy, GlobalErrIds.PSWD_PLCY_NULL);
+        setEntitySession(CLS_NM, methodName, policy);
+        policyP.update(policy);
+    }
+
+
+    /**
+     * This method will delete exiting policy entry from the POLICIES data set.  This command is valid
+     * if and only if the policy entry is already present in the POLICIES data set.  Existing users that
+     * are assigned this policy will be removed from association.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PwPolicy#name} - Maps to name attribute of pwdPolicy object class being removed.</li>
+     * </ul>
+     *
+     * @param policy Object must contain {@link PwPolicy#name} of the policy entity to remove.
+     * @throws org.apache.directory.fortress.core.SecurityException In the event policy entity not found or system error.
+     */
+    @Override
+    public void delete(PwPolicy policy)
+        throws SecurityException
+    {
+        String methodName = "delete";
+        assertContext(CLS_NM, methodName, policy, GlobalErrIds.PSWD_PLCY_NULL);
+        policy.setAdminSession(adminSess);
+        setEntitySession(CLS_NM, methodName, policy);
+        policyP.delete(policy);
+    }
+
+
+    /**
+     * This method will return the password policy entity to the caller.  This command is valid
+     * if and only if the policy entry is present in the POLICIES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PwPolicy#name} - Maps to name attribute of pwdPolicy object class being read.</li>
+     * </ul>
+     *
+     * @return PswdPolicy entity returns fully populated with attributes.
+     * @return PswdPolicy entity returns fully populated with attributes.
+     * @throws SecurityException In the event policy entry not found, data validation or system error.
+     */
+    @Override
+    public PwPolicy read(String name)
+        throws SecurityException
+    {
+        String methodName = "read";
+        VUtil.assertNotNullOrEmpty(name, GlobalErrIds.PSWD_NAME_NULL, CLS_NM + "." + methodName);
+        checkAccess(CLS_NM, methodName);
+        PwPolicy policy = new PwPolicy(name);
+        policy.setContextId(this.contextId);
+        return policyP.read(policy);
+    }
+
+
+    /**
+     * This method will return a list of all password policy entities that match a particular search string.
+     * This command will return an empty list of no matching entries are found.
+     *
+     * @param searchVal String contains the leading chars of a policy entity.  This search is not case sensitive.
+     * @return List<PswdPolicy> contains all matching password policy entities. If no records found this will be empty.
+     * @throws SecurityException In the event of data validation or system error.
+     */
+    @Override
+    public List<PwPolicy> search(String searchVal)
+        throws SecurityException
+    {
+        String methodName = "search";
+        VUtil.assertNotNull(searchVal, GlobalErrIds.PSWD_NAME_NULL, CLS_NM + "." + methodName);
+        checkAccess(CLS_NM, methodName);
+        PwPolicy policy = new PwPolicy(searchVal);
+        policy.setContextId(this.contextId);
+        return policyP.search(policy);
+    }
+
+
+    /**
+     * This method will associate a user entity with a password policy entity.  This function is valid
+     * if and only if the user is a member of the USERS data set and the policyName refers to a
+     * policy that is a member of the PWPOLICIES data set.
+     *
+     * @param userId     Contains {@link org.apache.directory.fortress.core.rbac.User#userId} of a User entity in USERS data set.
+     * @param policyName String contains the {@link PwPolicy#name} of a pw policy entity contained within the PWPOLICIES data set.
+     * @throws SecurityException thrown in the event either user or policy not valid or system error.
+     */
+    @Override
+    public void updateUserPolicy(String userId, String policyName)
+        throws SecurityException
+    {
+        String methodName = "updateUserPolicy";
+        VUtil.assertNotNullOrEmpty(userId, GlobalErrIds.USER_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNullOrEmpty(policyName, GlobalErrIds.PSWD_NAME_NULL, CLS_NM + "." + methodName);
+        User user = new User(userId);
+        user.setPwPolicy(policyName);
+        user.setAdminSession(adminSess);
+        setEntitySession(CLS_NM, methodName, user);
+        userP.update(user);
+    }
+
+
+    /**
+     * This method will remove the pw policy assignment from a user entity.  This function is valid
+     * if and only if the user is a member of the USERS data set and the policy attribute is assigned.
+     * Removal of pw policy assignment will revert the user's policy to use the global default for OpenLDAP
+     * instance that contains user.
+     *
+     * @param userId Contains {@link User#userId} of a User entity in USERS data set.
+     * @throws SecurityException Thrown in the event either user not valid or system error.
+     */
+    @Override
+    public void deletePasswordPolicy(String userId)
+        throws SecurityException
+    {
+        String methodName = "deletePasswordPolicy";
+        VUtil.assertNotNullOrEmpty(userId, GlobalErrIds.USER_NULL, CLS_NM + "." + methodName);
+        User user = new User(userId);
+        user.setAdminSession(adminSess);
+        setEntitySession(CLS_NM, methodName, user);
+        userP.deletePwPolicy(user);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/Relationship.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Relationship.java b/src/main/java/org/apache/directory/fortress/core/rbac/Relationship.java
new file mode 100755
index 0000000..4849458
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Relationship.java
@@ -0,0 +1,133 @@
+/*
+ *   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.lang.String;
+
+/**
+ * Contains a parent child data entity that is used for hierarchical processing.  This entity is used to construct edges in graphs.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class Relationship
+    implements java.io.Serializable
+{
+    private String child;
+    private String parent;
+
+    /**
+     * No argument constructor is necessary for Ant admin utility
+     *
+     */
+    public Relationship()
+    {
+    }
+    /**
+     * Construct a new relationship given a child and parent name.
+     *
+     * @param child  contains the name of child.
+     * @param parent contains the name of parent.
+     */
+    public Relationship(String child, String parent)
+    {
+        this.child = child;
+        this.parent = parent;
+    }
+
+    /**
+     * Return the child name.
+     *
+     * @return name of child.
+     */
+    public String getChild()
+    {
+        return child;
+    }
+
+    /**
+     * Set the child name.
+     *
+     * @param child contains the name of child.
+     */
+    public void setChild(String child)
+    {
+        this.child = child;
+    }
+
+    /**
+     * Return the parent name.
+     *
+     * @return name of parent.
+     */
+    public String getParent()
+    {
+        return parent;
+    }
+
+    /**
+     * Set the parent name.
+     *
+     * @param parent contains the name of parent.
+     */
+    public void setParent(String parent)
+    {
+        this.parent = parent;
+    }
+
+    /**
+     * Compute the hashcode on the parent and child values.  This is used for list processing.
+     *
+     * @return hashcode that includes parent concatenated with child.
+     */
+    public final int hashCode()
+    {
+        return child.hashCode() + parent.hashCode();
+    }
+
+    /**
+     * Matches the parent and child values from two Relationship entities.
+     *
+     * @param thatObj contains a Relationship entity.
+     * @return boolean indicating both objects contain matching parent and child names.
+     */
+    public boolean equals(Object thatObj)
+    {
+        if (this == thatObj)
+        {
+            return true;
+        }
+        if (this.getChild() == null || this.getParent() == null)
+        {
+            return false;
+        }
+        if (!(thatObj instanceof Relationship))
+        {
+            return false;
+        }
+        Relationship thatKey = (Relationship) thatObj;
+        if (thatKey.getChild() == null || thatKey.getParent() == null)
+        {
+            return false;
+        }
+        return ((thatKey.getChild().equalsIgnoreCase(this.getChild()) && thatKey.getParent().equalsIgnoreCase(this.getParent())));
+    }
+}


[36/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/ApacheDsDataProvider.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/ApacheDsDataProvider.java b/src/main/java/org/apache/directory/fortress/core/ldap/ApacheDsDataProvider.java
new file mode 100644
index 0000000..8a499be
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/ApacheDsDataProvider.java
@@ -0,0 +1,1384 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap;
+
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.apache.directory.api.ldap.model.cursor.CursorException;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.codec.api.LdapApiService;
+import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
+import org.apache.directory.api.ldap.codec.standalone.StandaloneLdapApiService;
+import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
+import org.apache.directory.api.ldap.model.entry.DefaultModification;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Modification;
+import org.apache.directory.api.ldap.model.entry.ModificationOperation;
+import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
+import org.apache.directory.api.ldap.model.exception.LdapOperationErrorException;
+import org.apache.directory.api.ldap.model.exception.LdapReferralException;
+import org.apache.directory.api.ldap.model.message.CompareRequest;
+import org.apache.directory.api.ldap.model.message.CompareRequestImpl;
+import org.apache.directory.api.ldap.model.message.CompareResponse;
+import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapConnectionPool;
+import org.apache.directory.ldap.client.api.PoolableLdapConnectionFactory;
+
+import org.apache.directory.fortress.core.CfgRuntimeException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.FortEntity;
+import org.apache.directory.fortress.core.rbac.Hier;
+import org.apache.directory.fortress.core.rbac.Relationship;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.crypto.EncryptUtil;
+import org.apache.directory.fortress.core.util.time.CUtil;
+import org.apache.directory.fortress.core.util.time.Constraint;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Abstract class contains methods to perform low-level entity to ldap persistence.  These methods are called by the
+ * Fortress DAO's, i.e. {@link org.apache.directory.fortress.core.rbac.dao.apache.UserDAO}. {@link org.apache.directory.fortress.core.rbac.dao.apache
+ * .RoleDAO}, {@link org.apache.directory.fortress.core.rbac.dao.apache.PermDAO}, ....
+ * These are low-level data utilities, very little if any data validations are performed here.
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public abstract class ApacheDsDataProvider
+{
+    // Logging
+    private static final String CLS_NM = ApacheDsDataProvider.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    private static final int MAX_DEPTH = 100;
+    private static final LdapCounters counters = new LdapCounters();
+    private static final String LDAP_HOST = "host";
+    private static final String LDAP_PORT = "port";
+    private static final String LDAP_ADMIN_POOL_MIN = "min.admin.conn";
+    private static final String LDAP_ADMIN_POOL_MAX = "max.admin.conn";
+    private static final String LDAP_ADMIN_POOL_UID = "admin.user";
+    private static final String LDAP_ADMIN_POOL_PW = "admin.pw";
+
+    // Used for TLS/SSL client-side configs:
+    private static final String ENABLE_LDAP_SSL = "enable.ldap.ssl";
+    private static final String ENABLE_LDAP_SSL_DEBUG = "enable.ldap.ssl.debug";
+    private static final String TRUST_STORE = Config.getProperty( "trust.store" );
+    private static final String TRUST_STORE_PW = Config.getProperty( "trust.store.password" );
+    private static final boolean IS_SSL = (
+        Config.getProperty( ENABLE_LDAP_SSL ) != null   &&
+            Config.getProperty( ENABLE_LDAP_SSL ).equalsIgnoreCase( "true" ) &&
+            TRUST_STORE      != null   &&
+            TRUST_STORE_PW   != null );
+
+    private static final String SET_TRUST_STORE_PROP = "trust.store.set.prop";
+    private static final boolean IS_SET_TRUST_STORE_PROP = (
+        IS_SSL &&
+            Config.getProperty( SET_TRUST_STORE_PROP ) != null   &&
+            Config.getProperty( SET_TRUST_STORE_PROP ).equalsIgnoreCase( "true" ));
+
+    private static final boolean IS_SSL_DEBUG = ( ( Config.getProperty( ENABLE_LDAP_SSL_DEBUG ) != null ) && ( Config
+        .getProperty( ENABLE_LDAP_SSL_DEBUG ).equalsIgnoreCase( "true" ) ) );
+
+    /**
+     * The Admin connection pool
+     */
+    private static LdapConnectionPool adminPool;
+
+    /**
+     * The Log connection pool
+     */
+    private static LdapConnectionPool logPool;
+
+    /**
+     * The User connection pool
+     */
+    private static LdapConnectionPool userPool;
+
+    static
+    {
+        String host = Config.getProperty( LDAP_HOST, "localhost" );
+        int port = Config.getInt( LDAP_PORT, 10389 );
+        int min = Config.getInt( LDAP_ADMIN_POOL_MIN, 1 );
+        int max = Config.getInt( LDAP_ADMIN_POOL_MAX, 10 );
+
+        if(IS_SET_TRUST_STORE_PROP)
+        {
+            LOG.info( "Set JSSE truststore properties in Apache LDAP client:");
+            LOG.info( "javax.net.ssl.trustStore: " + TRUST_STORE );
+            LOG.info( "javax.net.debug: " + new Boolean( IS_SSL_DEBUG ).toString());
+            System.setProperty( "javax.net.ssl.trustStore", TRUST_STORE );
+            System.setProperty( "javax.net.ssl.trustStorePassword", TRUST_STORE_PW );
+            System.setProperty( "javax.net.debug", new Boolean( IS_SSL_DEBUG ).toString() );
+        }
+
+        LdapConnectionConfig config = new LdapConnectionConfig();
+        config.setLdapHost( host );
+        config.setLdapPort( port );
+        config.setName( Config.getProperty( LDAP_ADMIN_POOL_UID, "" ) );
+
+        // added by smckinney for TLS/SSL config:
+        config.setUseSsl( IS_SSL );
+        //config.setTrustManagers( new NoVerificationTrustManager() );
+
+        config.setTrustManagers( new LdapClientTrustStoreManager(
+            TRUST_STORE,
+            TRUST_STORE_PW.toCharArray() , null, true ) );
+
+        String adminPw = null;
+
+        if ( EncryptUtil.isEnabled() )
+        {
+            adminPw = EncryptUtil.decrypt( Config.getProperty( LDAP_ADMIN_POOL_PW ) );
+        }
+        else
+        {
+            adminPw = Config.getProperty( LDAP_ADMIN_POOL_PW );
+        }
+
+        config.setCredentials( adminPw );
+        try
+        {
+            System.setProperty( StandaloneLdapApiService.EXTENDED_OPERATIONS_LIST,
+                "org.openldap.accelerator.impl.createSession.RbacCreateSessionFactory,"
+              + "org.openldap.accelerator.impl.checkAccess.RbacCheckAccessFactory,"
+              + "org.openldap.accelerator.impl.addRole.RbacAddRoleFactory,"
+              + "org.openldap.accelerator.impl.dropRole.RbacDropRoleFactory,"
+              + "org.openldap.accelerator.impl.deleteSession.RbacDeleteSessionFactory,"
+              + "org.openldap.accelerator.impl.sessionRoles.RbacSessionRolesFactory"
+                );
+
+            LdapApiService ldapApiService = new StandaloneLdapApiService();
+            if ( LdapApiServiceFactory.isInitialized() == false )
+            {
+                LdapApiServiceFactory.initialize( ldapApiService );
+            }
+            config.setLdapApiService( ldapApiService );
+        }
+        catch ( Exception ex )
+        {
+            String error =  "Exception caught initializing Admin Pool: " + ex;
+            throw new CfgRuntimeException( GlobalErrIds.FT_APACHE_LDAP_POOL_INIT_FAILED, error, ex );
+        }
+
+        PoolableLdapConnectionFactory factory = new PoolableLdapConnectionFactory( config );
+
+        // Create the Admin pool
+        adminPool = new LdapConnectionPool( factory );
+        adminPool.setTestOnBorrow( true );
+        adminPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
+        adminPool.setMaxActive( max );
+        adminPool.setMinIdle( min );
+
+        // Create the Log pool
+        logPool = new LdapConnectionPool( factory );
+        logPool.setTestOnBorrow( true );
+        logPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
+        logPool.setMaxActive( max );
+        logPool.setMinIdle( min );
+
+        // Create the User pool
+        userPool = new LdapConnectionPool( factory );
+        userPool.setTestOnBorrow( true );
+        userPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
+        userPool.setMaxActive( max );
+        userPool.setMinIdle( min );
+    }
+
+
+    /**
+     * Given a contextId and a fortress param name return the LDAP dn.
+     *
+     * @param contextId is to determine what sub-tree to use.
+     * @param root      contains the fortress parameter name that corresponds with a particular LDAP container.
+     * @return String contains the dn to use for operation.
+     */
+    protected String getRootDn( String contextId, String root )
+    {
+        String szDn = Config.getProperty( root );
+        StringBuilder dn = new StringBuilder();
+
+        // The contextId must not be null, or "HOME" or "null"
+        if ( VUtil.isNotNullOrEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL ) && !contextId
+            .equals( GlobalIds.HOME ) )
+        {
+            int idx = szDn.indexOf( Config.getProperty( GlobalIds.SUFFIX ) );
+
+            if ( idx != -1 )
+            {
+                // Found. The DN is ,ou=<contextId>,  
+                dn.append( szDn.substring( 0, idx - 1 ) ).append( "," ).append( GlobalIds.OU ).append( "=" ).append(
+                    contextId ).append( "," ).append( szDn.substring( idx ) );
+            }
+        }
+        else
+        {
+            dn.append( szDn );
+        }
+
+        return dn.toString();
+    }
+
+
+    /**
+     * Given a contextId return the LDAP dn that includes the suffix.
+     *
+     * @param contextId is to determine what sub-tree to use.
+     * @return String contains the dn to use for operation.
+     */
+    protected String getRootDn( String contextId )
+    {
+        StringBuilder dn = new StringBuilder();
+        if ( VUtil.isNotNullOrEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL ) && !contextId
+            .equals( GlobalIds.HOME ) )
+        {
+            dn.append( GlobalIds.OU ).append( "=" ).append( contextId ).append( "," +
+                "" ).append( Config.getProperty( GlobalIds.SUFFIX ) );
+        }
+        else
+        {
+            dn.append( Config.getProperty( GlobalIds.SUFFIX ) );
+        }
+        return dn.toString();
+    }
+
+
+    /**
+     * Read the ldap record from specified location.
+     *
+     * @param connection handle to ldap connection.
+     * @param dn         contains ldap distinguished name.
+     * @param attrs      array contains array names to pull back.
+     * @return ldap entry.
+     * @throws LdapException in the event system error occurs.
+     */
+    protected Entry read( LdapConnection connection, String dn, String[] attrs ) throws LdapException
+    {
+        counters.incrementRead();
+
+        return connection.lookup( dn, attrs );
+    }
+
+
+    /**
+     * Read the ldap record from specified location with user assertion.
+     *
+     * @param connection handle to ldap connection.
+     * @param dn         contains ldap distinguished name.
+     * @param attrs      array contains array names to pull back.                                        ,
+     *                   PoolMgr.ConnType.USER
+     * @param userDn     string value represents the identity of user on who's behalf the request was initiated.  The
+     *                   value will be stored in openldap auditsearch record AuthZID's attribute.
+     * @return ldap entry.
+     * @throws LdapException                in the event system error occurs.
+     * @throws UnsupportedEncodingException for search control errors.
+     */
+    protected Entry read( LdapConnection connection, String dn, String[] attrs, String userDn ) throws LdapException
+    {
+        counters.incrementRead();
+
+        return connection.lookup( dn, attrs );
+    }
+
+
+    /**
+     * Add a new ldap entry to the directory.  Do not add audit context.
+     *
+     * @param connection handle to ldap connection.
+     * @param entry      contains data to add..
+     * @throws LdapException in the event system error occurs.
+     */
+    protected void add( LdapConnection connection, Entry entry ) throws LdapException
+    {
+        counters.incrementAdd();
+        connection.add( entry );
+    }
+
+
+    /**
+     * Add a new ldap entry to the directory.  Add audit context.
+     *
+     * @param connection handle to ldap connection.
+     * @param entry      contains data to add..
+     * @param entity     contains audit context.
+     * @throws LdapException in the event system error occurs.
+     */
+    protected void add( LdapConnection connection, Entry entry, FortEntity entity ) throws LdapException
+    {
+        counters.incrementAdd();
+
+        if ( GlobalIds.IS_AUDIT && entity != null && entity.getAdminSession() != null )
+        {
+            if ( VUtil.isNotNullOrEmpty( entity.getAdminSession().getInternalUserId() ) )
+            {
+                entry.add( GlobalIds.FT_MODIFIER, entity.getAdminSession().getInternalUserId() );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getModCode() ) )
+            {
+                entry.add( GlobalIds.FT_MODIFIER_CODE, entity.getModCode() );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getModId() ) )
+            {
+                entry.add( GlobalIds.FT_MODIFIER_ID, entity.getModId() );
+            }
+        }
+
+        connection.add( entry );
+    }
+
+
+    /**
+     * Update exiting ldap entry to the directory.  Do not add audit context.
+     *
+     * @param connection handle to ldap connection.
+     * @param dn         contains distinguished node of entry.
+     * @param mods       contains data to modify.
+     * @throws LdapException in the event system error occurs.
+     */
+    protected void modify( LdapConnection connection, String dn, List<Modification> mods ) throws LdapException
+    {
+        counters.incrementMod();
+        connection.modify( dn, mods.toArray( new Modification[]{} ) );
+    }
+
+
+    /**
+     * Update exiting ldap entry to the directory.  Add audit context.
+     *
+     * @param connection handle to ldap connection.
+     * @param dn         contains distinguished node of entry.
+     * @param mods       contains data to modify.
+     * @param entity     contains audit context.
+     * @throws LdapException in the event system error occurs.
+     */
+    protected void modify( LdapConnection connection, String dn, List<Modification> mods,
+        FortEntity entity ) throws LdapException
+    {
+        counters.incrementMod();
+        audit( mods, entity );
+        connection.modify( dn, mods.toArray( new Modification[]{} ) );
+    }
+
+
+    /**
+     * Delete exiting ldap entry from the directory.  Do not add audit context.
+     *
+     * @param connection handle to ldap connection.
+     * @param dn         contains distinguished node of entry targeted for removal..
+     * @throws LdapException in the event system error occurs.
+     */
+    protected void delete( LdapConnection connection, String dn ) throws LdapException
+    {
+        counters.incrementDelete();
+        connection.delete( dn );
+    }
+
+
+    /**
+     * Delete exiting ldap entry from the directory.  Add audit context.  This method will call modify prior to
+     * delete which will
+     * force corresponding audit record to be written to slapd access log.
+     *
+     * @param connection handle to ldap connection.
+     * @param dn         contains distinguished node of entry targeted for removal..
+     * @param entity     contains audit context.
+     * @throws LdapException in the event system error occurs.
+     */
+    protected void delete( LdapConnection connection, String dn, FortEntity entity ) throws LdapException
+    {
+        counters.incrementDelete();
+        List<Modification> mods = new ArrayList<Modification>();
+        audit( mods, entity );
+
+        if ( mods.size() > 0 )
+        {
+            modify( connection, dn, mods );
+        }
+
+        connection.delete( dn );
+    }
+
+
+    /**
+     * Delete exiting ldap entry and all descendants from the directory.  Do not add audit context.
+     *
+     * @param connection handle to ldap connection.
+     * @param dn         contains distinguished node of entry targeted for removal..
+     * @throws LdapException   in the event system error occurs.
+     * @throws IOException
+     * @throws CursorException
+     */
+    protected void deleteRecursive( LdapConnection connection, String dn ) throws LdapException, CursorException
+    {
+        int recursiveCount = 0;
+        deleteRecursive( dn, connection, recursiveCount );
+    }
+
+
+    /**
+     * Delete exiting ldap entry and all descendants from the directory.  Add audit context.  This method will call
+     * modify prior to delete which will
+     * force corresponding audit record to be written to slapd access log.
+     *
+     * @param connection handle to ldap connection.
+     * @param dn         contains distinguished node of entry targeted for removal..
+     * @param entity     contains audit context.
+     * @throws LdapException   in the event system error occurs.
+     * @throws IOException
+     * @throws CursorException
+     */
+    protected void deleteRecursive( LdapConnection connection, String dn, FortEntity entity ) throws LdapException,
+        CursorException
+    {
+        List<Modification> mods = new ArrayList<Modification>();
+        audit( mods, entity );
+
+        if ( mods.size() > 0 )
+        {
+            modify( connection, dn, mods );
+        }
+
+        deleteRecursive( connection, dn );
+    }
+
+
+    /**
+     * Used to recursively remove all nodes up to record pointed to by dn attribute.
+     *
+     * @param dn             contains distinguished node of entry targeted for removal..
+     * @param connection     handle to ldap connection.
+     * @param recursiveCount keeps track of how many iterations have been performed.
+     * @throws LdapException   in the event system error occurs.
+     * @throws IOException
+     * @throws CursorException
+     */
+    private void deleteRecursive( String dn, LdapConnection connection, int recursiveCount ) throws LdapException,
+        CursorException
+    {
+        String method = "deleteRecursive";
+
+        // Sanity check - only allow max tree depth of 100
+        if ( recursiveCount++ > MAX_DEPTH )
+        {
+            // too deep inside of a recursive sequence;
+            String error = "." + method + " dn [" + dn + "] depth error in recursive";
+            throw new LdapOperationErrorException( error );
+        }
+
+        String theDN;
+
+        // Find child nodes
+        SearchCursor cursor = search( connection, dn, SearchScope.ONELEVEL, "(objectclass=*)", GlobalIds.NO_ATRS,
+            false, 0 );
+
+        // Iterate over all entries under this entry
+        while ( cursor.next() )
+        {
+            try
+            {
+                // Next directory entry
+                Entry entry = cursor.getEntry();
+                theDN = entry.getDn().getName();
+                // continue down:
+                deleteRecursive( theDN, connection, recursiveCount );
+                recursiveCount--;
+            }
+            catch ( LdapReferralException lre )
+            {
+                // cannot continue;
+                String error = "." + method + " dn [" + dn + "] caught LDAPReferralException=" + lre.getMessage() +
+                    "=" + lre.getReferralInfo();
+                throw lre;
+            }
+            catch ( LdapException le )
+            {
+                // cannot continue;
+                String error = "." + method + " dn [" + dn + "] caught LdapException=" + le.getMessage();
+                throw new LdapException( error );
+            }
+        }
+
+        // delete the node:
+        counters.incrementDelete();
+        delete( connection, dn );
+    }
+
+
+    /**
+     * Add the audit context variables to the modfication set.
+     *
+     * @param mods   used to update ldap attributes.
+     * @param entity contains audit context.
+     * @throws LdapException in the event of error with ldap client.
+     */
+    private void audit( List<Modification> mods, FortEntity entity )
+    {
+        if ( GlobalIds.IS_AUDIT && ( entity != null ) && ( entity.getAdminSession() != null ) )
+        {
+            if ( VUtil.isNotNullOrEmpty( entity.getAdminSession().getInternalUserId() ) )
+            {
+                Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
+                    GlobalIds.FT_MODIFIER, entity.getAdminSession().getInternalUserId() );
+                mods.add( modification );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getModCode() ) )
+            {
+                Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
+                    GlobalIds.FT_MODIFIER_CODE, entity.getModCode() );
+                mods.add( modification );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getModId() ) )
+            {
+                Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
+                    GlobalIds.FT_MODIFIER_ID, entity.getModId() );
+                mods.add( modification );
+            }
+        }
+    }
+
+
+    /**
+     * Perform normal ldap search accepting default batch size.
+     *
+     * @param connection is LdapConnection object used for all communication with host.
+     * @param baseDn     contains address of distinguished name to begin ldap search
+     * @param scope      indicates depth of search starting at basedn.  0 (base dn),
+     *                   1 (one level down) or 2 (infinite) are valid values.
+     * @param filter     contains the search criteria
+     * @param attrs      is the requested list of attritubutes to return from directory search.
+     * @param attrsOnly  if true pull back attribute names only.
+     * @return result set containing ldap entries returned from directory.
+     * @throws LdapException thrown in the event of error in ldap client or server code.
+     */
+    protected SearchCursor search( LdapConnection connection, String baseDn, SearchScope scope, String filter,
+        String[] attrs, boolean attrsOnly ) throws LdapException
+    {
+        counters.incrementSearch();
+
+        SearchRequest searchRequest = new SearchRequestImpl();
+        searchRequest.setBase( new Dn( baseDn ) );
+        searchRequest.setScope( scope );
+        searchRequest.setFilter( filter );
+        searchRequest.setTypesOnly( attrsOnly );
+        searchRequest.addAttributes( attrs );
+        SearchCursor result = connection.search( searchRequest );
+
+        return result;
+    }
+
+
+    /**
+     * Perform normal ldap search specifying default batch size.
+     *
+     * @param connection is LdapConnection object used for all communication with host.
+     * @param baseDn     contains address of distinguished name to begin ldap search
+     * @param scope      indicates depth of search starting at basedn.  0 (base dn),
+     *                   1 (one level down) or 2 (infinite) are valid values.
+     * @param filter     contains the search criteria
+     * @param attrs      is the requested list of attributes to return from directory search.
+     * @param attrsOnly  if true pull back attribute names only.
+     * @param batchSize  Will block until this many entries are ready to return from server.  0 indicates to block
+     *                   until all results are ready.
+     * @return result set containing ldap entries returned from directory.
+     * @throws LdapException thrown in the event of error in ldap client or server code.
+     */
+    protected SearchCursor search( LdapConnection connection, String baseDn, SearchScope scope, String filter,
+        String[] attrs, boolean attrsOnly, int batchSize ) throws LdapException
+    {
+        counters.incrementSearch();
+
+        SearchRequest searchRequest = new SearchRequestImpl();
+
+        searchRequest.setBase( new Dn( baseDn ) );
+        searchRequest.setFilter( filter );
+        searchRequest.setScope( scope );
+        searchRequest.setSizeLimit( batchSize );
+        searchRequest.setTypesOnly( attrsOnly );
+        searchRequest.addAttributes( attrs );
+
+        SearchCursor result = connection.search( searchRequest );
+
+        return result;
+    }
+
+
+    /**
+     * Perform normal ldap search specifying default batch size and max entries to return.
+     *
+     * @param connection is LdapConnection object used for all communication with host.
+     * @param baseDn     contains address of distinguished name to begin ldap search
+     * @param scope      indicates depth of search starting at basedn.  0 (base dn),
+     *                   1 (one level down) or 2 (infinite) are valid values.
+     * @param filter     contains the search criteria
+     * @param attrs      is the requested list of attritubutes to return from directory search.
+     * @param attrsOnly  if true pull back attribute names only.
+     * @param batchSize  Will block until this many entries are ready to return from server.  0 indicates to block
+     *                   until all results are ready.
+     * @param maxEntries specifies the maximum number of entries to return in this search query.
+     * @return result set containing ldap entries returned from directory.
+     * @throws LdapException thrown in the event of error in ldap client or server code.
+     */
+    protected SearchCursor search( LdapConnection connection, String baseDn, SearchScope scope, String filter,
+        String[] attrs, boolean attrsOnly, int batchSize, int maxEntries ) throws LdapException
+    {
+        counters.incrementSearch();
+
+        SearchRequest searchRequest = new SearchRequestImpl();
+
+        searchRequest.setBase( new Dn( baseDn ) );
+        searchRequest.setFilter( filter );
+        searchRequest.setScope( scope );
+        searchRequest.setSizeLimit( batchSize );
+        searchRequest.setTypesOnly( attrsOnly );
+        searchRequest.addAttributes( attrs );
+
+        SearchCursor result = connection.search( searchRequest );
+
+        return result;
+    }
+
+
+    /**
+     * This method will search the directory and return at most one record.  If more than one record is found
+     * an ldap exception will be thrown.
+     *
+     * @param connection is LdapConnection object used for all communication with host.
+     * @param baseDn     contains address of distinguished name to begin ldap search
+     * @param scope      indicates depth of search starting at basedn.  0 (base dn),
+     *                   1 (one level down) or 2 (infinite) are valid values.
+     * @param filter     contains the search criteria
+     * @param attrs      is the requested list of attritubutes to return from directory search.
+     * @param attrsOnly  if true pull back attribute names only.
+     * @return entry   containing target ldap node.
+     * @throws LdapException   thrown in the event of error in ldap client or server code.
+     * @throws IOException
+     * @throws CursorException
+     */
+    protected Entry searchNode( LdapConnection connection, String baseDn, SearchScope scope, String filter,
+        String[] attrs, boolean attrsOnly ) throws LdapException, CursorException, IOException
+    {
+        SearchRequest searchRequest = new SearchRequestImpl();
+
+        searchRequest.setBase( new Dn( baseDn ) );
+        searchRequest.setFilter( filter );
+        searchRequest.setScope( scope );
+        searchRequest.setTypesOnly( attrsOnly );
+        searchRequest.addAttributes( attrs );
+
+        SearchCursor result = connection.search( searchRequest );
+
+        Entry entry = result.getEntry();
+
+        if ( result.next() )
+        {
+            throw new LdapException( "searchNode failed to return unique record for LDAP search of base DN [" +
+                baseDn + "] filter [" + filter + "]" );
+        }
+
+        return entry;
+    }
+
+
+    /**
+     * This search method uses OpenLDAP Proxy Authorization Control to assert arbitrary user identity onto connection.
+     *
+     * @param connection is LdapConnection object used for all communication with host.
+     * @param baseDn     contains address of distinguished name to begin ldap search
+     * @param scope      indicates depth of search starting at basedn.  0 (base dn),
+     *                   1 (one level down) or 2 (infinite) are valid values.
+     * @param filter     contains the search criteria
+     * @param attrs      is the requested list of attritubutes to return from directory search.
+     * @param attrsOnly  if true pull back attribute names only.
+     * @param userDn     string value represents the identity of user on who's behalf the request was initiated.  The
+     *                   value will be stored in openldap auditsearch record AuthZID's attribute.
+     * @return entry   containing target ldap node.
+     * @throws LdapException   thrown in the event of error in ldap client or server code.
+     * @throws IOException
+     * @throws CursorException
+     */
+    protected Entry searchNode( LdapConnection connection, String baseDn, SearchScope scope, String filter,
+        String[] attrs, boolean attrsOnly, String userDn ) throws LdapException, CursorException, IOException
+    {
+        counters.incrementSearch();
+
+        SearchRequest searchRequest = new SearchRequestImpl();
+
+        searchRequest.setBase( new Dn( baseDn ) );
+        searchRequest.setFilter( filter );
+        searchRequest.setScope( scope );
+        searchRequest.setTypesOnly( attrsOnly );
+        searchRequest.addAttributes( attrs );
+
+        SearchCursor result = connection.search( searchRequest );
+
+        Entry entry = result.getEntry();
+
+        if ( result.next() )
+        {
+            throw new LdapException( "searchNode failed to return unique record for LDAP search of base DN [" +
+                baseDn + "] filter [" + filter + "]" );
+        }
+
+        return entry;
+    }
+
+
+    /**
+     * This method uses the compare ldap func to assert audit record into the directory server's configured audit
+     * logger.
+     *
+     * @param connection is LdapConnection object used for all communication with host.
+     * @param dn         contains address of distinguished name to begin ldap search
+     * @param userDn     dn for user node
+     * @param attribute  attribute used for compare
+     * @return true if compare operation succeeds
+     * @throws LdapException                thrown in the event of error in ldap client or server code.
+     * @throws UnsupportedEncodingException in the event the server cannot perform the operation.
+     */
+    protected boolean compareNode( LdapConnection connection, String dn, String userDn,
+        Attribute attribute ) throws LdapException, UnsupportedEncodingException
+    {
+        counters.incrementCompare();
+
+        CompareRequest compareRequest = new CompareRequestImpl();
+        compareRequest.setName( new Dn( dn ) );
+        compareRequest.setAttributeId( attribute.getId() );
+        compareRequest.setAssertionValue( attribute.getString() );
+
+        CompareResponse response = connection.compare( compareRequest );
+
+        return response.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS;
+    }
+
+
+    /**
+     * Method wraps ldap client to return multi-occurring attribute values by name within a given entry and returns
+     * as a list of strings.
+     *
+     * @param entry         contains the target ldap entry.
+     * @param attributeName name of ldap attribute to retrieve.
+     * @return List of type string containing attribute values.
+     * @throws LdapException in the event of ldap client error.
+     */
+    protected List<String> getAttributes( Entry entry, String attributeName )
+    {
+        List<String> attrValues = new ArrayList<>();
+        if ( entry != null )
+        {
+            Attribute attr = entry.get( attributeName );
+            if ( attr != null )
+            {
+                for ( Value<?> value : attr )
+                {
+                    attrValues.add( value.getString() );
+                }
+            }
+            else
+            {
+                return null;
+            }
+        }
+
+        return attrValues;
+    }
+
+
+    protected byte[] getPhoto( Entry entry, String attributeName ) throws LdapInvalidAttributeValueException
+    {
+        byte[] photo = null;
+        Attribute attr = entry.get( attributeName );
+
+        if ( attr != null )
+        {
+            photo = attr.getBytes();
+        }
+
+        return photo;
+    }
+
+
+    /**
+     * Method wraps ldap client to return multi-occurring attribute values by name within a given entry and returns
+     * as a set of strings.
+     *
+     * @param entry         contains the target ldap entry.
+     * @param attributeName name of ldap attribute to retrieve.
+     * @return List of type string containing attribute values.
+     * @throws LdapException in the event of ldap client error.
+     */
+    protected Set<String> getAttributeSet( Entry entry, String attributeName )
+    {
+        // create Set with case insensitive comparator:
+        Set<String> attrValues = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+
+        if ( entry != null && entry.containsAttribute( attributeName ) )
+        {
+            for ( Value<?> value : entry.get( attributeName ) )
+            {
+                attrValues.add( value.getString() );
+            }
+        }
+
+        return attrValues;
+    }
+
+
+    /**
+     * Method wraps ldap client to return attribute value by name within a given entry and returns as a string.
+     *
+     * @param entry         contains the target ldap entry.
+     * @param attributeName name of ldap attribute to retrieve.
+     * @return value contained in a string variable.
+     * @throws LdapInvalidAttributeValueException
+     *
+     * @throws LdapException in the event of ldap client error.
+     */
+    protected String getAttribute( Entry entry, String attributeName ) throws LdapInvalidAttributeValueException
+    {
+        if ( entry != null )
+        {
+            Attribute attr = entry.get( attributeName );
+
+            if ( attr != null )
+            {
+                return attr.getString();
+            }
+            else
+            {
+                return null;
+            }
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * Method will retrieve the relative distinguished name from a distinguished name variable.
+     *
+     * @param dn contains ldap distinguished name.
+     * @return rDn as string.
+     * @throws LdapException in the event of ldap client error.
+     */
+    protected String getRdn( String dn )
+    {
+        try
+        {
+            return new Dn( dn ).getRdn().getName();
+        }
+        catch ( LdapInvalidDnException lide )
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * Create multi-occurring ldap attribute given array of strings and attribute name.
+     *
+     * @param name   contains attribute name to create.
+     * @param values array of string that contains attribute values.
+     * @return Attribute containing multi-occurring attribute set.
+     * @throws LdapException in the event of ldap client error.
+     */
+    protected Attribute createAttributes( String name, String values[] ) throws LdapException
+    {
+        Attribute attr = new DefaultAttribute( name, values );
+
+        return attr;
+    }
+
+
+    /**
+     * Convert constraint from raw ldap format to application entity.
+     *
+     * @param le         ldap entry containing constraint.
+     * @param ftDateTime reference to {@link org.apache.directory.fortress.util.time.Constraint} containing formatted data.
+     * @throws LdapInvalidAttributeValueException
+     *
+     * @throws LdapException in the event of ldap client error.
+     */
+    protected void unloadTemporal( Entry le, Constraint ftDateTime ) throws LdapInvalidAttributeValueException
+    {
+        String szRawData = getAttribute( le, GlobalIds.CONSTRAINT );
+
+        if ( szRawData != null && szRawData.length() > 0 )
+        {
+            CUtil.setConstraint( szRawData, ftDateTime );
+        }
+    }
+
+
+    /**
+     * Given an ldap attribute name and a list of attribute values, construct an ldap attribute set to be added to directory.
+     *
+     * @param list     list of type string containing attribute values to load into attribute set.
+     * @param entry    contains ldap attribute set targeted for adding.
+     * @param attrName name of ldap attribute being added.
+     */
+    protected void loadAttrs( List<String> list, Entry entry, String attrName ) throws LdapException
+    {
+        if ( list != null && list.size() > 0 )
+        {
+            entry.add( attrName, list.toArray( new String[]{} ) );
+        }
+    }
+
+
+    /**
+     * Given an ldap attribute name and a list of attribute values, construct an ldap modification set to be updated
+     * in directory.
+     *
+     * @param list     list of type string containing attribute values to load into modification set.
+     * @param mods     contains ldap modification set targeted for updating.
+     * @param attrName name of ldap attribute being modified.
+     */
+    protected void loadAttrs( List<String> list, List<Modification> mods, String attrName )
+    {
+        if ( ( list != null ) && ( list.size() > 0 ) )
+        {
+            mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attrName,
+                list.toArray( new String[]{} ) ) );
+        }
+    }
+
+
+    /**
+     * Given a collection of {@link org.apache.directory.fortress.core.rbac.Relationship}s, convert to raw data name-value format and
+     * load into ldap modification set in preparation for ldap modify.
+     *
+     * @param list     contains List of type {@link org.apache.directory.fortress.core.rbac.Relationship} targeted for updating in ldap.
+     * @param mods     ldap modification set containing parent-child relationships in raw ldap format.
+     * @param attrName contains the name of the ldap attribute to be updated.
+     * @param op       specifies type of mod: {@link Hier.Op#ADD}, {@link org.apache.directory.fortress.core.rbac.Hier.Op#MOD},
+     * {@link Hier.Op#REM}
+     */
+    protected void loadRelationshipAttrs( List<Relationship> list, List<Modification> mods, String attrName,
+        Hier.Op op )
+    {
+        if ( list != null )
+        {
+            Attribute attr;
+
+            for ( Relationship rel : list )
+            {
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                attr = new DefaultAttribute( attrName, rel.getChild() + GlobalIds.PROP_SEP + rel.getParent() );
+
+                switch ( op )
+                {
+                    case ADD:
+                        mods.add( new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, attr ) );
+                        break;
+
+                    case MOD:
+                        mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attr ) );
+                        break;
+
+                    case REM:
+                        mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attr ) );
+                        break;
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Given an ldap attribute name and a set of attribute values, construct an ldap modification set to be updated
+     * in directory.
+     *
+     * @param values   set of type string containing attribute values to load into modification set.
+     * @param mods     contains ldap modification set targeted for updating.
+     * @param attrName name of ldap attribute being updated.
+     */
+    protected void loadAttrs( Set<String> values, List<Modification> mods, String attrName )
+    {
+        if ( ( values != null ) && ( values.size() > 0 ) )
+        {
+            mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attrName,
+                values.toArray( new String[]{} ) ) );
+        }
+    }
+
+
+    /**
+     * Given an ldap attribute name and a set of attribute values, construct an ldap attribute set to be added to
+     * directory.
+     *
+     * @param values   set of type string containing attribute values to load into attribute set.
+     * @param entry    contains ldap entry to pull attrs from.
+     * @param attrName name of ldap attribute being added.
+     * @throws LdapException
+     */
+    protected void loadAttrs( Set<String> values, Entry entry, String attrName ) throws LdapException
+    {
+        if ( ( values != null ) && ( values.size() > 0 ) )
+        {
+            entry.add( attrName, values.toArray( new String[]{} ) );
+        }
+    }
+
+
+    /**
+     * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
+     * modification set in preparation for ldap modify.
+     *
+     * @param props    contains {@link java.util.Properties} targeted for updating in ldap.
+     * @param mods     ldap modification set containing name-value pairs in raw ldap format.
+     * @param attrName contains the name of the ldap attribute to be updated.
+     * @param replace  boolean variable, if set to true use {@link ModificationOperation#REPLACE_ATTRIBUTE} else {@link
+     * ModificationOperation#ADD_ATTRIBUTE}.
+     */
+    protected void loadProperties( Properties props, List<Modification> mods, String attrName, boolean replace )
+    {
+        loadProperties( props, mods, attrName, replace, GlobalIds.PROP_SEP );
+    }
+
+
+    /**
+     * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
+     * modification set in preparation for ldap modify.
+     *
+     * @param props    contains {@link java.util.Properties} targeted for updating in ldap.
+     * @param mods     ldap modification set containing name-value pairs in raw ldap format.
+     * @param attrName contains the name of the ldap attribute to be updated.
+     * @param replace  boolean variable, if set to true use {@link ModificationOperation#REPLACE_ATTRIBUTE} else {@link
+     * ModificationOperation#ADD_ATTRIBUTE}.
+     * @param separator contains the char value used to separate name and value in ldap raw format.
+     */
+    protected void loadProperties( Properties props, List<Modification> mods, String attrName, boolean replace, char separator )
+    {
+        if ( props != null && props.size() > 0 )
+        {
+            if ( replace )
+            {
+                mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attrName ) );
+            }
+
+            for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                mods.add( new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, attrName,
+                    key + separator + val ) );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
+     * modification set in preparation for ldap modify.
+     *
+     * @param props    contains {@link java.util.Properties} targeted for removal from ldap.
+     * @param mods     ldap modification set containing name-value pairs in raw ldap format to be removed.
+     * @param attrName contains the name of the ldap attribute to be removed.
+     */
+    protected void removeProperties( Properties props, List<Modification> mods, String attrName )
+    {
+        if ( props != null && props.size() > 0 )
+        {
+            Attribute prop;
+
+            for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attrName,
+                    key + GlobalIds.PROP_SEP + val ) );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap
+     * modification set in preparation for ldap add.
+     *
+     * @param props    contains {@link java.util.Properties} targeted for adding to ldap.
+     * @param entry    contains ldap entry to pull attrs from.
+     * @param attrName contains the name of the ldap attribute to be added.
+     * @throws LdapException
+     */
+    protected void loadProperties( Properties props, Entry entry, String attrName ) throws LdapException
+    {
+        if ( ( props != null ) && ( props.size() > 0 ) )
+        {
+            Attribute attr = new DefaultAttribute( attrName );
+
+            for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+                String prop = key + GlobalIds.PROP_SEP + val;
+
+                attr.add( prop );
+            }
+
+            if ( attr.size() != 0 )
+            {
+                entry.add( attr );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of {@link java.util.Properties}, convert to raw data name-value format and load into ldap modification set in preparation for ldap add.
+     *
+     * @param props    contains {@link java.util.Properties} targeted for adding to ldap.
+     * @param entry    contains ldap entry to push attrs into.
+     * @param attrName contains the name of the ldap attribute to be added.
+     * @param separator contains the char value used to separate name and value in ldap raw format.
+     * @throws LdapException
+     */
+    protected void loadProperties( Properties props, Entry entry, String attrName, char separator ) throws LdapException
+    {
+        if ( props != null && props.size() > 0 )
+        {
+            Attribute attr = null;
+            for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+                String prop = key + separator + val;
+                if ( attr == null )
+                {
+                    attr = new DefaultAttribute( attrName );
+                }
+                else
+                {
+                    attr.add( prop );
+                }
+            }
+            if ( attr != null )
+            {
+                entry.add( attr );
+            }
+        }
+    }
+
+
+    /**
+     * @param value
+     * @param validLen
+     * @return String containing encoded data.
+     * @throws LdapException
+     */
+    protected String encodeSafeText( String value, int validLen ) throws LdapException
+    {
+        if ( VUtil.isNotNullOrEmpty( value ) )
+        {
+            int length = value.length();
+            if ( length > validLen )
+            {
+                String error = "encodeSafeText value [" + value + "] invalid length [" + length + "]";
+                throw new LdapException( error );
+            }
+            if ( GlobalIds.LDAP_FILTER_SIZE_FOUND )
+            {
+                value = VUtil.escapeLDAPSearchFilter( value );
+            }
+        }
+        return value;
+    }
+
+
+    /**
+     * Calls the PoolMgr to perform an LDAP bind for a user/password combination.  This function is valid
+     * if and only if the user entity is a member of the USERS data set.  The LDAP directory
+     * will return the OpenLDAP PW Policy control.
+     *
+     * @param connection connection to ldap server.
+     * @param userDn     contains the LDAP dn to the user entry.
+     * @param password   contains the password in clear text.
+     * @return boolean value - true if bind successful, false otherwise.
+     * @throws LdapException in the event of LDAP error.
+     */
+    protected boolean bind( LdapConnection connection, String userDn, char[] password ) throws LdapException
+    {
+        counters.incrementBind();
+
+        connection.bind( userDn, new String( password ) );
+        return true;
+    }
+
+
+    /**
+     * Calls the PoolMgr to close the Admin LDAP connection.
+     *
+     * @param connection handle to ldap connection object.
+     * @throws Exception
+     */
+    protected void closeAdminConnection( LdapConnection connection )
+    {
+        try
+        {
+            adminPool.releaseConnection( connection );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e.getMessage() );
+        }
+    }
+
+
+    /**
+     * Calls the PoolMgr to close the Log LDAP connection.
+     *
+     * @param connection handle to ldap connection object.
+     * @throws Exception
+     */
+    protected void closeLogConnection( LdapConnection connection )
+    {
+        try
+        {
+            logPool.releaseConnection( connection );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e.getMessage() );
+        }
+    }
+
+
+    /**
+     * Calls the PoolMgr to close the User LDAP connection.
+     *
+     * @param connection handle to ldap connection object.
+     * @throws Exception
+     */
+    protected void closeUserConnection( LdapConnection connection )
+    {
+        try
+        {
+            userPool.releaseConnection( connection );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e.getMessage() );
+        }
+    }
+
+
+    /**
+     * Calls the PoolMgr to get an Admin connection to the LDAP server.
+     *
+     * @return ldap connection.
+     * @throws LdapException
+     */
+    protected LdapConnection getAdminConnection() throws LdapException
+    {
+        try
+        {
+            return adminPool.getConnection();
+        }
+        catch ( Exception e )
+        {
+            throw new LdapException( e.getMessage() );
+        }
+    }
+
+
+    /**
+     * Calls the PoolMgr to get an Log connection to the LDAP server.
+     *
+     * @return ldap connection.
+     * @throws LdapException
+     */
+    protected LdapConnection getLogConnection() throws LdapException
+    {
+        try
+        {
+            return logPool.getConnection();
+        }
+        catch ( Exception e )
+        {
+            throw new LdapException( e.getMessage() );
+        }
+    }
+
+
+    /**
+     * Calls the PoolMgr to get an User connection to the LDAP server.
+     *
+     * @return ldap connection.
+     * @throws LdapException
+     */
+    protected LdapConnection getUserConnection() throws LdapException
+    {
+        try
+        {
+            return userPool.getConnection();
+        }
+        catch ( Exception e )
+        {
+            throw new LdapException( e.getMessage() );
+        }
+    }
+
+
+    /**
+     * Return to call reference to dao counter object with running totals for ldap operations add, mod, delete, search, etc.
+     *
+     * @return {@link LdapCounters} contains long values of atomic ldap operations for current running process.
+     */
+    public static LdapCounters getLdapCounters()
+    {
+        return counters;
+    }
+}
\ 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/ldap/ConnectionPool.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/ConnectionPool.java b/src/main/java/org/apache/directory/fortress/core/ldap/ConnectionPool.java
new file mode 100755
index 0000000..c6dc457
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/ConnectionPool.java
@@ -0,0 +1,664 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap;
+
+
+import java.security.GeneralSecurityException;
+import java.util.Date;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.JavaToLDAPSocketFactory;
+import com.unboundid.util.ssl.SSLUtil;
+import com.unboundid.util.ssl.TrustStoreTrustManager;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
+
+import javax.net.ssl.SSLSocketFactory;
+
+
+/**
+ * This connection pool class is used by Fortress {@link PoolMgr}.
+ * PoolMgr operations utilize multiple instances of this class to connections for different purposes.
+ * For example the 'admin' pool contains connections that have privileges to make modifications to the directory data during administrative operations {@link org.apache.directory.fortress.core.AdminMgr}.
+ * The 'user' pool contain unprivileged connections used for authentication processing only, {@link org.apache.directory.fortress.core.AccessMgr}.
+ * A 3rd pool, may be used to interrogate data stored by OpenLDAP's slapo access log info, This is used interrogating the fortress audit log events, {@link org.apache.directory.fortress.core.AuditMgr}.
+ * The contents of this file have been derived from the original, Mozilla Java LDAP SDK, and are subject to the Netscape Public License Version 1.1 (the "License")
+ * as described at the top of this file;
+ * The code mods include additional functionality to enable SSL connections in pool.  There have been other updates to the original functions to integrate with UnboundID's Java LDAP SDK.
+ * </p>
+ * Original Mozilla javadoc:
+ * Class to maintain a pool of individual connections to the
+ * same server. Specify the initial size and the max size
+ * when constructing a pool. Call getConnection() to obtain
+ * a connection from the pool and close() to return it. If
+ * the pool is fully extended and there are no free connections,
+ * getConnection() blocks until a connection has been returned
+ * to the pool.<BR>
+ * Call destroy() to release all connections.
+ * <BR><BR>Example:<BR>
+ * <PRE>
+ * ConnectionPool pool = null;
+ * try {
+ * pool = new ConnectionPool( 10, 30,
+ * "foo.acme.com",389,
+ * "uid=me, o=acme.com",
+ * "password" );
+ * } catch ( LDAPException e ) {
+ * System.err.println( "Unable to create connection pool" );
+ * System.exit( 1 );
+ * }
+ * while ( clientsKnocking ) {
+ * String filter = getSearchFilter();
+ * LDAPConnection ld = pool.getConnection();
+ * try {
+ * LDAPSearchResults res = ld.search( BASE, ld.SCOPE_SUB,
+ * filter, attrs,
+ * false );
+ * pool.close( ld );
+ * while( res.hasMoreElements() ) {
+ * ...
+ * </PRE>
+ */
+class ConnectionPool
+{
+    // Logging
+    private static final String CLS_NM = ConnectionPool.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+
+    /**
+     * Create a new instance of connection pool with specified parameters.  These connections will be used by the Fortress DAO
+     * methods for processing ldap server operations.
+     *
+     * @param min    initial number of connections
+     * @param max    maximum number of connections
+     * @param host   hostname of LDAP server
+     * @param port   port number of LDAP server
+     * @param authdn DN to authenticate as
+     * @param authpw password for authentication
+     * @throws LDAPException on failure to create connections
+     */
+    ConnectionPool( int min, int max,
+        String host, int port,
+        String authdn, String authpw )
+        throws LDAPException
+    {
+        this( min, max, host, port, authdn, authpw, null );
+    }
+
+
+    /*
+     * Constructor for using an existing connection to clone
+     * from
+     * 
+     * @param min initial number of connections
+     * @param max maximum number of connections
+     * @param host hostname of LDAP server
+     * @param port port number of LDAP server
+     * @param authdn DN to authenticate as
+     * @param authpw password for authentication
+     * @param ldc connection to clone 
+     * @exception LDAPException on failure to create connections 
+     */
+    private ConnectionPool( int min, int max,
+        String host, int port,
+        String authdn, String authpw,
+        LDAPConnection ldc )
+        throws LDAPException
+    {
+        this.poolSize = min;
+        this.poolMax = max;
+        this.host = host;
+        this.port = port;
+        this.authdn = authdn;
+        this.authpw = authpw;
+        this.ldc = ldc;
+        this.debugMode = false;
+        createPool();
+    }
+
+
+    /**
+     * Destroy the whole pool - called during a shutdown
+     */
+    void destroy()
+    {
+        for ( int i = 0; i < pool.size(); i++ )
+        {
+            disconnect( ( LDAPConnectionObject ) pool.elementAt( i ) );
+        }
+        pool.removeAllElements();
+    }
+
+
+    /**
+     * Gets a connection from the pool
+     * <p/>
+     * If no connections are available, the pool will be
+     * extended if the number of connections is less than
+     * the maximum; if the pool cannot be extended, the method
+     * blocks until a free connection becomes available.
+     *
+     * @return an active connection.
+     */
+    LDAPConnection getConnection()
+    {
+        LDAPConnection con;
+
+        while ( ( con = getConnFromPool() ) == null )
+        {
+            synchronized ( pool )
+            {
+                try
+                {
+                    pool.wait();
+                }
+                catch ( InterruptedException e )
+                {
+                    LOG.warn( "getConnection caught InterruptedException" );
+                }
+            }
+        }
+        return con;
+    }
+
+
+    /**
+     * Gets a connection from the pool within a time limit.
+     * <p/>
+     * If no connections are available, the pool will be
+     * extended if the number of connections is less than
+     * the maximum; if the pool cannot be extended, the method
+     * blocks until a free connection becomes available or the
+     * time limit is exceeded.
+     *
+     * @param timeout timeout in milliseconds
+     * @return an active connection or <CODE>null</CODE> if timed out.
+     */
+    LDAPConnection getConnection( int timeout )
+    {
+        LDAPConnection con;
+
+        while ( ( con = getConnFromPool() ) == null )
+        {
+            long t1, t0 = System.currentTimeMillis();
+
+            if ( timeout <= 0 )
+            {
+                return con;
+            }
+
+            synchronized ( pool )
+            {
+                try
+                {
+                    pool.wait( timeout );
+                }
+                catch ( InterruptedException e )
+                {
+                    LOG.warn( "getConnection caught InterruptedException for timeout: " + timeout );
+                    return null;
+                }
+            }
+
+            t1 = System.currentTimeMillis();
+            timeout -= ( t1 - t0 );
+        }
+        return con;
+    }
+
+
+    /**
+     * Gets a connection from the pool
+     * <p/>
+     * If no connections are available, the pool will be
+     * extended if the number of connections is less than
+     * the maximum; if the pool cannot be extended, the method
+     * returns null.
+     *
+     * @return an active connection or null.
+     */
+    synchronized LDAPConnection getConnFromPool()
+    {
+        LDAPConnection con = null;
+        LDAPConnectionObject ldapconnobj = null;
+
+        int pSize = pool.size();
+
+        // Get an available connection
+        for ( int i = 0; i < pSize; i++ )
+        {
+
+            // Get the ConnectionObject from the pool
+            LDAPConnectionObject co =
+                ( LDAPConnectionObject ) pool.elementAt( i );
+
+            if ( co.isAvailable() )
+            { // Conn available?
+                ldapconnobj = co;
+                break;
+            }
+        }
+
+        if ( ldapconnobj == null )
+        {
+            // If there there were no conns in pool, can we grow
+            // the pool?
+            if ( ( poolMax < 0 ) ||
+                ( ( poolMax > 0 ) &&
+                ( pSize < poolMax ) ) )
+            {
+
+                // Yes we can grow it
+                int i = addConnection();
+
+                // If a new connection was created, use it
+                if ( i >= 0 )
+                {
+                    ldapconnobj =
+                        ( LDAPConnectionObject ) pool.elementAt( i );
+                }
+            }
+            else
+            {
+                debug( "All pool connections in use" );
+            }
+        }
+
+        if ( ldapconnobj != null )
+        {
+            ldapconnobj.setInUse( true ); // Mark as in use
+            con = ldapconnobj.getLDAPConn();
+        }
+        return con;
+    }
+
+
+    /**
+     * This is our soft close - all we do is mark
+     * the connection as available for others to use.
+     * We also reset the auth credentials in case
+     * they were changed by the caller.
+     *
+     * @param ld a connection to return to the pool
+     */
+    synchronized void close( LDAPConnection ld )
+    {
+
+        int index = find( ld );
+        if ( index != -1 )
+        {
+            LDAPConnectionObject co =
+                ( LDAPConnectionObject ) pool.elementAt( index );
+            // Reset the auth if necessary
+            if ( ldc == null )
+            {
+                boolean reauth = false;
+                //if user bound anon then getAuthenticationDN is null
+                if ( ld.getAuthenticationDN() == null )
+                {
+                    reauth = ( authdn != null );
+                }
+                else if ( !ld.getAuthenticationDN().equalsIgnoreCase( authdn ) )
+                {
+                    reauth = true;
+                }
+            }
+            co.setInUse( false ); // Mark as available
+            synchronized ( pool )
+            {
+                pool.notifyAll();
+            }
+        }
+    }
+
+
+    /**
+     * Debug method to print the contents of the pool
+     */
+    public void printPool()
+    {
+        System.out.println( "--ConnectionPool--" );
+        for ( int i = 0; i < pool.size(); i++ )
+        {
+            LDAPConnectionObject co =
+                ( LDAPConnectionObject ) pool.elementAt( i );
+            String msg = "" + i + "=" + co;
+            LOG.info( "printPool: " + msg );
+        }
+    }
+
+
+    private void disconnect(
+        LDAPConnectionObject ldapconnObject )
+    {
+        if ( ldapconnObject != null )
+        {
+            if ( ldapconnObject.isAvailable() )
+            {
+                LDAPConnection ld = ldapconnObject.getLDAPConn();
+                if ( ( ld != null ) && ( ld.isConnected() ) )
+                {
+                    try
+                    {
+                        ld.disconnect();
+                    }
+                    catch ( LDAPException e )
+                    {
+                        debug( "disconnect: " + e.toString() );
+                        LOG.warn( "disconnect caught LDAPException: " + e.getMessage() );
+                    }
+                }
+                ldapconnObject.setLDAPConn( null ); // Clear conn
+            }
+        }
+    }
+
+
+    private void createPool() throws LDAPException
+    {
+        // Called by the constructors
+        if ( poolSize <= 0 )
+        {
+            throw new LDAPException( "ConnectionPoolSize invalid" );
+        }
+        if ( poolMax < poolSize )
+        {
+            debug( "ConnectionPoolMax is invalid, set to " +
+                poolSize );
+            poolMax = poolSize;
+        }
+
+        debug( "****Initializing LDAP Pool****" );
+        debug( "LDAP host = " + host + " on port " + port );
+        debug( "Number of connections=" + poolSize );
+        debug( "Maximum number of connections=" + poolMax );
+        debug( "******" );
+
+        pool = new java.util.Vector(); // Create pool vector
+        setUpPool( poolSize ); // Initialize it
+    }
+
+
+    private int addConnection()
+    {
+        int index = -1;
+
+        debug( "adding a connection to pool..." );
+        try
+        {
+            int size = pool.size() + 1; // Add one connection
+            setUpPool( size );
+
+            if ( size == pool.size() )
+            {
+                // New size is size requested?
+                index = size - 1;
+            }
+        }
+        catch ( Exception ex )
+        {
+            debug( "Adding a connection: " + ex.toString() );
+            LOG.warn( "addConnection caught Exception: " + ex.getMessage() );
+        }
+        return index;
+    }
+
+
+    /**
+     * *** FORTRESS MOD ****
+     *
+     * Create pool of LDAP connections to server.  Add SSL capability using unboundId's compatibility utility.
+     *
+     * @param size number of connections to generate and store in pool
+     * @throws LDAPException in the event of system error.
+     */
+    private synchronized void setUpPool( int size )
+        throws LDAPException
+    {
+        // Loop on creating connections
+        while ( pool.size() < size )
+        {
+            LDAPConnectionObject co =
+                new LDAPConnectionObject();
+
+            LDAPConnection newConn = createConnection( );
+            newConn.connect( host, port, authdn, authpw );
+            co.setLDAPConn( newConn );
+            co.setInUse( false ); // Mark not in use
+            pool.addElement( co );
+        }
+    }
+
+    /**
+     * Used to manage trust store properties.  If enabled, create SSL connection.
+     *
+     */
+    private static final String ENABLE_LDAP_SSL = "enable.ldap.ssl";
+    private static final String ENABLE_LDAP_SSL_DEBUG = "enable.ldap.ssl.debug";
+    private static final String TRUST_STORE = Config.getProperty( "trust.store" );
+    private static final String TRUST_STORE_PW = Config.getProperty( "trust.store.password" );
+    private static final boolean IS_SSL = (
+        Config.getProperty( ENABLE_LDAP_SSL ) != null   &&
+            Config.getProperty( ENABLE_LDAP_SSL ).equalsIgnoreCase( "true" ) &&
+            TRUST_STORE      != null   &&
+            TRUST_STORE_PW   != null );
+
+    private static final String SET_TRUST_STORE_PROP = "trust.store.set.prop";
+    private static final boolean IS_SET_TRUST_STORE_PROP = (
+        IS_SSL &&
+            Config.getProperty( SET_TRUST_STORE_PROP ) != null   &&
+            Config.getProperty( SET_TRUST_STORE_PROP ).equalsIgnoreCase( "true" ));
+
+    private static final boolean IS_SSL_DEBUG = ( ( Config.getProperty( ENABLE_LDAP_SSL_DEBUG ) != null ) && ( Config
+        .getProperty( ENABLE_LDAP_SSL_DEBUG ).equalsIgnoreCase( "true" ) ) );
+
+    static
+    {
+        if(IS_SET_TRUST_STORE_PROP)
+        {
+            LOG.info( "Set JSSE truststore properties:");
+            LOG.info( "javax.net.ssl.trustStore: " + TRUST_STORE );
+            LOG.info( "javax.net.debug: " + new Boolean( IS_SSL_DEBUG ).toString());
+            System.setProperty( "javax.net.ssl.trustStore", TRUST_STORE );
+            System.setProperty( "javax.net.ssl.trustStorePassword", TRUST_STORE_PW );
+            System.setProperty( "javax.net.debug", new Boolean( IS_SSL_DEBUG ).toString() );
+        }
+    }
+
+    /**
+     * *** FORTRESS MOD ****
+     *
+     * If enabled, use Unbound compatibility lib to create SSL connection.
+     *
+     * @return handle to LDAPConnection
+     * @throws LDAPException wrap GeneralSecurityException or throws ldapexcep.
+     */
+    private LDAPConnection createConnection() throws LDAPException
+    {
+        LDAPConnection newConn = null;
+        if( IS_SSL)
+        {
+            // Generate SSL Connection using Unbound compatibility lib utils:
+            // http://stackoverflow.com/questions/22672477/unboundid-ldap-jdk-migration
+            SSLSocketFactory sslSocketFactory;
+            //SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager());
+            // These config values set in fortress.properties
+            SSLUtil sslUtil = new SSLUtil(
+                new TrustStoreTrustManager(
+                    TRUST_STORE,
+                    TRUST_STORE_PW.toCharArray() , null, true ) );
+            try
+            {
+                sslSocketFactory = sslUtil.createSSLSocketFactory();
+            }
+            catch(GeneralSecurityException e)
+            {
+                String error = "GeneralSecurityException while creating SSL socket factory=" + e;
+                throw new LDAPException( error, LDAPException.CONNECT_ERROR );
+            }
+            JavaToLDAPSocketFactory ldapSocketFactory =
+                new JavaToLDAPSocketFactory(sslSocketFactory);
+            newConn = new LDAPConnection(ldapSocketFactory);
+        }
+        else
+        {
+            // Make LDAP connection, using template if available
+            newConn = new LDAPConnection();
+        }
+        return newConn;
+    }
+
+    private int find( LDAPConnection con )
+    {
+        // Find the matching Connection in the pool
+        if ( con != null )
+        {
+            for ( int i = 0; i < pool.size(); i++ )
+            {
+                LDAPConnectionObject co =
+                    ( LDAPConnectionObject ) pool.elementAt( i );
+                if ( co.getLDAPConn() == con )
+                {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+
+    /**
+     * Sets the debug printout mode.
+     *
+     * @param mode debug mode to use
+     */
+    public synchronized void setDebug( boolean mode )
+    {
+        debugMode = mode;
+    }
+
+
+    /**
+     * Reports the debug printout mode.
+     *
+     * @return debug mode in use.
+     */
+    public boolean getDebug()
+    {
+        return debugMode;
+    }
+
+
+    private void debug( String s )
+    {
+        if ( debugMode )
+            System.out.println( "ConnectionPool (" +
+                new Date() + ") : " + s );
+    }
+
+
+    private void debug( String s, boolean severe )
+    {
+        if ( debugMode || severe )
+        {
+            System.out.println( "ConnectionPool (" +
+                new Date() + ") : " + s );
+        }
+    }
+
+    /**
+     * Wrapper for LDAPConnection object in pool
+     */
+    class LDAPConnectionObject
+    {
+
+        /**
+         * Returns the associated LDAPConnection.
+         *
+         * @return the LDAPConnection.
+         */
+        LDAPConnection getLDAPConn()
+        {
+            return this.ld;
+        }
+
+
+        /**
+         * Sets the associated LDAPConnection
+         *
+         * @param ld the LDAPConnection
+         */
+        void setLDAPConn( LDAPConnection ld )
+        {
+            this.ld = ld;
+        }
+
+
+        /**
+         * Marks a connection in use or available
+         *
+         * @param inUse <code>true</code> to mark in use, <code>false</code> if available
+         */
+        void setInUse( boolean inUse )
+        {
+            this.inUse = inUse;
+        }
+
+
+        /**
+         * Returns whether the connection is available
+         * for use by another user.
+         *
+         * @return <code>true</code> if available.
+         */
+        boolean isAvailable()
+        {
+            return !inUse;
+        }
+
+
+        /**
+         * Debug method
+         *
+         * @return s user-friendly rendering of the object.
+         */
+        public String toString()
+        {
+            return "LDAPConnection=" + ld + ",inUse=" + inUse;
+        }
+
+        private LDAPConnection ld; // LDAP Connection
+        private boolean inUse; // In use? (true = yes)
+    }
+
+    private final int poolSize; // Min pool size
+    private int poolMax; // Max pool size
+    private final String host; // LDAP host
+    private final int port; // Port to connect at
+    private final String authdn; // Identity of connections
+    private final String authpw; // Password for authdn
+    private LDAPConnection ldc = null; // Connection to clone
+    private java.util.Vector pool; // the actual pool
+    private boolean debugMode;
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/LdapClientTrustStoreManager.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/LdapClientTrustStoreManager.java b/src/main/java/org/apache/directory/fortress/core/ldap/LdapClientTrustStoreManager.java
new file mode 100644
index 0000000..6819150
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/LdapClientTrustStoreManager.java
@@ -0,0 +1,251 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.directory.fortress.core.CfgRuntimeException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implement the X509TrustManager interface which will be used during JSSE truststore manager initialization for LDAP
+ * client-to-server communications over TLS/SSL.
+ * It is used during certificate validation operations within JSSE.
+ * <p/>
+ * Note: This class allows self-signed certificates to pass the validation checks.
+ *
+ * @author Shawn McKinney
+ */
+public final class LdapClientTrustStoreManager implements X509TrustManager, Serializable
+{
+    // Logging
+    private static final String CLS_NM = LdapClientTrustStoreManager.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    // Config variables
+    private final boolean isExamineValidityDates;
+    private final char[] trustStorePw;
+    private final String trustStoreFile;
+    private final String trustStoreFormat;
+
+    /**
+     * Constructor used by connection configuration utility to load trust store manager.
+     *
+     * @param trustStoreFile    contains fully qualified name of trust store file.
+     * @param trustStorePw      contains the password for trust store
+     * @param trustStoreFormat  contains the format for trust store
+     * @param isExamineValidity boolean var determines if certificate will be examined for valid dates on load.
+     */
+    public LdapClientTrustStoreManager( final String trustStoreFile, final char[] trustStorePw,
+        final String trustStoreFormat, final boolean isExamineValidity )
+    {
+        if ( trustStoreFile == null )
+        {
+            // Cannot continue, throw an unchecked exception:
+            throw new CfgRuntimeException( GlobalErrIds.FT_CONFIG_JSSE_TRUSTSTORE_NULL,
+                "FortressTrustStoreManager constructor : input file name is null" );
+        }
+        // contains the fully-qualified file name of a valid JSSE TrustStore on local file system:
+        this.trustStoreFile = trustStoreFile;
+        // the password to the JSSE TrustStore:
+        this.trustStorePw = trustStorePw;
+        // If true, verify the current date is within the validity period for every certificate in the TrustStore:
+        this.isExamineValidityDates = isExamineValidity;
+        if ( trustStoreFormat == null )
+        {
+            this.trustStoreFormat = KeyStore.getDefaultType();
+        }
+        else
+        {
+            this.trustStoreFormat = trustStoreFormat;
+        }
+    }
+
+    /**
+     * Determine if client certificate is to be trusted.
+     *
+     * @param x509Chain
+     * @param authNType
+     * @throws CertificateException
+     */
+    public synchronized void checkClientTrusted( final X509Certificate[] x509Chain,
+        final String authNType ) throws CertificateException
+    {
+        // For each certificate in the chain, check validity:
+        for ( final X509TrustManager trustMgr : getTrustManagers( x509Chain ) )
+        {
+            trustMgr.checkClientTrusted( x509Chain, authNType );
+        }
+    }
+
+    /**
+     * Determine if server certificate is to be trusted.
+     *
+     * @param x509Chain
+     * @param authNType
+     * @throws CertificateException
+     */
+    public synchronized void checkServerTrusted( final X509Certificate[] x509Chain, final String authNType ) throws
+        CertificateException
+    {
+        for ( final X509TrustManager trustManager : getTrustManagers( x509Chain ) )
+        {
+            trustManager.checkServerTrusted( x509Chain, authNType );
+        }
+    }
+
+    /**
+     * Return the list of accepted issuers for this trust manager.
+     *
+     * @return array of accepted issuers
+     */
+    public synchronized X509Certificate[] getAcceptedIssuers()
+    {
+        return new X509Certificate[0];
+    }
+
+    /**
+     * Return array of trust managers to caller.  Will verify that current date is within certs validity period.
+     *
+     * @param x509Chain contains input X.509 certificate chain.
+     * @return array of X.509 trust managers.
+     * @throws CertificateException if trustStoreFile instance variable is null.
+     */
+    private synchronized X509TrustManager[] getTrustManagers( final X509Certificate[] x509Chain ) throws
+        CertificateException
+    {
+        // If true, verify the current date is within each certificates validity period.
+        if ( isExamineValidityDates )
+        {
+            final Date currentDate = new Date();
+            for ( final X509Certificate x509Cert : x509Chain )
+            {
+                x509Cert.checkValidity( currentDate );
+            }
+        }
+        // The trustStoreFile should contain the fully-qualified name of a Java TrustStore on local file system.
+        final File trustStoreFile = new File( this.trustStoreFile );
+        if ( !trustStoreFile.exists() )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.getTrustManagers : file not found" );
+        }
+        return loadTrustManagers( getTrustStore() );
+    }
+
+    /**
+     * Return an array of X.509 TrustManagers.
+     *
+     * @param trustStore handle to input trustStore
+     * @return array of trust managers
+     * @throws CertificateException if problem occurs during TrustManager initialization.
+     */
+    private X509TrustManager[] loadTrustManagers( final KeyStore trustStore ) throws CertificateException
+    {
+        final X509TrustManager[] x509TrustManagers;
+        try
+        {
+            final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory
+                .getDefaultAlgorithm() );
+            trustManagerFactory.init( trustStore );
+            final TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
+            x509TrustManagers = new X509TrustManager[trustManagers.length];
+            for ( int i = 0; i < trustManagers.length; i++ )
+            {
+                x509TrustManagers[i] = ( X509TrustManager ) trustManagers[i];
+            }
+        }
+        catch ( NoSuchAlgorithmException e )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.loadTrustManagers caught " +
+                "NoSuchAlgorithmException", e );
+        }
+        catch ( KeyStoreException e )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.loadTrustManagers caught KeyStoreException", e );
+        }
+        return x509TrustManagers;
+    }
+
+    /**
+     * Load the TrustStore file into JSSE KeyStore instance.
+     *
+     * @return instance of JSSE KeyStore containing the LDAP Client's TrustStore file info.     *
+     * @throws CertificateException if cannot process file load.
+     */
+    private KeyStore getTrustStore() throws CertificateException
+    {
+        final KeyStore trustStore;
+        try
+        {
+            trustStore = KeyStore.getInstance( trustStoreFormat );
+        }
+        catch ( KeyStoreException e )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.getTrustManagers caught KeyStoreException", e );
+        }
+        FileInputStream trustStoreInputStream = null;
+        try
+        {
+            trustStoreInputStream = new FileInputStream( trustStoreFile );
+            trustStore.load( trustStoreInputStream, trustStorePw );
+        }
+        catch ( NoSuchAlgorithmException e )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.getTrustManagers caught " +
+                "NoSuchAlgorithmException", e );
+        }
+        catch ( IOException e )
+        {
+            throw new CertificateException( "FortressTrustStoreManager.getTrustManagers caught KeyStoreException", e );
+        }
+        finally
+        {
+            // Close the input stream.
+            if ( trustStoreInputStream != null )
+            {
+                try
+                {
+                    trustStoreInputStream.close();
+                }
+                catch ( IOException e )
+                {
+                    // Eat this ioexception because it shouldn't be a problem, but log just in case:
+                    LOG.warn( "FortressTrustStoreManager.getTrustManagers finally block on input stream close " +
+                        "operation caught IOException=" + e.getMessage() );
+                }
+            }
+        }
+        return trustStore;
+    }
+}


[45/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ObjectFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ObjectFactory.java b/src/main/java/org/apache/directory/fortress/core/ObjectFactory.java
new file mode 100755
index 0000000..6502f27
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ObjectFactory.java
@@ -0,0 +1,476 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.ldap.group.Group;
+import org.apache.directory.fortress.core.rbac.*;
+import org.apache.directory.fortress.core.rest.FortRequest;
+import org.apache.directory.fortress.core.rest.FortResponse;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.annotation.XmlElementDecl;
+import javax.xml.bind.annotation.XmlRegistry;
+import javax.xml.namespace.QName;
+
+
+/**
+ *
+ * This class contains factory methods for each Java content interface and Java element interface
+ * generated in the org.apache.directory.fortress packages.
+ * <p>An ObjectFactory allows you to programatically
+ * construct new instances of the Java representation
+ * for XML content. The Java representation of XML
+ * content can consist of schema derived interfaces
+ * and classes representing the binding of schema
+ * type definitions, element declarations and model
+ * groups.  Factory methods for each of these are
+ * provided in this class.
+ * @author Shawn McKinney
+ *
+ */
+@XmlRegistry
+public class ObjectFactory
+{
+    private final static QName _FortUser_QNAME = new QName("", "fortUser");
+    private final static QName _FortSession_QNAME = new QName("", "fortSession");
+    private final static QName _FortRole_QNAME = new QName("", "fortRole");
+    private final static QName _FortGrant_QNAME = new QName("", "fortGrant");
+    private final static QName _FortOrgUnit_QNAME = new QName("", "fortOrgUnit");
+    private final static QName _FortEntity_QNAME = new QName("", "fortEntity");
+    private final static QName _FortAdminRole_QNAME = new QName("", "fortAdminRole");
+    private final static QName _FortUserRole_QNAME = new QName("", "fortUserRole");
+    private final static QName _FortObject_QNAME = new QName("", "fortObject");
+    private final static QName _FortPermission_QNAME = new QName("", "fortPermission");
+    private final static QName _FortRoleRelationship_QNAME = new QName("", "fortRoleRelationship");
+    private final static QName _FortSet_QNAME = new QName("", "fortSet");
+    private final static QName _FortPolicy_QNAME = new QName("", "fortPolicy");
+    private final static QName _FortUserAdminRole_QNAME = new QName("", "fortUserAdminRole");
+    private final static QName _FortAdminRoleRelationship_QNAME = new QName("", "fortAdminRoleRelationship");
+    private final static QName _FortOrgUnitRelationship_QNAME = new QName("", "fortOrgUnitRelationship");
+    private final static QName _FortBind_QNAME = new QName("", "fortBind");
+    private final static QName _FortUserAudit_QNAME = new QName("", "fortUserAudit");
+    private final static QName _FortAuthZ_QNAME = new QName("", "fortAuthZ");
+    private final static QName _FortMod_QNAME = new QName("", "fortMod");
+    private final static QName _FortRolePerm_QNAME = new QName("", "fortRolePerm");
+    private final static QName _FortResponse_QNAME = new QName("", "fortResponse");
+    private final static QName FortRequest_QNAME = new QName("", "fortRequest");
+    private final static QName FortAddress_QNAME = new QName("", "fortAddress");
+    private final static QName _FortProps_QNAME = new QName("", "fortProps");
+    private final static QName _FortWarning_QNAME = new QName("", "fortWarning");
+    private final static QName _FortGroup_QNAME = new QName("", "fortGroup");
+
+
+    @XmlElementDecl(namespace = "", name = "fortEntity")
+    public JAXBElement<FortEntity> createFortEntity(FortEntity value)
+    {
+        return new JAXBElement<>(_FortEntity_QNAME, FortEntity.class, null, value);
+    }
+
+    @XmlElementDecl(namespace = "", name = "fortResponse")
+    public JAXBElement<FortResponse> createFortResponse(FortResponse value)
+    {
+        return new JAXBElement<>(_FortResponse_QNAME, FortResponse.class, null, value);
+    }
+
+    @XmlElementDecl(namespace = "", name = "fortRequest")
+    public JAXBElement<FortRequest> createFortRequest(FortRequest value)
+    {
+        return new JAXBElement<>(FortRequest_QNAME, FortRequest.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.SDSet }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortSet")
+    public JAXBElement<SDSet> createFortSet(SDSet value)
+    {
+        return new JAXBElement<>(_FortSet_QNAME, SDSet.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.PwPolicy }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortPolicy")
+    public JAXBElement<PwPolicy> createFortPolicy(PwPolicy value)
+    {
+        return new JAXBElement<>(_FortPolicy_QNAME, PwPolicy.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.Session }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortSession")
+    public JAXBElement<Session> createFortSession(Session value)
+    {
+        return new JAXBElement<>(_FortSession_QNAME, Session.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.User }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortUser")
+    public JAXBElement<User> createFortUser(User value)
+    {
+        return new JAXBElement<>(_FortUser_QNAME, User.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.UserRole }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortUserRole")
+    public JAXBElement<UserRole> createFortUserRole(UserRole value)
+    {
+        return new JAXBElement<>(_FortUserRole_QNAME, UserRole.class, null, value);
+    }
+
+    @XmlElementDecl(namespace = "", name = "fortOrgUnit")
+    public JAXBElement<OrgUnit> createFortOrgUnit(OrgUnit value)
+    {
+        return new JAXBElement<>(_FortOrgUnit_QNAME, OrgUnit.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.Role }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortRole")
+    public JAXBElement<Role> createFortRole(Role value)
+    {
+        return new JAXBElement<>(_FortRole_QNAME, Role.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.Role }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortGrant")
+    public JAXBElement<PermGrant> createFortGrant(PermGrant value)
+    {
+        return new JAXBElement<>(_FortGrant_QNAME, PermGrant.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.OrgUnitRelationship}{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortAdminRoleRelationship")
+    public JAXBElement<AdminRoleRelationship> createFortAdminRoleRelationship(AdminRoleRelationship value)
+    {
+        return new JAXBElement<>(_FortAdminRoleRelationship_QNAME, AdminRoleRelationship.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.OrgUnitRelationship}{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortOrgUnitRelationship")
+    public JAXBElement<OrgUnitRelationship> createFortOrgUnitRelationship(OrgUnitRelationship value)
+    {
+        return new JAXBElement<>(_FortOrgUnitRelationship_QNAME, OrgUnitRelationship.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.RoleRelationship}{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortRoleRelationship")
+    public JAXBElement<RoleRelationship> createFortRoleRelationship(RoleRelationship value)
+    {
+        return new JAXBElement<>(_FortRoleRelationship_QNAME, RoleRelationship.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.Role }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortAdminRole")
+    public JAXBElement<AdminRole> createFortAdminRole(AdminRole value)
+    {
+        return new JAXBElement<>(_FortAdminRole_QNAME, AdminRole.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.UserAdminRole }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortUserAdminRole")
+    public JAXBElement<UserAdminRole> createFortUserRole(UserAdminRole value)
+    {
+        return new JAXBElement<>(_FortUserAdminRole_QNAME, UserAdminRole.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.PermObj }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortObject")
+    public JAXBElement<PermObj> createFortObject(PermObj value)
+    {
+        return new JAXBElement<>(_FortObject_QNAME, PermObj.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.rbac.Permission }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortPermission")
+    public JAXBElement<Permission> createFortPermission(Permission value)
+    {
+        return new JAXBElement<>(_FortPermission_QNAME, Permission.class, null, value);
+    }
+
+    @XmlElementDecl(namespace = "", name = "fortBind")
+    public JAXBElement<Bind> createFortEntity(Bind value)
+    {
+        return new JAXBElement<>(_FortBind_QNAME, Bind.class, null, value);
+    }
+
+    @XmlElementDecl(namespace = "", name = "fortUserAudit")
+    public JAXBElement<UserAudit> createFortUserAudit(UserAudit value)
+    {
+        return new JAXBElement<>(_FortUserAudit_QNAME, UserAudit.class, null, value);
+    }
+
+    @XmlElementDecl(namespace = "", name = "fortAuthZ")
+    public JAXBElement<AuthZ> createFortAuthZ(AuthZ value)
+    {
+        return new JAXBElement<>(_FortAuthZ_QNAME, AuthZ.class, null, value);
+    }
+
+    @XmlElementDecl(namespace = "", name = "fortMod")
+    public JAXBElement<Mod> createFortMod(Mod value)
+    {
+        return new JAXBElement<>(_FortMod_QNAME, Mod.class, null, value);
+    }
+
+    @XmlElementDecl(namespace = "", name = "fortRolePerm")
+    public JAXBElement<RolePerm> createFortRolePerm(RolePerm value)
+    {
+        return new JAXBElement<>(_FortRolePerm_QNAME, RolePerm.class, null, value);
+    }
+
+    @XmlElementDecl(namespace = "", name = "fortAddress")
+    public JAXBElement<Address> createFortAddress(Address value)
+    {
+        return new JAXBElement<>(FortAddress_QNAME, Address.class, null, value);
+    }
+
+    @XmlElementDecl(namespace = "", name = "fortProps")
+    public JAXBElement<Props> createFortProps(Props value)
+    {
+        return new JAXBElement<>(_FortProps_QNAME, Props.class, null, value);
+    }
+
+    @XmlElementDecl(namespace = "", name = "fortWarning")
+    public JAXBElement<Warning> createFortWarning(Warning value)
+    {
+        return new JAXBElement<Warning>(_FortWarning_QNAME, Warning.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link JAXBElement }{@code <}{@link org.apache.directory.fortress.core.ldap.group.Group }{@code >}}
+     */
+    @XmlElementDecl(namespace = "", name = "fortGroup")
+    public JAXBElement<Group> createFortGroup(Group value)
+    {
+        return new JAXBElement<>(_FortGroup_QNAME, Group.class, null, value);
+    }
+
+    /**
+     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.apache.directory.fortress.model2
+     */
+    public ObjectFactory()
+    {
+    }
+
+    /**
+     * Create an instance of {@link User }
+     */
+    public User createUser()
+    {
+        return new User();
+    }
+
+    /**
+     * Create an instance of {@link org.apache.directory.fortress.core.rbac.PwPolicy }
+     */
+    public PwPolicy createPswdPolicy()
+    {
+        return new PwPolicy();
+    }
+
+    /**
+     * Create an instance of {@link Session }
+     */
+    public Session createSession()
+    {
+        return new Session();
+    }
+
+    /**
+     * Create an instance of {@link SDSet }
+     */
+    public SDSet createSDset()
+    {
+        return new SDSet();
+    }
+
+    /**
+     * Create an instance of {@link Role }
+     */
+    public Role createRole()
+    {
+        return new Role();
+    }
+
+    /**
+     * Create an instance of {@link Group }
+     */
+    public Group createGroup()
+    {
+        return new Group();
+    }
+
+    /**
+     * Create an instance of {@link PermGrant }
+     */
+    public PermGrant createPermGrant()
+    {
+        return new PermGrant();
+    }
+
+    /**
+     * Create an instance of {@link RoleRelationship }
+     */
+    public RoleRelationship createRoleRelationship()
+    {
+        return new RoleRelationship();
+    }
+
+    /**
+     * Create an instance of {@link AdminRoleRelationship }
+     */
+    public AdminRoleRelationship createAdminRoleRelationship()
+    {
+        return new AdminRoleRelationship();
+    }
+
+    /**
+     * Create an instance of {@link OrgUnitRelationship }
+     */
+    public OrgUnitRelationship createOrgUnitRelationship()
+    {
+        return new OrgUnitRelationship();
+    }
+
+    /**
+     * Create an instance of {@link PermObj }
+     */
+    public PermObj createPermObj()
+    {
+        return new PermObj();
+    }
+
+    /**
+     * Create an instance of {@link Permission }
+     */
+    public Permission createPermission()
+    {
+        return new Permission();
+    }
+
+    /**
+     * Create an instance of {@link Role }
+     */
+    public AdminRole createAdminRole()
+    {
+        return new AdminRole();
+    }
+
+    /**
+     * Create an instance of {@link UserRole }
+     */
+    public UserRole createUserRole()
+    {
+        return new UserRole();
+    }
+
+    /**
+     * Create an instance of {@link OrgUnit }
+     */
+    public OrgUnit createOrgUnit()
+    {
+        return new OrgUnit();
+    }
+
+    /**
+     * Create an instance of {@link UserAdminRole }
+     */
+    public UserAdminRole createUserAdminRole()
+    {
+        return new UserAdminRole();
+    }
+
+    public UserAudit createUserAudit()
+    {
+        return new UserAudit();
+    }
+
+    public Bind createBind()
+    {
+        return new Bind();
+    }
+
+    public AuthZ createAuthZ()
+    {
+        return new AuthZ();
+    }
+
+    public Mod createMod()
+    {
+        return new Mod();
+    }
+
+    public RolePerm createRolePerm()
+    {
+        return new RolePerm();
+    }
+
+    public FortResponse createFortResponse()
+    {
+        return new FortResponse();
+    }
+
+    public FortRequest createFortRequest()
+    {
+        return new FortRequest();
+    }
+
+    public Address createAddress()
+    {
+        return new Address();
+    }
+
+    public Props createProps()
+    {
+        return new Props();
+    }
+
+    public Warning createWarning(int id, String msg, Warning.Type type)
+    {
+        return new Warning(id, msg, type);
+    }
+
+    public Warning createWarning(int id, String msg, Warning.Type type, String name)
+    {
+        return new Warning(id, msg, type, name);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/PasswordException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/PasswordException.java b/src/main/java/org/apache/directory/fortress/core/PasswordException.java
new file mode 100755
index 0000000..4f7c44f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/PasswordException.java
@@ -0,0 +1,42 @@
+/*
+ *   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;
+
+
+/**
+ * This exception extends {@link SecurityException} and is thrown when password check fails.
+ * See the {@link GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+public class PasswordException extends SecurityException
+{
+    /**
+     * Create an exception with an error code that maps to {@link GlobalErrIds} and message text.
+     *
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     */
+    public PasswordException(int errorId, String msg)
+    {
+        super(errorId, msg);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/PwPolicyMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/PwPolicyMgr.java b/src/main/java/org/apache/directory/fortress/core/PwPolicyMgr.java
new file mode 100755
index 0000000..fb7d51d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/PwPolicyMgr.java
@@ -0,0 +1,305 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.rbac.PwPolicy;
+
+import java.util.List;
+
+
+/**
+ * This class is used to perform administrative and review functions on the PWPOLICIES and USERS data sets.
+ * <p/>
+ * <h4>Password Policies</h4>
+ * <a href="http://www.openldap.org/">OpenLDAP</a> supports the IETF draft <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10/">Password Policies LDAP directories</a></li>.  Policies may be applied at the user, group or global level.
+ * <p/>
+ * <img src="./doc-files/PasswordPolicy.png">
+ * <p/>
+ * Password enforcement options include:
+ * <ol>
+ * <li>A configurable limit on failed authentication attempts.</li>
+ * <li>A counter to track the number of failed authentication attempts.</li>
+ * <li>A time frame in which the limit of consecutive failed authentication attempts must happen before action is taken.</li>
+ * <li>The action to be taken when the limit is reached. The action will either be nothing, or the account will be locked.</li>
+ * <li>An amount of time the account is locked (if it is to be locked) This can be indefinite.</li>
+ * <li>Password expiration.</li>
+ * <li>Expiration warning</li>
+ * <li>Grace authentications</li>
+ * <li>Password history</li>
+ * <li>Password minimum age</li>
+ * <li>Password minimum length</li>
+ * <li>Password Change after Reset</li>
+ * <li>Safe Modification of Password</li>
+ * </ol>
+ * <p/>
+ * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.apache.directory.fortress.core.rbac.Session)}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public interface PwPolicyMgr extends Manageable
+{
+    /**
+     * This method will add a new policy entry to the POLICIES data set.  This command is valid
+     * if and only if the policy entry is not already present in the POLICIES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#name} - Maps to name attribute of pwdPolicy object class being added.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#minAge} - This attribute holds the number of seconds that must elapse between
+     * modifications to the password.  If this attribute is not present, 0
+     * seconds is assumed.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#maxAge} - This attribute holds the number of seconds after which a modified
+     * password will expire. If this attribute is not present, or if the value is 0 the password
+     * does not expire.  If not 0, the value must be greater than or equal
+     * to the value of the pwdMinAge.
+     * </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#inHistory} - This attribute specifies the maximum number of used passwords stored
+     * in the pwdHistory attribute. If this attribute is not present, or if the value is 0, used
+     * passwords are not stored in the pwdHistory attribute and thus may be reused.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#minLength} - When quality checking is enabled, this attribute holds the minimum
+     * number of characters that must be used in a password.  If this
+     * attribute is not present, no minimum password length will be
+     * enforced.  If the server is unable to check the length (due to a
+     * hashed password or otherwise), the server will, depending on the
+     * value of the pwdCheckQuality attribute, either accept the password
+     * without checking it ('0' or '1') or refuse it ('2').</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#expireWarning} - This attribute specifies the maximum number of seconds before a
+     * password is due to expire that expiration warning messages will be
+     * returned to an authenticating user.  If this attribute is not present, or if the value is 0 no warnings
+     * will be returned.  If not 0, the value must be smaller than the value
+     * of the pwdMaxAge attribute.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#graceLoginLimit} - This attribute specifies the number of times an expired password can
+     * be used to authenticate.  If this attribute is not present or if the
+     * value is 0, authentication will fail. </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#lockout} - This attribute indicates, when its value is "TRUE", that the password
+     * may not be used to authenticate after a specified number of
+     * consecutive failed bind attempts.  The maximum number of consecutive
+     * failed bind attempts is specified in pwdMaxFailure.  If this attribute is not present, or if the
+     * value is "FALSE", the password may be used to authenticate when the number of failed bind
+     * attempts has been reached.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#lockoutDuration} - This attribute holds the number of seconds that the password cannot
+     * be used to authenticate due to too many failed bind attempts.  If
+     * this attribute is not present, or if the value is 0 the password
+     * cannot be used to authenticate until reset by a password
+     * administrator.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#maxFailure} - This attribute specifies the number of consecutive failed bind
+     * attempts after which the password may not be used to authenticate.
+     * If this attribute is not present, or if the value is 0, this policy
+     * is not checked, and the value of pwdLockout will be ignored.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#failureCountInterval} - This attribute holds the number of seconds after which the password
+     * failures are purged from the failure counter, even though no
+     * successful authentication occurred.  If this attribute is not present, or if its value is 0, the failure
+     * counter is only reset by a successful authentication.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#mustChange} - This attribute specifies with a value of "TRUE" that users must
+     * change their passwords when they first bind to the directory after a
+     * password is set or reset by a password administrator.  If this
+     * attribute is not present, or if the value is "FALSE", users are not
+     * required to change their password upon binding after the password
+     * administrator sets or resets the password.  This attribute is not set
+     * due to any actions specified by this document, it is typically set by
+     * a password administrator after resetting a user's password.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#allowUserChange} - This attribute indicates whether users can change their own
+     * passwords, although the change operation is still subject to access
+     * control.  If this attribute is not present, a value of "TRUE" is
+     * assumed.  This attribute is intended to be used in the absence of an access control mechanism.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#safeModify} - This attribute specifies whether or not the existing password must be
+     * sent along with the new password when being changed.  If this
+     * attribute is not present, a "FALSE" value is assumed.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#checkQuality} - This attribute indicates how the password quality will be verified
+     * while being modified or added.  If this attribute is not present, or
+     * if the value is '0', quality checking will not be enforced.  A value
+     * of '1' indicates that the server will check the quality, and if the
+     * server is unable to check it (due to a hashed password or other
+     * reasons) it will be accepted.  A value of '2' indicates that the
+     * server will check the quality, and if the server is unable to verify
+     * it, it will return an error refusing the password. </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#attribute} - This holds the name of the attribute to which the password policy is
+     * applied.  For example, the password policy may be applied to the
+     * userPassword attribute </li>
+     * </ul>
+     *
+     * @param policy Object must contain {@link org.apache.directory.fortress.core.rbac.PwPolicy#name} and optionally other attributes.
+     * @throws SecurityException In the event of data validation or system error.
+     */
+    public void add(PwPolicy policy)
+        throws SecurityException;
+
+
+    /**
+     * This method will update an exiting policy entry to the POLICIES data set.  This command is valid
+     * if and only if the policy entry is already present in the POLICIES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#name} - Maps to name attribute of pwdPolicy object class being updated.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#minAge} - This attribute holds the number of seconds that must elapse between
+     * modifications to the password.  If this attribute is not present, 0
+     * seconds is assumed.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#maxAge} - This attribute holds the number of seconds after which a modified
+     * password will expire. If this attribute is not present, or if the value is 0 the password
+     * does not expire.  If not 0, the value must be greater than or equal
+     * to the value of the pwdMinAge.
+     * </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#inHistory} - This attribute specifies the maximum number of used passwords stored
+     * in the pwdHistory attribute. If this attribute is not present, or if the value is 0, used
+     * passwords are not stored in the pwdHistory attribute and thus may be reused.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#minLength} - When quality checking is enabled, this attribute holds the minimum
+     * number of characters that must be used in a password.  If this
+     * attribute is not present, no minimum password length will be
+     * enforced.  If the server is unable to check the length (due to a
+     * hashed password or otherwise), the server will, depending on the
+     * value of the pwdCheckQuality attribute, either accept the password
+     * without checking it ('0' or '1') or refuse it ('2').</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#expireWarning} - This attribute specifies the maximum number of seconds before a
+     * password is due to expire that expiration warning messages will be
+     * returned to an authenticating user.  If this attribute is not present, or if the value is 0 no warnings
+     * will be returned.  If not 0, the value must be smaller than the value
+     * of the pwdMaxAge attribute.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#graceLoginLimit} - This attribute specifies the number of times an expired password can
+     * be used to authenticate.  If this attribute is not present or if the
+     * value is 0, authentication will fail. </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#lockout} - This attribute indicates, when its value is "TRUE", that the password
+     * may not be used to authenticate after a specified number of
+     * consecutive failed bind attempts.  The maximum number of consecutive
+     * failed bind attempts is specified in pwdMaxFailure.  If this attribute is not present, or if the
+     * value is "FALSE", the password may be used to authenticate when the number of failed bind
+     * attempts has been reached.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#lockoutDuration} - This attribute holds the number of seconds that the password cannot
+     * be used to authenticate due to too many failed bind attempts.  If
+     * this attribute is not present, or if the value is 0 the password
+     * cannot be used to authenticate until reset by a password
+     * administrator.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#maxFailure} - This attribute specifies the number of consecutive failed bind
+     * attempts after which the password may not be used to authenticate.
+     * If this attribute is not present, or if the value is 0, this policy
+     * is not checked, and the value of pwdLockout will be ignored.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#failureCountInterval} - This attribute holds the number of seconds after which the password
+     * failures are purged from the failure counter, even though no
+     * successful authentication occurred.  If this attribute is not present, or if its value is 0, the failure
+     * counter is only reset by a successful authentication.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#mustChange} - This attribute specifies with a value of "TRUE" that users must
+     * change their passwords when they first bind to the directory after a
+     * password is set or reset by a password administrator.  If this
+     * attribute is not present, or if the value is "FALSE", users are not
+     * required to change their password upon binding after the password
+     * administrator sets or resets the password.  This attribute is not set
+     * due to any actions specified by this document, it is typically set by
+     * a password administrator after resetting a user's password.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#allowUserChange} - This attribute indicates whether users can change their own
+     * passwords, although the change operation is still subject to access
+     * control.  If this attribute is not present, a value of "TRUE" is
+     * assumed.  This attribute is intended to be used in the absence of an access control mechanism.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#safeModify} - This attribute specifies whether or not the existing password must be
+     * sent along with the new password when being changed.  If this
+     * attribute is not present, a "FALSE" value is assumed.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#checkQuality} - This attribute indicates how the password quality will be verified
+     * while being modified or added.  If this attribute is not present, or
+     * if the value is '0', quality checking will not be enforced.  A value
+     * of '1' indicates that the server will check the quality, and if the
+     * server is unable to check it (due to a hashed password or other
+     * reasons) it will be accepted.  A value of '2' indicates that the
+     * server will check the quality, and if the server is unable to verify
+     * it, it will return an error refusing the password. </li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#attribute} - This holds the name of the attribute to which the password policy is
+     * applied.  For example, the password policy may be applied to the
+     * userPassword attribute </li>
+     * </ul>
+     *
+     * @param policy Object must contain {@link org.apache.directory.fortress.core.rbac.PwPolicy#name} and optionally all non-null attributes will be updated.  null attributes will be ignored.
+     * @throws SecurityException In the event policy not found , data validation or system error.
+     */
+    public void update(PwPolicy policy)
+        throws SecurityException;
+
+
+    /**
+     * This method will delete exiting policy entry from the POLICIES data set.  This command is valid
+     * if and only if the policy entry is already present in the POLICIES data set.  Existing users that
+     * are assigned this policy will be removed from association.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#name} - Maps to name attribute of pwdPolicy object class being removed.</li>
+     * </ul>
+     *
+     * @param policy Object must contain {@link org.apache.directory.fortress.core.rbac.PwPolicy#name} of the policy entity to remove.
+     * @throws SecurityException In the event policy entity not found or system error.
+     */
+    public void delete(PwPolicy policy)
+        throws SecurityException;
+
+
+    /**
+     * This method will return the password policy entity to the caller.  This command is valid
+     * if and only if the policy entry is present in the POLICIES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PwPolicy#name} - Maps to name attribute of pwdPolicy object class being read.</li>
+     * </ul>
+     *
+     * @param name String contains the {@link org.apache.directory.fortress.core.rbac.PwPolicy#name} of the policy entity to read.
+     * @return PswdPolicy entity returns fully populated with attributes.
+     * @throws SecurityException In the event policy entry not found, data validation or system error.
+     */
+    public PwPolicy read(String name)
+        throws SecurityException;
+
+
+    /**
+     * This method will return a list of all password policy entities that match a particular search string.
+     * This command will return an empty list of no matching entries are found.
+     *
+     * @param searchVal String contains the leading chars of a policy entity.  This search is not case sensitive.
+     * @return List<PswdPolicy> contains all matching password policy entities. If no records found this will be empty.
+     * @throws SecurityException In the event of data validation or system error.
+     */
+    public List<PwPolicy> search(String searchVal)
+        throws SecurityException;
+
+
+    /**
+     * This method will associate a user entity with a password policy entity.  This function is valid
+     * if and only if the user is a member of the USERS data set and the policyName refers to a
+     * policy that is a member of the PWPOLICIES data set.
+     *
+     * @param userId     Contains {@link org.apache.directory.fortress.core.rbac.User#userId} of a User entity in USERS data set.
+     * @param policyName String contains the {@link org.apache.directory.fortress.core.rbac.PwPolicy#name} of a pw policy entity contained within the PWPOLICIES data set.
+     * @throws SecurityException thrown in the event either user or policy not valid or system error.
+     */
+    public void updateUserPolicy(String userId, String policyName)
+        throws SecurityException;
+
+
+    /**
+     * This method will remove the pw policy assignment from a user entity.  This function is valid
+     * if and only if the user is a member of the USERS data set and the policy attribute is assigned.
+     * Removal of pw policy assignment will revert the user's policy to use the global default for OpenLDAP
+     * instance that contains user.
+     *
+     * @param userId Contains {@link org.apache.directory.fortress.core.rbac.User#userId} of a User entity in USERS data set.
+     * @throws SecurityException Thrown in the event either user not valid or system error.
+     */
+    public void deletePasswordPolicy(String userId)
+        throws SecurityException;
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/PwPolicyMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/PwPolicyMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/PwPolicyMgrFactory.java
new file mode 100755
index 0000000..d432df1
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/PwPolicyMgrFactory.java
@@ -0,0 +1,112 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.rbac.PwPolicyMgrImpl;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rest.PwPolicyMgrRestImpl;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Creates an instance of the PwPolicyMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link PwPolicyMgrImpl} but can be overridden by
+ * adding the {@link GlobalIds#PSWD_POLICY_IMPLEMENTATION} config property.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class PwPolicyMgrFactory
+{
+    private static String policyClassName = Config.getProperty(GlobalIds.PSWD_POLICY_IMPLEMENTATION);
+    private static final String CLS_NM = PwPolicyMgrFactory.class.getName();
+
+    /**
+     * Create and return a reference to {@link PwPolicyMgr} object using HOME context.
+     *
+     * @return instance of {@link PwPolicyMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static PwPolicyMgr createInstance()
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME );
+    }
+
+    /**
+     * Create and return a reference to {@link PwPolicyMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return instance of {@link PwPolicyMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static PwPolicyMgr createInstance(String contextId)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance");
+        if (!VUtil.isNotNullOrEmpty(policyClassName))
+        {
+            if(GlobalIds.IS_REST)
+            {
+                policyClassName = PwPolicyMgrRestImpl.class.getName();
+            }
+            else
+            {
+                policyClassName = PwPolicyMgrImpl.class.getName();
+            }
+        }
+
+        PwPolicyMgr policyMgr = (PwPolicyMgr) ClassUtil.createInstance(policyClassName);
+        policyMgr.setContextId(contextId);
+        return policyMgr;
+    }
+
+    /**
+     * Create and return a reference to {@link PwPolicyMgr} object using HOME context.
+     *
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link PwPolicyMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static PwPolicyMgr createInstance(Session adminSess)
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME, adminSess );
+    }
+
+    /**
+     * Create and return a reference to {@link PwPolicyMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link PwPolicyMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static PwPolicyMgr createInstance(String contextId, Session adminSess)
+        throws SecurityException
+    {
+        PwPolicyMgr policyMgr = createInstance(contextId);
+        policyMgr.setAdmin(adminSess);
+        return policyMgr;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/RemoveException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/RemoveException.java b/src/main/java/org/apache/directory/fortress/core/RemoveException.java
new file mode 100755
index 0000000..c16ca4f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/RemoveException.java
@@ -0,0 +1,52 @@
+/*
+ *   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;
+
+/**
+ * This exception extends {@link SecurityException} and is thrown when DAO cannot delete entity.
+ * See the {@link GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+public class RemoveException extends SecurityException
+{
+    /**
+     * Create an exception with an error code that maps to {@link GlobalErrIds} and message text.
+     *
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     */
+    public RemoveException(int errorId, String msg)
+    {
+        super(errorId, msg);
+    }
+
+    /**
+     * Create exception with error id, message and related exception.
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     * @param previousException contains reference to related exception which usually is system related, i.e. ldap.
+     */
+    public RemoveException(int errorId, String msg, Exception previousException)
+    {
+        super(errorId, msg, previousException);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/RestException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/RestException.java b/src/main/java/org/apache/directory/fortress/core/RestException.java
new file mode 100644
index 0000000..e6b3a69
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/RestException.java
@@ -0,0 +1,52 @@
+/*
+ *   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;
+
+
+/**
+ * This exception extends {@link SecurityException} and is thrown when Fortress cannot call En Masse to perform a particular operation via RESTful interface.
+ * See the {@link GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+public class RestException extends SecurityException
+{
+
+    /**
+     * Create an exception with an error code that maps to {@link GlobalErrIds} and message text.
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     */
+    public RestException(int errorId, String msg)
+    {
+        super(errorId, msg);
+    }
+
+    /**
+     * Create exception with error id, message and related exception.
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     * @param previousException contains reference to related exception which usually is system related, i.e. ldap.
+     */
+    public RestException(int errorId, String msg, Exception previousException)
+    {
+        super(errorId, msg, previousException);
+    }
+}
\ 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/ReviewMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ReviewMgr.java b/src/main/java/org/apache/directory/fortress/core/ReviewMgr.java
new file mode 100755
index 0000000..90917c7
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ReviewMgr.java
@@ -0,0 +1,612 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.SDSet;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.UserRole;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This interface prescribes the administrative review functions on already provisioned Fortress RBAC entities
+ * that reside in LDAP directory.  These APIs map directly to similar named APIs specified by ANSI and NIST RBAC models.
+ * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
+ * The RBAC Functional specification describes administrative operations for the creation
+ * and maintenance of RBAC element sets and relations; administrative review functions for
+ * performing administrative queries; and system functions for creating and managing
+ * RBAC attributes on user sessions and making access control decisions.
+ * <p/>
+ * <hr>
+ * <h4>RBAC0 - Core</h4>
+ * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
+ * <p/>
+ * <img src="./doc-files/RbacCore.png">
+ * <hr>
+ * <h4>RBAC1 - General Hierarchical Roles</h4>
+ * Simplifies role engineering tasks using inheritance of one or more parent roles.
+ * <p/>
+ * <img src="./doc-files/RbacHier.png">
+ * <hr>
+ * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+ * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
+ * <p/>
+ * <img src="./doc-files/RbacSSD.png">
+ * <hr>
+ * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+ * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+ * <p/>
+ * <img src="./doc-files/RbacDSD.png">
+ * <hr>
+ * <p/>
+ * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.apache.directory.fortress.core.rbac.Session)}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public interface ReviewMgr extends Manageable
+{
+
+    /**
+     * This method returns a matching permission entity to caller.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param permission must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return Permission entity that is loaded with data.
+     * @throws SecurityException
+     *          if permission not found or system error occurs.
+     */
+    public Permission readPermission(Permission permission)
+        throws SecurityException;
+
+    /**
+     * Method reads permission object from perm container in directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param permObj entity contains the {@link PermObj#objName} of target record.
+     * @return PermObj loaded with perm object data.
+     * @throws SecurityException is thrown if object not found or system error.
+     */
+    public PermObj readPermObj(PermObj permObj)
+        throws SecurityException;
+
+    /**
+     * Method returns a list of type Permission that match the perm object search string.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains one or more characters of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains one or more characters of existing permission operation</li>
+     * </ul>
+     *
+     * @param permission contains object and operation name search strings.  Each contains 1 or more leading chars that correspond to object or op name.
+     * @return List of type Permission.  Fortress permissions are object->operation mappings.  The permissions may contain
+     *         assigned user, role or group entities as well.
+     * @throws SecurityException
+     *          thrown in the event of system error.
+     */
+    public List<Permission> findPermissions(Permission permission)
+        throws SecurityException;
+
+
+    /**
+     * Method returns a list of type PermObj that match the perm object search string.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains one or more characters of existing object being targeted</li>
+     * </ul>
+     *
+     * @param permObj contains object name search string.  The search val contains 1 or more leading chars that correspond to object name.
+     * @return List of type PermObj.  Fortress permissions are object->operation mappings.
+     * @throws SecurityException thrown in the event of system error.
+     */
+    public List<PermObj> findPermObjs(PermObj permObj)
+        throws SecurityException;
+
+
+    /**
+     * Method returns a list of type Permission that match the perm object search string.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link OrgUnit#name} - contains one or more characters of org unit associated with existing object being targeted</li>
+     * </ul>
+     *
+     * @param ou contains org unit name {@link org.apache.directory.fortress.core.rbac.OrgUnit#name}.  The search val contains the full name of matching ou in OS-P data set.
+     * @return List of type PermObj.  Fortress permissions are object->operation mappings.
+     * @throws SecurityException
+     *          thrown in the event of system error.
+     */
+    public List<PermObj> findPermObjs(OrgUnit ou)
+        throws SecurityException;
+
+
+    /**
+     * Method reads Role entity from the role container in directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role to read.</li>
+     * </ul>
+     *
+     * @param role contains role name, {@link Role#name}, to be read.
+     * @return Role entity that corresponds with role name.
+     * @throws SecurityException
+     *          will be thrown if role not found or system error occurs.
+     */
+    public Role readRole(Role role)
+        throws SecurityException;
+
+
+    /**
+     * Method will return a list of type Role matching all or part of Role name, {@link Role#name}.
+     *
+     * @param searchVal contains all or some of the chars corresponding to role entities stored in directory.
+     * @return List of type Role containing role entities that match the search criteria.
+     * @throws SecurityException in the event of system error.
+     */
+    public List<Role> findRoles(String searchVal)
+        throws SecurityException;
+
+
+    /**
+     * Method returns a list of roles of type String.  This method can be limited by integer value that indicates max
+     * number of records that may be contained in the result set.  This number can further limit global default but can
+     * not increase the max.  This method is called by the Websphere Realm impl.
+     *
+     * @param searchVal contains all or some leading chars that correspond to roles stored in the role container in the directory.
+     * @param limit     integer value specifies the max records that may be returned in the result set.
+     * @return List of type String containing matching Role names.
+     * @throws SecurityException
+     *          in the event of system error.
+     */
+    public List<String> findRoles(String searchVal, int limit)
+        throws SecurityException;
+
+
+    /**
+     * Method returns matching User entity that is contained within the people container in the directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for read.</li>
+     * </ul>
+     *
+     * @param user entity contains a value {@link User#userId} that matches record in the directory.  userId is globally unique in
+     *             people container.
+     * @return entity containing matching user data.
+     * @throws SecurityException if record not found or system error occurs.
+     */
+    public User readUser(User user)
+        throws SecurityException;
+
+
+    /**
+     * Return a list of type User of all users in the people container that match all or part of the {@link User#userId} field passed in User entity.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains all or some leading chars that match userId(s) stored in the directory.</li>
+     * </ul>
+     *
+     * @param user contains all or some leading chars that match userIds stored in the directory.
+     * @return List of type User.
+     * @throws SecurityException In the event of system error.
+     */
+    public List<User> findUsers(User user)
+        throws SecurityException;
+
+
+    /**
+     * Return a list of type User of all users in the people container that match the name field passed in OrgUnit entity.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link OrgUnit#name} - contains one or more characters of org unit associated with existing object(s) being targeted</li>
+     * </ul>
+     *
+     * @param ou contains name of User OU, {@link OrgUnit#name} that match ou attribute associated with User entity in the directory.
+     * @return List of type User.
+     * @throws SecurityException
+     *          In the event of system error.
+     */
+    public List<User> findUsers(OrgUnit ou)
+        throws SecurityException;
+
+
+    /**
+     * Return a list of type String of all users in the people container that match the userId field passed in User entity.
+     * This method is used by the Websphere realm component.  The max number of returned users may be set by the integer limit arg.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for read.</li>
+     * <li>limit - max number of objects to return.</li>
+     * </ul>
+     *
+     * @param user  contains all or some leading chars that correspond to users stored in the directory.
+     * @param limit integer value sets the max returned records.
+     * @return List of type String containing matching userIds.
+     * @throws SecurityException in the event of system error.
+     */
+    public List<String> findUsers(User user, int limit)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the set of users assigned to a given role. The function is valid if and
+     * only if the role is a member of the ROLES data set.
+     * The max number of users returned is constrained by limit argument.
+     * This method is used by the Websphere realm component.  This method does NOT use hierarchical rbac.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * <li>limit - max number of objects to return.</li>
+     * </ul>
+     *
+     * @param role  Contains {@link Role#name} of Role entity assigned to user.
+     * @param limit integer value sets the max returned records.
+     * @return List of type String containing userIds assigned to a particular role.
+     * @throws SecurityException
+     *          in the event of data validation or system error.
+     */
+    public List<String> assignedUsers(Role role, int limit)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the set of roles assigned to a given user. The function is valid if and
+     * only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains {@link User#userId} matching User entity targeted in the directory.
+     * @return List of type UserRole containing the Roles assigned to User.
+     * @throws SecurityException
+     *          If user not found or system error occurs.
+     */
+    public List<UserRole> assignedRoles(User user)
+        throws SecurityException;
+
+    /**
+     * This method returns the data set of all users who are assigned the given role.  This searches the User data set for
+     * Role relationship.  This method does NOT search for hierarchical RBAC Roles relationships.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role contains the role name, {@link Role#name} used to search the User data set.
+     * @return List of type User containing the users assigned data.
+     * @throws SecurityException
+     *          If system error occurs.
+     */
+    public List<User> assignedUsers(Role role)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the set of roles assigned to a given user. The function is valid if and
+     * only if the user is a member of the USERS data set.
+     *
+     * @param userId matches userId stored in the directory.
+     * @return List of type String containing the role names of all roles assigned to user.
+     * @throws SecurityException
+     *          If user not found or system error occurs.
+     */
+    public List<String> assignedRoles(String userId)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the set of users authorized to a given role, i.e., the users that are assigned to a role that
+     * inherits the given role. The function is valid if and only if the given role is a member of the ROLES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role Contains role name, {@link Role#name} of Role entity assigned to User.
+     * @return List of type User containing all user's that having matching role assignment.
+     * @throws SecurityException
+     *          In the event the role is not present in directory or system error occurs.
+     */
+    public List<User> authorizedUsers(Role role)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the set of roles authorized for a given user. The function is valid if
+     * and only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains the {@link User#userId} matching User entity stored in the directory.
+     * @return Set of type String containing the roles assigned and roles inherited.
+     * @throws SecurityException If user not found or system error occurs.
+     */
+    public Set<String> authorizedRoles(User user)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the set of all permissions (op, obj), granted to or inherited by a
+     * given role. The function is valid if and only if the role is a member of the ROLES data
+     * set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role contains role name, {@link Role#name} of Role entity Permission is granted to.
+     * @return List of type Permission that contains all perms granted to a role.
+     * @throws SecurityException
+     *          In the event system error occurs.
+     */
+    public List<Permission> rolePermissions(Role role)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the set of permissions a given user gets through his/her authorized
+     * roles. The function is valid if and only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains the {@link User#userId} of User targeted for search.
+     * @return List of type Permission containing matching permission entities.
+     * @throws SecurityException
+     *          in the event of validation or system error.
+     */
+    public List<Permission> userPermissions(User user)
+        throws SecurityException;
+
+
+    /**
+     * Return a list of type String of all roles that have granted a particular permission.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return List of type string containing the Role names that have the matching perm granted.
+     * @throws SecurityException in the event permission not found or system error occurs.
+     */
+    public List<String> permissionRoles(Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * Return all role names that have been authorized for a given permission.  This will process role hierarchies to determine set of all Roles who have access to a given permission.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return Set of type String containing all roles names that have been granted a particular permission.
+     * @throws SecurityException
+     *          in the event of validation or system error.
+     */
+    public Set<String> authorizedPermissionRoles(Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * Return all userIds that have been granted (directly) a particular permission.  This will not consider assigned or authorized Roles.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return List of type String containing all userIds that have been granted a particular permission.
+     * @throws SecurityException
+     *          in the event of validation or system error.
+     */
+    public List<String> permissionUsers(Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * Return all userIds that have been authorized for a given permission.  This will process role hierarchies to determine set of all Users who have access to a given permission.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return Set of type String containing all userIds that have been granted a particular permission.
+     * @throws SecurityException
+     *          in the event of validation or system error.
+     */
+    public Set<String> authorizedPermissionUsers(Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the list of all SSD role sets that have a particular Role as member or Role's
+     * parent as a member.  If the Role parameter is left blank, function will return all SSD role sets.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role Will contain the role name, {@link Role#name}, for targeted SSD set or null to return all
+     * @return List containing all matching SSD's.
+     * @throws SecurityException
+     *          in the event of data or system error.
+     */
+    public List<SDSet> ssdRoleSets(Role role)
+        throws SecurityException;
+
+    /**
+     * This function returns the SSD data set that matches a particular set name.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param set Will contain the name for existing SSD data set, {@link SDSet#name}.
+     * @return SDSet containing all attributes from matching SSD name.
+     * @throws SecurityException
+     *          in the event of data or system error.
+     */
+    public SDSet ssdRoleSet(SDSet set)
+        throws SecurityException;
+
+    /**
+     * This function returns the list of SSDs that match a given ssd name value.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param ssd contains the name for the SSD set targeted, {@link SDSet#name}.
+     * @return List containing all SSDSets that match a given SSDSet name.
+     * @throws SecurityException in the event of data or system error.
+     */
+    public List<SDSet> ssdSets(SDSet ssd)
+        throws SecurityException;
+
+    /**
+     * This function returns the set of roles of a SSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param ssd contains the name for the SSD set targeted, {@link SDSet#name}.
+     * @return Set containing all Roles that are members of SSD data set.
+     * @throws SecurityException in the event of data or system error.
+     */
+    public Set<String> ssdRoleSetRoles(SDSet ssd)
+        throws SecurityException;
+
+    /**
+     * This function returns the cardinality associated with a SSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param ssd contains the name of the SSD set targeted, {@link SDSet#name}.
+     * @return int value containing cardinality of SSD set.
+     * @throws SecurityException in the event of data or system error.
+     */
+    public int ssdRoleSetCardinality(SDSet ssd)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the list of all dSD role sets that have a particular Role as member or Role's
+     * parent as a member.  If the Role parameter is left blank, function will return all dSD role sets.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role Will contain the role name, {@link Role#name}, for targeted dSD set or null to return all
+     * @return List containing all matching dSD's.
+     * @throws SecurityException
+     *          in the event of data or system error.
+     */
+    public List<SDSet> dsdRoleSets(Role role)
+        throws SecurityException;
+
+    /**
+     * This function returns the DSD data set that matches a particular set name.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param set Will contain the name for existing DSD data set, {@link SDSet#name}.
+     * @return SDSet containing all attributes from matching DSD name.
+     * @throws SecurityException
+     *          in the event of data or system error.
+     */
+    public SDSet dsdRoleSet(SDSet set)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the list of DSDs that match a given dsd name value.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param dsd contains the name for the DSD set targeted, {@link SDSet#name}.
+     * @return List containing all DSDSets that match a given DSDSet name.
+     * @throws SecurityException in the event of data or system error.
+     */
+    public List<SDSet> dsdSets(SDSet dsd)
+        throws SecurityException;
+
+    /**
+     * This function returns the set of roles of a DSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param dsd contains the name for the DSD set targeted, {@link SDSet#name}.
+     * @return Set containing all Roles that are members of DSD data set.
+     * @throws SecurityException
+     *          in the event of data or system error.
+     */
+    public Set<String> dsdRoleSetRoles(SDSet dsd)
+        throws SecurityException;
+
+    /**
+     * This function returns the cardinality associated with a DSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param dsd contains the name of the DSD set targeted, {@link SDSet#name}.
+     * @return int value containing cardinality of DSD set.
+     * @throws SecurityException in the event of data or system error.
+     */
+    public int dsdRoleSetCardinality(SDSet dsd)
+        throws SecurityException;
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ReviewMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ReviewMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/ReviewMgrFactory.java
new file mode 100755
index 0000000..95baef6
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ReviewMgrFactory.java
@@ -0,0 +1,112 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.rbac.ReviewMgrImpl;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rest.ReviewMgrRestImpl;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Creates an instance of the ReviewMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link ReviewMgrImpl} but can be overridden by
+ * adding the {@link GlobalIds#REVIEW_IMPLEMENTATION} config property.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class ReviewMgrFactory
+{
+    private static String reviewClassName = Config.getProperty(GlobalIds.REVIEW_IMPLEMENTATION);
+    private static final String CLS_NM = ReviewMgrFactory.class.getName();
+
+    /**
+     * Create and return a reference to {@link ReviewMgr} object using HOME context.
+     *
+     * @return instance of {@link ReviewMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static ReviewMgr createInstance()
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME );
+    }
+
+    /**
+     * Create and return a reference to {@link ReviewMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return instance of {@link ReviewMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static ReviewMgr createInstance(String contextId)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance");
+        if (!VUtil.isNotNullOrEmpty(reviewClassName))
+        {
+            if(GlobalIds.IS_REST)
+            {
+                reviewClassName = ReviewMgrRestImpl.class.getName();
+            }
+            else
+            {
+                reviewClassName = ReviewMgrImpl.class.getName();
+            }
+        }
+
+        ReviewMgr reviewMgr = ( ReviewMgr ) ClassUtil.createInstance(reviewClassName);
+        reviewMgr.setContextId(contextId);
+        return reviewMgr;
+    }
+
+    /**
+     * Create and return a reference to {@link ReviewMgr} object using HOME context.
+     *
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link ReviewMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static ReviewMgr createInstance(Session adminSess)
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME, adminSess );
+    }
+
+    /**
+     * Create and return a reference to {@link ReviewMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @param adminSess contains a valid Fortress A/RBAC Session object.
+     * @return instance of {@link ReviewMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static ReviewMgr createInstance(String contextId, Session adminSess)
+        throws SecurityException
+    {
+        ReviewMgr reviewMgr = createInstance(contextId);
+        reviewMgr.setAdmin(adminSess);
+        return reviewMgr;
+    }
+}
+


[46/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/FinderException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/FinderException.java b/src/main/java/org/apache/directory/fortress/core/FinderException.java
new file mode 100755
index 0000000..bafeba5
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/FinderException.java
@@ -0,0 +1,53 @@
+/*
+ *   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;
+
+
+/**
+ * This exception extends {@link SecurityException} and is thrown when DAO cannot find entity.
+ * See the {@link GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+public class FinderException extends SecurityException
+{
+    /**
+     * Create an exception with an error code that maps to {@link GlobalErrIds} and message text.
+     *
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     */
+    public FinderException(int errorId, String msg)
+    {
+        super(errorId, msg);
+    }
+
+    /**
+     * Create exception with error id, message and related exception.
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     * @param previousException contains reference to related exception which usually is system related, i.e. ldap.
+     */
+    public FinderException(int errorId, String msg, Exception previousException)
+    {
+        super(errorId, msg, previousException);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/GlobalErrIds.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/GlobalErrIds.java b/src/main/java/org/apache/directory/fortress/core/GlobalErrIds.java
new file mode 100755
index 0000000..bbafa03
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/GlobalErrIds.java
@@ -0,0 +1,1639 @@
+/*
+ *   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;
+
+/**
+ * This module contains error identifiers that are used when exception need be thrown.
+ * The Fortress Manager APIs declare {@code SecurityException} as thrown even though the child exception may vary according to type:
+ * <ul>
+ * <li>{@link CfgException} in the event the cfg of runtime fails.
+ * <li>{@link CreateException} in the event DAO cannot create entity.
+ * <li>{@link FinderException} in the event DAO cannot find the entity.
+ * <li>{@link PasswordException} in the event user fails password checks.
+ * <li>{@link RemoveException} in the event DAO cannot remove entity.
+ * <li>{@link SecurityException} in the event security check fails.
+ * <li>{@link UpdateException} in the event DAO cannot update entity.
+ * <li>{@link ValidationException} in the event entity validation fails.
+ * </ul>
+ * <p/>
+ * All Fortress public Manager Impl APIs will throw exception derived from {@link SecurityException} and containing
+ * an id that maps to one of these error codes.
+ *
+ * @author Shawn McKinney
+ */
+public class GlobalErrIds
+{
+    /**
+     * Group 1 - Configuration Errors:
+     */
+
+    /**
+     * The supplied context is required but was null or empty.
+     */
+    public final static int CONTEXT_NULL = 101;
+
+    /**
+     * The Manager impl could not be instantiated because the supplied class name was not found.
+     */
+    public final static int FT_MGR_CLASS_NOT_FOUND = 103;
+
+    /**
+     * The reflection API could not create the Manager instance due to instantiation exception.
+     */
+    public final static int FT_MGR_INST_EXCEPTION = 104;
+
+    /**
+     * The reflection API could not create the Manager instance due to illegal access exception.
+     */
+    public final static int FT_MGR_ILLEGAL_ACCESS = 105;
+
+    /**
+     * The Manager impl class name was not found in the cfg.
+     */
+    public final static int FT_MGR_CLASS_NAME_NULL = 106;
+
+    /**
+     * The remote cfg instance could not be found on the ldap server.
+     */
+    public final static int FT_CONFIG_NOT_FOUND = 107;
+
+    /**
+     * The cfg node name was not found in cfg file.
+     */
+    public final static int FT_CONFIG_NAME_NULL = 108;
+
+    /**
+     * The name specified for config instance is too long.  Check to ensure length is less than {@link GlobalIds#OU_LEN}.
+     */
+    public final static int FT_CONFIG_NAME_INVLD = 109;
+
+    /**
+     * The config API was called with an empty properties list.
+     */
+    public final static int FT_CONFIG_PROPS_NULL = 110;
+
+    /**
+     * The config node could not be created on ldap server.
+     */
+    public final static int FT_CONFIG_CREATE_FAILED = 120;
+
+    /**
+     * The config node could not be updated on ldap server.
+     */
+    public final static int FT_CONFIG_UPDATE_FAILED = 121;
+
+    /**
+     * The config node could not be removed from ldap.
+     */
+    public final static int FT_CONFIG_DELETE_FAILED = 122;
+
+    /**
+     * The config parameters could not be removed from ldap.
+     */
+    public final static int FT_CONFIG_DELETE_PROPS_FAILED = 123;
+
+    /**
+     * The config node could not be read from ldap.
+     */
+    public final static int FT_CONFIG_READ_FAILED = 124;
+
+    /**
+     * The config node could not be created because it already exists.
+     */
+    public final static int FT_CONFIG_ALREADY_EXISTS = 125;
+
+    /**
+     * The config node could not be read from ldap.
+     */
+    public final static int FT_CONFIG_BOOTSTRAP_FAILED = 126;
+
+    /**
+     * The config node could not be read from ldap.
+     */
+    public final static int FT_CONFIG_INITIALIZE_FAILED = 127;
+
+    /**
+     * The resource could not be located on the runtime classloader path.
+     */
+    public final static int FT_RESOURCE_NOT_FOUND = 128;
+
+    /**
+     * The Fortress cache is not configured.
+     */
+    public final static int FT_CACHE_NOT_CONFIGURED = 129;
+
+    /**
+     * The Fortress cache get operation failed.
+     */
+    public final static int FT_CACHE_GET_ERR = 130;
+
+    /**
+     * The Fortress cache put operation failed.
+     */
+    public final static int FT_CACHE_PUT_ERR = 131;
+
+    /**
+     * The Fortress cache clear operation failed.
+     */
+    public final static int FT_CACHE_CLEAR_ERR = 132;
+
+    /**
+     * The Fortress cache flush operation failed.
+     */
+    public final static int FT_CACHE_FLUSH_ERR = 133;
+
+    /**
+     * The Fortress cache is null.
+     */
+    public final static int FT_NULL_CACHE = 134;
+
+    /**
+     * Could not initialize Apache LDAP Connection Pool.
+     */
+    public final static int FT_APACHE_LDAP_POOL_INIT_FAILED = 135;
+
+    /**
+     * Cannot load JSSE TrustStore because the full-qualified input file name is null.
+     */
+    public final static int FT_CONFIG_JSSE_TRUSTSTORE_NULL = 136;
+
+    /**
+     * 1000's - User Entity Rule and LDAP Errors
+     */
+
+    /**
+     * The User node could not be searched in ldap.
+     */
+    public final static int USER_SEARCH_FAILED = 1000;
+
+    /**
+     * The User node could not be read from ldap.
+     */
+    public final static int USER_READ_FAILED = 1001;
+
+    /**
+     * The User node could not be added to ldap.
+     */
+    public final static int USER_ADD_FAILED = 1002;
+
+    /**
+     * The User node could not be updated in ldap.
+     */
+    public final static int USER_UPDATE_FAILED = 1003;
+
+    /**
+     * The User node could not be deleted from ldap.
+     */
+    public final static int USER_DELETE_FAILED = 1004;
+
+    /**
+     * The User node was not found in ldap.
+     */
+    public final static int USER_NOT_FOUND = 1005;
+
+    /**
+     * The supplied userId was null and is required for this operation.
+     */
+    public final static int USER_ID_NULL = 1006;
+
+    /**
+     * The User could not be added because it already exists in ldap.
+     */
+    public final static int USER_ID_DUPLICATE = 1007;
+
+    /**
+     * The operation failed because the supplied User entity is null and is required.
+     */
+    public final static int USER_NULL = 1008;
+
+    /**
+     * The operation failed because the supplied User's password is required but was found to be null.
+     */
+    public final static int USER_PW_NULL = 1009;
+
+    /**
+     * The operation failed because the supplied User password is too long.  Ensure the length does not exceed {@link GlobalIds#PASSWORD_LEN}.
+     */
+    public final static int USER_PW_INVLD_LEN = 1010;
+
+    /**
+     * The operation failed because of policy violation due to being designated a 'system' user..
+     */
+    public final static int USER_PLCY_VIOLATION = 1011;
+
+    /**
+     * The PW Policy node could not be removed from ldap.
+     */
+    public final static int USER_PW_PLCY_DEL_FAILED = 1012;
+
+    /**
+     * The supplied User password was invalid.
+     */
+    public final static int USER_PW_INVLD = 1013;
+
+    /**
+     * The User password check failed in ldap.
+     */
+    public final static int USER_PW_CHK_FAILED = 1014;
+
+    /**
+     * The User's password is in reset state which requires change.
+     */
+    public final static int USER_PW_RESET = 1015;
+
+    /**
+     * Authentication failed because User's password has been locked on the server.
+     */
+    public final static int USER_PW_LOCKED = 1016;
+
+    /**
+     * Authentication failed because User's password is expired on the server.
+     */
+    public final static int USER_PW_EXPIRED = 1017;
+
+    /**
+     * The password change failed because User is not allowed to change password.
+     */
+    public final static int USER_PW_MOD_NOT_ALLOWED = 1018;
+
+    /**
+     * The password change failed because User did not supply old password.
+     */
+    public final static int USER_PW_MUST_SUPPLY_OLD = 1019;
+
+    /**
+     * The password change failed because supplied password is not of sufficient quality.
+     */
+    public final static int USER_PW_NSF_QUALITY = 1020;
+
+    /**
+     * The password change failed because supplied User password was too short.
+     */
+    public final static int USER_PW_TOO_SHORT = 1021;
+
+    /**
+     * The password change failed because the supplied User password is too young.
+     */
+    public final static int USER_PW_TOO_YOUNG = 1022;
+
+    /**
+     * The password change failed because supplied User password was found in history.
+     */
+    public final static int USER_PW_IN_HISTORY = 1023;
+
+    /**
+     * The password unlock operation failed on the server.
+     */
+    public final static int USER_PW_UNLOCK_FAILED = 1024;
+
+    /**
+     * The password lock operation failed on the server.
+     */
+    public final static int USER_PW_LOCK_FAILED = 1025;
+
+    /**
+     * The password change failed on the server.
+     */
+    public final static int USER_PW_CHANGE_FAILED = 1026;
+
+    /**
+     * The reset password operation failed on the server.
+     */
+    public final static int USER_PW_RESET_FAILED = 1027;
+
+    /**
+     * The User has been prevented to logon due to Fortress Constraints.
+     */
+    public final static int USER_LOCKED_BY_CONST = 1028;
+
+    /**
+     * The User session could not be created.
+     */
+    public final static int USER_SESS_CREATE_FAILED = 1029;
+
+    /**
+     * The required User Session was not supplied and is required.
+     */
+    public final static int USER_SESS_NULL = 1030;
+
+    /**
+     * The logged on administrator is not authorized to perform the function.
+     */
+    public final static int USER_ADMIN_NOT_AUTHORIZED = 1031;
+
+    /**
+     * The common name was not supplied but is required.
+     */
+    public final static int USER_CN_NULL = 1032;
+
+    /**
+     * The surname was not supplied but is required.
+     */
+    public final static int USER_SN_NULL = 1033;
+
+    /**
+     * The policy name supplied for User was not found on server.
+     */
+    public final static int USER_PW_PLCY_INVALID = 1034;
+
+    /**
+     * The User ou name supplied for User was not found on server.
+     */
+    public final static int USER_OU_INVALID = 1035;
+
+    /**
+     * The required User Session was not supplied and is required.  Used by fortress realm.
+     */
+    public final static int SESS_CTXT_NULL = 1036;
+
+    /**
+     * The User bind operation failed on server.
+     */
+    public final static int USER_BIND_FAILED = 1037;
+
+    /**
+     * 2000's User-Role assignments
+     */
+
+    /**
+     * The UserRole entity was not supplied but is required.
+     */
+    public final static int URLE_NULL = 2003;
+
+    /**
+     * The User RBAC Role assignment failed.
+     */
+    public final static int URLE_ASSIGN_FAILED = 2004;
+
+    /**
+     * The User RBAC Role deassignment failed.
+     */
+    public final static int URLE_DEASSIGN_FAILED = 2005;
+
+    /**
+     * The supplied RBAC Role could not be activated in the User's Session.
+     */
+    public final static int URLE_ACTIVATE_FAILED = 2006;
+
+    /**
+     * The supplied RBAC Role could not be deactivated from the User's session.
+     */
+    public final static int URLE_DEACTIVE_FAILED = 2007;
+
+    /**
+     * The RBAC Role could not be assigned to User already has it assigned.
+     */
+    public final static int URLE_ASSIGN_EXIST = 2008;
+
+    /**
+     * The RBAC Role could not be deassigned from User because it wasn't assigned in the first place.
+     */
+    public final static int URLE_ASSIGN_NOT_EXIST = 2009;
+
+    /**
+     * The RBAC Role search could failed on server.
+     */
+    public final static int URLE_SEARCH_FAILED = 2010;
+
+    /**
+     * The RBAC Role is already activated in User's Session.
+     */
+    public final static int URLE_ALREADY_ACTIVE = 2011;
+
+    /**
+     * The supplied RBAC Role is not activated in User's Session.
+     */
+    public final static int URLE_NOT_ACTIVE = 2022;
+
+    /**
+     * The logged on administrator cannot assign RBAC Role to User because unauthorized.
+     */
+    public final static int URLE_ADMIN_CANNOT_ASSIGN = 2023;
+
+    /**
+     * The logged on administrator cannot deassign RBAC Role to User because unauthorized.
+     */
+    public final static int URLE_ADMIN_CANNOT_DEASSIGN = 2024;
+
+    /**
+     * The logged on administrator cannot grant RBAC Role to Permission because unauthorized.
+     */
+    public final static int URLE_ADMIN_CANNOT_GRANT = 2025;
+
+    /**
+     * The logged on administrator cannot revoke RBAC Role from Permission because unauthorized.
+     */
+    public final static int URLE_ADMIN_CANNOT_REVOKE = 2026;
+
+    /**
+     * Temporal Constraint Activation Violations
+     */
+
+    /**
+     * Entity activation failed due to day validation failure.
+     */
+    public final static int ACTV_FAILED_DAY = 2050;
+
+    /**
+     * Entity activation failed due to date validation failure.
+     */
+    public final static int ACTV_FAILED_DATE = 2051;
+
+    /**
+     * Entity activation failed due to time validation failure.
+     */
+    public final static int ACTV_FAILED_TIME = 2052;
+
+    /**
+     * Entity activation failed due to Session timeout validation failure.
+     */
+    public final static int ACTV_FAILED_TIMEOUT = 2053;
+
+    /**
+     * Entity activation failed due to lockout date.
+     */
+    public final static int ACTV_FAILED_LOCK = 2054;
+
+    /**
+     * Entity activation failed due to Dynamic Separation of Duty restriction on Role.
+     */
+    public final static int ACTV_FAILED_DSD = 2055;
+
+    /**
+     * 3000's - Permission Entity
+     */
+
+    /**
+     * The supplied Permission could not be searched due to server failure.
+     */
+    public final static int PERM_SEARCH_FAILED = 3000;
+
+    /**
+     * The supplied Permission operation could not be read due to server failure.
+     */
+    public final static int PERM_READ_OP_FAILED = 3001;
+
+    /**
+     * The supplied Permission object could not be read due to server failure.
+     */
+    public final static int PERM_READ_OBJ_FAILED = 3002;
+
+    /**
+     * The supplied Permission could not be added to ldap server.
+     */
+    public final static int PERM_ADD_FAILED = 3003;
+
+    /**
+     * The supplied Permission could not be updated on ldap server.
+     */
+    public final static int PERM_UPDATE_FAILED = 3004;
+
+    /**
+     * The supplied Permission could not be removed from ldap server.
+     */
+    public final static int PERM_DELETE_FAILED = 3005;
+
+    /**
+     * The supplied Permission operation could not be found on ldap server.
+     */
+    public final static int PERM_OP_NOT_FOUND = 3006;
+
+    /**
+     * The supplied Permission object could not be found on ldap server.
+     */
+    public final static int PERM_OBJ_NOT_FOUND = 3007;
+
+    /**
+     * The supplied Permission entity is required but was passed as null.
+     */
+    public final static int PERM_NULL = 3008;
+
+    /**
+     * The supplied Permission operation is required but was passed as null.
+     */
+    public final static int PERM_OPERATION_NULL = 3009;
+
+    /**
+     * The supplied Permission object is required but was passed as null.
+     */
+    public final static int PERM_OBJECT_NULL = 3010;
+
+    /**
+     * The Permission could not be added because it already exists on ldap server.
+     */
+    public final static int PERM_DUPLICATE = 3011;
+
+    /**
+     * The Permission could not be granted to Role.
+     */
+    public final static int PERM_GRANT_FAILED = 3012;
+
+    /**
+     * The Permission could not be granted to User.
+     */
+    public final static int PERM_GRANT_USER_FAILED = 3013;
+
+    /**
+     * The Permission could not be revoked from Role.
+     */
+    public final static int PERM_REVOKE_FAILED = 3024;
+
+    /**
+     * The Permission has already been granted.
+     */
+    public final static int PERM_ROLE_EXIST = 3015;
+
+    /**
+     * The Permission could not be revoked because it does not exist on server.
+     */
+    public final static int PERM_ROLE_NOT_EXIST = 3016;
+
+    /**
+     * The Permission could not be granted to User because it already exists on server.
+     */
+    public final static int PERM_USER_EXIST = 3017;
+
+    /**
+     * The Permission could not be revoked from User because it does not exist on server.
+     */
+    public final static int PERM_USER_NOT_EXIST = 3018;
+
+    /**
+     * The Role-Permission search failed on server.
+     */
+    public final static int PERM_ROLE_SEARCH_FAILED = 3019;
+
+    /**
+     * The User-Permission search failed on ldap server.
+     */
+    public final static int PERM_USER_SEARCH_FAILED = 3020;
+
+    /**
+     * The search for authorized Permission failed on server.
+     */
+    public final static int PERM_SESS_SEARCH_FAILED = 3021;
+
+    /**
+     * The operation to revoke all Permissions from User failed on server.
+     */
+    public final static int PERM_BULK_USER_REVOKE_FAILED = 3022;
+
+    /**
+     * The operation to revoke all Permissions from RBAC Role failed on server.
+     */
+    public final static int PERM_BULK_ROLE_REVOKE_FAILED = 3023;
+
+    /**
+     * The operation to revoke all administrative Permissions from AdminRole failed on server.
+     */
+    public final static int PERM_BULK_ADMINROLE_REVOKE_FAILED = 3024;
+
+    /**
+     * The supplied Perm OU was not found on ldap server.
+     */
+    public final static int PERM_OU_INVALID = 3025;
+
+    /**
+     * The supplied Permission operation name is required but was passed as null.
+     */
+    public final static int PERM_OPERATION_NM_NULL = 3026;
+
+    /**
+     * The supplied Permission object name is required but was passed as null.
+     */
+    public final static int PERM_OBJECT_NM_NULL = 3027;
+    /**
+     * The supplied Permission operation could not be read due to server failure.
+     */
+    public final static int PERM_COMPARE_OP_FAILED = 3028;
+    /**
+     * The supplied Permission does not exist in LDAP DIT.
+     */
+    public final static int PERM_NOT_EXIST = 3029;
+
+    /**
+     * 4000's - Password Policy Entity
+     */
+
+    /**
+     * The Password policy could not be read from ldap server.
+     */
+    public final static int PSWD_READ_FAILED = 4000;
+
+    /**
+     * The supplied Password policy could not be added to ldap server.
+     */
+    public final static int PSWD_CREATE_FAILED = 4001;
+
+    /**
+     * The supplied Password policy could not be updated on ldap server.
+     */
+    public final static int PSWD_UPDATE_FAILED = 4002;
+
+    /**
+     * The supplied Password policy could not be removed from ldap server.
+     */
+    public final static int PSWD_DELETE_FAILED = 4003;
+
+    /**
+     * The supplied Password policy could not be searched on ldap server.
+     */
+    public final static int PSWD_SEARCH_FAILED = 4004;
+
+    /**
+     * The supplied Password policy was not found on ldap server.
+     */
+    public final static int PSWD_NOT_FOUND = 4005;
+
+    /**
+     * The supplied Password policy name failed length check.  Ensure that does not exceed {@link GlobalIds#PWPOLICY_NAME_LEN}.
+     */
+    public final static int PSWD_NAME_INVLD_LEN = 4006;
+
+    /**
+     * The supplied Password quality value failed length check.
+     */
+    public final static int PSWD_QLTY_INVLD_LEN = 4007;
+
+    /**
+     * The supplied Password quality value invalid.
+     */
+    public final static int PSWD_QLTY_INVLD = 4008;
+
+    /**
+     * The supplied Password max age value is invalid.
+     */
+    public final static int PSWD_MAXAGE_INVLD = 4009;
+
+    /**
+     * The supplied Password min age value is invalid.
+     */
+    public final static int PSWD_MINAGE_INVLD = 4010;
+
+    /**
+     * The supplied Password minLength is invalid.
+     */
+    public final static int PSWD_MINLEN_INVLD = 4011;
+
+    /**
+     * The supplied Password interval value invalid.
+     */
+    public final static int PSWD_INTERVAL_INVLD = 4012;
+
+    /**
+     * The Password max failure count invalid.
+     */
+    public final static int PSWD_MAXFAIL_INVLD = 4013;
+
+    /**
+     * The Password must change value invalid.
+     */
+    public final static int PSWD_MUSTCHG_INVLD = 4014;
+
+    /**
+     * The supplied Password safe change attribute invalid.
+     */
+    public final static int PSWD_SAFECHG_INVLD = 4015;
+
+    /**
+     * The supplied Password allow change attribute invalid.
+     */
+    public final static int PSWD_ALLOWCHG_INVLD = 4016;
+
+    /**
+     * The supplied Password history value invalid.
+     */
+    public final static int PSWD_HISTORY_INVLD = 4017;
+
+    /**
+     * The supplied Password grace value invalid.
+     */
+    public final static int PSWD_GRACE_INVLD = 4018;
+
+    /**
+     * The supplied lockout duration was invalid.
+     */
+    public final static int PSWD_LOCKOUTDUR_INVLD = 4019;
+
+    /**
+     * The supplied password expiration value was invalid.
+     */
+    public final static int PSWD_EXPWARN_INVLD = 4020;
+
+    /**
+     * The supplied password lockout attribute is invalid.
+     */
+    public final static int PSWD_LOCKOUT_INVLD = 4021;
+
+    /**
+     * The supplied Password policy name is required and cannot be null.
+     */
+    public final static int PSWD_NAME_NULL = 4022;
+
+    /**
+     * The supplied Password entity is required and cannot be null.
+     */
+    public final static int PSWD_PLCY_NULL = 4023;
+
+    /**
+     * Server returned password policy constraint violation.
+     */
+    public final static int PSWD_CONST_VIOLATION = 4024;
+
+
+    /**
+     * 5000's - RBAC
+     */
+
+    /**
+     * Role Rule and System errors
+     */
+
+    /**
+     * The RBAC Role search failed on ldap server.
+     */
+    public final static int ROLE_SEARCH_FAILED = 5000;
+
+    /**
+     * The RBAC Role read failed on ldap server.
+     */
+    public final static int ROLE_READ_FAILED = 5001;
+
+    /**
+     * The supplied RBAC Role could not be added to ldap server.
+     */
+    public final static int ROLE_ADD_FAILED = 5002;
+
+    /**
+     * The supplied RBAC Role could not be updated on ldap server.
+     */
+    public final static int ROLE_UPDATE_FAILED = 5003;
+
+    /**
+     * The supplied RBAC Role could not be removed from ldap server.
+     */
+    public final static int ROLE_DELETE_FAILED = 5004;
+
+    /**
+     * The RBAC Role name is required and cannot be null.
+     */
+    public final static int ROLE_NM_NULL = 5005;
+
+    /**
+     * The RBAC Role was not found on ldap server.
+     */
+    public final static int ROLE_NOT_FOUND = 5006;
+
+    /**
+     * The RBAC Role entity is required and cannot be null
+     */
+    public final static int ROLE_NULL = 5007;
+
+    /**
+     * The RBAC Role assignment failed on the ldap server.
+     */
+    public final static int ROLE_USER_ASSIGN_FAILED = 5008;
+
+    /**
+     * The RBAC Role deassignment operation failed on the ldap server.
+     */
+    public final static int ROLE_USER_DEASSIGN_FAILED = 5009;
+
+    /**
+     * The RBAC Role list is required and cannot be null.
+     */
+    public final static int ROLE_LST_NULL = 5010;
+
+    /**
+     * Role occupant search failed.
+     */
+    public final static int ROLE_OCCUPANT_SEARCH_FAILED = 5011;
+
+    /**
+     * The operation to remove User as occupant to Roles failed..
+     */
+    public final static int ROLE_REMOVE_OCCUPANT_FAILED = 5012;
+
+    /**
+     * The RBAC Parent Role entity is required for this operation and cannot be null
+     */
+    public final static int PARENT_ROLE_NULL = 5013;
+
+    /**
+     * The RBAC Child Role entity is required for this operation and cannot be null
+     */
+    public final static int CHILD_ROLE_NULL = 5014;
+
+    /**
+     * The operation to remove parent attribute to Role failed..
+     */
+    public final static int ROLE_REMOVE_PARENT_FAILED = 5015;
+    /**
+     * Hierarchical Constraints
+     */
+
+    /**
+     * The Hierarchical node could not be read from the ldap server.
+     */
+    public final static int HIER_READ_FAILED = 5051;
+
+    /**
+     * The supplied Hierarchical data could not be added to the ldap server.
+     */
+    public final static int HIER_ADD_FAILED = 5052;
+
+    /**
+     * The supplied Hierarchical data could not be updated on the ldap server.
+     */
+    public final static int HIER_UPDATE_FAILED = 5053;
+
+    /**
+     * The supplied Hierarchical data could not be removed from the ldap server.
+     */
+    public final static int HIER_DELETE_FAILED = 5054;
+
+    /**
+     * The requested Hierarchical data could not be found on the ldap server.
+     */
+    public final static int HIER_NOT_FOUND = 5056;
+
+    /**
+     * The specified relationship is invalid.
+     */
+    public final static int HIER_REL_INVLD = 5057;
+
+    /**
+     * The parent cannot be removed from ldap server because it has child.  Must remove child first.
+     */
+    public final static int HIER_DEL_FAILED_HAS_CHILD = 5058;
+
+    /**
+     * The specified parent-child relationship already exists on the server.
+     */
+    public final static int HIER_REL_EXIST = 5059;
+
+    /**
+     * The specified parent-child relationship does not exist on the server.
+     */
+    public final static int HIER_REL_NOT_EXIST = 5060;
+
+    /**
+     * The supplied Hierarchical entity is required and cannot be null.
+     */
+    public final static int HIER_NULL = 5061;
+
+    /**
+     * The supplied Hierarchical type is required and cannot be null.
+     */
+    public final static int HIER_TYPE_NULL = 5062;
+
+    /**
+     * The supplied Hierarchical type is required and cannot be null.
+     */
+    public final static int HIER_CANNOT_PERFORM = 5063;
+
+    /**
+     * The specified relationship would cause a cyclic dependency in graph.
+     */
+    public final static int HIER_REL_CYCLIC = 5064;
+
+
+    /**
+     * Separation of Duty Relations
+     */
+
+    /**
+     * The Static Separation of Duty constraint search failed on the ldap server.
+     */
+    public final static int SSD_SEARCH_FAILED = 5080;
+
+    /**
+     * The Static Separation of Duty constraint read failed on the ldap server.
+     */
+    public final static int SSD_READ_FAILED = 5081;
+
+    /**
+     * The Static Separation of Duty constraint cannot be added to the ldap server.
+     */
+    public final static int SSD_ADD_FAILED = 5082;
+
+    /**
+     * The Static Separation of Duty constraint cannot be updated on the ldap server.
+     */
+    public final static int SSD_UPDATE_FAILED = 5083;
+
+    /**
+     * The Static Separation of Duty constraint cannot be removed from the ldap server.
+     */
+    public final static int SSD_DELETE_FAILED = 5084;
+
+    /**
+     * The Static Separation of Duty name is required and cannot be null.
+     */
+    public final static int SSD_NM_NULL = 5085;
+
+    /**
+     * The Static Separation of Duty constraint could not be found on the ldap server.
+     */
+    public final static int SSD_NOT_FOUND = 5086;
+
+    /**
+     * The Static Separation of Duty Constraint entity is required and cannot be null.
+     */
+    public final static int SSD_NULL = 5087;
+
+    /**
+     * The validation for Static Separation of Duty constraint data failed.
+     */
+    public final static int SSD_VALIDATION_FAILED = 5088;
+
+    /**
+     * The Dynamic Separation of Duty constraint search failed on the ldap server.
+     */
+    public final static int DSD_SEARCH_FAILED = 5089;
+
+    /**
+     * The Dynamic Separation of Duty constraint read failed on the ldap server.
+     */
+    public final static int DSD_READ_FAILED = 5090;
+
+    /**
+     * The Dynamic Separation of Duty constraint cannot be added to the ldap server.
+     */
+    public final static int DSD_ADD_FAILED = 5091;
+
+    /**
+     * The Dynamic Separation of Duty constraint cannot be updated on the ldap server.
+     */
+    public final static int DSD_UPDATE_FAILED = 5092;
+
+    /**
+     * The Dynamic Separation of Duty constraint cannot be removed from the ldap server.
+     */
+    public final static int DSD_DELETE_FAILED = 5093;
+
+    /**
+     * The Dynamic Separation of Duty name is required and cannot be null.
+     */
+    public final static int DSD_NM_NULL = 5094;
+
+    /**
+     * The Dynamic Separation of Duty constraint could not be found on the ldap server.
+     */
+    public final static int DSD_NOT_FOUND = 5095;
+
+    /**
+     * The Dynamic Separation of Duty Constraint entity is required and cannot be null.
+     */
+    public final static int DSD_NULL = 5096;
+
+    /**
+     * The validation for Dynamic Separation of Duty constraint data failed.
+     */
+    public final static int DSD_VALIDATION_FAILED = 5097;
+
+
+    /**
+     * 6000's - LDAP Suffix and Container Entities
+     */
+
+    /**
+     * The supplied ldap subdirectory node could not be created on ldap server.
+     */
+    public final static int CNTR_CREATE_FAILED = 6001;
+
+    /**
+     * The supplied ldap subdirectory node could not be removed from the ldap server.
+     */
+    public final static int CNTR_DELETE_FAILED = 6002;
+
+    /**
+     * The subdirectory node name is required and cannot be null.
+     */
+    public final static int CNTR_NAME_NULL = 6003;
+
+    /**
+     * The subdirectory node name failed length check.
+     */
+    public final static int CNTR_NAME_INVLD = 6004;
+
+    /**
+     * The supplied parent node name is required and cannot be null.
+     */
+    public final static int CNTR_PARENT_NULL = 6005;
+
+    /**
+     * The supplied parent node name is invalid.
+     */
+    public final static int CNTR_PARENT_INVLD = 6006;
+
+    /**
+     * The ldap suffix could not be created on the ldap server.
+     */
+    public final static int SUFX_CREATE_FAILED = 6010;
+
+    /**
+     * The ldap suffix node could not be removed from the ldap server.
+     */
+    public final static int SUFX_DELETE_FAILED = 6011;
+
+    /**
+     * The suffix name is required and cannot be null.
+     */
+    public final static int SUFX_NAME_NULL = 6012;
+
+    /**
+     * The supplied suffix name failed length check.
+     */
+    public final static int SUFX_NAME_INVLD = 6013;
+
+    /**
+     * The suffix domain component top level qualifier is required and cannot be null.
+     */
+    public final static int SUFX_DCTOP_NULL = 6014;
+
+    /**
+     * The Suffix domain component top level qualifier name failed the length check.
+     */
+    public final static int SUFX_DCTOP_INVLD = 6015;
+
+
+    /**
+     * 7000's - Audit Activities
+     */
+
+    /**
+     * The audit bind search failed on the ldap server.
+     */
+    public final static int AUDT_BIND_SEARCH_FAILED = 7000;
+
+    /**
+     * The Audit input entity is required on this method and cannot be supplied as null
+     */
+    public final static int AUDT_INPUT_NULL = 7001;
+
+    /**
+     * The Audit search for Fortress authorization records failed on the ldap server.
+     */
+    public final static int AUDT_AUTHZ_SEARCH_FAILED = 7002;
+
+    /**
+     * The Audit search for modifications failed on the ldap server.
+     */
+    public final static int AUDT_MOD_SEARCH_FAILED = 7003;
+
+    /**
+     * The Audit mod search by administrator internal id failed on ldap server.
+     */
+    public final static int AUDT_MOD_ADMIN_SEARCH_FAILED = 7004;
+
+    /**
+     * The Audit search for authentication events failed on the ldap server.
+     */
+    public final static int AUDT_AUTHN_INVALID_FAILED = 7005;
+
+
+    /**
+     * 8000's Organizational Unit Rule and System errors
+     */
+
+    /**
+     * The supplied organization unity entity is required and cannot be null.
+     */
+    public final static int ORG_NULL = 8001;
+
+    /**
+     * The supplied {@link org.apache.directory.fortress.core.rbac.OrgUnit#type} is required and cannot be null.
+     */
+    public final static int ORG_TYPE_NULL = 8002;
+
+    /**
+     * The supplied User OU entity could not be read due to ldap error.
+     */
+    public final static int ORG_READ_FAILED_USER = 8011;
+
+    /**
+     * The supplied User OU entity could not be added due to ldap error.
+     */
+    public final static int ORG_ADD_FAILED_USER = 8012;
+
+    /**
+     * The supplied User OU entity could not be updated due to ldap error.
+     */
+    public final static int ORG_UPDATE_FAILED_USER = 8013;
+
+    /**
+     * The supplied User OU entity could not be removed due to ldap error.
+     */
+    public final static int ORG_DELETE_FAILED_USER = 8014;
+
+    /**
+     * The OU User search failed due to ldap error.
+     */
+    public final static int ORG_SEARCH_FAILED_USER = 8015;
+
+    /**
+     * The search for User OU's failed on ldap server.
+     */
+    public final static int ORG_GET_FAILED_USER = 8016;
+
+    /**
+     * The supplied User OU not found on ldap server.
+     */
+    public final static int ORG_NOT_FOUND_USER = 8017;
+
+    /**
+     * The supplied User OU is required and cannot be null.
+     */
+    public final static int ORG_NULL_USER = 8018;
+
+    /**
+     * The supplied User OU type is required and cannot be null.
+     */
+    public final static int ORG_TYPE_NULL_USER = 8019;
+
+    /**
+     * The supplied User OU entry could not be removed from the server.
+     */
+    public final static int ORG_DEL_FAILED_USER = 8020;
+
+    /**
+     * The supplied Perm OU entity parent attribute could not be updated due to ldap error.
+     */
+    public final static int ORG_REMOVE_PARENT_FAILED_USER = 8021;
+
+    /**
+     * The supplied Perm OU entity could not be read due to ldap error.
+     */
+    public final static int ORG_READ_FAILED_PERM = 8061;
+
+    /**
+     * The supplied Perm OU entity could not be added due to ldap error.
+     */
+    public final static int ORG_ADD_FAILED_PERM = 8062;
+
+    /**
+     * The supplied Perm OU entity could not be updated due to ldap error.
+     */
+    public final static int ORG_UPDATE_FAILED_PERM = 8063;
+
+    /**
+     * The supplied Perm OU entity could not be removed due to ldap error.
+     */
+    public final static int ORG_DELETE_FAILED_PERM = 8064;
+
+    /**
+     * The OU Perm search failed due to ldap error.
+     */
+    public final static int ORG_SEARCH_FAILED_PERM = 8065;
+
+    /**
+     * The search for Perm OU's failed on ldap server.
+     */
+    public final static int ORG_GET_FAILED_PERM = 8066;
+
+    /**
+     * The supplied Perm OU not found on ldap server.
+     */
+    public final static int ORG_NOT_FOUND_PERM = 8067;
+
+    /**
+     * The supplied Perm OU is required and cannot be null.
+     */
+    public final static int ORG_NULL_PERM = 8068;
+
+    /**
+     * The supplied Perm OU type is required and cannot be null.
+     */
+    public final static int ORG_TYPE_NULL_PERM = 8069;
+
+    /**
+     * The supplied Perm OU entry could not be removed from the server.
+     */
+    public final static int ORG_DEL_FAILED_PERM = 8070;
+
+    /**
+     * The supplied OU name exceed maximum allowed {@link GlobalIds#OU_LEN}.
+     */
+    public final static int ORG_LEN_INVLD = 8071;
+
+    /**
+     * The supplied Parent OU is required for this operation and cannot be null.
+     */
+    public final static int ORG_PARENT_NULL = 8072;
+
+    /**
+     * The supplied Parent OU is required for this operation and cannot be null.
+     */
+    public final static int ORG_CHILD_NULL = 8073;
+
+    /**
+     * The supplied Perm OU parent attribute could not be removed due to ldap error.
+     */
+    public final static int ORG_REMOVE_PARENT_FAILED_PERM = 8074;
+
+    /**
+     * 9000's Administrative RBAC
+     */
+
+    /**
+     * The Administrative Role search failed on ldap server.
+     */
+    public final static int ARLE_SEARCH_FAILED = 9000;
+
+    /**
+     * The Administrative Role read failed on ldap server.
+     */
+    public final static int ARLE_READ_FAILED = 9001;
+
+    /**
+     * The supplied Administrative Role could not be added to ldap server.
+     */
+    public final static int ARLE_ADD_FAILED = 9002;
+
+    /**
+     * The supplied Administrative Role could not be updated on ldap server.
+     */
+    public final static int ARLE_UPDATE_FAILED = 9003;
+
+    /**
+     * The supplied Administrative Role could not be removed from ldap server.
+     */
+    public final static int ARLE_DELETE_FAILED = 9004;
+
+    /**
+     * The Administrative Role name is required and cannot be null.
+     */
+    public final static int ARLE_NM_NULL = 9005;
+
+    /**
+     * The Administrative Role was not found on ldap server.
+     */
+    public final static int ARLE_NOT_FOUND = 9006;
+
+    /**
+     * The Administrative Role entity is required and cannot be null
+     */
+    public final static int ARLE_NULL = 9007;
+
+    /**
+     * The User Administrative Role assignment failed.
+     */
+    public final static int ARLE_USER_ASSIGN_FAILED = 9008;
+
+    /**
+     * The User Administrative Role deassignment failed.
+     */
+    public final static int ARLE_USER_DEASSIGN_FAILED = 9009;
+
+    /**
+     * Method requires list of Administrative Roles and cannot be null.
+     */
+    public final static int ARLE_LST_NULL = 9010;
+
+    /**
+     * The supplied begin range for Administrative Role is required and cannot be null.
+     */
+    public final static int ARLE_BEGIN_RANGE_NULL = 9011;
+
+    /**
+     * The supplied end range for Administrative Role is required and cannot be null.
+     */
+    public final static int ARLE_END_RANGE_NULL = 9011;
+
+    /**
+     * The supplied range for Administrative Role is invalid.
+     */
+    public final static int ARLE_INVLD_RANGE = 9012;
+
+    /**
+     * The supplied range for Administrative Role inclusion is invalid.
+     */
+    public final static int ARLE_INVLD_RANGE_INCLUSIVE = 9013;
+
+    /**
+     * The supplied Administrative Role could not be activated in the User's Session.
+     */
+    public final static int ARLE_ACTIVATE_FAILED = 9014;
+
+    /**
+     * The supplied Administrative Role could not be deactivated from the User's session.
+     */
+    public final static int ARLE_DEACTIVE_FAILED = 9015;
+
+    /**
+     * The Administrative Role is already activated in User's Session.
+     */
+    public final static int ARLE_ALREADY_ACTIVE = 9016;
+
+    /**
+     * The supplied Administrative Role is not activated in User's Session.
+     */
+    public final static int ARLE_NOT_ACTIVE = 9017;
+
+    /**
+     * The Administrative Role search could failed on server.
+     */
+    public final static int ARLE_USER_SEARCH_FAILED = 9018;
+
+    /**
+     * The Parent Administrative Role entity is required and cannot be null
+     */
+    public final static int ARLE_PARENT_NULL = 9019;
+
+    /**
+     * The Child Administrative Role entity is required and cannot be null
+     */
+    public final static int ARLE_CHILD_NULL = 9020;
+
+    /**
+     * The Admin Role could not be assigned to User already has it assigned.
+     */
+    public final static int ARLE_ASSIGN_EXIST = 9021;
+
+    /**
+     * The User Admin Role could not be deassigned from User because it wasn't assigned in the first place.
+     */
+    public final static int ARLE_ASSIGN_NOT_EXIST = 9022;
+
+    /**
+     * The User Admin Role could not be deassigned from User because it wasn't assigned in the first place.
+     */
+    public final static int ARLE_DEASSIGN_NOT_EXIST = 9023;
+
+    /**
+     * The User Admin Role assignment failed.
+     */
+    public final static int ARLE_ASSIGN_FAILED = 9024;
+
+    /**
+     * The User Admin Role deassignment failed.
+     */
+    public final static int ARLE_DEASSIGN_FAILED = 9025;
+
+    /**
+     * AdminRole occupant search failed.
+     */
+    public final static int ARLE_OCCUPANT_SEARCH_FAILED = 9026;
+
+    /**
+     * The operation to remove User as occupant to AdminRoles failed..
+     */
+    public final static int ARLE_REMOVE_OCCUPANT_FAILED = 9027;
+
+    /**
+     * The supplied Administrative Role parent attribute could not be removed on ldap server.
+     */
+    public final static int ARLE_REMOVE_PARENT_FAILED = 9028;
+
+    /**
+     * 10000's - Temporal Constraint Validation Error Ids
+     */
+
+    /**
+     * The constraint contains invalid text.
+     */
+    public final static int CONST_INVLD_TEXT = 10001;
+
+    /**
+     * The Constraint value failed length check.
+     */
+    public final static int CONST_INVLD_FIELD_LEN = 10002;
+
+    /**
+     * The Constraint contains an invalid timeout value.
+     */
+    public final static int CONST_TIMEOUT_INVLD = 10003;
+
+    /**
+     * The Constraint contains an invalid beginTime value.
+     */
+    public final static int CONST_BEGINTIME_INVLD = 10004;
+
+    /**
+     * The Constraint contains an invalid beginTime length.
+     */
+    public final static int CONST_BEGINTIME_LEN_ERR = 10005;
+
+    /**
+     * The Constraint contains an invalid endTime value.
+     */
+    public final static int CONST_ENDTIME_INVLD = 10006;
+
+    /**
+     * The Constraint contains an invalid endTime length.
+     */
+    public final static int CONST_ENDTIME_LEN_ERR = 10007;
+
+    /**
+     * The Constraint contains an invalid beginDate value.
+     */
+    public final static int CONST_BEGINDATE_INVLD = 10008;
+
+    /**
+     * The Constraint contains an invalid beginDate length.
+     */
+    public final static int CONST_BEGINDATE_NULL = 10009;
+
+    /**
+     * The Constraint contains an invalid endDate value.
+     */
+    public final static int CONST_ENDDATE_INVLD = 10010;
+
+    /**
+     * The Constraint contains an invalid endDate length.
+     */
+    public final static int CONST_ENDDATE_NULL = 10011;
+
+    /**
+     * The Constraint contains an invalid dayMask value.
+     */
+    public final static int CONST_DAYMASK_INVLD = 10012;
+
+    /**
+     * The Constraint contains a null dayMask value.
+     */
+    public final static int CONST_DAYMASK_NULL = 10013;
+
+    /**
+     * The Constraint description is optional but cannot exceed length of {@link GlobalIds#DESC_LEN} if supplied.
+     */
+    public final static int CONST_DESC_LEN_INVLD = 10014;
+
+    /**
+     * The Constraint contains a null value.
+     */
+    public final static int CONST_NULL_TEXT = 10015;
+
+    /**
+     * 10100's - REST Error Ids
+     */
+
+    /**
+     * The REST function failed with HTTP error.
+     */
+    public final static int REST_WEB_ERR = 10101;
+
+    /**
+     * The REST function failed with an IO error.
+     */
+    public final static int REST_IO_ERR = 10102;
+
+    /**
+     * The REST function failed during XML marshaling.
+     */
+    public final static int REST_MARSHALL_ERR = 10103;
+
+    /**
+     * The REST function failed during XML unmarshal
+     */
+    public final static int REST_UNMARSHALL_ERR = 10104;
+
+    /**
+     * The REST fucntion failed with HTTP Get.
+     */
+    public final static int REST_GET_FAILED = 10105;
+
+    /**
+     * The REST endpoint was not found.
+     */
+    public final static int REST_NOT_FOUND_ERR = 10106;
+
+    /**
+     *  The REST function failed with an unknown error.
+     */
+    public final static int REST_UNKNOWN_ERR = 10107;
+
+    /**
+     * The REST function failed with HTTP forbidden error.
+     */
+    public final static int REST_FORBIDDEN_ERR = 10108;
+
+    /**
+     * The REST function failed with an HTTP unauthorized error.
+     */
+    public final static int REST_UNAUTHORIZED_ERR = 10109;
+
+    /**
+     * 10200's - RBAC Accelerator Error Ids
+     */
+
+    /**
+     * The RBAC Accelerator function failed because CreateSession LDAP extended operation error.
+     */
+    public final static int ACEL_CREATE_SESSION_ERR = 10201;
+
+    /**
+     * The RBAC Accelerator function failed because DeleteSession LDAP extended operation error.
+     */
+    public final static int ACEL_DELETE_SESSION_ERR = 10202;
+
+    /**
+     * The RBAC Accelerator function failed because CheckAccess LDAP extended operation error.
+     */
+    public final static int ACEL_CHECK_ACCESS_ERR = 10203;
+
+    /**
+     * The RBAC Accelerator function failed because AddRole LDAP extended operation error.
+     */
+    public final static int ACEL_ADD_ROLE_ERR = 10204;
+
+    /**
+     * The RBAC Accelerator function failed because DropRole LDAP extended operation error.
+     */
+    public final static int ACEL_DROP_ROLE_ERR = 10205;
+
+    /**
+     * The RBAC Accelerator function failed because SessionRoles LDAP extended operation error.
+     */
+    public final static int ACEL_SESSION_ROLES_ERR = 10206;
+    /**
+     * 10300's - Group Error Ids
+     */
+    /**
+     * The Group search failed on ldap server.
+     */
+    public final static int GROUP_SEARCH_FAILED = 10300;
+
+    /**
+     * The Group read failed on ldap server.
+     */
+    public final static int GROUP_READ_FAILED = 10301;
+
+    /**
+     * The supplied Group could not be added to ldap server.
+     */
+    public final static int GROUP_ADD_FAILED = 10302;
+
+    /**
+     * The supplied Group could not be updated on ldap server.
+     */
+    public final static int GROUP_UPDATE_FAILED = 10303;
+
+    /**
+     * The supplied Group could not be removed from ldap server.
+     */
+    public final static int GROUP_DELETE_FAILED = 10304;
+
+    /**
+     * The supplied Group could not be updated on ldap server.
+     */
+    public final static int GROUP_ADD_PROPERTY_FAILED = 10305;
+
+    /**
+     * The supplied Group could not be removed from ldap server.
+     */
+    public final static int GROUP_DELETE_PROPERTY_FAILED = 10306;
+
+    /**
+     * The Group was not found on ldap server.
+     */
+    public final static int GROUP_NOT_FOUND = 10307;
+
+    /**
+     * The Group entity is required and cannot be null
+     */
+    public final static int GROUP_NULL = 10308;
+
+    /**
+     * The Group assignment failed on the ldap server.
+     */
+    public final static int GROUP_USER_ASSIGN_FAILED = 10309;
+
+    /**
+     * The Group deassignment operation failed on the ldap server.
+     */
+    public final static int GROUP_USER_DEASSIGN_FAILED = 10310;
+
+    /**
+     * The group name is required and cannot be null.
+     */
+    public final static int GROUP_NAME_NULL = 10311;
+
+    /**
+     * The supplied group name failed length check.
+     */
+    public final static int GROUP_NAME_INVLD = 10312;
+
+    /**
+     * The supplied group protocol name failed length check.
+     */
+    public final static int GROUP_PROTOCOL_INVLD = 10313;
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/GlobalIds.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/GlobalIds.java b/src/main/java/org/apache/directory/fortress/core/GlobalIds.java
new file mode 100755
index 0000000..6dc1609
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/GlobalIds.java
@@ -0,0 +1,580 @@
+/*
+ *   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;
+
+
+import org.apache.directory.fortress.core.cfg.Config;
+
+
+/**
+ * This class contains constants that must be defined globally but are not to be used by external programs.
+ * The constants are used internally by Fortress when looking up cfg values, performing maintenance on
+ * standard and custom ldap objects and attributes, instantiating manager instances, validating objects and attributes, and more.
+ * Some of the values for public constants defined here must be known to end users of system to declare system cfg parameters, see {@link org.apache.directory.fortress.core.cfg.Config}.
+ * For example the {@link #SUFFIX} constant uses key name {@code suffix} which must have a corresponding value, i.e. {@code dc=example,dc=com},
+ * which tells location of Directory Information Tree to the Fortress runtime processor.
+ * </p>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+public class GlobalIds
+{
+    public static final String HOME = "HOME";
+    public static final String TENANT = "tenant";
+    private static final String ENABLE_AUDIT = "enable.audit";
+    public static final boolean IS_AUDIT = ( ( Config.getProperty( ENABLE_AUDIT ) != null ) && ( Config
+        .getProperty( ENABLE_AUDIT ).equalsIgnoreCase( "true" ) ) );
+    private static final String ENABLE_REST = "enable.mgr.impl.rest";
+    public static final boolean IS_REST = ( ( Config.getProperty( ENABLE_REST ) != null ) && ( Config
+        .getProperty( ENABLE_REST ).equalsIgnoreCase( "true" ) ) );
+
+    /**
+     * The following constants are used within the factory classes:
+     */
+
+    /**
+     * When this optional tag, {@code accessmgr.implementation}, is placed in Fortress properties, its class name will be the default {@link AccessMgr} instance used.
+     */
+    public final static String ACCESS_IMPLEMENTATION = "accessmgr.implementation";
+
+    /**
+     * When this optional tag, {@code adminImplementation}, is placed in Fortress properties, its class name will be the default {@link AdminMgr} instance used.
+     */
+    public final static String ADMIN_IMPLEMENTATION = "adminmgr.implementation";
+
+    /**
+     * When this optional tag, {@code daoConnector}, is placed in Fortress properties,
+     */
+    public final static String DAO_CONNECTOR = "dao.connector";
+
+    /**
+     * When this optional tag, {@code reviewImplementation}, is placed in Fortress properties, its class name will be the default {@link ReviewMgr} instance used.
+     */
+    public final static String REVIEW_IMPLEMENTATION = "reviewmgr.implementation";
+
+    /**
+     * When this optional tag, {@code policyImplementation}, is placed in Fortress properties, its class name will be the default {@link PwPolicyMgr} instance used.
+     */
+    public final static String PSWD_POLICY_IMPLEMENTATION = "policymgr.implementation";
+
+    /**
+     * When this optional tag, {@code auditmgr.implementation}, is placed in Fortress properties, its class name will be the default {@link AuditMgr} instance used.
+     */
+    public final static String AUDIT_IMPLEMENTATION = "auditmgr.implementation";
+
+    /**
+     * When this optional tag, {@code delegatedAdminImplementation}, is placed in Fortress properties, its class name will be the default {@link DelAdminMgr} instance used.
+     */
+    public final static String DELEGATED_ADMIN_IMPLEMENTATION = "delegated.adminmgr.implementation";
+
+    /**
+     * When this optional tag, {@code delegatedReviewImplementation}, is placed in Fortress properties, its class name will be the default {@link DelReviewMgr} instance used.
+     */
+    public final static String DELEGATED_REVIEW_IMPLEMENTATION = "delegated.reviewmgr.implementation";
+
+    /**
+     * When this optional tag, {@code delegatedAccessImplementation}, is placed in Fortress properties, its class name will be the default {@link DelAccessMgr} instance used.
+     */
+    public final static String DELEGATED_ACCESS_IMPLEMENTATION = "delegated.accessmgr.implementation";
+
+    /**
+     * When this optional tag, {@code configImplementation}, is placed in Fortress properties, its class name will be the default {link ConfigMgr} instance used.
+     */
+    public final static String CONFIG_IMPLEMENTATION = "configmgr.implementation";
+
+    /**
+     * When this optional tag, {@code accelsmgr.implementation}, is placed in Fortress properties, its class name will be the default {@link AccelMgr} instance used.
+     */
+    public final static String ACCEL_IMPLEMENTATION = "accelmgr.implementation";
+
+    /**
+     * When this optional tag, {@code groupImplementation}, is placed in Fortress properties, its class name will be the default {link GroupMgr} instance used.
+     */
+    public final static String GROUP_IMPLEMENTATION = "groupmgr.implementation";
+
+    //	AUTHENTICATION_TYPE
+    /**
+     * This property is used to specify if authentication is being performed within a security realm.
+     */
+    public final static String AUTHENTICATION_TYPE = "authn.type";
+
+    /**
+     * Specifies realm authentication mode.
+     */
+    public final static String REALM_TYPE = "REALM";
+
+    /**
+     * Used to declare validation modules that are used to process constraint checks during session activation.
+     */
+    public final static String VALIDATOR_PROPS = "temporal.validator.";
+
+    /**
+     * The DSD validator performs Dynamic Separation of Duty checks during role activation.
+     */
+    public final static String DSD_VALIDATOR_PROP = "temporal.validator.dsd";
+
+    /**
+     * This constant is used during authentication to determine if runtime is security realm.  If IS_REALM == true,
+     * the authentication module will not throw SecurityException on password resets.  This is to enable the authentication
+     * event to succeed allowing the application to prompt user to change their password.
+     */
+    public final static boolean IS_REALM = GlobalIds.REALM_TYPE.equalsIgnoreCase( Config
+        .getProperty( GlobalIds.AUTHENTICATION_TYPE ) );
+
+    /**
+     * Constant is used to tell ldap server to return no attributes on search.
+     */
+    public final static String[] NO_ATRS =
+        {
+            "1.1"
+    };
+
+    /**
+     * Parameter specifies the distinguished name (dn) of the LDAP suffix.  The is the root or top-most node for a Directory Information Tree (DIT).  The typical
+     * Fortress suffix format is {@code dc=example,dc=com}.
+     */
+    public final static String SUFFIX = "suffix";
+
+    /**
+     * Specifies the dn of the container where the Fortress User data set is located within DIT.  This is typically in the format of
+     * {@code ou=People, dc=example, dc=com}
+     */
+    public final static String USER_ROOT = "user.root";
+
+    /**
+     * Specifies the dn of the container where the Fortress Permissions are located.  This is typically in the format of
+     * {@code ou=Permissions,ou=RBAC,dc=example,dc=com}
+     */
+    public final static String PERM_ROOT = "perm.root";
+
+    /**
+     * Specifies the dn of the container where the Fortress RBAC Roles are located.  This is typically in the format of
+     * {@code ou=Roles,ou=RBAC,dc=example,dc=com}
+     */
+    public final static String ROLE_ROOT = "role.root";
+
+    /**
+     * Specifies the dn of the container where the Fortress Password Polices are located.  This is typically in the format of
+     * {@code ou=Policies,dc=example,dc=com}
+     */
+    public final static String PPOLICY_ROOT = "pwpolicy.root";
+
+    /**
+     * Specifies the dn of the container where the Fortress SSD and DSD constraints are located.  This is typically in the format of
+     * {@code ou=Constraints,ou=RBAC,dc=example,dc=com}
+     */
+    public final static String SD_ROOT = "sdconstraint.root";
+
+    /**
+     * Specifies the dn of the container where the Fortress User OU pools are located.  This is typically in the format of
+     * {@code ou=OS-U,ou=ARBAC,dc=example,dc=com}
+     */
+    public final static String OSU_ROOT = "userou.root";
+
+    /**
+     * Specifies the dn of the container where the Fortress Permission OU pools are located.  This is typically in the format of
+     * {@code ou=OS-P,ou=ARBAC,dc=example,dc=com}
+     */
+    public final static String PSU_ROOT = "permou.root";
+
+    /**
+     * Specifies the dn of the container where the Fortress Administrative Roles are located.  This is typically in the format of
+     * {@code ou=AdminRoles,ou=ARBAC,dc=example,dc=com}
+     */
+    public final static String ADMIN_ROLE_ROOT = "adminrole.root";
+
+    /**
+     * Specifies the dn of the container where the Fortress Administrative Permissions are located.  This is typically in the format of
+     * {@code ou=AdminPerms,ou=ARBAC,dc=example,dc=com}
+     */
+    public final static String ADMIN_PERM_ROOT = "adminperm.root";
+
+    /**
+     * Specifies the dn of the container where the Groups are located.  This is typically in the format of
+     * {@code ou=Groups,dc=example,dc=com}
+     */
+    public final static String GROUP_ROOT = "group.root";
+
+    /*
+      *  *************************************************************************
+      *  **  BEGIN LDAP STANDARD ATTRIBUTE NAMES
+      *  ************************************************************************
+      */
+
+    /*
+     * Constant contains the top object class name that is at the root of all ldap object class structures.
+     */
+    public final static String TOP = "top";
+
+    /**
+     * Constant contains the organization object class name.
+     */
+    public final static String ORGANIZATION_CLASS = "organization";
+
+    /**
+     * Constant contains the suffix's dcObject object class name.
+     */
+    public final static String SUFFIX_CLASS = "dcObject";
+
+    /**
+     * Constant contains the userId attribute name for inetOrgPerson object class.
+     */
+    public final static String UID = "uid";
+
+    /**
+     * Constant contains the common name attribute name used within inetOrgPerson and other ldap object classes.
+     */
+    public final static String CN = "cn";
+
+    /**
+     * Constant contains the ldap distinguished name attribute.
+     */
+    public final static String DN = "dn";
+
+    /**
+     * Used within search operation using the OpenLDAP proxy control.
+     */
+    public final static String UTF8 = "UTF-8";
+
+    /**
+     * Constant contains the description attribute name used within inetOrgPerson and other ldap object classes.
+     */
+    public final static String DESC = "description";
+
+    /**
+     * Constant contains the ou attribute name used within inetOrgPerson and other ldap object classes.
+     */
+    public final static String OU = "ou";
+
+    /**
+     * Password policy object class structure uses cn attribute name.
+     */
+    public final static String POLICY_NODE_TYPE = CN;
+
+    /**
+     * Constant contains the ldap object class attribute name.
+     */
+    public final static String OBJECT_CLASS = "objectclass";
+
+    /*
+    *  *************************************************************************
+    *  **  OPENLDAP PW POLICY ATTRIBUTES AND CONSTANTS
+    *  ************************************************************************
+    */
+
+    public static final String SERVER_TYPE = "ldap.server.type";
+    public static final boolean IS_OPENLDAP = ( ( Config.getProperty( SERVER_TYPE ) != null ) && ( Config
+        .getProperty( SERVER_TYPE ).equalsIgnoreCase( "openldap" ) ) );
+
+    /**
+     * OpenLDAP uses this object class to store policy definitions that are processed by the pw policy overlay.
+     */
+    //private final static String OPENLDAP_PW_POLICY_IMPL = "password.policy";
+
+    /**
+     * When openldap password policy is in effect the openldap pw policy response control is interrogated subsequent to bind operations.
+     */
+    //private final static String OPENLDAP_SERVER = "openldap";
+
+    /**
+     * When set to true the pw policy control is interrogated.
+     */
+    //public final static boolean OPENLDAP_IS_PW_POLICY_ENABLED = (org.apache.directory.fortress.cfg.Config.getProperty(GlobalIds.OPENLDAP_PW_POLICY_IMPL) != null && (Config.getProperty(GlobalIds.OPENLDAP_PW_POLICY_IMPL)).equalsIgnoreCase(GlobalIds.OPENLDAP_SERVER));
+
+    /**
+     * This is control id openldap uses to communicate password messages to the ldap client subsequent to bind operations:
+     */
+    public final static String OPENLDAP_PW_RESPONSE_CONTROL = "1.3.6.1.4.1.42.2.27.8.5.1";
+
+    /*
+      *  *************************************************************************
+      *  **  OpenAccessMgr AUDIT
+      *  ************************************************************************
+      */
+    /**
+     * This object class contains Fortress audit contextual information.
+     */
+    public final static String FT_MODIFIER_AUX_OBJECT_CLASS_NAME = "ftMods";
+
+    /**
+     * The ftModifier contains the internalUserId of administrator who performed action.
+     */
+    public final static String FT_MODIFIER = "ftModifier";
+
+    /**
+     * The {@code ftModCode} attribute contains the permission object name and operation of admin function performed.
+     */
+    public final static String FT_MODIFIER_CODE = "ftModCode";
+
+    /**
+     * The {@code ftModId} contains a globally unique id that is bound to the audit event entity.
+     */
+    public final static String FT_MODIFIER_ID = "ftModId";
+
+    /**
+     * The {@code ftId} contains a globally unique id that is bound to the application entity.
+     */
+    public final static String FT_IID = "ftId";
+
+    /**
+     * This string literal contains a common start for most ldap search filters that fortress uses.
+     */
+    public final static String FILTER_PREFIX = "(&(objectclass=";
+
+    /*
+      *  *************************************************************************
+      *  **  OpenAccessMgr PROPERTIES are used by USER, PERM, CONFIG DAO'S.
+      *  ************************************************************************
+      */
+    /**
+     * The {@code ftProperties} object class contains name-value pairs that are neither validated nor constrained.
+     * Properties are application defined parameters and clients may store any reasonable values.
+     */
+    public final static String PROPS_AUX_OBJECT_CLASS_NAME = "ftProperties";
+
+    /**
+     * The {@code ftProps} attribute contains a single name-value pairs that is {@code :} separated.
+     */
+    public final static String PROPS = "ftProps";
+
+    /*
+      *  *************************************************************************
+      *  **  OpenAccessMgr ROLE STATICS are used by RBAC and ARBAC DAO
+      *  ************************************************************************
+      */
+
+    /**
+     * The object class is used to store Fortress Role entity data.
+     */
+    public final static String ROLE_OBJECT_CLASS_NM = "ftRls";
+
+    /**
+     * Defines the object class structure used within Fortress Role processing.
+     */
+    public final static String ROLE_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP,
+            ROLE_OBJECT_CLASS_NM,
+            GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME,
+            GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+
+    /*
+      *  *************************************************************************
+      *  **  OpenAccessMgr CONSTRAINTS are used by USER, ROLE, ADMINROLE DAO'S.
+      *  ************************************************************************
+      */
+
+    /**
+     * Constraint AUX Object Class Schema definitions:
+     */
+
+    /**
+     * This single occurring attribute is used to store constraint policies on Fortress User objects.
+     */
+    public final static String CONSTRAINT = "ftCstr";
+
+    // USER Role Definitions:
+
+    /**
+     * Multi-occurring attribute contains RBAC Role assignments for Users.
+     */
+    public final static String USER_ROLE_ASSIGN = "ftRA";
+
+    /**
+     * Multi-occurring attribute contains constraint policies for RBAC Role assignments for Users.
+     */
+    public final static String USER_ROLE_DATA = "ftRC";
+
+    /**
+     * Multi-occurring attribute contains Administrative Role assignments for Users.
+     */
+    public final static String USER_ADMINROLE_ASSIGN = "ftARA";
+
+    /**
+     * Multi-occurring attribute contains constraint policies for Administrative Role assignments for Users.
+     */
+    public final static String USER_ADMINROLE_DATA = "ftARC";
+
+    /**
+     * Attribute name for storing Fortress permission object names.
+     */
+    public final static String POBJ_NAME = "ftObjNm";
+
+    /**
+     * Attribute name for storing parent node names for hierarchical processing.
+     */
+    public final static String PARENT_NODES = "ftParents";
+
+    /*
+    *  *************************************************************************
+    *  **  RBAC Entity maximum length constants
+    *  ************************************************************************
+    */
+
+    /**
+     * Fortress userId cannot exceed length of 40.
+     */
+    public final static int USERID_LEN = 40;
+
+    /**
+     * Fortress role names cannot exceed length of 40.
+     */
+    public final static int ROLE_LEN = 40;
+
+    /**
+     * Fortress description text cannot exceed length of 80.
+     */
+    public final static int DESC_LEN = 180;
+
+    /**
+     * Fortress permission names cannot exceed length of 100.
+     */
+    public final static int PERM_LEN = 100;
+
+    /**
+     * Fortress User passwords must have length of 50 or less..
+     */
+    public final static int PASSWORD_LEN = 50;
+
+    /**
+     * Fortress password policy names cannot exceed length of 40.
+     */
+    public final static int PWPOLICY_NAME_LEN = 40;
+
+    /**
+     * Fortress ou's cannot exceed length of 40.
+     */
+    public final static int OU_LEN = 40;
+
+    /**
+     * Fortress User surname cannot exceed length of 80.
+     */
+    public final static int SN_LEN = 80;
+
+    /**
+     * Fortress common name attributes cannot exceed length of 80.
+     */
+    public final static int CN_LEN = 80;
+
+    /**
+     * Fortress properties cannot exceed length of 100.
+     */
+    public final static int PROP_LEN = 100;
+
+    // Regular Expression Patterns stored in Fortress config file:
+    public final static String REG_EX_SAFE_TEXT = "regXSafetext";
+
+    /*
+      *  *************************************************************************
+      *  **  LDAP FILTER CONSTANTS
+      *  ************************************************************************
+      */
+    /**
+     * Used to define characters that must be encoded before being processed by ldap operations.
+     */
+    public final static String LDAP_FILTER = "ldap.filter.";
+
+    /**
+     * Used to define encoded replacements for characters to be filtered.
+     */
+    public final static String LDAP_SUB = "ldap.sub.";
+
+    /**
+     * Defines how many entries are to be stored in the encoding set.
+     */
+    public final static String LDAP_FILTER_SIZE_PROP = "ldap.filter.size";
+
+    /**
+     * Used during ldap filter processing.
+     */
+    public final static boolean LDAP_FILTER_SIZE_FOUND = ( Config
+        .getProperty( LDAP_FILTER_SIZE_PROP ) != null );
+    public static final String APACHE_LDAP_API = "apache";
+    public static final String AUTH_Z_FAILED = "authzfailed";
+    public static final String AUTH_Z_FAILED_VALUE = "ftOpNm=" + AUTH_Z_FAILED;
+
+    /**
+     * maximum number of entries allowed for ldap filter replacements.
+     */
+    private static int ldapFilterSize = 25;
+
+    /**
+     * enable the ldap filter size variable to be used later during filter processing.
+     */
+    static
+    {
+        try
+        {
+            String lenProp = Config.getProperty( LDAP_FILTER_SIZE_PROP );
+            if ( LDAP_FILTER_SIZE_FOUND )
+            {
+                Integer len = new Integer( lenProp );
+                ldapFilterSize = len;
+            }
+        }
+        catch ( java.lang.NumberFormatException nfe )
+        {
+            //ignore
+        }
+    }
+
+    /**
+     * Maximum number of entries allowed for ldap filter replacements.
+     */
+    public static final int LDAP_FILTER_SIZE = ldapFilterSize;
+
+    /**
+     * This property contains the location for the remote Fortress properties stored in ldap.  This is typically in the format of
+     * {@code cn=DEFAULT,ou=Config,dc=example,dc=com}
+     */
+    public static final String CONFIG_REALM = "config.realm";
+
+    /**
+     * Fortress stores name-value pairs within multi-occurring attributes in ldap.  Usually a separator of ':' is used
+     * format: {@code name:value},
+     */
+    public final static char PROP_SEP = ':';
+
+    /**
+     * Fortress stores complex attribute types within a single attribute in ldap.  Usually a delimiter of '$' is used for string tokenization.
+     * format: {@code part1$part2$part3....}  Stored in fortress.properties as 'attr.delimiter=$'
+     */
+    public static final String DELIMITER = Config.getProperty( "attr.delimiter", "$" );
+
+    /**
+     * Maximum number of records for ldap client to wait on while processing results sets from ldap server.
+     */
+    public static final int BATCH_SIZE = 100;
+
+    /**
+     * Attribute is used in Fortress time/date constraints as default which will always pass.  i.e. values stored as beginDate=none or beginTime=none will turn the date and time constraints off
+     * for a particular entity..
+     */
+    public static final String NONE = "none";
+
+    /**
+     * Attribute is used in Fortress day mask constraints as default which will always pass.  i.e. values stored as dayMask=all will always pass the day of week constraint.
+     */
+    public static final String ALL = "all";
+    public static final String NULL = "null";
+    public static final String POP_NAME = "ftOpNm";
+}
\ 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/Manageable.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/Manageable.java b/src/main/java/org/apache/directory/fortress/core/Manageable.java
new file mode 100644
index 0000000..ff9aa5b
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/Manageable.java
@@ -0,0 +1,54 @@
+/*
+ *   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;
+
+
+import org.apache.directory.fortress.core.rbac.Session;
+
+/**
+ * Interface allows outside clients to manage security and multi-tenant concerns within the Fortress runtime.
+ * The {@link #setAdmin(org.apache.directory.fortress.core.rbac.Session)} method allows A/RBAC sessions to be loaded and allows authorization
+ * to be performed on behalf of the user who is contained within the Session object itself.
+ * The ARBAC permissions will be checked each time outside client makes calls into Fortress API.
+ * This interface also allows Fortress clients to operate in a multi-tenant fashion using {@link #setContextId(String)}.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public interface Manageable
+{
+    /**
+     * Use this method to load an administrative user's ARBAC Session object into Manager object which will enable authorization to
+     * be performed on behalf of admin user.
+     * Setting Session into this object will enforce ARBAC controls and render this class' implementer thread unsafe.
+     *
+     * @param session contains a valid Fortress ARBAC Session object.
+     */
+    public void setAdmin(Session session);
+
+    /**
+     * Use this method to set the tenant id onto function call into Fortress which allows segregation of data by customer.
+     * The contextId is used for multi-tenancy to isolate data sets within a particular sub-tree within DIT.
+     * Setting contextId into this object will render this class' implementer thread unsafe.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     */
+    public void setContextId(String contextId);
+}
\ No newline at end of file


[13/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/AdminRoleDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/AdminRoleDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/AdminRoleDAO.java
new file mode 100755
index 0000000..db33695
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/AdminRoleDAO.java
@@ -0,0 +1,656 @@
+/*
+ *   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.unboundid;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.UnboundIdDataProvider;
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.AdminRoleP;
+import org.apache.directory.fortress.core.rbac.AdminRoleUtil;
+import org.apache.directory.fortress.core.rbac.Graphable;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.time.CUtil;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttribute;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModification;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModificationSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPSearchResults;
+
+
+/**
+ * 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 final class AdminRoleDAO extends UnboundIdDataProvider implements org.apache.directory.fortress.core.rbac.dao.AdminRoleDAO
+{
+    private static final String ROLE_OCCUPANT = "roleOccupant";
+    private static final String ROLE_OSP = "ftOSP";
+    private static final String ROLE_OSU = "ftOSU";
+    private static final String ROLE_RANGE = "ftRange";
+    private static final String POOLS_AUX_OBJECT_CLASS_NAME = "ftPools";
+    private static final String ADMIN_ROLE_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP,
+            GlobalIds.ROLE_OBJECT_CLASS_NM,
+            GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME,
+            POOLS_AUX_OBJECT_CLASS_NAME,
+            GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+    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,
+            ROLE_OSP,
+            ROLE_OSU,
+            ROLE_RANGE,
+            GlobalIds.PARENT_NODES
+    };
+
+
+    /**
+     * 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.
+     */
+    public final AdminRole create( AdminRole entity )
+        throws CreateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            LDAPAttributeSet attrs = new LDAPAttributeSet();
+            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS, ADMIN_ROLE_OBJ_CLASS ) );
+            entity.setId();
+            attrs.add( createAttribute( GlobalIds.FT_IID, entity.getId() ) );
+            attrs.add( createAttribute( ROLE_NM, entity.getName() ) );
+            // description field is optional on this object class:
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                attrs.add( createAttribute( GlobalIds.DESC, entity.getDescription() ) );
+            }
+            // CN attribute is required for this object class:
+            attrs.add( createAttribute( GlobalIds.CN, entity.getName() ) );
+            attrs.add( createAttribute( GlobalIds.CONSTRAINT, CUtil.setConstraint( entity ) ) );
+            loadAttrs( entity.getOsP(), attrs, ROLE_OSP );
+            loadAttrs( entity.getOsU(), attrs, ROLE_OSU );
+            String szRaw = entity.getRoleRangeRaw();
+            if ( VUtil.isNotNullOrEmpty( szRaw ) )
+            {
+                attrs.add( createAttribute( ROLE_RANGE, szRaw ) );
+            }
+            // These multi-valued attributes are optional.  The utility function will return quietly if no items are loaded into collection:
+            loadAttrs( entity.getParents(), attrs, GlobalIds.PARENT_NODES );
+
+            LDAPEntry myEntry = new LDAPEntry( dn, attrs );
+            ld = getAdminConnection();
+            add( ld, myEntry, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "create role [" + entity.getName() + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new CreateException( GlobalErrIds.ARLE_ADD_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * 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.
+     */
+    public final AdminRole update( AdminRole entity )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                LDAPAttribute desc = new LDAPAttribute( GlobalIds.DESC, entity.getDescription() );
+                mods.add( LDAPModification.REPLACE, desc );
+            }
+            if ( VUtil.isNotNullOrEmpty( entity.getOccupants() ) )
+            {
+                for ( String name : entity.getOccupants() )
+                {
+                    LDAPAttribute occupant = new LDAPAttribute( ROLE_OCCUPANT, name );
+                    mods.add( LDAPModification.REPLACE, occupant );
+                }
+            }
+            if ( entity.isTemporalSet() )
+            {
+                String szRawData = CUtil.setConstraint( entity );
+                if ( VUtil.isNotNullOrEmpty( szRawData ) )
+                {
+                    LDAPAttribute constraint = new LDAPAttribute( GlobalIds.CONSTRAINT, szRawData );
+                    mods.add( LDAPModification.REPLACE, constraint );
+                }
+            }
+            loadAttrs( entity.getOsU(), mods, ROLE_OSU );
+            loadAttrs( entity.getOsP(), mods, ROLE_OSP );
+            String szRaw = entity.getRoleRangeRaw();
+            if ( VUtil.isNotNullOrEmpty( szRaw ) )
+            {
+                LDAPAttribute raw = new LDAPAttribute( ROLE_RANGE, szRaw );
+                mods.add( LDAPModification.REPLACE, raw );
+            }
+            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.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ARLE_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     *
+     * @param entity
+     * @throws UpdateException
+     */
+    public final void deleteParent( AdminRole entity )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute occupant = new LDAPAttribute( GlobalIds.PARENT_NODES );
+            mods.add( LDAPModification.DELETE, occupant );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "deleteParent name [" + entity.getName() + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ARLE_REMOVE_PARENT_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * 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.
+     */
+    public final AdminRole assign( AdminRole entity, String userDn )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute occupant = new LDAPAttribute( ROLE_OCCUPANT, userDn );
+            mods.add( LDAPModification.ADD, occupant );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "assign role name [" + entity.getName() + "] user dn [" + userDn + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ARLE_USER_ASSIGN_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * 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.
+     */
+    public final AdminRole deassign( AdminRole entity, String userDn )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute occupant = new LDAPAttribute( ROLE_OCCUPANT, userDn );
+            mods.add( LDAPModification.DELETE, occupant );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "deassign role name [" + entity.getName() + "] user dn [" + userDn
+                + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ARLE_USER_DEASSIGN_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * 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.
+     */
+    public final void remove( AdminRole role )
+        throws RemoveException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( role );
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, dn, role );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "remove role name=" + role.getName() + " LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new RemoveException( GlobalErrIds.ARLE_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * 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.
+     */
+    public final AdminRole getRole( AdminRole adminRole )
+        throws FinderException
+    {
+        AdminRole entity = null;
+        LDAPConnection ld = null;
+        String dn = getDn( adminRole );
+        try
+        {
+            ld = getAdminConnection();
+            LDAPEntry findEntry = read( ld, dn, ROLE_ATRS );
+            entity = unloadLdapEntry( findEntry, 0, adminRole.getContextId() );
+            if ( entity == null )
+            {
+                String warning = "getRole name [" + adminRole.getName() + "] no entry found dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.ARLE_NOT_FOUND, warning );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "getRole name [" + adminRole.getName() + "] Obj COULD NOT FIND ENTRY for dn [" + dn
+                    + "]";
+                throw new FinderException( GlobalErrIds.ARLE_NOT_FOUND, warning );
+            }
+            String error = "getRole dn [" + dn + "] LEXCD=" + e.getLDAPResultCode() + " LEXMSG=" + e;
+            throw new FinderException( GlobalErrIds.ARLE_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param adminRole
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final List<AdminRole> findRoles( AdminRole adminRole )
+        throws FinderException
+    {
+        List<AdminRole> roleList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String roleRoot = getRootDn( adminRole.getContextId(), GlobalIds.ADMIN_ROLE_ROOT );
+        String filter;
+        try
+        {
+            String searchVal = encodeSafeText( adminRole.getName(), GlobalIds.ROLE_LEN );
+            filter = GlobalIds.FILTER_PREFIX + GlobalIds.ROLE_OBJECT_CLASS_NM + ")("
+                + ROLE_NM + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            searchResults = search( ld, roleRoot,
+                LDAPConnection.SCOPE_ONE, filter, ROLE_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                roleList.add( unloadLdapEntry( searchResults.next(), sequence++, adminRole.getContextId() ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findRoles name [" + adminRole.getName() + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return roleList;
+    }
+
+
+    /**
+     * @param adminRole
+     * @param limit
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final List<String> findRoles( AdminRole adminRole, int limit )
+        throws FinderException
+    {
+        List<String> roleList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String roleRoot = getRootDn( adminRole.getContextId(), GlobalIds.ADMIN_ROLE_ROOT );
+        String filter;
+        String searchVal = null;
+        try
+        {
+            searchVal = encodeSafeText( adminRole.getName(), GlobalIds.ROLE_LEN );
+            filter = GlobalIds.FILTER_PREFIX + GlobalIds.ROLE_OBJECT_CLASS_NM + ")("
+                + ROLE_NM + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            searchResults = search( ld, roleRoot,
+                LDAPConnection.SCOPE_ONE, filter, ROLE_NM_ATR, false, GlobalIds.BATCH_SIZE, limit );
+            while ( searchResults.hasMoreElements() )
+            {
+                LDAPEntry entry = searchResults.next();
+                roleList.add( getAttribute( entry, ROLE_NM ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findRoles name [" + searchVal + "] caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return roleList;
+    }
+
+
+    /**
+     * @param userDn
+     * @return
+     * @throws FinderException
+     */
+    public final List<String> findAssignedRoles( String userDn, String contextId )
+        throws FinderException
+    {
+        List<String> roleNameList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String roleRoot = getRootDn( contextId, GlobalIds.ADMIN_ROLE_ROOT );
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + GlobalIds.ROLE_OBJECT_CLASS_NM + ")";
+            filter += "(" + ROLE_OCCUPANT + "=" + userDn + "))";
+            ld = getAdminConnection();
+            searchResults = search( ld, roleRoot,
+                LDAPConnection.SCOPE_ONE, filter, ROLE_NM_ATR, false, GlobalIds.BATCH_SIZE );
+            while ( searchResults.hasMoreElements() )
+            {
+                roleNameList.add( getAttribute( searchResults.next(), ROLE_NM ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findAssignedRoles userDn [" + userDn + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_OCCUPANT_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return roleNameList;
+    }
+
+
+    /**
+      *
+      * @param contextId
+      * @return
+      * @throws FinderException
+      */
+    public final List<Graphable> getAllDescendants( String contextId )
+        throws FinderException
+    {
+        String[] DESC_ATRS =
+            { ROLE_NM, GlobalIds.PARENT_NODES };
+        List<Graphable> descendants = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String roleRoot = getRootDn( contextId, GlobalIds.ADMIN_ROLE_ROOT );
+        String filter = null;
+        try
+        {
+            filter = GlobalIds.FILTER_PREFIX + GlobalIds.ROLE_OBJECT_CLASS_NM + ")("
+                + GlobalIds.PARENT_NODES + "=*))";
+            ld = getAdminConnection();
+            searchResults = search( ld, roleRoot,
+                LDAPConnection.SCOPE_ONE, filter, DESC_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                descendants.add( unloadDescendants( searchResults.next(), sequence++, contextId ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "getAllDescendants filter [" + filter + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return descendants;
+    }
+
+
+    /**
+    *
+    * @param le
+    * @param sequence
+    * @param contextId
+    * @return
+    * @throws LDAPException
+    */
+    private Graphable unloadDescendants( LDAPEntry le, long sequence, String contextId )
+    {
+        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
+     * @return
+     * @throws LDAPException
+     */
+    private AdminRole unloadLdapEntry( LDAPEntry le, long sequence, String contextId )
+    {
+        AdminRole entity = new ObjectFactory().createAdminRole();
+        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.setOsP( getAttributeSet( le, ROLE_OSP ) );
+        entity.setOsU( getAttributeSet( le, ROLE_OSU ) );
+        unloadTemporal( le, entity );
+        entity.setRoleRangeRaw( getAttribute( le, ROLE_RANGE ) );
+        //entity.setParents(AdminRoleUtil.getParents(entity.getName().toUpperCase(), contextId));
+        entity.setParents( getAttributeSet( le, GlobalIds.PARENT_NODES ) );
+        entity.setChildren( AdminRoleUtil.getChildren( entity.getName().toUpperCase(), contextId ) );
+        return entity;
+    }
+
+
+    private String getDn( AdminRole adminRole )
+    {
+        return GlobalIds.CN + "=" + adminRole.getName() + ","
+            + getRootDn( adminRole.getContextId(), GlobalIds.ADMIN_ROLE_ROOT );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/AuditDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/AuditDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/AuditDAO.java
new file mode 100755
index 0000000..ea7e16c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/AuditDAO.java
@@ -0,0 +1,835 @@
+/*
+ *   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.unboundid;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.cfg.Config;
+import org.apache.directory.fortress.core.ldap.UnboundIdDataProvider;
+import org.apache.directory.fortress.core.rbac.AuthZ;
+import org.apache.directory.fortress.core.rbac.Bind;
+import org.apache.directory.fortress.core.rbac.Mod;
+import org.apache.directory.fortress.core.rbac.UserAudit;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPSearchResults;
+
+
+/**
+ * This class performs data access for OpenLDAP synch repl log data
+ * <p/>
+ * <h3>1. Binds</h3>
+ * <p/>
+ * The auditBind Structural object class is used to store authentication events that can later be queried via ldap API.<br />
+ * <code># The Bind class includes the reqVersion attribute which contains the LDAP</code>
+ * <code># protocol version specified in the Bind as well as the reqMethod attribute</code>
+ * <code># which contains the Bind Method used in the Bind. This will be the string</code>
+ * <code># SIMPLE for LDAP Simple Binds or SASL(mech) for SASL Binds. Note that unless</code>
+ * <code># configured as a global overlay, only Simple Binds using DNs that reside in</code>
+ * <code># the current database will be logged:</code>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass (  1.3.6.1.4.1.4203.666.11.5.2.6 NAME 'auditBind'</code>
+ * <li> <code>DESC 'Bind operation'</code>
+ * <li> <code>SUP auditObject STRUCTURAL</code>
+ * <li> <code>MUST ( reqVersion $ reqMethod ) )</code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <h3>2. Authorizations</h3>
+ * <code>For  the  Search class the reqScope attribute contains the scope of the</code><br />
+ * <code>original search request, using the values specified for  the  LDAP  URL</code><br />
+ * <code>format. I.e.  base, one, sub, or subord.  The reqDerefAliases attribute</code><br />
+ * <code>is one of never, finding, searching, or always,  denoting  how  aliases</code><br />
+ * <code>will  be  processed during the search.  The reqAttrsOnly attribute is a</code><br />
+ * <code>Boolean value showing TRUE if only attribute names were  requested,  or</code><br />
+ * <code>FALSE  if  attributes  and  their values were requested.  The reqFilter</code><br />
+ * <code>attribute carries the filter used in the search request.   The  reqAttr</code><br />
+ * <code>attribute  lists  the  requested attributes if specific attributes were</code><br />
+ * <code>requested.  The reqEntries attribute is the integer count of  how  many</code><br />
+ * <code>entries  were  returned  by  this search request.  The reqSizeLimit and</code><br />
+ * <code>reqTimeLimit attributes indicate what  limits  were  requested  on  the</code><br />
+ * <code>search operation.</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass  (  1.3.6.1.4.1.4203.666.11.5.2.11</code>
+ * <li> <code>NAME 'auditSearch'</code>
+ * <li> <code>DESC 'Search operation'</code>
+ * <li> <code>SUP auditReadObject STRUCTURAL</code>
+ * <li> <code>MUST ( reqScope $ reqDerefAliases $ reqAttrsOnly )</code>
+ * <li> <code>MAY ( reqFilter $ reqAttr $ reqEntries $ reqSizeLimit $</code>
+ * <li> <code>reqTimeLimit ) )</code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <p/>
+ * <p/>
+ * <h3>3. Modifications</h3>
+ * The auditModify Structural object class is used to store Fortress update and delete events that can later be queried via ldap API.<br />
+ * The deletions can be recorded in this manner and associated with Fortress context because deletions will perform a modification first
+ * if audit is enabled.
+ * <p/>
+ * <code>The Modify operation contains a description  of  modifications  in  the</code><br />
+ * <code>reqMod  attribute,  which  was  already  described  above  in  the  Add</code><br />
+ * <code>operation. It may optionally  contain  the  previous  contents  of  any</code><br />
+ * <code>modified  attributes  in the reqOld attribute, using the same format as</code><br />
+ * <code>described above for the Delete operation.  The reqOld attribute is only</code><br />
+ * <code>populated  if  the  entry  being modified matches the configured logold</code><br />
+ * <code>filter.</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass (  1.3.6.1.4.1.4203.666.11.5.2.9</code>
+ * <li> <code>NAME 'auditModify'</code>
+ * <li> <code>DESC 'Modify operation'</code>
+ * <li> <code>SUP auditWriteObject STRUCTURAL</code>
+ * <li> <code>MAY reqOld MUST reqMod )</code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <p/>
+ * Note this class used descriptions pulled from man pages on slapd access log.
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+public final class AuditDAO extends UnboundIdDataProvider implements org.apache.directory.fortress.core.rbac.dao.AuditDAO
+{
+    private static final String CREATETIMESTAMP = "createTimestamp";
+    private static final String CREATORSNAME = "creatorsName";
+    private static final String ENTRYCSN = "entryCSN";
+    private static final String ENTRYDN = "entryDN";
+    private static final String ENTRYUUID = "entryUUID";
+    private static final String HASSUBORDINATES = "hasSubordinates";
+    private static final String MODIFIERSNAME = "modifiersName";
+    private static final String MODIFYTIMESTAMP = "modifyTimestamp";
+    private static final String OBJECTCLASS = "objectClass";
+    private static final String REQUAUTHZID = "reqAuthzID";
+    private static final String REQCONTROLS = "reqControls";
+    private static final String REQDN = "reqDN";
+    private static final String REQEND = "reqEnd";
+    private static final String REQMETHOD = "reqMethod";
+    private static final String REQRESULT = "reqResult";
+    private static final String REQSESSION = "reqSession";
+    private static final String REQSTART = "reqStart";
+    private static final String REQTYPE = "reqType";
+    private static final String REQVERSION = "reqVersion";
+    private static final String REQMOD = "reqMod";
+    private static final String STRUCTURALOBJECTCLASS = "structuralObjectClass";
+    private static final String SUBSCHEMAENTRY = "subschemaSubentry";
+    private static final String REQATTR = "reqAttr";
+    private static final String REQATTRSONLY = "reqAttrsOnly";
+    private static final String REQDREFALIASES = "reqDerefAliases";
+    private static final String REQENTRIES = "reqEntries";
+    private static final String REQFILTER = "reqFilter";
+    private static final String REQSCOPE = "reqScope";
+    private static final String REQSIZELIMIT = "reqSizeLimit";
+    private static final String REQTIMELIMIT = "reqTimeLimit";
+    private static final String REQASSERTION = "reqAssertion";
+    private static final String ACCESS_BIND_CLASS_NM = "auditBind";
+    //private static final String ACCESS_AUTHZ_CLASS_NM = "auditSearch";
+    private static final String ACCESS_AUTHZ_CLASS_NM = "auditCompare";
+    private static final String ACCESS_MOD_CLASS_NM = "auditModify";
+    private static final String ACCESS_ADD_CLASS_NM = "auditAdd";
+    private static final String AUDIT_ROOT = "audit.root";
+
+    private static final String[] AUDIT_AUTHZ_ATRS =
+        {
+            CREATETIMESTAMP, CREATORSNAME, ENTRYCSN, ENTRYDN, ENTRYUUID, HASSUBORDINATES, MODIFIERSNAME,
+            MODIFYTIMESTAMP, OBJECTCLASS, REQATTR, REQATTRSONLY, REQUAUTHZID, REQCONTROLS, REQDN, REQDREFALIASES,
+            REQEND, REQENTRIES, REQFILTER, REQRESULT, REQSCOPE, REQSESSION, REQSIZELIMIT, REQSTART, REQTIMELIMIT,
+            REQTYPE, REQASSERTION, STRUCTURALOBJECTCLASS, SUBSCHEMAENTRY
+    };
+
+    private static final String[] AUDIT_BIND_ATRS =
+        {
+            CREATETIMESTAMP, CREATORSNAME, ENTRYCSN, ENTRYDN, ENTRYUUID, HASSUBORDINATES, MODIFIERSNAME,
+            MODIFYTIMESTAMP, OBJECTCLASS, REQUAUTHZID, REQCONTROLS, REQDN, REQEND, REQMETHOD, REQRESULT,
+            REQSESSION, REQSTART, REQTYPE, REQVERSION, STRUCTURALOBJECTCLASS, SUBSCHEMAENTRY
+    };
+
+    private static final String[] AUDIT_MOD_ATRS =
+        {
+            OBJECTCLASS, REQUAUTHZID, REQDN, REQEND, REQRESULT, REQSESSION, REQSTART, REQTYPE, REQMOD
+    };
+
+
+    /**
+     * This method returns failed authentications where the userid is not present in the directory.  This
+     * is possible because Fortress performs read on user before the bind.
+     * User:
+     * dn: reqStart=20101014235402.000000Z, cn=log
+     * reqStart: 20101014235402.000000Z
+     * reqEnd: 20101014235402.000001Z
+     * reqAuthzID: cn=Manager,dc=jts,dc=com
+     * reqDerefAliases: never
+     * reqSession: 84
+     * reqAttrsOnly: FALSE
+     * reqSizeLimit: -1
+     * objectClass: auditSearch
+     * reqResult: 32
+     * reqAttr: ftId
+     * reqAttr: uid
+     * reqAttr: userpassword
+     * reqAttr: description
+     * reqAttr: ou
+     * reqAttr: cn
+     * reqAttr: sn
+     * reqAttr: ftRoleCstr
+     * reqAttr: ftCstr
+     * reqAttr: ftRoleAsgn
+     * reqAttr: pwdReset
+     * reqAttr: pwdAccountLockedTime
+     * reqAttr: ftProps
+     * reqEntries: 0
+     * reqFilter: (|(objectClass=*)(?objectClass=ldapSubentry))
+     * reqType: search
+     * reqDN: uid=foo,ou=People,dc=jts,dc=com        /cal/cal2.jsp
+     * reqTimeLimit: -1
+     * reqScope: base
+     *
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<AuthZ> searchInvalidAuthNs( UserAudit audit )
+        throws FinderException
+    {
+        List<AuthZ> auditList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+        String userRoot = Config.getProperty( GlobalIds.USER_ROOT );
+        try
+        {
+            // use wildcard for user if not passed in:
+            //reqDN: uid=foo,ou=People,dc=jts,dc=com
+            //(&
+            //  (objectclass=auditSearch)
+            //      (reqDN=uid=*,ou=People,dc=jts,dc=com)
+            //      (reqAuthzID=cn=Manager,dc=jts,dc=com)
+            //      (reqEntries=0)
+            // )
+
+            String filter = GlobalIds.FILTER_PREFIX + ACCESS_AUTHZ_CLASS_NM + ")(";
+            String userId;
+            if ( VUtil.isNotNullOrEmpty( audit.getUserId() ) )
+            {
+                userId = audit.getUserId();
+                filter += REQDN + "=" + GlobalIds.UID + "=" + userId + "," + userRoot + ")(" +
+                    REQUAUTHZID + "=" + "cn=Manager," + Config.getProperty( GlobalIds.SUFFIX ) + ")";
+            }
+            else
+            {
+                // pull back all failed authN attempts for all users:
+                filter += REQATTR + "=" + GlobalIds.UID + ")(" +
+                    REQUAUTHZID + "=" + "cn=Manager," + Config.getProperty( GlobalIds.SUFFIX ) + ")";
+            }
+
+            if ( audit.isFailedOnly() )
+            {
+                filter += "(" + REQENTRIES + "=" + 0 + ")";
+            }
+            if ( audit.getBeginDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                filter += "(" + REQEND + ">=" + szTime + ")";
+            }
+            filter += ")";
+
+            //log.warn("filter=" + filter);
+            ld = getLogConnection();
+            searchResults = search( ld, auditRoot,
+                LDAPConnection.SCOPE_ONE, filter, AUDIT_AUTHZ_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                AuthZ authZ = getAuthzEntityFromLdapEntry( searchResults.next(), sequence++ );
+                // todo: fix this workaround. This search will return failed role assign searches as well.  
+                // Work around is to remove the ou=People failed searches from user failed searches on authN.
+                if ( !AttrHelper.getAuthZId( authZ.getReqDN() ).equalsIgnoreCase( "People" ) )
+                    auditList.add( authZ );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "LDAPException in AuditDAO.searchAuthZs id=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_AUTHN_INVALID_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+        return auditList;
+    }
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<AuthZ> searchAuthZs( UserAudit audit )
+        throws FinderException
+    {
+        List<AuthZ> auditList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+        String permRoot = getRootDn( audit.isAdmin(), audit.getContextId() );
+        String userRoot = getRootDn( audit.getContextId(), GlobalIds.USER_ROOT );
+        try
+        {
+            String reqDn = PermDAO.getOpRdn( audit.getOpName(), audit.getObjId() ) + "," + GlobalIds.POBJ_NAME + "="
+                + audit.getObjName() + "," + permRoot;
+            String filter = GlobalIds.FILTER_PREFIX + ACCESS_AUTHZ_CLASS_NM + ")(" + REQDN + "=" +
+                reqDn + ")(" + REQUAUTHZID + "=" + GlobalIds.UID + "=" + audit.getUserId() + "," + userRoot + ")";
+/*
+            todo: fixme (can't search on reqAssertion attribute):
+            if ( audit.isFailedOnly() )
+            {
+                //filter += "(!(" + REQRESULT + "=" + 6 + "))";
+                filter += "(" + REQASSERTION + "=" + GlobalIds.AUTH_Z_FAILED_VALUE + ")";
+            }
+*/
+            if ( audit.getBeginDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                filter += "(" + REQEND + ">=" + szTime + ")";
+            }
+            filter += ")";
+
+            //System.out.println("filter=" + filter);
+            ld = getLogConnection();
+            searchResults = search( ld, auditRoot,
+                LDAPConnection.SCOPE_ONE, filter, AUDIT_AUTHZ_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                auditList.add( getAuthzEntityFromLdapEntry( searchResults.next(), sequence++ ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "LDAPException in AuditDAO.searchAuthZs id=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_AUTHZ_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+        return auditList;
+    }
+
+
+    private String getRootDn( boolean isAdmin, String contextId )
+    {
+        String dn;
+        if ( isAdmin )
+        {
+            dn = getRootDn( contextId, GlobalIds.ADMIN_PERM_ROOT );
+        }
+        else
+        {
+            dn = getRootDn( contextId, GlobalIds.PERM_ROOT );
+        }
+        return dn;
+    }
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<AuthZ> getAllAuthZs( UserAudit audit )
+        throws FinderException
+    {
+        List<AuthZ> auditList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+        String userRoot = getRootDn( audit.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + ACCESS_AUTHZ_CLASS_NM + ")(";
+            if (VUtil.isNotNullOrEmpty( audit.getUserId() ) )
+            {
+                filter += REQUAUTHZID + "=" + GlobalIds.UID + "=" + audit.getUserId() + "," + userRoot + ")";
+            }
+            else
+            {
+                // have to limit the query to only authorization entries.
+                // TODO: determine why the cn=Manager user is showing up in this search:
+                filter += REQUAUTHZID + "=*)(!(" + REQUAUTHZID + "=cn=Manager," + Config.getProperty(GlobalIds.SUFFIX) + "))";
+            }
+            //if( VUtil.isNotNullOrEmpty( audit.getObjName() ) && VUtil.isNotNullOrEmpty( audit.getOpName() ) )
+            if( VUtil.isNotNullOrEmpty( audit.getDn() ) )
+            {
+                //filter += "(" + REQDN + "=" + GlobalIds.POP_NAME + "=" + audit.getOpName() + "," + GlobalIds.POBJ_NAME + "=" + audit.getObjName() + ",*)";
+                filter += "(" + REQDN + "=" + audit.getDn() + ")";
+            }
+/*
+            todo: fixme (can't search on reqAssertion attribute):
+            if (audit.isFailedOnly())
+            {
+                //filter += "(!(" + REQRESULT + "=" + 6 + "))";
+                filter += "(" + REQASSERTION + "=" + GlobalIds.AUTH_Z_FAILED_VALUE + ")";
+            }
+*/
+            if ( audit.getBeginDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                filter += "(" + REQEND + ">=" + szTime + ")";
+            }
+            if (audit.getEndDate() != null)
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime(audit.getEndDate());
+                filter += "(" + REQEND + "<=" + szTime + ")";
+            }
+            filter += ")";
+
+            //log.warn("filter=" + filter);
+            ld = getLogConnection();
+            searchResults = search( ld, auditRoot,
+                LDAPConnection.SCOPE_ONE, filter, AUDIT_AUTHZ_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                auditList.add( getAuthzEntityFromLdapEntry( searchResults.next(), sequence++ ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "LDAPException in AuditDAO.getAllAuthZs id=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_AUTHZ_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+        return auditList;
+    }
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Bind> searchBinds( UserAudit audit )
+        throws FinderException
+    {
+        List<Bind> auditList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+        String userRoot = getRootDn( audit.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String filter;
+            if ( audit.getUserId() != null && audit.getUserId().length() > 0 )
+            {
+                filter = GlobalIds.FILTER_PREFIX + ACCESS_BIND_CLASS_NM + ")(" +
+                    REQDN + "=" + GlobalIds.UID + "=" + audit.getUserId() + "," + userRoot + ")";
+                if ( audit.isFailedOnly() )
+                {
+                    filter += "(" + REQRESULT + ">=" + 1 + ")";
+                }
+                if ( audit.getBeginDate() != null )
+                {
+                    String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                    filter += "(" + REQEND + ">=" + szTime + ")";
+                }
+                filter += ")";
+            }
+            else
+            {
+                filter = GlobalIds.FILTER_PREFIX + ACCESS_BIND_CLASS_NM + ")";
+                if ( audit.isFailedOnly() )
+                {
+                    filter += "(" + REQRESULT + ">=" + 1 + ")";
+                }
+                if ( audit.getBeginDate() != null )
+                {
+                    String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                    filter += "(" + REQEND + ">=" + szTime + ")";
+                }
+                filter += ")";
+            }
+            //log.warn("filter=" + filter);
+            ld = getLogConnection();
+            searchResults = search( ld, auditRoot,
+                LDAPConnection.SCOPE_ONE, filter, AUDIT_BIND_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                auditList.add( getBindEntityFromLdapEntry( searchResults.next(), sequence++ ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "LDAPException in AuditDAO.searchBinds id=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_BIND_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+        return auditList;
+    }
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<Mod> searchUserMods( UserAudit audit )
+        throws FinderException
+    {
+        List<Mod> modList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+
+        String userRoot = getRootDn( audit.getContextId(), GlobalIds.USER_ROOT );
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + ACCESS_MOD_CLASS_NM + ")(" +
+                REQDN + "=" + GlobalIds.UID + "=" + audit.getUserId() + "," + userRoot + ")";
+            if ( audit.getBeginDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                filter += "(" + REQEND + ">=" + szTime + ")";
+            }
+            filter += ")";
+            //log.warn("filter=" + filter);
+            ld = getLogConnection();
+            searchResults = search( ld, auditRoot,
+                LDAPConnection.SCOPE_ONE, filter, AUDIT_MOD_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                modList.add( getModEntityFromLdapEntry( searchResults.next(), sequence++ ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "searchUserMods caught LDAPException id=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_MOD_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+        return modList;
+    }
+
+
+    /**
+     * @param audit
+     * @return
+     * @throws FinderException
+     */
+    public final List<Mod> searchAdminMods( UserAudit audit )
+        throws FinderException
+    {
+        List<Mod> modList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String auditRoot = Config.getProperty( AUDIT_ROOT );
+
+        try
+        {
+            /*
+                # 20110117075053.000006Z, log
+                dn: reqStart=20110117075053.000006Z,cn=log
+                objectClass: auditModify
+                reqStart: 20110117075053.000006Z
+                reqEnd: 20110117075053.000007Z
+                reqType: modify
+                reqSession: 12
+                reqAuthzID: cn=Manager,dc=jts,dc=com
+                reqDN: ftObjId=004+ftOpNm=TOP2_4,ftObjNm=TOB2_3,ou=Permissions,ou=RBAC,dc=m
+                 ims,dc=com
+                reqResult: 0
+                reqMod: ftRoles:- ftT2ROLE5
+                reqMod: ftModifier:= -42f31b5d:12d92f18440:-7eb8
+                reqMod: ftModCode:= AdminMgrImpl.revokePermission
+                reqMod: ftModId:= -42f31b5d:12d92f18440:-6674
+                reqMod: entryCSN:= 20110117075053.093893Z#000000#000#000000
+                reqMod: modifiersName:= cn=Manager,dc=jts,dc=com
+                reqMod: modifyTimestamp:= 20110117075053Z
+
+                ldapsearch -x -D "cn=Manager,cn=log" -w secret -b 'cn=log' -s SUB -h localhost -p 389 '(&(objectclass=auditModify)(reqMod=ftModCode:= AdminMgrImpl.addDescendant)(reqMod=ftModifier:= -6a20c261:12d92e15581:-7eb8))'
+
+                # limit search by dn works:
+                ldapsearch -x -D "cn=Manager,cn=log" -w secret -b 'cn=log' -s SUB -h localhost -p 389 '(&(objectclass=auditModify)(reqDN=cn=Hierarchies,ou=Roles,ou=RBAC,dc=jts,dc=com))'
+
+                # wild card works on reqMod:
+                ldapsearch -x -D "cn=Manager,cn=log" -w secret -b 'cn=log' -s SUB -h localhost -p 389 '(&(objectclass=auditModify)(reqMod=ftModCode:= AdminMgrImpl.add*)(reqMod=ftModifier:= -6a20c261:12d92e15581:-7eb8))'
+
+             */
+            String filter = "(&(|(objectclass=" + ACCESS_MOD_CLASS_NM + ")";
+            filter += "(objectclass=" + ACCESS_ADD_CLASS_NM + "))";
+            if ( VUtil.isNotNullOrEmpty( audit.getDn() ) )
+            {
+                filter += "(" + REQDN + "=" + audit.getDn() + ")";
+            }
+            if ( VUtil.isNotNullOrEmpty( audit.getObjName() ) )
+            {
+                filter += "(|(" + REQMOD + "=" + GlobalIds.FT_MODIFIER_CODE + ":= " + audit.getObjName() + ".";
+                if ( VUtil.isNotNullOrEmpty( audit.getOpName() ) )
+                {
+                    filter += audit.getOpName();
+                }
+                filter += "*)";
+                filter += "(" + REQMOD + "=" + GlobalIds.FT_MODIFIER_CODE + ":+ " + audit.getObjName() + ".";
+                if ( VUtil.isNotNullOrEmpty( audit.getOpName() ) )
+                {
+                    filter += audit.getOpName();
+                }
+                filter += "*))";
+            }
+            if ( VUtil.isNotNullOrEmpty( audit.getInternalUserId() ) )
+            {
+                filter += "(|(" + REQMOD + "=" + GlobalIds.FT_MODIFIER + ":= " + audit.getInternalUserId() + ")";
+                filter += "(" + REQMOD + "=" + GlobalIds.FT_MODIFIER + ":+ " + audit.getInternalUserId() + "))";
+            }
+            if ( audit.getBeginDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getBeginDate() );
+                filter += "(" + REQEND + ">=" + szTime + ")";
+            }
+            if ( audit.getEndDate() != null )
+            {
+                String szTime = AttrHelper.encodeGeneralizedTime( audit.getEndDate() );
+                filter += "(" + REQEND + "<=" + szTime + ")";
+            }
+
+            filter += ")";
+            //log.warn("filter=" + filter);
+            ld = getLogConnection();
+            searchResults = search( ld, auditRoot,
+                LDAPConnection.SCOPE_ONE, filter, AUDIT_MOD_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                modList.add( getModEntityFromLdapEntry( searchResults.next(), sequence++ ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "searchAdminMods caught LDAPException id=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.AUDT_MOD_ADMIN_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeLogConnection( ld );
+        }
+        return modList;
+    }
+
+
+    /**
+     * @param le
+     * @return
+     * @throws LDAPException
+     */
+    private Bind getBindEntityFromLdapEntry( LDAPEntry le, long sequence )
+    {
+
+        /*
+        public class Bind
+            private String createTimestamp;
+            private String creatorsName;
+            private String entryCSN;
+            private String entryDN;
+            private String entryUUID;
+            private String hasSubordinates;
+            private String modifiersName;
+            private String modifyTimestamp;
+            private String objectClass;
+            private String reqAuthzID;
+            private String reqControls;
+            private String reqDN;
+            private String reqEnd;
+            private String reqMethod;
+            private String reqResult;
+            private String reqSession;
+            private String reqStart;
+            private String reqType;
+            private String reqVersion;
+            private String structuralObjectClass;
+            */
+
+        Bind auditBind = new ObjectFactory().createBind();
+        auditBind.setSequenceId( sequence );
+        auditBind.setCreateTimestamp( getAttribute( le, CREATETIMESTAMP ) );
+        auditBind.setCreatorsName( getAttribute( le, CREATORSNAME ) );
+        auditBind.setEntryCSN( getAttribute( le, ENTRYCSN ) );
+        auditBind.setEntryDN( getAttribute( le, ENTRYDN ) );
+        auditBind.setEntryUUID( getAttribute( le, ENTRYUUID ) );
+        auditBind.setHasSubordinates( getAttribute( le, HASSUBORDINATES ) );
+        auditBind.setModifiersName( getAttribute( le, MODIFIERSNAME ) );
+        auditBind.setModifyTimestamp( getAttribute( le, MODIFYTIMESTAMP ) );
+        auditBind.setObjectClass( getAttribute( le, OBJECTCLASS ) );
+        auditBind.setReqAuthzID( getAttribute( le, REQUAUTHZID ) );
+        auditBind.setReqControls( getAttribute( le, REQCONTROLS ) );
+        auditBind.setReqDN( getAttribute( le, REQDN ) );
+        auditBind.setReqEnd( getAttribute( le, REQEND ) );
+        auditBind.setReqMethod( getAttribute( le, REQMETHOD ) );
+        auditBind.setReqResult( getAttribute( le, REQRESULT ) );
+        auditBind.setReqSession( getAttribute( le, REQSESSION ) );
+        auditBind.setReqStart( getAttribute( le, REQSTART ) );
+        auditBind.setReqType( getAttribute( le, REQTYPE ) );
+        auditBind.setReqVersion( getAttribute( le, REQVERSION ) );
+        auditBind.setStructuralObjectClass( getAttribute( le, STRUCTURALOBJECTCLASS ) );
+        return auditBind;
+    }
+
+
+    /**
+     * @param le
+     * @return
+     * @throws LDAPException
+     */
+    private AuthZ getAuthzEntityFromLdapEntry( LDAPEntry le, long sequence )
+    {
+
+        /*
+        public class AuthZ
+        {
+            private String createTimestamp;
+            private String creatorsName;
+            private String entryCSN;
+            private String entryDN;
+            private String entryUUID;
+            private String hasSubordinates;
+            private String modifiersName;
+            private String modifyTimestamp;
+            private String objectClass;
+            private String reqAttr;
+            private String reqAttrsOnly;
+            private String reqAuthzID;
+            private String reqControls;
+            private String reqDN;
+            private String reqDerefAliases;
+            private String reqEnd;
+            private String reqEntries;
+            private String reqFilter;
+            private String reqResult;
+            private String reqScope;
+            private String reqSession;
+            private String reqSizeLimit;
+            private String reqStart;
+            private String reqTimeLimit;
+            private String reqType;
+            private String reqAssertion;
+            private String structuralObjectClass;
+            private String subschemaSubentry;
+        }*/
+        // these attrs also on audit bind OC:
+        AuthZ authZ = new ObjectFactory().createAuthZ();
+        authZ.setSequenceId( sequence );
+        authZ.setCreateTimestamp( getAttribute( le, CREATETIMESTAMP ) );
+        authZ.setCreatorsName( getAttribute( le, CREATORSNAME ) );
+        authZ.setEntryCSN( getAttribute( le, ENTRYCSN ) );
+        authZ.setEntryDN( getAttribute( le, ENTRYDN ) );
+        authZ.setEntryUUID( getAttribute( le, ENTRYUUID ) );
+        authZ.setHasSubordinates( getAttribute( le, HASSUBORDINATES ) );
+        authZ.setModifiersName( getAttribute( le, MODIFIERSNAME ) );
+        authZ.setModifyTimestamp( getAttribute( le, MODIFYTIMESTAMP ) );
+        authZ.setObjectClass( getAttribute( le, OBJECTCLASS ) );
+        authZ.setReqAuthzID( getAttribute( le, REQUAUTHZID ) );
+        authZ.setReqControls( getAttribute( le, REQCONTROLS ) );
+        authZ.setReqDN( getAttribute( le, REQDN ) );
+        authZ.setReqEnd( getAttribute( le, REQEND ) );
+        authZ.setReqResult( getAttribute( le, REQRESULT ) );
+        authZ.setReqSession( getAttribute( le, REQSESSION ) );
+        authZ.setReqStart( getAttribute( le, REQSTART ) );
+        authZ.setReqType( getAttribute( le, REQTYPE ) );
+        authZ.setStructuralObjectClass( getAttribute( le, STRUCTURALOBJECTCLASS ) );
+
+        // these attrs only on audit search OC:
+        authZ.setReqAttr( getAttribute( le, REQATTR ) );
+        authZ.setReqAttrsOnly( getAttribute( le, REQATTRSONLY ) );
+        authZ.setReqDerefAliases( getAttribute( le, REQDREFALIASES ) );
+        authZ.setReqEntries( getAttribute( le, REQENTRIES ) );
+        authZ.setReqFilter( getAttribute( le, REQFILTER ) );
+        authZ.setReqScope( getAttribute( le, REQSCOPE ) );
+        authZ.setReqSizeLimit( getAttribute( le, REQSIZELIMIT ) );
+        authZ.setReqTimeLimit( getAttribute( le, REQTIMELIMIT ) );
+        authZ.setReqAssertion( getAttribute( le, REQASSERTION ) );
+        return authZ;
+    }
+
+
+    private Mod getModEntityFromLdapEntry( LDAPEntry le, long sequence )
+    {
+        /*
+        public class Mod
+        {
+            private String reqSession;
+            private String objectClass;
+            private String reqAuthzID;
+            private String reqDN;
+            private String reqResult;
+            private String reqStart;
+            private String reqEnd;
+            private String reqType;
+            private String[] reqMod;
+        }
+        */
+
+        Mod mod = new ObjectFactory().createMod();
+        mod.setSequenceId( sequence );
+        mod.setObjectClass( getAttribute( le, OBJECTCLASS ) );
+        mod.setReqAuthzID( getAttribute( le, REQUAUTHZID ) );
+        mod.setReqDN( getAttribute( le, REQDN ) );
+        mod.setReqEnd( getAttribute( le, REQEND ) );
+        mod.setReqResult( getAttribute( le, REQRESULT ) );
+        mod.setReqSession( getAttribute( le, REQSESSION ) );
+        mod.setReqStart( getAttribute( le, REQSTART ) );
+        mod.setReqType( getAttribute( le, REQTYPE ) );
+        mod.setReqMod( getAttributes( le, REQMOD ) );
+        return mod;
+    }
+}
\ 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/unboundid/OrgUnitDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/OrgUnitDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/OrgUnitDAO.java
new file mode 100755
index 0000000..b0d66fc
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/OrgUnitDAO.java
@@ -0,0 +1,621 @@
+/*
+ *   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.unboundid;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.UnboundIdDataProvider;
+import org.apache.directory.fortress.core.rbac.Graphable;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.PsoUtil;
+import org.apache.directory.fortress.core.rbac.UsoUtil;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttribute;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModification;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModificationSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPSearchResults;
+
+
+/**
+ * This class provides dataaccess to the OrgUnit datasets in LDAP.
+ * <p/>
+ * The OrgUnitDAO maintains the following structural and aux object classes:
+ * <h4>1. organizationalUnit Structural Object Class is used to store basic attributes like ou and description</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 2.5.6.5 NAME 'organizationalUnit'</code>
+ * <li> <code>DESC 'RFC2256: an organizational unit'</code>
+ * <li> <code>SUP top STRUCTURAL</code>
+ * <li> <code>MUST ou</code>
+ * <li> <code>MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $</code>
+ * <li> <code>x121Address $ registeredAddress $ destinationIndicator $</code>
+ * <li> <code>preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $</code>
+ * <li> <code>telephoneNumber $ internationaliSDNNumber $</code>
+ * <li> <code>facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $</code>
+ * <li> <code>postalAddress $ physicalDeliveryOfficeName $ st $ l $ description ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>2. ftOrgUnit Structural objectclass is used to store the OrgUnit internal id</h4>
+ * <ul>                                                              org.apache.directory.fortress.arbac.
+ * <li>  ------------------------------------------
+ * <li> <code> objectclass	( 1.3.6.1.4.1.38088.2.6</code>
+ * <li> <code>NAME 'ftOrgUnit'</code>
+ * <li> <code>DESC 'Fortress OrgUnit Class'</code>
+ * <li> <code>SUP organizationalunit</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST ( ftId ) )</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
+ * @created September 18, 2010
+ */
+public final class OrgUnitDAO extends UnboundIdDataProvider implements org.apache.directory.fortress.core.rbac.dao.OrgUnitDAO
+{
+    private static final String CLS_NM = OrgUnitDAO.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final String ORGUNIT_OBJECT_CLASS_NM = "ftOrgUnit";
+
+    private static final String ORGUNIT_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP, ORGUNIT_OBJECT_CLASS_NM, GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+    private static final String[] ORGUNIT_ATRS =
+        {
+            GlobalIds.FT_IID, GlobalIds.OU, GlobalIds.DESC, GlobalIds.PARENT_NODES
+    };
+
+    private static final String[] ORGUNIT_ATR =
+        {
+            GlobalIds.OU
+    };
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    public final OrgUnit create( OrgUnit entity )
+        throws CreateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            LDAPAttributeSet attrs = new LDAPAttributeSet();
+            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS, ORGUNIT_OBJ_CLASS ) );
+            entity.setId();
+            attrs.add( createAttribute( GlobalIds.FT_IID, entity.getId() ) );
+            if ( entity.getDescription() != null && entity.getDescription().length() > 0 )
+                attrs.add( createAttribute( GlobalIds.DESC, entity.getDescription() ) );
+            // organizational name requires OU attribute:
+            attrs.add( createAttribute( GlobalIds.OU, entity.getName() ) );
+
+            // These multi-valued attributes are optional.  The utility function will return quietly if no items are loaded into collection:
+            loadAttrs( entity.getParents(), attrs, GlobalIds.PARENT_NODES );
+
+            LDAPEntry myEntry = new LDAPEntry( dn, attrs );
+            ld = getAdminConnection();
+            add( ld, myEntry, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "create orgUnit name [" + entity.getName() + "] type [" + entity.getType()
+                + "] root [" + dn + "] caught LDAPException=" + e;
+            int errCode;
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_ADD_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_ADD_FAILED_USER;
+
+            }
+            throw new CreateException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    public final OrgUnit update( OrgUnit entity )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            if ( entity.getDescription() != null && entity.getDescription().length() > 0 )
+            {
+                LDAPAttribute desc = new LDAPAttribute( GlobalIds.DESC, entity.getDescription() );
+                mods.add( LDAPModification.REPLACE, desc );
+            }
+            loadAttrs( entity.getParents(), mods, GlobalIds.PARENT_NODES );
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods, entity );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "update orgUnit name [" + entity.getName() + "] type [" + entity.getType()
+                + "] root [" + dn + "] caught LDAPException=" + e;
+            int errCode;
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_UPDATE_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_UPDATE_FAILED_USER;
+            }
+
+            throw new UpdateException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    public final void deleteParent( OrgUnit entity )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute occupant = new LDAPAttribute( GlobalIds.PARENT_NODES );
+            mods.add( LDAPModification.DELETE, occupant );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "deleteParent orgUnit name [" + entity.getName() + "] type [" + entity.getType()
+                + "] root [" + dn + "] caught LDAPException=" + e;
+            int errCode;
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_REMOVE_PARENT_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_REMOVE_PARENT_FAILED_USER;
+            }
+
+            throw new UpdateException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.RemoveException
+     *
+     */
+    public final OrgUnit remove( OrgUnit entity )
+        throws RemoveException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, dn, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "remove orgUnit name [" + entity.getName() + "] type [" + entity.getType()
+                + "] root [" + dn + "] caught LDAPException=" + e;
+            int errCode;
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_DELETE_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_DELETE_FAILED_USER;
+            }
+
+            throw new RemoveException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final OrgUnit findByKey( OrgUnit entity )
+        throws FinderException
+    {
+        OrgUnit oe = null;
+        LDAPConnection ld = null;
+        String dn = getDn( entity );
+        try
+        {
+            ld = getAdminConnection();
+            LDAPEntry findEntry = read( ld, dn, ORGUNIT_ATRS );
+            if ( findEntry == null )
+            {
+                String warning = "findByKey orgUnit name [" + entity.getName() + "] type ["
+                    + entity.getType() + "] COULD NOT FIND ENTRY for dn [" + dn + "]";
+                int errCode;
+                if ( entity.getType() == OrgUnit.Type.PERM )
+                {
+                    errCode = GlobalErrIds.ORG_NOT_FOUND_PERM;
+                }
+                else
+                {
+                    errCode = GlobalErrIds.ORG_NOT_FOUND_USER;
+                }
+                throw new FinderException( errCode, warning );
+            }
+            oe = getEntityFromLdapEntry( findEntry, 0, entity.getContextId() );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "findByKey orgUnit name [" + entity.getName() + "] type ["
+                    + entity.getType() + "] COULD NOT FIND ENTRY for dn [" + dn + "]";
+                int errCode;
+                if ( entity.getType() == OrgUnit.Type.PERM )
+                {
+                    errCode = GlobalErrIds.ORG_NOT_FOUND_PERM;
+                }
+                else
+                {
+                    errCode = GlobalErrIds.ORG_NOT_FOUND_USER;
+                }
+                throw new FinderException( errCode, warning );
+            }
+            else
+            {
+                String error = "findByKey orgUnitName [" + entity.getName() + "] type [" + entity.getType()
+                    + "] dn [" + dn + "] caught LDAPException=" + e;
+                int errCode;
+                if ( entity.getType() == OrgUnit.Type.PERM )
+                {
+                    errCode = GlobalErrIds.ORG_READ_FAILED_PERM;
+                }
+                else
+                {
+                    errCode = GlobalErrIds.ORG_READ_FAILED_USER;
+                }
+                throw new FinderException( errCode, error, e );
+            }
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return oe;
+    }
+
+
+    /**
+     * @param orgUnit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<OrgUnit> findOrgs( OrgUnit orgUnit )
+        throws FinderException
+    {
+        List<OrgUnit> orgUnitList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String orgUnitRoot = getOrgRoot( orgUnit );
+        try
+        {
+            String searchVal = encodeSafeText( orgUnit.getName(), GlobalIds.ROLE_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + ORGUNIT_OBJECT_CLASS_NM + ")("
+                + GlobalIds.OU + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            searchResults = search( ld, orgUnitRoot,
+                LDAPConnection.SCOPE_ONE, filter, ORGUNIT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                orgUnitList.add( getEntityFromLdapEntry( searchResults.next(), sequence++, orgUnit.getContextId() ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findOrgs search val [" + orgUnit.getName() + "] type [" + orgUnit.getType()
+                + "] root [" + orgUnitRoot + "] caught LDAPException=" + e;
+            int errCode;
+            if ( orgUnit.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_SEARCH_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_SEARCH_FAILED_USER;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return orgUnitList;
+    }
+
+
+    /**
+     *
+     * @param orgUnit
+     * @return
+     * @throws FinderException
+     */
+    public final Set<String> getOrgs( OrgUnit orgUnit )
+        throws FinderException
+    {
+        Set<String> ouSet = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        LDAPConnection ld = null;
+        String orgUnitRoot = getOrgRoot( orgUnit );
+        try
+        {
+            String filter = "(objectclass=" + ORGUNIT_OBJECT_CLASS_NM + ")";
+            ld = getAdminConnection();
+            LDAPSearchResults searchResults = search( ld, orgUnitRoot,
+                LDAPConnection.SCOPE_ONE, filter, ORGUNIT_ATR, false, GlobalIds.BATCH_SIZE );
+            while ( searchResults.hasMoreElements() )
+            {
+                ouSet.add( getAttribute( searchResults.next(), GlobalIds.OU ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "getOrgs type [" + orgUnit.getType() + "] root [" + orgUnitRoot
+                + "] caught LDAPException=" + e;
+            int errCode;
+            if ( orgUnit.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_GET_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_GET_FAILED_USER;
+            }
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return ouSet;
+    }
+
+
+    /**
+      *
+      * @param orgUnit
+      * @return
+      * @throws FinderException
+      */
+    public final List<Graphable> getAllDescendants( OrgUnit orgUnit )
+        throws FinderException
+    {
+        String orgUnitRoot = getOrgRoot( orgUnit );
+        String[] DESC_ATRS =
+            { GlobalIds.OU, GlobalIds.PARENT_NODES };
+        List<Graphable> descendants = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String filter = null;
+        try
+        {
+            filter = GlobalIds.FILTER_PREFIX + ORGUNIT_OBJECT_CLASS_NM + ")("
+                + GlobalIds.PARENT_NODES + "=*))";
+            ld = getAdminConnection();
+            searchResults = search( ld, orgUnitRoot,
+                LDAPConnection.SCOPE_ONE, filter, DESC_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                descendants.add( unloadDescendants( searchResults.next(), sequence++, orgUnit.getContextId() ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "getAllDescendants filter [" + filter + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return descendants;
+    }
+
+
+    /**
+     * @param orgUnit
+     * @return
+     */
+    private String getDn( OrgUnit orgUnit )
+    {
+        String dn = null;
+        switch ( orgUnit.type )
+        {
+            case USER:
+                dn = GlobalIds.OU + "=" + orgUnit.getName() + ","
+                    + getRootDn( orgUnit.getContextId(), GlobalIds.OSU_ROOT );
+                break;
+            case PERM:
+                dn = GlobalIds.OU + "=" + orgUnit.getName() + ","
+                    + getRootDn( orgUnit.getContextId(), GlobalIds.PSU_ROOT );
+                break;
+            default:
+                String warning = "getDn invalid type";
+                LOG.warn( warning );
+                break;
+        }
+        return dn;
+    }
+
+
+    /**
+     *
+     * @param orgUnit
+     * @return
+     */
+    private String getOrgRoot( OrgUnit orgUnit )
+    {
+        String dn = null;
+        switch ( orgUnit.type )
+        {
+            case USER:
+                dn = getRootDn( orgUnit.getContextId(), GlobalIds.OSU_ROOT );
+                break;
+            case PERM:
+                dn = getRootDn( orgUnit.getContextId(), GlobalIds.PSU_ROOT );
+                break;
+            default:
+                String warning = "getOrgRootDn invalid type";
+                LOG.warn( warning );
+                break;
+        }
+        return dn;
+    }
+
+
+    /**
+    *
+    * @param le
+    * @param sequence
+    * @param contextId
+    * @return
+    * @throws LDAPException
+    */
+    private Graphable unloadDescendants( LDAPEntry le, long sequence, String contextId )
+    {
+        OrgUnit entity = new ObjectFactory().createOrgUnit();
+        entity.setSequenceId( sequence );
+        entity.setName( getAttribute( le, GlobalIds.OU ) );
+        entity.setParents( getAttributeSet( le, GlobalIds.PARENT_NODES ) );
+        return entity;
+    }
+
+
+    /**
+     *
+     * @param le
+     * @param sequence
+     * @param contextId
+     * @return
+     * @throws LDAPException
+     */
+    private OrgUnit getEntityFromLdapEntry( LDAPEntry le, long sequence, String contextId )
+    {
+        OrgUnit entity = new ObjectFactory().createOrgUnit();
+        entity.setSequenceId( sequence );
+        entity.setId( getAttribute( le, GlobalIds.FT_IID ) );
+        entity.setName( getAttribute( le, GlobalIds.OU ) );
+        entity.setDescription( getAttribute( le, GlobalIds.DESC ) );
+        String dn = le.getDN();
+        if ( dn.contains( getRootDn( contextId, GlobalIds.PSU_ROOT ) ) )
+        {
+            entity.setType( OrgUnit.Type.PERM );
+            //entity.setParents(PsoUtil.getParents(entity.getName().toUpperCase(), contextId));
+            entity.setChildren( PsoUtil.getChildren( entity.getName().toUpperCase(), contextId ) );
+        }
+        else if ( dn.contains( getRootDn( contextId, GlobalIds.OSU_ROOT ) ) )
+        {
+            entity.setType( OrgUnit.Type.USER );
+            //entity.setParents(UsoUtil.getParents(entity.getName().toUpperCase(), contextId));
+            entity.setChildren( UsoUtil.getChildren( entity.getName().toUpperCase(), contextId ) );
+        }
+        entity.setParents( getAttributeSet( le, GlobalIds.PARENT_NODES ) );
+        return entity;
+    }
+}
\ No newline at end of file


[42/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Delsuffix.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delsuffix.java b/src/main/java/org/apache/directory/fortress/core/ant/Delsuffix.java
new file mode 100755
index 0000000..5918882
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delsuffix.java
@@ -0,0 +1,96 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.ldap.suffix.Suffix;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to create new {@link org.apache.directory.fortress.core.ldap.suffix.Suffix} used to drive {@link org.apache.directory.fortress.core.ldap.suffix.SuffixP#delete(org.apache.directory.fortress.core.ldap.suffix.Suffix)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delsuffix', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <delsuffix>
+ *   ...
+ * </delsuffix>
+ * }
+ * </pre>
+ * <font size="3" color="red">
+ * This class is destructive as it will remove all nodes below the suffix using recursive delete function.<BR>
+ * Extreme care should be taken during execution to ensure target dn is correct and permanent removal of data is intended.  There is no
+ * 'undo' for this operation.
+ * </font>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class Delsuffix
+{
+    final private List<Suffix> suffixes = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delsuffix()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addSuffix', is used for derived xml tag 'suffix' in the load script.</p>
+     * <pre>
+     * {@code
+     * <target name="all">
+     *     <FortressAdmin>
+     *         <delsuffix>
+     *           ...
+     *         </delsuffix>
+     *     </FortressAdmin>
+     * </target>
+     * }
+     * </pre>
+     * <p/>
+     * <font size="2" color="red">
+     * This method is destructive and will remove all nodes below.<BR>
+     * Extreme care should be taken during execution to ensure target dn is correct and permanent removal of data is intended.  There is no
+     * 'undo' for this operation.
+     * </font>
+     *
+     * @param suffix contains reference to data element targeted for removal..
+     */
+    public void addSuffix( Suffix suffix)
+    {
+        this.suffixes.add(suffix);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#deleteSuffixes()} to retrieve list of Suffixes as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.ldap.suffix.Suffix}s targeted for removal.
+     */
+    public List<Suffix> getSuffixes()
+    {
+        return this.suffixes;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Deluser.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Deluser.java b/src/main/java/org/apache/directory/fortress/core/ant/Deluser.java
new file mode 100755
index 0000000..ee8a721
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Deluser.java
@@ -0,0 +1,87 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link UserAnt}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#disableUser(org.apache.directory.fortress.core.rbac.User)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Deluser', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <deluser>
+ *           ...
+ *         </deluser>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Deluser
+{
+    final private List<UserAnt> users = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Deluser()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addUser', is used for derived xml tag 'user' in the load script.</p>
+     * <pre>
+     * {@code
+     * <deluser>
+     *     <user userId="demoUser1"/>
+     *     <user userId="demoUser3"/>
+     *     <user userId="demoUser4"/>
+     *     <user userId="demoUser5"/>
+     *     <user userId="demoUser7"/>
+     *     <user userId="demoUser9"/>
+     * </deluser>
+     * }
+     * </pre>
+     *
+     * @param user contains reference to data element targeted for removal.
+     */
+    public void addUser(UserAnt user)
+    {
+        this.users.add(user);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#deleteUsers()} to retrieve list of Users as defined in input xml file.
+     *
+     * @return collection containing {@link UserAnt}s targeted for removal.
+     */
+    public List<UserAnt> getUsers()
+    {
+        return this.users;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Deluseradminrole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Deluseradminrole.java b/src/main/java/org/apache/directory/fortress/core/ant/Deluseradminrole.java
new file mode 100755
index 0000000..d0191bc
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Deluseradminrole.java
@@ -0,0 +1,83 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link org.apache.directory.fortress.core.rbac.UserAdminRole}s used to drive {@link org.apache.directory.fortress.core.DelAdminMgr#deassignUser(org.apache.directory.fortress.core.rbac.UserAdminRole)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Deluseradminrole', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <deluseradminrole>
+ *           ...
+ *         </deluseradminrole>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Deluseradminrole
+{
+    final private List<UserAdminRole> userroles = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Deluseradminrole()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addUserRole', is used for derived xml tag 'userrole' in the load script.</p>
+     * <pre>
+     * {@code
+     * <deluseradminrole>
+     *     <userrole userId="demouser4" name="DemoAdminUsers"/>
+     * </deluseradminrole>
+     * }
+     * </pre>
+     *
+     * @param userRole contains reference to data element targeted for removal.
+     */
+    public void addUserRole(UserAdminRole userRole)
+    {
+        this.userroles.add(userRole);
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#delUserAdminRoles()} to retrieve list of UserAdminRoles as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.UserAdminRole}s targeted for removal.
+     */
+    public List<UserAdminRole> getUserRoles()
+    {
+        return this.userroles;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Deluserorgunitinheritance.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Deluserorgunitinheritance.java b/src/main/java/org/apache/directory/fortress/core/ant/Deluserorgunitinheritance.java
new file mode 100755
index 0000000..176738c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Deluserorgunitinheritance.java
@@ -0,0 +1,87 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.Relationship;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link Relationship}s used to drive {@link org.apache.directory.fortress.core.DelAdminMgr#deleteInheritance(org.apache.directory.fortress.core.rbac.OrgUnit, org.apache.directory.fortress.core.rbac.OrgUnit)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Deluserorgunitinheritance', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <deluserorgunitinheritance>
+ *           ...
+ *         </deluserorgunitinheritance>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ *
+ * @author Shawn McKinney
+ */
+public class Deluserorgunitinheritance
+{
+    final private List<Relationship> relationships = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Deluserorgunitinheritance()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addRelationship', is used for derived xml tag 'relationship' in the load script.</p>
+     * <pre>
+     * {@code
+     * <deluserorgunitinheritance>
+     *     <relationship child="ou2" parent="ou1"/>
+     *     <relationship child="ou3" parent="ou1"/>
+     *     <relationship child="ou4" parent="ou1"/>
+     * </deluserorgunitinheritance>
+     * }
+     * </pre>
+     *
+     * @param relationship contains reference to data element targeted for removal.
+     */
+    public void addRelationship(Relationship relationship)
+    {
+        this.relationships.add(relationship);
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#deleteUserOrgunitInheritances()} to retrieve list of User OrgUnit relationships as defined in input xml file.
+     *
+     * @return collection containing {@link Relationship}s targeted for removal.
+     */
+    public List<Relationship> getRelationships()
+    {
+        return this.relationships;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Deluserrole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Deluserrole.java b/src/main/java/org/apache/directory/fortress/core/ant/Deluserrole.java
new file mode 100755
index 0000000..15522ca
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Deluserrole.java
@@ -0,0 +1,85 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.UserRole;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link org.apache.directory.fortress.core.rbac.UserRole}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#deassignUser(org.apache.directory.fortress.core.rbac.UserRole)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Deluserrole', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <deluserrole>
+ *           ...
+ *         </deluserrole>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Deluserrole
+{
+    final private List<UserRole> userroles = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Deluserrole()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addUserRole', is used for derived xml tag 'userrole' in the load script.</p>
+     * <pre>
+     * {@code
+     * <deluserrole>
+     *     <userrole userId="demoUser1" name="role1"/>
+     *     <userrole userId="demoUser5" name="role1"/>
+     *     <userrole userId="demoUser7" name="role1"/>
+     *     <userrole userId="demoUser9" name="role1"/>
+     * </deluserrole>
+     * }
+     * </pre>
+     *
+     * @param userRole contains reference to data element targeted for removal..
+     */
+    public void addUserRole(UserRole userRole)
+    {
+        this.userroles.add(userRole);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#delUserRoles()} to retrieve list of UserRoles as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.UserRole}s targeted for removal.
+     */
+    public List<UserRole> getUserRoles()
+    {
+        return this.userroles;
+    }
+}
\ No newline at end of file


[07/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rest/AuditMgrRestImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/AuditMgrRestImpl.java b/src/main/java/org/apache/directory/fortress/core/rest/AuditMgrRestImpl.java
new file mode 100644
index 0000000..7bfbf0b
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/AuditMgrRestImpl.java
@@ -0,0 +1,384 @@
+/*
+ *   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.rest;
+
+import org.apache.directory.fortress.core.AuditMgr;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.AuthZ;
+import org.apache.directory.fortress.core.rbac.Bind;
+import org.apache.directory.fortress.core.rbac.Manageable;
+import org.apache.directory.fortress.core.rbac.Mod;
+import org.apache.directory.fortress.core.rbac.UserAudit;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class performs searches across <a href="http://www.openldap.org/">OpenLDAP</a>'s slapd access log using HTTP access to En Masse REST server.
+ * The access log events are
+ * persisted in <a href="http://www.oracle.com/technetwork/database/berkeleydb/overview/index.html">BDB</a>.
+ * Audit entries stored on behalf of Fortress operations correspond to runtime authentication {@link org.apache.directory.fortress.core.rbac.Bind}, authorization {@link org.apache.directory.fortress.core.rbac.AuthZ} and modification {@link Mod}
+ * events as they occur automatically on the server when audit is enabled.
+ * <h4>Audit Interrogator</h4>
+ * Provides an OpenLDAP access log retrieval mechanism that enables security event monitoring.
+ * <ol>
+ * <li>Authentication events:
+ * <li>Session enablement events
+ * <li>Authorization events
+ * <li>Entity mods and deletes
+ * </li>
+ * </ol>
+ * <img src="../doc-files/Audit.png">
+ * <p/>
+ * All events include Fortress context, see {@link org.apache.directory.fortress.core.rbac.FortEntity}.
+ * <p/>
+ * <h4>
+ * The following APIs generate events subsequently stored in this access log:
+ * </h4>
+ * <ul>
+ * <li> {@link org.apache.directory.fortress.core.AccessMgr}
+ * <li> {@link org.apache.directory.fortress.core.AdminMgr}
+ * <li> {@link org.apache.directory.fortress.core.AdminMgr}
+ * <li> {@link org.apache.directory.fortress.core.DelAdminMgr}
+ * <li> {@link org.apache.directory.fortress.core.cfg.ConfigMgr}
+ * <li> {@link org.apache.directory.fortress.core.PwPolicyMgr}
+ * </ul>
+ * <h4>
+ * The following reports are supported using search input: {@link org.apache.directory.fortress.core.rbac.UserAudit}
+ * </h4>
+ * <ul>
+ * <li>User Authentications:     <code>List<{@link org.apache.directory.fortress.core.rbac.Bind}>  {@link org.apache.directory.fortress.core.AuditMgr#searchBinds(org.apache.directory.fortress.core.rbac.UserAudit)}</code>
+ * <li>Invalid Users AuthN:      <code>List<{@link org.apache.directory.fortress.core.rbac.Bind}>  {@link org.apache.directory.fortress.core.AuditMgr#searchInvalidUsers(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>User Authorizations 1:    <code>List<{@link org.apache.directory.fortress.core.rbac.AuthZ}> {@link org.apache.directory.fortress.core.AuditMgr#getUserAuthZs(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>User Authorizations 2:    <code>List<{@link org.apache.directory.fortress.core.rbac.AuthZ}> {@link org.apache.directory.fortress.core.AuditMgr#searchAuthZs(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>User Session Activations: <code>List<{@link Mod}>   {@link org.apache.directory.fortress.core.AuditMgr#searchUserSessions(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * <li>Entity Modifications:     <code>List<{@link Mod}>   {@link org.apache.directory.fortress.core.AuditMgr#searchAdminMods(org.apache.directory.fortress.core.rbac.UserAudit)} </code>
+ * </ul>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class AuditMgrRestImpl extends Manageable implements AuditMgr
+{
+    private static final String CLS_NM = AuditMgrRestImpl.class.getName();
+
+    /**
+     * This method returns a list of authorization events for a particular user {@link org.apache.directory.fortress.core.rbac.UserAudit#userId}
+     * and given timestamp field {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.<BR>
+     * Method also can discriminate between all events or failed only by setting {@link org.apache.directory.fortress.core.rbac.UserAudit#failedOnly}.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId</li>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one authorization event.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if a runtime system error occurs.
+     */
+    @Override
+    public List<AuthZ> getUserAuthZs(UserAudit uAudit)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(uAudit, GlobalErrIds.AUDT_INPUT_NULL, CLS_NM + ".getUserAuthZs");
+        List<AuthZ> outRecords;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(uAudit);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.AUDIT_UAUTHZS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            outRecords = response.getEntities();
+            // do not return a null list to the caller:
+            if (outRecords == null)
+            {
+                outRecords = new ArrayList<>();
+            }
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return outRecords;
+    }
+
+
+    /**
+     * This method returns a list of authorization events for a particular user {@link org.apache.directory.fortress.core.rbac.UserAudit#userId},
+     * object {@link org.apache.directory.fortress.core.rbac.UserAudit#objName}, and given timestamp field {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.<BR>
+     * Method also can discriminate between all events or failed only by setting flag {@link org.apache.directory.fortress.core.rbac.UserAudit#failedOnly}..
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId<</li>
+     * <li>{@link UserAudit#objName} - contains the object (authorization resource) name</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one authorization event.
+     * @throws SecurityException if a runtime system error occurs.
+     */
+    @Override
+    public List<AuthZ> searchAuthZs(UserAudit uAudit)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(uAudit, GlobalErrIds.AUDT_INPUT_NULL, CLS_NM + ".searchAuthZs");
+        List<AuthZ> outRecords;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(uAudit);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.AUDIT_AUTHZS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            outRecords = response.getEntities();
+            // do not return a null list to the caller:
+            if (outRecords == null)
+            {
+                outRecords = new ArrayList<>();
+            }
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return outRecords;
+    }
+
+
+    /**
+     * This method returns a list of authentication audit events for a particular user {@link org.apache.directory.fortress.core.rbac.UserAudit#userId},
+     * and given timestamp field {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.<BR>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId<</li>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type Bind.  Each Bind object contains one bind event.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if a runtime system error occurs.
+     */
+    @Override
+    public List<Bind> searchBinds(UserAudit uAudit)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(uAudit, GlobalErrIds.AUDT_INPUT_NULL, CLS_NM + ".searchBinds");
+        List<Bind> outRecords;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(uAudit);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.AUDIT_BINDS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            outRecords = response.getEntities();
+            // do not return a null list to the caller:
+            if (outRecords == null)
+            {
+                outRecords = new ArrayList<>();
+            }
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return outRecords;
+    }
+
+    /**
+     * This method returns a list of sessions created for a given user {@link org.apache.directory.fortress.core.rbac.UserAudit#userId},
+     * and timestamp {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.<BR>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId<</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type Mod.  Each Mod object in list corresponds to one update or delete event on directory.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if a runtime system error occurs.
+     */
+    @Override
+    public List<Mod> searchUserSessions(UserAudit uAudit)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(uAudit, GlobalErrIds.AUDT_INPUT_NULL, CLS_NM + ".searchUserSessions");
+        List<Mod> outRecords;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(uAudit);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.AUDIT_SESSIONS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            outRecords = response.getEntities();
+            // do not return a null list to the caller:
+            if (outRecords == null)
+            {
+                outRecords = new ArrayList<>();
+            }
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return outRecords;
+    }
+
+    /**
+     * This method returns a list of admin operations events for a particular entity {@link org.apache.directory.fortress.core.rbac.UserAudit#dn},
+     * object {@link org.apache.directory.fortress.core.rbac.UserAudit#objName} and timestamp {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.  If the internal
+     * userId {@link org.apache.directory.fortress.core.rbac.UserAudit#internalUserId} is set it will limit search by that field.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#dn} - contains the LDAP distinguished name for the updated object.  For example if caller
+     * wants to find out what changes were made to John Doe's user object this would be 'uid=jdoe,ou=People,dc=example,dc=com'</li>
+     * <li>{@link UserAudit#objName} - contains the object (authorization resource) name corresponding to the event.  For example if caller
+     * wants to return events where User object was modified, this would be 'updateUser'</li>
+     * <li>{@link UserAudit#internalUserId} - maps to the internalUserId of user who changed the record in LDAP.  This maps to {@link org.apache.directory.fortress.core.rbac.User#internalId}.</li>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#endDate} - contains the date in which to end search</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type Mod.  Each Mod object in list corresponds to one update or delete event on directory.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if a runtime system error occurs.
+     */
+    @Override
+    public List<Mod> searchAdminMods(UserAudit uAudit)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(uAudit, GlobalErrIds.AUDT_INPUT_NULL, CLS_NM + ".searchAdminMods");
+        List<Mod> outRecords;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(uAudit);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.AUDIT_MODS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            outRecords = response.getEntities();
+            // do not return a null list to the caller:
+            if (outRecords == null)
+            {
+                outRecords = new ArrayList<>();
+            }
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return outRecords;
+    }
+
+
+    /**
+     * This method returns a list of failed authentication events for a particular invalid user {@link org.apache.directory.fortress.core.rbac.UserAudit#userId},
+     * and given timestamp {@link org.apache.directory.fortress.core.rbac.UserAudit#beginDate}.  If the {@link org.apache.directory.fortress.core.rbac.UserAudit#failedOnly} is true it will
+     * return only authentication attempts made with invalid userId.
+     * </p>
+     * This is possible because Fortress performs read on user before the bind.
+     * </p>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserAudit#userId} - contains the target userId</li>
+     * <li>{@link UserAudit#beginDate} - contains the date in which to begin search</li>
+     * <li>{@link UserAudit#failedOnly} - if set to 'true', return only failed authorization events</li>
+     * </ul>
+     *
+     * @param uAudit This entity is instantiated and populated before invocation.
+     * @return a List of objects of type AuthZ.  Each AuthZ object contains one failed authentication event.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if a runtime system error occurs.
+     */
+    @Override
+    public List<AuthZ> searchInvalidUsers(UserAudit uAudit)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(uAudit, GlobalErrIds.AUDT_INPUT_NULL, CLS_NM + ".searchInvalidUsers");
+        List<AuthZ> outRecords;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(uAudit);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.AUDIT_INVLD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            outRecords = response.getEntities();
+            // do not return a null list to the caller:
+            if (outRecords == null)
+            {
+                outRecords = new ArrayList<>();
+            }
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return outRecords;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rest/CachedJaxbContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/CachedJaxbContext.java b/src/main/java/org/apache/directory/fortress/core/rest/CachedJaxbContext.java
new file mode 100644
index 0000000..fe337a6
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/CachedJaxbContext.java
@@ -0,0 +1,90 @@
+/*
+ *   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.rest;
+
+import java.util.Hashtable;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+/**
+ * This class contains a very simple caching mechanism for storing JAXBContext objects associated with Fortress XML
+ * processing.
+ * The intent is to reduce the performance penalty for calling JAXBContext.newInstance( class );
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+@SuppressWarnings( "rawtypes" )
+public class CachedJaxbContext
+{
+
+    private static volatile Hashtable<Class, JAXBCachedEntry> jaxbInstanceCache = new Hashtable();
+
+    /**
+     * Once constructed this object can be stored as static member of class that performs JAX XML processing.
+     *
+     * @param type contains the class name that is being marshalled/unmarshalled.     *
+     * @return handle to JAXBContext to be used to marshall or unmarshall XML data.
+     * @throws JAXBException in the event the JAXBContext cannot be obtained.
+     */
+    public synchronized JAXBContext getJaxbContext( Class type ) throws JAXBException
+    {
+
+        JAXBCachedEntry cache = jaxbInstanceCache.get( type );
+        if ( cache == null )
+        {
+            cache = new JAXBCachedEntry( type );
+            jaxbInstanceCache.put( type, cache );
+            return cache.getContext();
+        }
+        return cache.getContext();
+    }
+
+    /**
+     * Return a handle to JAXB unmarshaller for a particular data type.  JAXBContext itself is thread safe.
+     *
+     * @param type contains the class name associated with a particular data type.
+     * @return handel to JAXB unmarshaller.
+     * @throws JAXBException in the event the unmarshaller cannot be retrieved.
+     */
+    public Unmarshaller createUnMarshaller( Class type ) throws JAXBException
+    {
+        JAXBContext context = getJaxbContext( type );
+        return context.createUnmarshaller();
+    }
+
+
+    /**
+     * Return a handle to JAXB unmarshaller for a particular data type.  JAXBContext itself is thread safe.
+     *
+     * @param type contains the class name associated with a particular data type.
+     * @return handel to JAXB marshaller.
+     * @throws JAXBException in the event the marshaller cannot be retrieved.
+     */
+    public Marshaller createMarshaller( Class type ) throws JAXBException
+    {
+        JAXBContext context = getJaxbContext( type );
+        return context.createMarshaller();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rest/ConfigMgrRestImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/ConfigMgrRestImpl.java b/src/main/java/org/apache/directory/fortress/core/rest/ConfigMgrRestImpl.java
new file mode 100644
index 0000000..9799ba8
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/ConfigMgrRestImpl.java
@@ -0,0 +1,199 @@
+/*
+ *   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.rest;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.cfg.ConfigMgr;
+import org.apache.directory.fortress.core.rbac.Props;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.Properties;
+
+/**
+ * This Manager impl supplies CRUD methods used to manage properties stored within the ldap directory using HTTP access to En Masse REST server.
+ * The Fortress config nodes are used to remotely share Fortress client specific properties between processes.
+ * Fortress places no limits on the number of unique configurations that can be present at one time in the directory.
+ * The Fortress client will specify the preferred cfg node by name via a property named, {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM}.
+ * Each process using Fortress client is free to share an existing node with other processes or create its own unique config
+ * instance using the methods within this class.<BR>
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class ConfigMgrRestImpl implements ConfigMgr
+{
+    private static final String CLS_NM = ConfigMgrRestImpl.class.getName();
+
+    /**
+     * Create a new cfg node with given name and properties.  The name is required.  If node already exists,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_ALREADY_EXISTS} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProperties contains {@link Properties} with list of name/value pairs to add to existing config node.
+     * @return {@link java.util.Properties} containing the collection of name/value pairs just added.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event entry already present or other system error.
+     */
+    @Override
+    public Properties add(String name, Properties inProperties) throws SecurityException
+    {
+        VUtil.assertNotNull(name, GlobalErrIds.FT_CONFIG_NAME_NULL, CLS_NM + ".add");
+        VUtil.assertNotNull(inProperties, GlobalErrIds.FT_CONFIG_PROPS_NULL, CLS_NM + ".add");
+        Properties retProperties;
+        FortRequest request = new FortRequest();
+        Props inProps = RestUtils.getProps(inProperties);
+        request.setEntity(inProps);
+        request.setValue(name);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.CFG_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Props outProps = (Props) response.getEntity();
+            retProperties = RestUtils.getProperties(outProps);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retProperties;
+    }
+
+    /**
+     * Update existing cfg node with additional properties, or, replace existing properties.  The name is required.  If node does not exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name    attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @param inProperties contains {@link Properties} with list of name/value pairs to add or udpate from existing config node.
+     * @return {@link Properties} containing the collection of name/value pairs to be added to existing node.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event entry not present or other system error.
+     */
+    @Override
+    public Properties update(String name, Properties inProperties) throws SecurityException
+    {
+        VUtil.assertNotNull(name, GlobalErrIds.FT_CONFIG_NAME_NULL, CLS_NM + ".update");
+        VUtil.assertNotNull(inProperties, GlobalErrIds.FT_CONFIG_PROPS_NULL, CLS_NM + ".update");
+        Properties retProperties;
+        FortRequest request = new FortRequest();
+        Props inProps = RestUtils.getProps(inProperties);
+        request.setEntity(inProps);
+        request.setValue(name);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.CFG_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Props outProps = (Props) response.getEntity();
+            retProperties = RestUtils.getProperties(outProps);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retProperties;
+    }
+
+    /**
+      * Completely removes named cfg node from the directory.
+     * <p/>
+     * <font size="3" color="red">This method is destructive and will remove the cfg node completely from directory.<BR>
+     * Care should be taken during execution to ensure target name is correct and permanent removal of all parameters located
+     * there is intended.  There is no 'undo' for this operation.
+     * </font>
+     *
+     * @param name is required and maps to 'cn' attribute on 'device' object class of node targeted for operation.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of system error.
+     */
+    @Override
+    public void delete(String name) throws SecurityException
+    {
+        VUtil.assertNotNull(name, GlobalErrIds.FT_CONFIG_NAME_NULL, CLS_NM + ".deleteProp");
+        FortRequest request = new FortRequest();
+        request.setValue(name);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.CFG_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * Delete properties from existing cfg node.  The name is required.  If node does not exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+     */
+    @Override
+    public void delete(String name, Properties inProperties) throws SecurityException
+    {
+        VUtil.assertNotNull(name, GlobalErrIds.FT_CONFIG_NAME_NULL, CLS_NM + ".delete");
+        VUtil.assertNotNull(inProperties, GlobalErrIds.FT_CONFIG_PROPS_NULL, CLS_NM + ".delete");
+        FortRequest request = new FortRequest();
+        Props inProps = RestUtils.getProps(inProperties);
+        request.setEntity(inProps);
+        request.setValue(name);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.CFG_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * Read an existing cfg node with given name and return to caller.  The name is required.  If node doesn't exist,
+     * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+     *
+     * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+     * @return {@link Properties} containing the collection of name/value pairs just added. Maps to 'ftProps' attribute in 'ftProperties' object class.
+     * @throws SecurityException in the event entry doesn't exist or other system error.
+     */
+    @Override
+    public Properties read(String name) throws SecurityException
+    {
+        VUtil.assertNotNull(name, GlobalErrIds.FT_CONFIG_NAME_NULL, CLS_NM + ".readRole");
+        Properties retProps;
+        FortRequest request = new FortRequest();
+        request.setValue(name);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.CFG_READ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        Props props;
+        if (response.getErrorCode() == 0)
+        {
+            props = (Props) response.getEntity();
+            retProps = RestUtils.getProperties(props);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retProps;
+    }
+}
\ 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/rest/DelAccessMgrRestImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/DelAccessMgrRestImpl.java b/src/main/java/org/apache/directory/fortress/core/rest/DelAccessMgrRestImpl.java
new file mode 100644
index 0000000..a21896a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/DelAccessMgrRestImpl.java
@@ -0,0 +1,450 @@
+/*
+ *   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.rest;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.rbac.RolePerm;
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+import org.apache.directory.fortress.core.DelAccessMgr;
+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 org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.SecurityException;
+
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * This class implements the ARBAC02 DelAccessMgr interface for performing runtime delegated access control operations on objects that are provisioned Fortress ARBAC entities
+ * using HTTP access to En Masse REST server.  These APIs map directly to similar named APIs specified by ARBAC02 functions.  The ARBAC Functional specification describes delegated administrative
+ * operations for the creation and maintenance of ARBAC element sets and relations.  Delegated administrative review functions for performing administrative queries
+ * and system functions for creating and managing ARBAC attributes on user sessions and making delegated administrative access control decisions.
+ *
+ * This class also extends the RBAC AccessMgrImpl object which is used for performing runtime session creation and
+ * access control decisions based on behalf of administrative user who is logged onto the system.  (See the AccessMgr javadoc for more info of how RBAC works).
+ *
+ * This class provides both sets of functionality as is necessary to fulfill runtime delegated administrative access control functionality
+ * within RBAC provisioning systems.
+ * <h3>Administrative Role Based Access Control (ARBAC)</h3>
+ * <img src="../doc-files/ARbac.png">
+ * <p/>
+ * Fortress fully supports the Oh/Sandhu/Zhang ARBAC02 model for delegated administration.  ARBAC provides large enterprises the capability to delegate administrative authority to users that reside outside of the security admin group.
+ * Decentralizing administration helps because it provides security provisioning capability to work groups without sacrificing regulations for accountability or traceability.
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+ * @author Shawn McKinney
+ */
+public class DelAccessMgrRestImpl extends AccessMgrRestImpl implements DelAccessMgr
+{
+    private static final String CLS_NM = DelAccessMgrRestImpl.class.getName();
+
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized assignment control over
+     * User-Role Assignment (URA).  This adheres to the ARBAC02 functional specification for can-assign URA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession(org.apache.directory.fortress.core.rbac.User, boolean)} before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param user    Instantiated User entity requires only valid userId attribute set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws org.apache.directory.fortress.core.SecurityException In the event of data validation error (i.e. invalid userId or role name) or system error.
+     */
+    @Override
+    public boolean canAssign(Session session, User user, Role role)
+        throws SecurityException
+    {
+        String methodName = CLS_NM + ".canAssign";
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, methodName);
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, methodName);
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, methodName);
+        boolean result;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        UserRole uRole = new UserRole(user.getUserId(), role.getName());
+        request.setSession(session);
+        request.setEntity(uRole);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ADMIN_ASSIGN);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            result = response.getAuthorized();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return result;
+    }
+
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized revoke control over
+     * User-Role Assignment (URA).  This adheres to the ARBAC02 functional specification for can-revoke URA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param user    Instantiated User entity requires only valid userId attribute set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws SecurityException In the event of data validation error (i.e. invalid userId or role name) or system error.
+     */
+    @Override
+    public boolean canDeassign(Session session, User user, Role role)
+        throws SecurityException
+    {
+        String methodName = CLS_NM + ".canDeassign";
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, methodName);
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, methodName);
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, methodName);
+        boolean result;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        UserRole uRole = new UserRole(user.getUserId(), role.getName());
+        request.setSession(session);
+        request.setEntity(uRole);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ADMIN_DEASSIGN);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            result = response.getAuthorized();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return result;
+    }
+
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized assignment control over
+     * Permission-Role Assignment (PRA).  This adheres to the ARBAC02 functional specification for can-assign-p PRA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param perm    Instantiated Permission entity requires valid object name and operation name attributes set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws org.apache.directory.fortress.core.SecurityException In the event of data validation error (i.e. invalid perm or role name) or system error.
+     */
+    @Override
+    public boolean canGrant(Session session, Role role, Permission perm)
+        throws SecurityException
+    {
+        String methodName = CLS_NM + "canGrant";
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, methodName);
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OBJECT_NULL, methodName);
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, methodName);
+        boolean result;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        RolePerm context = new RolePerm();
+        context.setPerm(perm);
+        context.setRole(role);
+        request.setSession(session);
+        request.setEntity(context);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ADMIN_GRANT);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            result = response.getAuthorized();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return result;
+    }
+
+    /**
+     * This function will determine if the user contains an AdminRole that is authorized revoke control over
+     * Permission-Role Assignment (PRA).  This adheres to the ARBAC02 functional specification for can-revoke-p PRA.
+     *
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @param perm    Instantiated Permission entity requires valid object name and operation name attributes set.
+     * @param role    Instantiated Role entity requires only valid role name attribute set.
+     * @return boolean value true indicates access allowed.
+     * @throws SecurityException In the event of data validation error (i.e. invalid perm or role name) or system error.
+     */
+    @Override
+    public boolean canRevoke(Session session, Role role, Permission perm)
+        throws SecurityException
+    {
+        String methodName = CLS_NM + "canRevoke";
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, methodName);
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OBJECT_NULL, methodName);
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, methodName);
+        boolean result;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        RolePerm context = new RolePerm();
+        context.setPerm(perm);
+        context.setRole(role);
+        request.setSession(session);
+        request.setEntity(context);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ADMIN_REVOKE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            result = response.getAuthorized();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return result;
+    }
+
+    /**
+     * This function overrides same in RBAC's AccessMgrImpl, but instead processes permissions contained within AdminPerm dataset.
+     * Function returns a Boolean value containing result of a given administrator's access to perform a given operation on a given object.
+     * The function is valid if and only if the session is a valid Fortress session, the object is a member of the AdminPerm OBJS data set,
+     * and the operation is a member of the AdminPerms OPS data set. The session's subject has the permission
+     * to perform the operation on that object if and only if that permission is assigned to (at least)
+     * one of the session's active roles. This implementation will verify the roles or userId correspond
+     * to the subject's active roles are registered in the object's access control list.
+     *
+     * @param perm object contains obj attribute which is a String and contains the name of the object user is trying to access;
+     * perm object contains operation attribute which is also a String and contains the operation name for the object.
+     * @param session This object must be instantiated by calling {@link org.apache.directory.fortress.core.AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return True of user has access, false otherwise.
+     * @throws SecurityException In the event of data validation error (i.e. invalid perm name) or system error.
+     */
+    @Override
+    public boolean checkAccess(Session session, Permission perm)
+        throws SecurityException
+    {
+        String methodName = CLS_NM + ".checkAccess";
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_NULL, methodName);
+        VUtil.assertNotNullOrEmpty(perm.getOpName(), GlobalErrIds.PERM_OPERATION_NULL, methodName);
+        VUtil.assertNotNullOrEmpty(perm.getObjName(), GlobalErrIds.PERM_OBJECT_NULL, methodName);
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, methodName);
+        boolean result;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        request.setEntity(perm);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ADMIN_AUTHZ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            result = response.getAuthorized();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return result;
+    }
+
+
+    /**
+     * This function adds an adminRole as an active role of a session whose owner is a given user.
+     * <p>
+     * The function is valid if and only if:
+     * <ul>
+     *  <li> the user is a member of the USERS data set
+     *  <li> the role is a member of the ADMIN ROLES data set
+     *  <li> the session is a valid Fortress session
+     *  <li> the user is authorized to that admin role
+     *  <li> the session is owned by that user.
+     * </ul>
+     * </p>
+     * @param session object contains the user's returned RBAC and ARBAC sessions from the createSession method.
+     * @param role    object contains the adminRole name to be activated into session.
+     * @throws org.apache.directory.fortress.core.SecurityException is thrown if user is not allowed to activate or runtime error occurs with system.
+     */
+    @Override
+    public void addActiveRole(Session session, UserAdminRole role)
+        throws SecurityException
+    {
+        String methodName = CLS_NM + ".addActiveRole";
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, methodName);
+        VUtil.assertNotNull(role, GlobalErrIds.ARLE_NULL, methodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        request.setEntity(role);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ADMIN_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This function deactivates adminRole from the active adminRole set of a session owned by a given user.
+     * The function is valid if and only if the user is a member of the USERS data set, the
+     * session object contains a valid Fortress session, the session is owned by the user,
+     * and the adminRole is an active adminRole of that session.
+     *
+     * @param session object contains the user's returned RBAC and ARBAC sessions from the createSession method.
+     * @param role    object contains the adminRole name to be deactivated.
+     * @throws org.apache.directory.fortress.core.SecurityException is thrown if user is not allowed to deactivate or runtime error occurs with system.
+     */
+    @Override
+    public void dropActiveRole(Session session, UserAdminRole role)
+        throws SecurityException
+    {
+        String methodName = CLS_NM + ".dropActiveRole";
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, methodName);
+        VUtil.assertNotNull(role, GlobalErrIds.ARLE_NULL, methodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        request.setEntity(role);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ADMIN_DROP);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This function returns the active admin roles associated with a session. The function is valid if
+     * and only if the session is a valid Fortress session.
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return List<UserAdminRole> containing all adminRoles active in user's session.  This will NOT contain inherited roles.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    @Override
+    public List<UserAdminRole> sessionAdminRoles(Session session)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, CLS_NM + ".sessionAdminRoles");
+        List<UserAdminRole> roles;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ADMIN_ROLES);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            roles = response.getEntities();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return roles;
+    }
+
+    /**
+     * This function returns the authorized admin roles associated with a session based on hierarchical relationships. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned ARBAC session from the createSession method.
+     * @return Set<String> containing all adminRoles authorized in user's session.  This will contain inherited roles.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    @Override
+    public Set<String> authorizedAdminRoles(Session session)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, CLS_NM + ".authorizedAdminRoles");
+        Set<String> retRoleNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ADMIN_AUTHZ_ROLES);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Set<String> tempNames = response.getValueSet();
+            // This is done to use a case insensitive TreeSet for returned names.
+            retRoleNames.addAll(tempNames);
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRoleNames;
+        //throw new java.lang.UnsupportedOperationException();
+    }
+
+    /**
+     * This function returns the ARBAC (administrative) permissions of the session, i.e., the permissions assigned
+     * to its authorized admin roles. The function is valid if and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned ARBAC session from the createSession method.
+     * @return List<Permission> containing admin permissions (op, obj) active for user's session.
+     * @throws SecurityException in the event runtime error occurs with system.
+     */
+    @Override
+    public List<Permission> sessionPermissions(Session session)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, CLS_NM + ".sessionPermissions");
+        List<Permission> retPerms;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ADMIN_PERMS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPerms = response.getEntities();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPerms;
+        //throw new java.lang.UnsupportedOperationException();
+    }
+}
\ No newline at end of file


[11/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/RoleDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/RoleDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/RoleDAO.java
new file mode 100755
index 0000000..b11d15d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/RoleDAO.java
@@ -0,0 +1,593 @@
+/*
+ *   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.unboundid;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.UnboundIdDataProvider;
+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;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttribute;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModification;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModificationSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPSearchResults;
+
+
+/**
+ * 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
+ */
+public final class RoleDAO extends UnboundIdDataProvider implements org.apache.directory.fortress.core.rbac.dao.RoleDAO
+{
+    /*
+      *  *************************************************************************
+      *  **  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
+     */
+    public final Role create( Role entity )
+        throws CreateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+        try
+        {
+            LDAPAttributeSet attrs = new LDAPAttributeSet();
+            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS, GlobalIds.ROLE_OBJ_CLASS ) );
+            entity.setId();
+            attrs.add( createAttribute( GlobalIds.FT_IID, entity.getId() ) );
+            attrs.add( createAttribute( ROLE_NM, entity.getName() ) );
+            // description field is optional on this object class:
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                attrs.add( createAttribute( GlobalIds.DESC, entity.getDescription() ) );
+            }
+            // CN attribute is required for this object class:
+            attrs.add( createAttribute( GlobalIds.CN, entity.getName() ) );
+            attrs.add( createAttribute( 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(), attrs, GlobalIds.PARENT_NODES );
+
+            LDAPEntry myEntry = new LDAPEntry( dn, attrs );
+            ld = getAdminConnection();
+            add( ld, myEntry, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "create role [" + entity.getName() + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + 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
+     *
+     */
+    public final Role update( Role entity )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                LDAPAttribute desc = new LDAPAttribute( GlobalIds.DESC, entity.getDescription() );
+                mods.add( LDAPModification.REPLACE, desc );
+            }
+            if ( entity.isTemporalSet() )
+            {
+                String szRawData = CUtil.setConstraint( entity );
+                if ( VUtil.isNotNullOrEmpty( szRawData ) )
+                {
+                    LDAPAttribute constraint = new LDAPAttribute( GlobalIds.CONSTRAINT, szRawData );
+                    mods.add( LDAPModification.REPLACE, constraint );
+                }
+            }
+            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.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ROLE_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     *
+     * @param entity
+     * @throws UpdateException
+     */
+    public final void deleteParent( Role entity )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute occupant = new LDAPAttribute( GlobalIds.PARENT_NODES );
+            mods.add( LDAPModification.DELETE, occupant );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "deleteParent name [" + entity.getName() + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + 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
+     *
+     */
+    public final Role assign( Role entity, String userDn )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+        try
+        {
+            //ld = getAdminConnection();
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute occupant = new LDAPAttribute( ROLE_OCCUPANT, userDn );
+            mods.add( LDAPModification.ADD, occupant );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "assign role name [" + entity.getName() + "] user dn [" + userDn + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + 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
+     *
+     */
+    public final Role deassign( Role entity, String userDn )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute occupant = new LDAPAttribute( ROLE_OCCUPANT, userDn );
+            mods.add( LDAPModification.DELETE, occupant );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "deassign role name [" + entity.getName() + "] user dn [" + userDn
+                + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ROLE_USER_DEASSIGN_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param role
+     * @throws RemoveException
+     */
+    public 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.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new RemoveException( GlobalErrIds.ROLE_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final Role getRole( Role role )
+        throws FinderException
+    {
+        Role entity = null;
+        LDAPConnection ld = null;
+        String dn = getDn( role.getName(), role.getContextId() );
+        try
+        {
+            ld = getAdminConnection();
+            LDAPEntry findEntry = read( ld, dn, ROLE_ATRS );
+            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 ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "getRole Obj COULD NOT FIND ENTRY for dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.ROLE_NOT_FOUND, warning );
+            }
+            String error = "getRole dn [" + dn + "] LEXCD=" + e.getLDAPResultCode() + " LEXMSG=" + 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
+     *
+     */
+    public final List<Role> findRoles( Role role )
+        throws FinderException
+    {
+        List<Role> roleList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        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();
+            searchResults = search( ld, roleRoot,
+                LDAPConnection.SCOPE_ONE, filter, ROLE_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                roleList.add( unloadLdapEntry( searchResults.next(), sequence++, role.getContextId() ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findRoles filter [" + filter + "] caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + 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
+     *
+     */
+    public final List<String> findRoles( Role role, int limit )
+        throws FinderException
+    {
+        List<String> roleList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        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();
+            searchResults = search( ld, roleRoot,
+                LDAPConnection.SCOPE_ONE, filter, ROLE_NM_ATR, false, GlobalIds.BATCH_SIZE, limit );
+            while ( searchResults.hasMoreElements() )
+            {
+                LDAPEntry entry = searchResults.next();
+                roleList.add( getAttribute( entry, ROLE_NM ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findRoles filter [" + filter + "] caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.ROLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return roleList;
+    }
+
+
+    /**
+     *
+     * @param userDn
+     * @param contextId
+     * @return
+     * @throws FinderException
+     */
+    public final List<String> findAssignedRoles( String userDn, String contextId )
+        throws FinderException
+    {
+        List<String> roleNameList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String roleRoot = getRootDn( contextId, GlobalIds.ROLE_ROOT );
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + GlobalIds.ROLE_OBJECT_CLASS_NM + ")";
+            filter += "(" + ROLE_OCCUPANT + "=" + userDn + "))";
+            ld = getAdminConnection();
+            searchResults = search( ld, roleRoot,
+                LDAPConnection.SCOPE_ONE, filter, ROLE_NM_ATR, false, GlobalIds.BATCH_SIZE );
+            while ( searchResults.hasMoreElements() )
+            {
+                roleNameList.add( getAttribute( searchResults.next(), ROLE_NM ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "findAssignedRoles userDn [" + userDn + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ROLE_OCCUPANT_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return roleNameList;
+    }
+
+
+    /**
+     *
+     * @param contextId
+     * @return
+     * @throws FinderException
+     */
+    public final List<Graphable> getAllDescendants( String contextId )
+        throws FinderException
+    {
+        String[] DESC_ATRS =
+            { ROLE_NM, GlobalIds.PARENT_NODES };
+        List<Graphable> descendants = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        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();
+            searchResults = search( ld, roleRoot,
+                LDAPConnection.SCOPE_ONE, filter, DESC_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                descendants.add( unloadDescendants( searchResults.next(), sequence++, contextId ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "getAllDescendants filter [" + filter + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ROLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return descendants;
+    }
+
+
+    /**
+     *
+     * @param le
+     * @param sequence
+     * @param contextId
+     * @return
+     * @throws LDAPException
+     */
+    private Graphable unloadDescendants( LDAPEntry le, long sequence, String contextId )
+    {
+        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 LDAPException
+     */
+    private Role unloadLdapEntry( LDAPEntry le, long sequence, String contextId )
+    {
+        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/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/SdDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/SdDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/SdDAO.java
new file mode 100755
index 0000000..84008c1
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/SdDAO.java
@@ -0,0 +1,557 @@
+/*
+ *   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.unboundid;
+
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+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.UnboundIdDataProvider;
+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;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttribute;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModification;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModificationSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPSearchResults;
+
+
+/**
+ * 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
+ */
+public final class SdDAO extends UnboundIdDataProvider implements org.apache.directory.fortress.core.rbac.dao.SdDAO
+
+{
+    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
+     */
+    public 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
+        {
+            LDAPAttributeSet attrs = new LDAPAttributeSet();
+            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS, objectClass ) );
+            entity.setId();
+            attrs.add( createAttribute( GlobalIds.FT_IID, entity.getId() ) );
+            attrs.add( createAttribute( SD_SET_NM, entity.getName() ) );
+            // description field is optional on this object class:
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                attrs.add( createAttribute( GlobalIds.DESC, entity.getDescription() ) );
+            }
+            // CN attribute is required for this object class:
+            attrs.add( createAttribute( GlobalIds.CN, entity.getName() ) );
+            loadAttrs( entity.getMembers(), attrs, ROLES );
+            attrs.add( createAttribute( SD_SET_CARDINALITY, "" + entity.getCardinality() ) );
+            LDAPEntry myEntry = new LDAPEntry( dn, attrs );
+            ld = getAdminConnection();
+            add( ld, myEntry, entity );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "create SD set name [" + entity.getName() + "] type [" + entity.getType()
+                + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + 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
+     */
+    public final SDSet update( SDSet entity )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String dn = getDn( entity.getName(), entity.getContextId() );
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                LDAPAttribute desc = new LDAPAttribute( GlobalIds.DESC, entity.getDescription() );
+                mods.add( LDAPModification.REPLACE, desc );
+            }
+            if ( entity.getCardinality() != null )
+            {
+                LDAPAttribute cardinality = new LDAPAttribute( SD_SET_CARDINALITY, "" + entity.getCardinality() );
+                mods.add( LDAPModification.REPLACE, cardinality );
+            }
+            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.getLDAPResultCode() + " msg=" + 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
+     */
+    public 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.getLDAPResultCode() + " msg=" + 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
+     */
+    public final SDSet getSD( SDSet sdSet )
+        throws FinderException
+    {
+        SDSet entity = null;
+        LDAPConnection ld = null;
+        String dn = getDn( sdSet.getName(), sdSet.getContextId() );
+        try
+        {
+            ld = getAdminConnection();
+            LDAPEntry 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 ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "getSD Obj COULD NOT FIND ENTRY for dn [" + dn + "]";
+                throw new FinderException( GlobalErrIds.SSD_NOT_FOUND, warning );
+            }
+            String error = "getSSD dn [" + dn + "] LEXCD=" + e.getLDAPResultCode() + " LEXMSG=" + 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
+     */
+    public final List<SDSet> search( SDSet sdset )
+        throws FinderException
+    {
+        List<SDSet> sdList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        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();
+            searchResults = search( ld, ssdRoot,
+                LDAPConnection.SCOPE_SUB, filter, SD_SET_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                sdList.add( unloadLdapEntry( searchResults.next(), sequence++ ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "search sdset name [" + sdset.getName() + "] type [" + sdset.getType()
+                + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + 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
+     */
+    public final List<SDSet> search( Role role, SDSet.SDType type )
+        throws FinderException
+    {
+        List<SDSet> sdList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        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();
+            searchResults = search( ld, ssdRoot,
+                LDAPConnection.SCOPE_SUB, filter, SD_SET_ATRS, false, GlobalIds.BATCH_SIZE );
+
+            long sequence = 0;
+            while ( searchResults.hasMoreElements() )
+            {
+                sdList.add( unloadLdapEntry( searchResults.next(), sequence++ ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "search role [" + role.getName() + "] type [" + type + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + 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
+     */
+    public final Set<SDSet> search( Set<String> roles, SDSet sdSet )
+        throws FinderException
+    {
+        Set<SDSet> sdList = new HashSet<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        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();
+                searchResults = search( ld, ssdRoot,
+                    LDAPConnection.SCOPE_SUB, filter, SD_SET_ATRS, false, GlobalIds.BATCH_SIZE );
+                long sequence = 0;
+                while ( searchResults.hasMoreElements() )
+                {
+                    sdList.add( unloadLdapEntry( searchResults.next(), sequence++ ) );
+                }
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String error = "search type [" + sdSet.getType() + "] caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + 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 LDAPException
+     */
+    private SDSet unloadLdapEntry( LDAPEntry le, long sequence )
+    {
+        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 );
+    }
+}


[08/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rest/AdminMgrRestImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/AdminMgrRestImpl.java b/src/main/java/org/apache/directory/fortress/core/rest/AdminMgrRestImpl.java
new file mode 100644
index 0000000..2ce550c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/AdminMgrRestImpl.java
@@ -0,0 +1,1872 @@
+/*
+ *   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.rest;
+
+import org.apache.directory.fortress.core.AdminMgr;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.rbac.PermGrant;
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.RoleRelationship;
+import org.apache.directory.fortress.core.rbac.SDSet;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.UserRole;
+import org.apache.directory.fortress.core.rbac.Manageable;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * This class performs administrative functions to provision Fortress RBAC entities using HTTP access to En Masse REST server.  These APIs
+ * map directly to similar named APIs specified by ANSI and NIST RBAC models.
+ * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
+ * The RBAC Functional specification describes administrative operations for the creation
+ * and maintenance of RBAC element sets and relations; administrative review functions for
+ * performing administrative queries; and system functions for creating and managing
+ * RBAC attributes on user sessions and making access control decisions.
+ * <p/>
+ * <hr>
+ * <h4>RBAC0 - Core</h4>
+ * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
+ * <p/>
+ * <img src="../doc-files/RbacCore.png">
+ * <hr>
+ * <h4>RBAC1 - General Hierarchical Roles</h4>
+ * Simplifies role engineering tasks using inheritance of one or more parent roles.
+ * <p/>
+ * <img src="../doc-files/RbacHier.png">
+ * <hr>
+ * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+ * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
+ * <p/>
+ * <img src="../doc-files/RbacSSD.png">
+ * <hr>
+ * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+ * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+ * <p/>
+ * <img src="../doc-files/RbacDSD.png">
+ * <hr>
+ * <p/>
+ * This class is NOT thread safe as it contains instance variables.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public final class AdminMgrRestImpl extends Manageable implements AdminMgr
+{
+    private static final String CLS_NM = AdminMgrRestImpl.class.getName();
+
+    /**
+     * This command creates a new RBAC user. The command is valid only if the new user is
+     * not already a member of the USERS data set. The USER data set is updated. The new user
+     * does not own any session at the time of its creation.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#userId} - maps to INetOrgPerson uid</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#password} - used to authenticate the User</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#ou} - contains the name of an already existing User OU node</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#pwPolicy} - contains the name of an already existing OpenLDAP password policy node</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#cn} - maps to INetOrgPerson common name attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#sn} - maps to INetOrgPerson surname attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#description} - maps to INetOrgPerson description attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#title} - maps to INetOrgPerson title attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#employeeType} - maps to INetOrgPerson employeeType attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#phones} * - multi-occurring attribute maps to organizationalPerson telephoneNumber  attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#mobiles} * - multi-occurring attribute maps to INetOrgPerson mobile attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#emails} * - multi-occurring attribute maps to INetOrgPerson mail attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#address} * - multi-occurring attribute maps to organizationalPerson postalAddress, st, l, postalCode, postOfficeBox attributes</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#beginTime} - HHMM - determines begin hour user may activate session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#endTime} - HHMM - determines end hour user may activate session.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#beginDate} - YYYYMMDD - determines date when user may sign on</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#endDate} - YYYYMMDD - indicates latest date user may sign on</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of user may sign on</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#timeout} - number in seconds of session inactivity time allowed</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#props} * - multi-occurring attribute contains property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#roles} * - multi-occurring attribute contains the name of already existing role to assign to user</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#adminRoles} * - multi-occurring attribute contains the name of already existing adminRole to assign to user</li>
+     * </ul>
+     *
+     * @param user User entity must contain {@link org.apache.directory.fortress.core.rbac.User#userId} and {@link org.apache.directory.fortress.core.rbac.User#ou} (required) and optional {@link org.apache.directory.fortress.core.rbac.User#description},{@link org.apache.directory.fortress.core.rbac.User#roles} and many others.
+     * @return Returns entity containing user data that was added.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public User addUser(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".addUser");
+        User retUser;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUser = (User) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUser;
+    }
+
+    /**
+     * This command disables an existing user in the RBAC database. The command is valid
+     * if and only if the user to be disabled is a member of the USERS data set. The USERS and
+     * UA data sets and the assigned_users function are updated.
+     * Method performs a "soft" delete.  It performs the following:
+     * - sets the user status to "deleted"
+     * - deassigns all roles from the user
+     * - locks the user's password in LDAP
+     * - revokes all perms that have been granted to user entity.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user Contains the {@link User#userId} of the User targeted for deletion.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void disableUser(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".disableUser");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_DISABLE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command deletes an existing user from the RBAC database. The command is valid
+     * if and only if the user to be deleted is a member of the USERS data set. The USERS and
+     * UA data sets and the assigned_users function are updated.
+     * 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.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user Contains the {@link User#userId} of the User targeted for deletion.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteUser(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".deleteUser");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This method performs an update on User entity in directory.  Prior to making this call the entity must exist in
+     * directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link User#password} - used to authenticate the User</li>
+     * <li>{@link User#ou} - contains the name of an already existing User OU node</li>
+     * <li>{@link User#pwPolicy} - contains the name of an already existing OpenLDAP password policy node</li>
+     * <li>{@link User#cn} - maps to INetOrgPerson common name attribute</li>
+     * <li>{@link User#sn} - maps to INetOrgPerson surname attribute</li>
+     * <li>{@link User#description} - maps to INetOrgPerson description attribute</li>
+     * <li>{@link User#phones} * - multi-occurring attribute maps to organizationalPerson telephoneNumber  attribute</li>
+     * <li>{@link User#mobiles} * - multi-occurring attribute maps to INetOrgPerson mobile attribute</li>
+     * <li>{@link User#emails} * - multi-occurring attribute maps to INetOrgPerson mail attribute</li>
+     * <li>{@link User#address} * - multi-occurring attribute maps to organizationalPerson postalAddress, st, l, postalCode, postOfficeBox attributes</li>
+     * <li>{@link User#beginTime} - HHMM - determines begin hour user may activate session</li>
+     * <li>{@link User#endTime} - HHMM - determines end hour user may activate session.</li>
+     * <li>{@link User#beginDate} - YYYYMMDD - determines date when user may sign on</li>
+     * <li>{@link User#endDate} - YYYYMMDD - indicates latest date user may sign on</li>
+     * <li>{@link User#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link User#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link User#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of user may sign on</li>
+     * <li>{@link User#timeout} - number in seconds of session inactivity time allowed</li>
+     * <li>{@link User#props} * - multi-occurring attribute contains property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link User#roles} * - multi-occurring attribute contains the name of already existing role to assign to user</li>
+     * <li>{@link User#adminRoles} * - multi-occurring attribute contains the name of already existing adminRole to assign to user</li>
+     * </ul>
+     *
+     * @param user must contain {@link User#userId} and optional entity data to update i.e. desc, ou, properties, all attributes that are not set will be ignored.
+     * @return Updated user entity data.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    @Override
+    public User updateUser(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".updateUser");
+        User retUser;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUser = (User) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUser;
+    }
+
+    /**
+     * Method will change user's password.  This method will evaluate user's password policies.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * <li>{@link User#password} - contains the User's old password</li>
+     * <li>newPassword - contains the User's new password</li>
+     * </ul>
+     *
+     * @param user        contains {@link User#userId} and old user password {@link User#password}.
+     * @param newPassword contains new user password.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Will be thrown in the event of password policy violation or system error.
+     */
+    @Override
+    public void changePassword(User user, char[] newPassword)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".changePassword");
+        VUtil.assertNotNullOrEmpty(newPassword, GlobalErrIds.USER_PW_NULL, CLS_NM + ".changePassword");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        user.setNewPassword(newPassword);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_CHGPW);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * Method will lock user's password which will prevent the user from authenticating with directory.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user entity contains {@link User#userId} of User to be locked.
+     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
+     */
+    @Override
+    public void lockUserAccount(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".lockUserAccount");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_LOCK);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * Method will unlock user's password which will enable user to authenticate with directory.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user entity contains {@link org.apache.directory.fortress.core.rbac.User#userId} of User to be unlocked.
+     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
+     */
+    @Override
+    public void unlockUserAccount(User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".unlockUserAccount");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_UNLOCK);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * Method will reset user's password which will require user to change password before successful authentication with directory.
+     * This method will not evaluate password policies on the new user password as it must be changed before use.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * <li>newPassword - contains the User's new password</li>
+     * </ul>
+     *
+     * @param user entity contains {@link User#userId} of User to be reset.
+     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
+     */
+    @Override
+    public void resetPassword(User user, char[] newPassword)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".resetPassword");
+        VUtil.assertNotNullOrEmpty(newPassword, GlobalErrIds.USER_PW_NULL, CLS_NM + ".resetPassword");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        user.setNewPassword(newPassword);
+        request.setEntity(user);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_RESET);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * Method will delete user's password policy designation.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * <li>newPassword - contains the User's new password</li>
+     * </ul>
+     *
+     * @param user  contains {@link User#userId}.
+     * @throws SecurityException will be thrown in the event of password policy violation or system error.
+     */
+    @Override
+    public void deletePasswordPolicy(User user)
+        throws SecurityException
+    {
+		throw new java.lang.UnsupportedOperationException();
+
+    }
+
+
+    /**
+     * This command creates a new role. The command is valid if and only if the new role is not
+     * already a member of the ROLES data set. The ROLES data set is updated.
+     * Initially, no user or permission is assigned to the new role.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#name} - contains the name to use for the Role to be created.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#description} - maps to description attribute on organizationalRole object class</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session</li>
+     * </ul>
+     *
+     * @param role must contains {@link org.apache.directory.fortress.core.rbac.Role#name} (required) and optional {@link org.apache.directory.fortress.core.rbac.Role#description}.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public Role addRole(Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".addRole");
+        Role retRole;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retRole = (Role) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRole;
+    }
+
+    /**
+     * This command deletes an existing role from the RBAC database. The command is valid
+     * if and only if the role to be deleted is a member of the ROLES data set.  This command will
+     * also deassign role from all users.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role to be deleted.</li>
+     * </ul>
+     *
+     * @param role Contains {@link Role#name} for Role to delete.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteRole(Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".deleteRole");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * Method will update a Role entity in the directory.  The role must exist prior to this call.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role to be updated.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Role#description} - maps to description attribute on organizationalRole object class</li>
+     * <li>{@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+     * <li>{@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+     * <li>{@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+     * <li>{@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+     * <li>{@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session</li>
+     * </ul>
+     *
+     * @param role must contains {@link Role#name} and may contain new description or {@link org.apache.directory.fortress.core.util.time.Constraint}
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of validation or system error.
+     */
+    @Override
+    public Role updateRole(Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".updateRole");
+        Role retRole;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(role);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retRole = (Role) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRole;
+    }
+
+    /**
+     * 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>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserRole#name} - contains the name for already existing Role to be assigned</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserRole#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserRole#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserRole#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserRole#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.UserRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session</li>
+     * </ul>
+     *
+     * @param uRole must contain {@link org.apache.directory.fortress.core.rbac.UserRole#userId} and {@link org.apache.directory.fortress.core.rbac.UserRole#name} and optional {@code Constraints}.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of validation or system error.
+     */
+    @Override
+    public void assignUser(UserRole uRole)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(uRole, GlobalErrIds.URLE_NULL, CLS_NM + ".assignUser");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(uRole);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_ASGN);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * 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.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserRole#name} - contains the name for already existing Role to be deassigned</li>
+     * <li>{@link UserRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     *
+     * @param uRole must contain {@link UserRole#userId} and {@link UserRole#name}.
+     * @throws SecurityException - in the event data error in user or role objects or system error.
+     */
+    @Override
+    public void deassignUser(UserRole uRole)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(uRole, GlobalErrIds.URLE_NULL, CLS_NM + ".deassignUser");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(uRole);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_DEASGN);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This method will add permission operation to an existing permission object which resides under {@code ou=Permissions,ou=RBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may have {@link org.apache.directory.fortress.core.rbac.Role} or {@link org.apache.directory.fortress.core.rbac.User} associations.  The target {@link org.apache.directory.fortress.core.rbac.Permission} must not exist prior to calling.
+     * A Fortress Permission instance exists in a hierarchical, one-many relationship between its parent and itself as stored in ldap tree: ({@link org.apache.directory.fortress.core.rbac.PermObj}*->{@link org.apache.directory.fortress.core.rbac.Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the name of existing object being targeted for the permission add</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the name of new permission operation being added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target along with optional other attributes..
+     * @return copy of Permission entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public Permission addPermission(Permission perm)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".addPermission");
+        Permission retPerm;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(perm);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPerm = (Permission) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPerm;
+    }
+
+    /**
+     * This method will update permission operation pre-existing in target directory under {@code ou=Permissions,ou=RBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may also contain {@link org.apache.directory.fortress.core.rbac.Role} or {@link org.apache.directory.fortress.core.rbac.User} associations to add or remove using this function.
+     * The perm operation must exist before making this call.  Only non-null attributes will be updated.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission update</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is being granted to</li>
+     * <li>{@link Permission#users} * - multi occurring attribute contains Users that permission operation is being granted to</li>
+     * <li>{@link Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * <li>{@link Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target and any optional data to update.  Null or empty attributes will be ignored.
+     * @return copy of permOp entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public Permission updatePermission(Permission perm)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".updatePermission");
+        Permission retPerm;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(perm);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPerm = (Permission) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPerm;
+    }
+
+    /**
+     * This method will remove permission operation entity from permission object. A Fortress permission is (object->operation).
+     * The perm operation must exist before making this call.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission delete</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation being removed</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public void deletePermission(Permission perm)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".deletePermission");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(perm);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.PERM_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This method will add permission object to perms container in directory. The perm object must not exist before making this call.
+     * A {@link org.apache.directory.fortress.core.rbac.PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link org.apache.directory.fortress.core.rbac.PermObj}*->{@link Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#objName} - contains the name of new object being added</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#description} - any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#type} - contains any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link org.apache.directory.fortress.core.rbac.PermObj#objName} and {@link org.apache.directory.fortress.core.rbac.PermObj#ou}.  The other attributes are optional.
+     * @return copy of permObj entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public PermObj addPermObj(PermObj pObj)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(pObj, GlobalErrIds.PERM_OBJECT_NULL, CLS_NM + ".addPermObj");
+        PermObj retObj;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(pObj);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.OBJ_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retObj = (PermObj) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retObj;
+    }
+
+    /**
+     * This method will update permission object in perms container in directory.  The perm object must exist before making this call.
+     * A {@link PermObj} instance exists in a hierarchical, one-many relationship between itself and children as stored in ldap tree: ({@link PermObj}*->{@link Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of existing object being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * <li>{@link PermObj#description} - any safe text</li>
+     * <li>{@link PermObj#type} - contains any safe text</li>
+     * <li>{@link PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link PermObj#objName}. Only non-null attributes will be updated.
+     * @return copy of newly updated permObj entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public PermObj updatePermObj(PermObj pObj)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(pObj, GlobalErrIds.PERM_OBJECT_NULL, CLS_NM + ".updatePermObj");
+        PermObj retObj;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(pObj);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.OBJ_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retObj = (PermObj) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retObj;
+    }
+
+    /**
+     * This method will remove permission object to perms container in directory.  This method will also remove
+     * in associated permission objects that are attached to this object.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of existing object targeted for removal</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link org.apache.directory.fortress.core.rbac.PermObj#objName} of object targeted for removal.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public void deletePermObj(PermObj pObj)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(pObj, GlobalErrIds.PERM_OBJECT_NULL, CLS_NM + ".deletePermObj");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(pObj);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.OBJ_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command grants a role the permission to perform an operation on an object to a role.
+     * The command is implemented by granting permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * and the role is a member of the ROLES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link Role#name} - contains the role name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param role must contains {@link Role#name}.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void grantPermission(Permission perm, Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".grantPermission");
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".grantPermission");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        PermGrant permGrant = new PermGrant();
+        permGrant.setAdmin(perm.isAdmin());
+        permGrant.setObjName(perm.getObjName());
+        permGrant.setObjId(perm.getObjId());
+        permGrant.setOpName(perm.getOpName());
+        permGrant.setRoleNm(role.getName());
+        request.setEntity(permGrant);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_GRANT);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command revokes the permission to perform an operation on an object from the set
+     * of permissions assigned to a role. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * the role is a member of the ROLES data set, and the permission is assigned to that role.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link Role#name} - contains the role name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param role must contains {@link Role#name}.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void revokePermission(Permission perm, Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".revokePermission");
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".revokePermission");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        PermGrant permGrant = new PermGrant();
+        permGrant.setAdmin(perm.isAdmin());
+        permGrant.setObjName(perm.getObjName());
+        permGrant.setObjId(perm.getObjId());
+        permGrant.setOpName(perm.getOpName());
+        permGrant.setRoleNm(role.getName());
+        request.setEntity(permGrant);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_REVOKE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command grants a user the permission to perform an operation on an object to a role.
+     * The command is implemented by granting permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * and the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param user must contain {@link User#userId} of target User entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void grantPermission(Permission perm, User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".grantPermissionUser");
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".grantPermissionUser");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        PermGrant permGrant = new PermGrant();
+        permGrant.setAdmin(perm.isAdmin());
+        permGrant.setObjName(perm.getObjName());
+        permGrant.setObjId(perm.getObjId());
+        permGrant.setOpName(perm.getOpName());
+        permGrant.setUserId(user.getUserId());
+        request.setEntity(permGrant);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_GRANT);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command revokes the permission to perform an operation on an object from the set
+     * of permissions assigned to a user. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * the user is a member of the USERS data set, and the permission is assigned to that user.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, that identifies target.
+     * @param user must contain {@link User#userId} of target User entity.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void revokePermission(Permission perm, User user)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_OPERATION_NULL, CLS_NM + ".revokePermission");
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".revokePermission");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        PermGrant permGrant = new PermGrant();
+        permGrant.setAdmin(perm.isAdmin());
+        permGrant.setObjName(perm.getObjName());
+        permGrant.setObjId(perm.getObjId());
+        permGrant.setOpName(perm.getOpName());
+        permGrant.setUserId(user.getUserId());
+        request.setEntity(permGrant);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.USER_REVOKE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command creates a new role childRole, and inserts it in the role hierarchy as an immediate descendant of
+     * the existing role parentRole. The command is valid if and only if childRole is not a member of the ROLES data set,
+     * and parentRole is a member of the ROLES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#name} - contains the name of existing Role to be parent</li>
+     * <li>childRole - {@link Role#name} - contains the name of new Role to be child</li>
+     * </ul>
+     * <h4>optional parameters childRole</h4>
+     * <ul>
+     * <li>childRole - {@link Role#description} - maps to description attribute on organizationalRole object class for new child</li>
+     * <li>childRole - {@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session for new child</li>
+     * <li>childRole - {@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session for new child</li>
+     * <li>childRole - {@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session for new child</li>
+     * <li>childRole - {@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session for new child</li>
+     * <li>childRole - {@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new child</li>
+     * <li>childRole - {@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new child</li>
+     * <li>childRole - {@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session for new child</li>
+     * </ul>
+     *
+     * @param parentRole This entity must be present in ROLE data set.  Success will add role rel with childRole.
+     * @param childRole  This entity must not be present in ROLE data set.  Success will add the new role entity to ROLE data set.
+     *                   This method:
+     *                   1 - Adds new role.
+     *                   2 - Assigns role relationship between new childRole and pre-existing parentRole.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addDescendant(Role parentRole, Role childRole)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(parentRole, GlobalErrIds.PARENT_ROLE_NULL, CLS_NM + ".addDescendant");
+        VUtil.assertNotNull(childRole, GlobalErrIds.CHILD_ROLE_NULL, CLS_NM + ".addDescendant");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        RoleRelationship relationship = new RoleRelationship();
+        relationship.setParent(parentRole);
+        relationship.setChild(childRole);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_DESC);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command creates a new role parentRole, and inserts it in the role hierarchy as an immediate ascendant of
+     * the existing role childRole. The command is valid if and only if parentRole is not a member of the ROLES data set,
+     * and childRole is a member of the ROLES data set.
+     * This method:
+     * 1 - Adds new role.
+     * 2 - Assigns role relationship between new parentRole and pre-existing childRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>childRole - {@link Role#name} - contains the name of existing child Role</li>
+     * <li>parentRole - {@link Role#name} - contains the name of new Role to be parent</li>
+     * </ul>
+     * <h4>optional parameters parentRole</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#description} - maps to description attribute on organizationalRole object class for new parent</li>
+     * <li>parentRole - {@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session for new parent</li>
+     * <li>parentRole - {@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session for new parent</li>
+     * <li>parentRole - {@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session for new parent</li>
+     * <li>parentRole - {@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session for new parent</li>
+     * <li>parentRole - {@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for new parent</li>
+     * <li>parentRole - {@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new parent</li>
+     * <li>parentRole - {@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated into user's RBAC session for new parent</li>
+     * </ul>
+     *
+     * @param parentRole completion of op assigns new child relationship with childRole.
+     * @param childRole  completion of op assigns new parent relationship with parentRole.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addAscendant(Role childRole, Role parentRole)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(parentRole, GlobalErrIds.PARENT_ROLE_NULL, CLS_NM + ".addAscendant");
+        VUtil.assertNotNull(childRole, GlobalErrIds.CHILD_ROLE_NULL, CLS_NM + ".addAscendant");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        RoleRelationship relationship = new RoleRelationship();
+        relationship.setParent(parentRole);
+        relationship.setChild(childRole);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_ASC);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command establishes a new immediate inheritance relationship parentRole <<-- childRole between existing
+     * roles parentRole, childRole. The command is valid if and only if parentRole and childRole are members of the ROLES data
+     * set, parentRole is not an immediate ascendant of childRole, and childRole does not properly inherit parentRole (in order to
+     * avoid cycle creation).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#name} - contains the name of existing Role to be parent</li>
+     * <li>childRole - {@link Role#name} - contains the name of existing Role to be child</li>
+     * </ul>
+     *
+     * @param parentRole completion of op deassigns child relationship with childRole.
+     * @param childRole  completion of op deassigns parent relationship with parentRole.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addInheritance(Role parentRole, Role childRole)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(parentRole, GlobalErrIds.PARENT_ROLE_NULL, CLS_NM + ".addInheritance");
+        VUtil.assertNotNull(childRole, GlobalErrIds.CHILD_ROLE_NULL, CLS_NM + ".addInheritance");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        RoleRelationship relationship = new RoleRelationship();
+        relationship.setParent(parentRole);
+        relationship.setChild(childRole);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_ADDINHERIT);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command deletes an existing immediate inheritance relationship parentRole <<-- childRole. The command is
+     * valid if and only if the roles parentRole and childRole are members of the ROLES data set, and parentRole is an
+     * immediate ascendant of childRole. The new inheritance relation is computed as the reflexive-transitive
+     * closure of the immediate inheritance relation resulted after deleting the relationship parentRole <<-- childRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#name} - contains the name of existing Role to remove parent relationship</li>
+     * <li>childRole - {@link Role#name} - contains the name of existing Role to remove child relationship</li>
+     * </ul>
+     *
+     * @param parentRole completion of op removes child relationship with childRole.
+     * @param childRole  completion of op removes parent relationship with parentRole.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteInheritance(Role parentRole, Role childRole)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(parentRole, GlobalErrIds.PARENT_ROLE_NULL, CLS_NM + ".deleteInheritance");
+        VUtil.assertNotNull(childRole, GlobalErrIds.CHILD_ROLE_NULL, CLS_NM + ".deleteInheritance");
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        RoleRelationship relationship = new RoleRelationship();
+        relationship.setParent(parentRole);
+        relationship.setChild(childRole);
+        request.setEntity(relationship);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.ROLE_DELINHERIT);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() != 0)
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This command creates a named SSD set of roles and sets the cardinality n of its subsets
+     * that cannot have common users. The command is valid if and only if:
+     * 1 - the name of the SSD set is not already in use
+     * 2 - all the roles in the SSD set are members of the ROLES data set
+     * 3 - n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the SSD role set,
+     * 4 - the SSD constraint for the new role set is satisfied.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.SDSet#name} - contains the name of new SSD role set to be added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to new SSD set containing, name, members, and cardinality (default 2)
+     * @return reference to newly created SSDSet object.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public SDSet createSsdSet(SDSet ssdSet)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(ssdSet, GlobalErrIds.SSD_NULL, CLS_NM + ".createSsdSet");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(ssdSet);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.SSD_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet;
+    }
+
+    /**
+     * This command updates existing SSD set of roles and sets the cardinality n of its subsets
+     * that cannot have common users.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li>The name of the SSD set already exists.
+     * <li> All the roles in the SSD set are members of the ROLES data set.
+     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the SSD role set.
+     * <li> The SSD constraint for the new role set is satisfied.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing SSD role set to be updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
+     * <li>{@link SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to existing SSD set containing, name, members, and cardinality (default 2)
+     * @return reference to SSDSet object targeted for update.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet updateSsdSet(SDSet ssdSet)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(ssdSet, GlobalErrIds.SSD_NULL, CLS_NM + ".updateSsdSet");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(ssdSet);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.SSD_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet;
+    }
+
+
+
+    /**
+     * This command adds a role to a named SSD set of roles. The cardinality associated with the role set remains unchanged.
+     * The command is valid if and only if:
+     * 1 - the SSD role set exists, and
+     * 2 - the role to be added is a member of the ROLES data set but not of a member of the SSD role set, and
+     * 3 - the SSD constraint is satisfied after the addition of the role to the SSD role set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
+     * <li>{@link Role#name} - contains the name of new {@link SDSet#members} to be added</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to new SSD set containing name.
+     * @param role   contains instantiated Role object with role name field set.
+     * @return reference to updated SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public SDSet addSsdRoleMember(SDSet ssdSet, Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(ssdSet, GlobalErrIds.SSD_NULL, CLS_NM + ".addSsdRoleMember");
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".addSsdRoleMember");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(ssdSet);
+        request.setValue(role.getName());
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.SSD_ADD_MEMBER);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet;
+    }
+
+    /**
+     * This command removes a role from a named SSD set of roles. The cardinality associated with the role set remains unchanged.
+     * The command is valid if and only if:
+     * 1 - the SSD role set exists, and
+     * 2 - the role to be removed is a member of the SSD role set, and
+     * 3 - the cardinality associated with the SSD role set is less than the number of elements of the SSD role set.
+     * Note that the SSD constraint should be satisfied after the removal of the role from the SSD role set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
+     * <li>{@link Role#name} - contains the name of existing {@link SDSet#members} to be removed</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to new SSD set containing name.
+     * @param role   contains instantiated Role object with role name field set.
+     * @return reference to updated SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public SDSet deleteSsdRoleMember(SDSet ssdSet, Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(ssdSet, GlobalErrIds.SSD_NULL, CLS_NM + ".deleteSsdRoleMember");
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".deleteSsdRoleMember");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(ssdSet);
+        request.setValue(role.getName());
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.SSD_DEL_MEMBER);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet;
+    }
+
+    /**
+     * This command deletes a SSD role set completely. The command is valid if and only if the SSD role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of new SSD role set to be removed</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to SSD set targeted for removal.
+     * @return reference to deleted SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public SDSet deleteSsdSet(SDSet ssdSet)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(ssdSet, GlobalErrIds.SSD_NULL, CLS_NM + ".deleteSsdSet");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(ssdSet);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.SSD_DELETE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet;
+    }
+
+    /**
+     * This command sets the cardinality associated with a given SSD role set. The command is valid if and only if:
+     * 1 - the SSD role set exists, and
+     * 2 - the new cardinality is a natural number greater than or equal to 2 and less than or equal to the number of elements of the SSD role set, and
+     * 3 - the SSD constraint is satisfied after setting the new cardinality.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
+     * <li>cardinality - contains new cardinality setting for SSD</li>
+     * </ul>
+     *
+     * @param ssdSet      contains an instantiated reference to new SSD set containing name.
+     * @param cardinality integer value contains new cardinality value for data set.
+     * @return reference to updated SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public SDSet setSsdSetCardinality(SDSet ssdSet, int cardinality)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(ssdSet, GlobalErrIds.SSD_NULL, CLS_NM + ".setSsdSetCardinality");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        ssdSet.setCardinality(cardinality);
+        request.setEntity(ssdSet);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.SSD_CARD_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet;
+    }
+
+    /**
+     * This command creates a named DSD set of roles and sets an associated cardinality n.
+     * The DSD constraint stipulates that the DSD role set cannot contain n or more roles
+     * simultaneously active in the same session.  The command is valid if and only if:
+     * 1 - the name of the DSD set is not already in use
+     * 2 - all the roles in the DSD set are members of the ROLES data set
+     * 3 - n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the DSD role set,
+     * 4 - the DSD constraint for the new role set is satisfied.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of new DSD role set to be added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
+     * <li>{@link SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to new DSD set containing, name, members, and cardinality (default 2)
+     * @return reference to newly created SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public SDSet createDsdSet(SDSet dsdSet)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(dsdSet, GlobalErrIds.SSD_NULL, CLS_NM + ".createDsdSet");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(dsdSet);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.DSD_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet;
+    }
+
+
+    /**
+     * This command updates existing DSD set of roles and sets the cardinality n of its subsets
+     * that cannot have common users.
+     * <p>
+     * The command is valid if and only if:
+     * <ul>
+     * <li>The name of the DSD set already exists.
+     * <li> All the roles in the DSD set are members of the ROLES data set.
+     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the DSD role set.
+     * <li> The DSD constraint for the new role set is satisfied.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing DSD role set to be updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be assigned to User from a particular set</li>
+     * <li>{@link SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to existing DSD set containing, name, members, and cardinality (default 2)
+     * @return reference to DSDSet object targeted for update.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet updateDsdSet(SDSet dsdSet)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(dsdSet, GlobalErrIds.SSD_NULL, CLS_NM + ".updateDsdSet");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(dsdSet);
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.DSD_UPDATE);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet;
+    }
+
+
+    /**
+     * This command adds a role to a named DSD set of roles. The cardinality associated with
+     * the role set remains unchanged. The command is valid if and only if:
+     * 1 - the DSD role set exists, and
+     * 2 - the role to be added is a member of the ROLES data set but not of a member of the DSD role set, and
+     * 3 - the DSD constraint is satisfied after the addition of the role to the SSD role set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of DSD role set to be modified</li>
+     * <li>{@link Role#name} - contains the name of new {@link SDSet#members} to be added</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to new DSD set containing name.
+     * @param role   contains instantiated Role object with role name field set.
+     * @return reference to updated DSDSet object.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public SDSet addDsdRoleMember(SDSet dsdSet, Role role)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(dsdSet, GlobalErrIds.SSD_NULL, CLS_NM + ".addDsdRoleMember");
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + ".addDsdRoleMember");
+        SDSet retSet;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(dsdSet);
+        request.setValue(role.getName());
+        if (this.adminSess != null)
+        {
+            request.setSession(adminSess);
+        }
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.DSD_ADD_MEMBER);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSet = (SDSet) response.getEntity();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSet;
+    }
+
+
+    /**
+     * This command removes a role from a named DSD set of roles. The cardinality associated
+     * with the role set remains unchanged. The command is valid if and only if:
+     * 1 - the DSD role set exists, and
+     * 2 - the role to be removed is a member of the DSD role set, and
+     * 3 - the cardinality associated with the DSD role set is less than the number of elements of the DSD role set.
+     * Note that the DSD constraint should be satisfied after the removal of the role from the DSD role set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of DSD role set to

<TRUNCATED>

[24/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/Permission.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Permission.java b/src/main/java/org/apache/directory/fortress/core/rbac/Permission.java
new file mode 100755
index 0000000..d8ed919
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Permission.java
@@ -0,0 +1,750 @@
+/*
+ *   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.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+
+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.XmlType;
+
+import org.apache.directory.fortress.core.rbac.dao.RoleDAO;
+import org.apache.directory.fortress.core.rbac.dao.UserDAO;
+
+/*
+## OC2: Fortress Permission Structural Object Class
+    objectclass	( 1.3.6.1.4.1.38088.2.2
+    NAME 'ftObject'
+    DESC 'Fortress Permission Object Class'
+    SUP organizationalunit
+    STRUCTURAL
+    MUST (
+    ftId $
+    ftObjNm
+    )
+    MAY (
+    ftType
+    )
+    )
+*/
+/**
+ * All entities ({@link org.apache.directory.fortress.core.rbac.User}, {@link org.apache.directory.fortress.core.rbac.Role}, {@link Permission},
+ * {@link org.apache.directory.fortress.core.rbac.PwPolicy} {@link org.apache.directory.fortress.core.rbac.SDSet} etc...) are used to carry data between three Fortress
+ * layers.starting with the (1) Manager layer down thru middle (2) Process layer and it's processing rules into
+ * (3) DAO layer where persistence with the OpenLDAP server occurs.
+ * <h4>Fortress Processing Layers</h4>
+ * <ol>
+ * <li>Manager layer:  {@link AdminMgrImpl}, {@link AccessMgrImpl}, {@link ReviewMgrImpl},...</li>
+ * <li>Process layer:  {@link org.apache.directory.fortress.core.rbac.UserP}, {@link org.apache.directory.fortress.core.rbac.RoleP}, {@link org.apache.directory.fortress.core.rbac.PermP},...</li>
+ * <li>DAO layer: {@link UserDAO}, {@link RoleDAO}, {@link org.apache.directory.fortress.core.rbac.dao.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 />
+ * For example, this entity requires {@link #setObjName} and {@link #setOpName} attributes set before passing into {@link AccessMgrImpl} APIs.
+ * Create methods usually require more attributes (than Read) due to constraints enforced between entities.
+ * <p/>
+ * <h4>Permission entity attribute usages include</h4>
+ * <ul>
+ * <li>{@link #setObjName} and {@link #setOpName} attributes set before calling {@link AccessMgrImpl#checkAccess(org.apache.directory.fortress.core.rbac.Session, Permission)}.
+ * <li>{@link #getRoles} may be set after calling {@link ReviewMgrImpl#readPermission(Permission)} or {@link AccessMgrImpl#sessionPermissions(org.apache.directory.fortress.core.rbac.Session)}.
+ * <li>{@link #getUsers} may be set after calling {@link ReviewMgrImpl#readPermission(Permission)} or {@link AccessMgrImpl#sessionPermissions(org.apache.directory.fortress.core.rbac.Session)}.
+ *
+ * </ul>
+ * <p/>
+ * <h4>More Permission entity notes</h4>
+ * <ul>
+ * <li>The unique key to locate a Permission entity (which is required for all authZ requests) is {@link Permission#objName} and {@link Permission#opName}.<br />
+ * <li>The Permission entity is used to target function points within computer programs needing authorization. This permission model allows a one-to-many relationship between the objects {@link org.apache.directory.fortress.core.rbac.PermObj} and operations {@link Permission}.
+ * <p/>
+ * <img src="../doc-files/RbacCore.png">
+ * <li>The object to operation pairings enable application resources to be mapped to Fortress permissions in a way that is natural for object oriented programming.
+ * <li>Permissions = Object {@link org.apache.directory.fortress.core.rbac.PermObj} 1<->* Operations {@link Permission}
+ * <li>Permissions in Fortress may also be assigned directly to {@link #users}.
+ * <li>Objects {@link #objName}, Operations {@link #opName}, Roles {@link #roles}, Users {@link #users} are not case sensitive for reads or searches.
+ * </ul>
+ * <p/>
+ * The application entity that requires authorization will be mapped to the {@link org.apache.directory.fortress.core.rbac.PermObj} entity and the application's methods or operation names
+ * will be mapped to {@link Permission} entities.
+ * For example, the application entity 'ShoppingCart' has 5 operations - 'create', 'read', 'update', 'delete' and 'checkout'.
+ * The following code will create the permissions and perform the necessary grants.
+ * <pre>
+ * try
+ * {
+ *  // Instantiate the AdminMgr first
+ *  AdminMgr adminMgr = AdminMgrFactory.createInstance();
+ *
+ *  // Now Instantiate the Object
+ *  PermObj shoppingCart = new PermObj("ShoppingCart", "KillerBikes.com");
+ *
+ *  // Add it to the directory
+ *  adminMgr.addPermObj(shoppingCart);
+ *
+ *  // Now create the permission operations and grant to applicable roles:
+ *  Permission create = new Permission(shoppingCart.getObjName(), "create");
+ *  adminMgr.addPermission(create);
+ *  adminMgr.grantPermission(create, new Role("Customer"));
+ *
+ *  Permission read = new Permission(shoppingCart.getObjName(), "read");
+ *  adminMgr.addPermission(read);
+ *  adminMgr.grantPermission(read, new Role("Customer"));
+ *
+ *  Permission update = new Permission(shoppingCart.getObjName(), "update");
+ *  adminMgr.addPermission(update);
+ *  adminMgr.grantPermission(update, new Role("Admin"));
+ *
+ *  Permission delete = new Permission(shoppingCart.getObjName(), "delete");
+ *  adminMgr.addPermission(delete);
+ *  adminMgr.grantPermission(delete, new Role("Manager"));
+ *
+ *  Permission checkout = new Permission(shoppingCart.getObjName(), "checkout");
+ *  adminMgr.addPermission(checkout);
+ *  adminMgr.grantPermission(delete, new Role("Customer"));
+ * }
+ * catch (SecurityException ex)
+ * {
+ *  // log or throw
+ * }
+ * </pre>
+ * <p/>
+ * <h4>Notes on the shopping cart example</h4>
+ * <ul>
+ * <li> {@link org.apache.directory.fortress.core.rbac.User} that activate 'Manager' role into their Sessions will be allowed access to 'ShoppingCart.delete' permission.
+ * <li> {@link org.apache.directory.fortress.core.rbac.User} that activate 'Admin' role may perform 'ShoppingCart.update'.
+ * <li> {@link org.apache.directory.fortress.core.rbac.User} with 'Customer' role may perform the 'ShoppingCart.create'  'ShoppingCart.read and 'ShoppingCart.checkout'.
+ * <li> {@link org.apache.directory.fortress.core.rbac.Role}s must exist in ldap before assignment here, see javadoc {@link org.apache.directory.fortress.core.rbac.Role} for details.
+ * <p/>
+ * </ul>
+ * <p/>
+ * <h4>Permission Schema</h4>
+ * This Permission entity extends a single standard ldap structural object class, {@code organizationalRole} with
+ * one extension structural class, {@code ftOperation}, and two auxiliary object classes, {@code ftProperties}, {@code ftMods}.
+ * The following 3 LDAP object classes will be mapped into this entity:
+ * <p/>
+ * 1. {@code ftOperation} STRUCTURAL Object Class is assigned roles and/or users which grants permissions which can be later checked
+ * using either 'checkAccess' or 'sessionPermissions APIs both methods that reside in the 'AccessMgrImpl' class.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Operation Structural Object Class
+ * objectclass	( 1.3.6.1.4.1.38088.2.3
+ *  NAME 'ftOperation'
+ *  DESC 'Fortress Permission Operation Structural Object Class'
+ *  SUP organizationalrole
+ *  STRUCTURAL
+ *  MUST (
+ *      ftId $
+ *      ftPermName $
+ *      ftObjNm $
+ *      ftOpNm
+ *  )
+ *  MAY (
+ *      ftObjId $
+ *      ftRoles $
+ *      ftUsers $
+ *      ftType
+ *  )
+ *  )
+ * 2. {@code ftProperties} AUXILIARY Object Class is used to store optional client or otherwise custom name/value pairs on target entity.<br />
+ * <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 />
+ * <pre>
+ * ------------------------------------------
+ * AC2: Fortress Properties Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.2
+ *  NAME 'ftProperties'
+ *  DESC 'Fortress Properties AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftProps
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 3. {@code ftMods} AUXILIARY Object Class is used to store Fortress audit variables on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Audit Modification Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.4
+ *  NAME 'ftMods'
+ *  DESC 'Fortress Modifiers AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftModifier $
+ *      ftModCode $
+ *      ftModId
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortPermission")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "permission", propOrder =
+    {
+        "objName",
+        "opName",
+        "objId",
+        "description",
+        "abstractName",
+        "internalId",
+        "type",
+        "users",
+        "roles",
+        "props",
+        "dn",
+        "admin"
+})
+public class Permission extends FortEntity
+    implements java.io.Serializable
+{
+    private boolean admin;
+    private String internalId;
+    private String opName;
+    private String objName;
+    private String objId;
+    private String abstractName;
+    private String type;
+    private String dn;
+    private String description;
+    @XmlElement(nillable = true)
+    private Props props = new Props();
+    //private Properties props;
+    @XmlElement(nillable = true)
+    private Set<String> roles;
+    @XmlElement(nillable = true)
+    private Set<String> users;
+
+
+    /**
+     * This constructor is commonly used to create Permission that is a target for authorization API.
+     *
+     * @param objName maps to 'ftObjNm' attribute in 'ftOperation' object class.
+     * @param opName     maps to 'ftOpNm' attribute in 'ftOperation' object class.
+     */
+    public Permission( String objName, String opName )
+    {
+        this.objName = objName;
+        this.opName = opName;
+    }
+
+
+    /**
+     * Default constructor is used by internal Fortress classes and not intended for external use.
+     */
+    public Permission()
+    {
+    }
+
+
+    /**
+     * Constructor is used for APIs that do not require opName for example ARBAC canGrant/canRevoke.
+     *
+     * @param objName maps to 'ftObjNm' attribute in 'ftOperation' object class.
+     */
+    public Permission( String objName )
+    {
+        this.objName = objName;
+    }
+
+
+    /**
+     * This constructor adds the objId which is used for creating Permissions that have an identity.
+     *
+     * @param objName maps to 'ftObjNm' attribute in 'ftOperation' object class.
+     * @param opName     maps to 'ftOpNm' attribute in 'ftOperation' object class.
+     * @param objId   maps to 'ftObjId' attribute in 'ftOperation' object class.
+     */
+    public Permission( String objName, String opName, String objId )
+    {
+        this.objName = objName;
+        this.opName = opName;
+        this.objId = objId;
+    }
+
+
+    /**
+     * This constructor adds the admin flag which is used to process as Administrative permission.
+     *
+     * @param objName maps to 'ftObjNm' attribute in 'ftOperation' object class.
+     * @param opName     maps to 'ftOpNm' attribute in 'ftOperation' object class.
+     * @param admin      attribute is used to specify the Permission is to be stored and processed in the Administrative RBAC data sets.
+     */
+    public Permission( String objName, String opName, boolean admin )
+    {
+        this.objName = objName;
+        this.opName = opName;
+        this.admin = admin;
+    }
+
+
+    /**
+     * Determine if this Permission is for RBAC or ARBAC processing.
+     *
+     * @return 'true' indicates administrative permission.
+     */
+    public boolean isAdmin()
+    {
+        return admin;
+    }
+
+
+    /**
+     * Set will determine if this Permission is for RBAC or ARBAC processing.
+     *
+     * @param admin contains is 'true' if ARBAC permission..
+     */
+    public void setAdmin( boolean admin )
+    {
+        this.admin = admin;
+    }
+
+
+    /**
+     * This attribute is required but is set automatically by Fortress DAO class before object is persisted to ldap.
+     * This generated internal id is associated with Permission.  This method is used by DAO class and
+     * is not available to outside classes.   The generated attribute maps to 'ftId' in 'ftOperation' object class.
+     */
+    public void setInternalId()
+    {
+        // generate a unique id that will be used as the rDn for this entry:
+        UUID uuid = UUID.randomUUID();
+        this.internalId = uuid.toString();
+    }
+
+
+    /**
+     * Set the internal id that is associated with Permission.  This method is used by DAO class and
+     * is generated automatically by Fortress.  Attribute stored in LDAP cannot be changed by external caller.
+     * This method can be used by client for search purposes only.
+     *
+     * @param internalId maps to 'ftId' in 'ftObject' object class.
+     */
+    public void setInternalId( String internalId )
+    {
+        this.internalId = internalId;
+    }
+
+
+    /**
+     * Return the internal id that is associated with Permission.  This attribute is generated automatically
+     * by Fortress when new PermObj is added to directory and is not known or changeable by external client.
+     *
+     * @return attribute maps to 'ftId' in 'ftOperation' object class.
+     */
+    public String getInternalId()
+    {
+        return internalId;
+    }
+
+
+    /**
+     * Get the Permission operation name.  This is used to specify method name - i.e. Create, Read, Update, Delete, ...
+     *
+     * @return opName maps to 'ftOpNm' attribute in 'ftOperation' object class.
+     */
+    public String getOpName()
+    {
+        return opName;
+    }
+
+
+    /**
+     * Set the Permission operation name.  This is used to specify method name - i.e. Create, Read, Update, Delete, ...
+     *
+     * @param opName maps to 'ftOpNm' attribute in 'ftOperation' object class.
+     */
+    public void setOpName( String opName )
+    {
+        this.opName = opName;
+    }
+
+
+    /**
+     * Get the authorization target's object name.  This is typically mapped to the class name for component
+     * that is the target for Fortress authorization check. For example 'PatientRelationshipInquire'.
+     *
+     * @return the name of the object which maps to 'ftObjNm' attribute in 'ftOperation' object class.
+     */
+    public String getObjName()
+    {
+        return this.objName;
+    }
+
+
+    /**
+     * This attribute is required and sets the authorization target object name.  This name is typically derived from the class name
+     * for component that is the target for Fortress authorization check. For example 'CustomerCheckOutPage'.
+     *
+     */
+    public void setObjName( String objName )
+    {
+        this.objName = objName;
+    }
+
+
+    /**
+     * Return the Permission's abstract name which is the value of objName concatenated with OpName, i.e. 'Patient.checkin'
+     * This value is automatically generated by the Fortress DAO class.
+     *
+     * @return abstractName maps to 'ftPermName' attribute in 'ftOperation' object class.
+     */
+    public String getAbstractName()
+    {
+        return abstractName;
+    }
+
+
+    /**
+     * Set the Permission's abstract name which is the value of objName concatenated with OpName, i.e. 'Patient.checkin'
+     * This value is automatically generated by the Fortress DAO class and value will be ignored if set by external client.
+     *
+     * @param abstractName maps to 'ftPermName' attribute in 'ftOperation' object class.
+     */
+    public void setAbstractName( String abstractName )
+    {
+        this.abstractName = abstractName;
+    }
+
+
+    /**
+     * Get the optional type name which is an unconstrained attribute on Permission entity.
+     *
+     * @return type maps to 'ftType' attribute in 'ftOperation' object class.
+     */
+    public String getType()
+    {
+        return type;
+    }
+
+
+    /**
+     * Set the optional type name which is an unconstrained attribute on Permission entity.
+     *
+     * @param type maps to 'ftType' attribute in 'ftOperation' object class.
+     */
+    public void setType( String type )
+    {
+        this.type = type;
+    }
+
+
+    /**
+     * Get optional objId attribute which can be used to tag a Permission object with an identity, i.e. objName='Customer', objId='12345'.
+     * This value is not constrained by any other object.
+     *
+     * @return maps to 'ftObjectId' attribute in 'ftOperation' object class.
+     */
+    public String getObjId()
+    {
+        return objId;
+    }
+
+
+    /**
+     * Set optional objId which can be used to tag a Permission object with an identity, i.e. objName='Account', objId='09876543'.
+     * This value is not constrained by any other object.
+     *
+     * @param objId maps to 'ftObjectId' attribute in 'ftOperation' object class.
+     */
+    public void setObjId( String objId )
+    {
+        this.objId = objId;
+    }
+
+
+    /**
+     * Add a Role name to list of Roles that are valid for this Permission.  This is optional attribute.
+     *
+     * @param role maps to 'ftRoles' attribute in 'ftOperation' object class.
+     */
+    public void setRole( String role )
+    {
+        if ( roles == null )
+        {
+            roles = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        }
+
+        this.roles.add( role );
+    }
+
+
+    /**
+     * Delete a Role name from list of Roles that are valid for this Permission.
+     *
+     * @param role maps to 'ftRoles' attribute in 'ftOperation' object class.
+     */
+    public void delRole( String role )
+    {
+        if ( this.roles != null )
+        {
+            this.roles.remove( role );
+        }
+    }
+
+
+    /**
+     * Return the collection of optional Roles that have been loaded into this entity.  This is stored as a multi-occurring
+     * attribute of Role names on the 'ftOperation' object class.
+     *
+     * @return Set containing the roles which maps to 'ftRoles' attribute in 'ftOperation' object class.
+     */
+    public Set<String> getRoles()
+    {
+        return this.roles;
+    }
+
+
+    /**
+     * Set the collection of optional Roles that have been loaded into this entity.  This is stored as a multi-occurring
+     * attribute of Role names on the 'ftOperation' object class.
+     *
+     * @param roles maps to 'ftRoles' attribute in 'ftOperation' object class.
+     */
+    public void setRoles( Set<String> roles )
+    {
+        this.roles = roles;
+    }
+
+
+    /**
+     * Add a UserId to list of Users that are valid for this Permission.  This is optional attribute.
+     *
+     * @param user maps to 'ftUsers' attribute in 'ftOperation' object class.
+     */
+    public void setUser( String user )
+    {
+        if ( users == null )
+        {
+            users = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        }
+
+        this.users.add( user );
+    }
+
+
+    /**
+     * Return the collection of optional Users that have been loaded into this entity.  This is stored as a multi-occurring
+     * attribute of ftUsers on the 'ftOperation' object class.
+     *
+     * @return Set containing the Users which maps to 'ftUsers' attribute in 'ftOperation' object class.
+     */
+    public Set<String> getUsers()
+    {
+        return this.users;
+    }
+
+
+    /**
+     * Set the collection of optional Users that have been loaded into this entity.  This is stored as a multi-occurring
+     * attribute of userIds on the 'ftOperation' object class.
+     *
+     * @param users maps to 'ftUsers' attribute in 'ftOperation' object class.
+     */
+    public void setUsers( Set<String> users )
+    {
+        this.users = users;
+    }
+
+
+    public String getDn()
+    {
+        return dn;
+    }
+
+    public void setDn( String dn )
+    {
+        this.dn = dn;
+    }
+
+    /**
+     * Return the description field on this entity.  The description is often used as a human readable label for the permission.
+     * @return String containing the description.
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+    /**
+     * Set the optional description field on this entity.  The description is used as a human readable label for the permission.
+     *
+     * @param description String contains the description.
+     */
+    public void setDescription( String description )
+    {
+        this.description = description;
+    }
+
+    /**
+      * Gets the value of the Props property.  This method is used by Fortress and En Masse and should not be called by external programs.
+      *
+      * @return
+      *     possible object is
+      *     {@link Props }
+      *
+      */
+    public Props getProps()
+    {
+        return props;
+    }
+
+
+    /**
+     * Sets the value of the Props property.  This method is used by Fortress and En Masse and should not be called by external programs.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link Props }
+     *
+     */
+    public void setProps( Props value )
+    {
+        this.props = value;
+    }
+
+
+    /**
+     * Add name/value pair to list of properties associated with Permission.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param key   contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     * @param value
+     */
+    public void addProperty( String key, String value )
+    {
+        Props.Entry entry = new Props.Entry();
+        entry.setKey( key );
+        entry.setValue( value );
+        this.props.getEntry().add( entry );
+    }
+
+
+    /**
+     * Get a name/value pair attribute from list of properties associated with Permission.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param key contains property name and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     * @return value containing name/value pair that maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public String getProperty( String key )
+    {
+        List<Props.Entry> props = this.props.getEntry();
+        Props.Entry keyObj = new Props.Entry();
+        keyObj.setKey( key );
+
+        String value = null;
+        int indx = props.indexOf( keyObj );
+        if ( indx != -1 )
+        {
+            Props.Entry entry = props.get( props.indexOf( keyObj ) );
+            value = entry.getValue();
+        }
+
+        return value;
+    }
+
+
+    /**
+     * Add new collection of name/value pairs to attributes associated with Permission.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @param props contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public void addProperties( Properties props )
+    {
+        if ( props != null )
+        {
+            for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                // This LDAP attr is stored as a name-value pair separated by a ':'.
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+                addProperty( key, val );
+            }
+        }
+    }
+
+
+    /**
+     * Return the collection of name/value pairs to attributes associated with Permission.  These values are not constrained by Fortress.
+     * Properties are optional.
+     *
+     * @return Properties contains collection of name/value pairs and maps to 'ftProps' attribute in 'ftProperties' aux object class.
+     */
+    public Properties getProperties()
+    {
+        Properties properties = null;
+        List<Props.Entry> props = this.props.getEntry();
+        if ( props.size() > 0 )
+        {
+            properties = new Properties();
+            //int size = props.size();
+            for ( Props.Entry entry : props )
+            {
+                String key = entry.getKey();
+                String val = entry.getValue();
+                properties.setProperty( key, val );
+            }
+        }
+        return properties;
+    }
+
+
+    /**
+     * Matches the objName and opName from two Permission entities.
+     *
+     * @param thatOp contains a Permission entity.
+     * @return boolean indicating both Permissions contain matching objName and opName attributes.
+     */
+    public boolean equals( Object thatOp )
+    {
+        if ( this == thatOp )
+            return true;
+        if ( this.getObjName() == null )
+            return false;
+        if ( !( thatOp instanceof Permission ) )
+            return false;
+        Permission thatPermission = ( Permission ) thatOp;
+        if ( thatPermission.getObjName() == null )
+            return false;
+        return ( ( thatPermission.getObjName().equalsIgnoreCase( this.getObjName() ) ) && ( thatPermission
+            .getOpName().equalsIgnoreCase( this.getOpName() ) ) );
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Permission{" +
+            "objName='" + objName + '\'' +
+            ", opName='" + opName + '\'' +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/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
new file mode 100755
index 0000000..e6f935f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PolicyP.java
@@ -0,0 +1,378 @@
+/*
+ *   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 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.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;
+
+
+/**
+ * Process module for the OpenLDAP Password Policy entity.  This class performs data validations and error mapping.
+ * It is typically called by internal Fortress manager class {@link PwPolicyMgrImpl} but also
+ * needed by {@link org.apache.directory.fortress.core.rbac.UserP#validate(org.apache.directory.fortress.core.rbac.User, boolean)}
+ * This class is not intended to be used by external programs.  This class will accept Fortress entity, {@link PwPolicy}, on its
+ * methods, validate contents and forward on to it's corresponding DAO class {@link PolicyDAO}.
+ * <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 uses one reference to synchronized data set {@link #policyCache} but is thread safe.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public final class PolicyP
+{
+
+    private static final String CLS_NM = PolicyP.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    // This is 5 years duration in seconds:
+    private static final int MAX_AGE = 157680000;
+
+    // DAO class for ol pw policy data sets must be initialized before the other statics:
+    private static final PolicyDAO olDao = new PolicyDAO();
+    // this field is used to synchronize access to the above static data set:
+    private static final Object policySetSynchLock = new Object();
+    // static field holds the list of names for all valid pw policies in effect:
+    private static Cache policyCache;
+    private static final int MIN_PW_LEN = 20;
+    private static final int MAX_FAILURE = 100;
+    private static final int MAX_GRACE_COUNT = 10;
+    private static final int MAX_HISTORY = 100;
+    private static final String POLICIES = "policies";
+    private static final String FORTRESS_POLICIES = "fortress.policies";
+
+    static
+    {
+        CacheMgr cacheMgr = CacheMgr.getInstance();
+        PolicyP.policyCache = cacheMgr.getCache( FORTRESS_POLICIES );
+    }
+
+
+    /**
+     * Package private constructor.
+     */
+    PolicyP()
+    {
+    }
+
+
+    /**
+     * This function uses a case insensitive search.
+     *
+     * @param policy
+     * @return
+     */
+    final boolean isValid( PwPolicy policy )
+    {
+        boolean result = false;
+        Set<String> policySet = getPolicySet( policy.getContextId() );
+        if ( policySet != null )
+            result = policySet.contains( policy.getName() );
+        return result;
+    }
+
+
+    /**
+     * This method will return the password policy entity to the caller.  This command is valid
+     * if and only if the policy entry is present in the POLICIES data set.
+     *
+     * @param policy contains the name of the policy entity.
+     * @return PswdPolicy entity returns fully populated with attributes.
+     * @throws SecurityException In the event policy entry not found, data validation or system error.
+     */
+    final PwPolicy read( PwPolicy policy ) throws SecurityException
+    {
+        // Call the finder method for the primary key.
+        return olDao.getPolicy( policy );
+    }
+
+
+    /**
+     * This method will add a new policy entry to the POLICIES data set.  This command is valid
+     * if and only if the policy entry is not already present in the POLICIES data set.
+     *
+     * @param policy Object contains the password policy attributes.
+     * @throws SecurityException In the event of data validation or system error.
+     */
+    final void add( PwPolicy policy ) throws SecurityException
+    {
+        validate( policy );
+        olDao.create( policy );
+        synchronized ( policySetSynchLock )
+        {
+            Set<String> policySet = getPolicySet( policy.getContextId() );
+            if ( policySet != null )
+                policySet.add( policy.getName() );
+        }
+    }
+
+
+    /**
+     * This method will update an exiting policy entry to the POLICIES data set.  This command is valid
+     * if and only if the policy entry is already present in the POLICIES data set.
+     *
+     * @param policy Object must contain the name of the policy entity.  All non-null attributes will
+     *               be updated.  null attributes will be ignored.
+     * @throws SecurityException In the event policy not found , data validation or system error.
+     */
+    final void update( PwPolicy policy ) throws SecurityException
+    {
+        validate( policy );
+        olDao.update( policy );
+    }
+
+
+    /**
+     * This method will delete exiting policy entry from the POLICIES data set.  This command is valid
+     * if and only if the policy entry is already present in the POLICIES data set.  Existing users that
+     * are assigned this policy will be removed from association.
+     *
+     * @param policy Object must contain the name of the policy entity.
+     * @throws SecurityException In the event policy entity not found or system error.
+     */
+    final void delete( PwPolicy policy ) throws SecurityException
+    {
+        olDao.remove( policy );
+        synchronized ( policySetSynchLock )
+        {
+            Set<String> policySet = getPolicySet( policy.getContextId() );
+            if ( policySet != null )
+                policySet.remove( policy.getName() );
+        }
+    }
+
+
+    /**
+     * This method will return a list of all password policy entities that match a particular search string.
+     * This command will return an empty list of no matching entries are found.
+     *
+     * @param policy contains the leading chars of a policy entity.  This search is not case sensitive.
+     * @return List<PswdPolicy> contains all matching password policy entities. If no records found this will be empty.
+     * @throws SecurityException In the event of data validation or system error.
+     */
+    final List<PwPolicy> search( PwPolicy policy ) throws SecurityException
+    {
+        return olDao.findPolicy( policy );
+    }
+
+
+    /**
+     * Method will perform simple validations to ensure the integrity of the OpenLDAP Password Policy entity targeted for insertion
+     * or updating in directory.  Data reasonability checks will be performed on all non-null attributes.
+     *
+     * @param policy contains data targeted for insertion or update.
+     * @throws ValidationException in the event of data validation error or DAO error on Org validation.
+     */
+    private void validate( PwPolicy policy ) throws ValidationException
+    {
+        int length = policy.getName().length();
+        if ( length < 1 || length > GlobalIds.PWPOLICY_NAME_LEN )
+        {
+            String error = "validate policy name [" + policy.getName() + "] INVALID LENGTH [" + length + "]";
+            LOG.error( error );
+            throw new ValidationException( GlobalErrIds.PSWD_NAME_INVLD_LEN, error );
+        }
+        if ( policy.getCheckQuality() != null )
+        {
+            try
+            {
+                if ( policy.getCheckQuality() < 0 || policy.getCheckQuality() > 2 )
+                {
+                    String error = "validate policy name [" + policy.getName() + "] value checkQuality ["
+                        + policy.getCheckQuality() + "] INVALID INT VALUE";
+                    LOG.error( error );
+                    throw new ValidationException( GlobalErrIds.PSWD_QLTY_INVLD, error );
+                }
+            }
+            catch ( java.lang.NumberFormatException nfe )
+            {
+                String error = "validate policy name [" + policy.getName() + "] value checkQuality ["
+                    + policy.getCheckQuality() + "] INVALID INT VALUE";
+                LOG.error( error );
+                throw new ValidationException( GlobalErrIds.PSWD_QLTY_INVLD, error );
+            }
+        }
+        if ( policy.getMaxAge() != null )
+        {
+            if ( policy.getMaxAge() > MAX_AGE )
+            {
+                String error = "validate policy name [" + policy.getName() + "] value maxAge [" + policy.getMaxAge()
+                    + "] INVALID INT VALUE";
+                LOG.error( error );
+                throw new ValidationException( GlobalErrIds.PSWD_MAXAGE_INVLD, error );
+            }
+        }
+        if ( policy.getMinAge() != null )
+        {
+            // policy.minAge
+            if ( policy.getMinAge() > MAX_AGE )
+            {
+                String error = "validate policy name [" + policy.getName() + "] value minAge [" + policy.getMinAge()
+                    + "] INVALID INT VALUE";
+                LOG.error( error );
+                throw new ValidationException( GlobalErrIds.PSWD_MINAGE_INVLD, error );
+            }
+        }
+        if ( policy.getMinLength() != null )
+        {
+            if ( policy.getMinLength() > MIN_PW_LEN )
+            {
+                String error = "validate policy name [" + policy.getName() + "] value minLength ["
+                    + policy.getMinLength() + "] INVALID INT VALUE";
+                LOG.error( error );
+                throw new ValidationException( GlobalErrIds.PSWD_MINLEN_INVLD, error );
+            }
+        }
+        if ( policy.getFailureCountInterval() != null )
+        {
+            if ( policy.getFailureCountInterval() > MAX_AGE )
+            {
+                String error = "validate policy name [" + policy.getName() + "] value failureCountInterval ["
+                    + policy.getFailureCountInterval() + "] INVALID INT VALUE";
+                LOG.error( error );
+                throw new ValidationException( GlobalErrIds.PSWD_INTERVAL_INVLD, error );
+            }
+        }
+        if ( policy.getMaxFailure() != null )
+        {
+            if ( policy.getMaxFailure() > MAX_FAILURE )
+            {
+                String error = "validate policy name [" + policy.getName() + "] value maxFailure ["
+                    + policy.getMaxFailure() + "] INVALID INT VALUE";
+                LOG.error( error );
+                throw new ValidationException( GlobalErrIds.PSWD_MAXFAIL_INVLD, error );
+            }
+        }
+        if ( policy.getInHistory() != null )
+        {
+            if ( policy.getInHistory() > MAX_HISTORY )
+            {
+                String error = "validate policy name [" + policy.getName() + "] value inHistory ["
+                    + policy.getInHistory() + "] INVALID VALUE";
+                LOG.error( error );
+                throw new ValidationException( GlobalErrIds.PSWD_HISTORY_INVLD, error );
+            }
+        }
+        if ( policy.getGraceLoginLimit() != null )
+        {
+            if ( policy.getGraceLoginLimit() > MAX_GRACE_COUNT )
+            {
+                String error = "validate policy name [" + policy.getName() + "] value graceLoginLimit ["
+                    + policy.getGraceLoginLimit() + "] INVALID VALUE";
+                LOG.error( error );
+                throw new ValidationException( GlobalErrIds.PSWD_GRACE_INVLD, error );
+            }
+        }
+        if ( policy.getLockoutDuration() != null )
+        {
+            if ( policy.getLockoutDuration() > MAX_AGE )
+            {
+                String error = "validate policy name [" + policy.getName() + "] value lockoutDuration ["
+                    + policy.getLockoutDuration() + "] INVALID VALUE";
+                LOG.error( error );
+                throw new ValidationException( GlobalErrIds.PSWD_LOCKOUTDUR_INVLD, error );
+            }
+        }
+        if ( policy.getExpireWarning() != null )
+        {
+            if ( policy.getExpireWarning() > MAX_AGE )
+            {
+                String error = "validate policy name [" + policy.getName() + "] value expireWarning ["
+                    + policy.getExpireWarning() + "] INVALID VALUE";
+                LOG.error( error );
+                throw new ValidationException( GlobalErrIds.PSWD_EXPWARN_INVLD, error );
+            }
+        }
+    }
+
+
+    /**
+     * Load the cache with read only list of valid openldap policy names.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of unique names.
+     */
+    private static Set<String> loadPolicySet( String contextId )
+    {
+        Set<String> policySet = null;
+        try
+        {
+            policySet = olDao.getPolicies( contextId );
+        }
+        catch ( SecurityException se )
+        {
+            String warning = "loadPolicySet static initializer caught SecurityException=" + se;
+            LOG.info( warning );
+        }
+        policyCache.put( getKey( contextId ), policySet );
+        return policySet;
+    }
+
+
+    /**
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return
+     */
+    private static Set<String> getPolicySet( String contextId )
+    {
+        Set<String> policySet = ( Set<String> ) policyCache.get( getKey( contextId ) );
+        if ( policySet == null )
+        {
+            policySet = loadPolicySet( contextId );
+        }
+        return policySet;
+    }
+
+
+    /**
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return
+     */
+    private static String getKey( String contextId )
+    {
+        String key = POLICIES;
+        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/Props.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Props.java b/src/main/java/org/apache/directory/fortress/core/rbac/Props.java
new file mode 100755
index 0000000..8ea082e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Props.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;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class is used as a container for {@code java.util.Properties} for passing to En Masse server.
+ * </p>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ *         <p/>
+ *         <p>The following schema fragment specifies the expected content contained within this class.
+ *         <p/>
+ *         <pre>
+ *                 &lt;complexType>
+ *                   &lt;complexContent>
+ *                     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                       &lt;sequence>
+ *                         &lt;element name="entry" maxOccurs="unbounded" minOccurs="0">
+ *                           &lt;complexType>
+ *                             &lt;complexContent>
+ *                               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                 &lt;sequence>
+ *                                   &lt;element name="key" type="{http://www.w3.org/2001/XMLSchema}anyType" minOccurs="0"/>
+ *                                   &lt;element name="value" type="{http://www.w3.org/2001/XMLSchema}anyType" minOccurs="0"/>
+ *                                 &lt;/sequence>
+ *                               &lt;/restriction>
+ *                             &lt;/complexContent>
+ *                           &lt;/complexType>
+ *                         &lt;/element>
+ *                       &lt;/sequence>
+ *                     &lt;/restriction>
+ *                   &lt;/complexContent>
+ *                 &lt;/complexType>
+ *                 </pre>
+ */
+@XmlRootElement(name = "fortProps")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "props", propOrder = {
+    "entry"
+})
+public class Props extends FortEntity implements Serializable
+{
+    private List<Props.Entry> entry;
+
+    /**
+     * Gets the value of the entry property.
+     *
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the entry property.
+     *
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getEntry().add(newItem);
+     * </pre>
+     *
+     *
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link Props.Entry }
+     *
+     *
+     */
+    public List<Props.Entry> getEntry()
+    {
+        if (entry == null)
+        {
+            entry = new ArrayList<>();
+        }
+        return this.entry;
+    }
+
+    /**
+     * <p>Java class for anonymous complex type.
+     *
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     *
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;sequence>
+     *         &lt;element name="key" type="{http://www.w3.org/2001/XMLSchema}anyType" minOccurs="0"/>
+     *         &lt;element name="value" type="{http://www.w3.org/2001/XMLSchema}anyType" minOccurs="0"/>
+     *       &lt;/sequence>
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     *
+     *
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+        "key",
+        "value"
+    })
+    public static class Entry implements Serializable
+    {
+
+        protected String key;
+        protected String value;
+
+        /**
+         * Gets the value of the key property.
+         *
+         * @return
+         *     possible object is
+         *     {@link Object }
+         *
+         */
+        public String getKey()
+        {
+            return key;
+        }
+
+        /**
+         * Sets the value of the key property.
+         *
+         * @param value
+         *     allowed object is
+         *     {@link Object }
+         *
+         */
+        public void setKey(String value)
+        {
+            this.key = value;
+        }
+
+        /**
+         * Gets the value of the value property.
+         *
+         * @return
+         *     possible object is
+         *     {@link Object }
+         *
+         */
+        public String getValue()
+        {
+            return value;
+        }
+
+        /**
+         * Sets the value of the value property.
+         *
+         * @param value
+         *     allowed object is
+         *     {@link Object }
+         *
+         */
+        public void setValue(String value)
+        {
+            this.value = value;
+        }
+
+        /**
+         *
+         * @param obj
+         * @return boolean value
+         */
+        public boolean equals(Object obj)
+        {
+            if (obj != null && obj instanceof Props.Entry)
+            {
+                Props.Entry inObj = (Props.Entry) obj;
+                return key.equals(inObj.getKey());
+            }
+            return false;
+        }
+    }
+}
\ 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/PsoUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/PsoUtil.java b/src/main/java/org/apache/directory/fortress/core/rbac/PsoUtil.java
new file mode 100755
index 0000000..2e2b937
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PsoUtil.java
@@ -0,0 +1,274 @@
+/*
+ *   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 Permissions, {@link org.apache.directory.fortress.core.rbac.OrgUnit.Type#PERM}.
+ * The {@code cn=Hierarchies, ou=OS-P} data contains Permission OU pools and within a data cache, {@link #psoCache}, 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 PsoUtil
+{
+    private static final Cache psoCache;
+    private static OrgUnitP orgUnitP = new OrgUnitP();
+    private static final String CLS_NM = PsoUtil.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    /**
+     * Initialize the Perm 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();
+        psoCache = cacheMgr.getCache( "fortress.pso" );
+    }
+
+
+    /**
+     * 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} maps on 'ftOrgUnit' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @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.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @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.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @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.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @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#PERM} 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.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @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#PERM}.
+     *
+     * @param ous       contains list of {@link org.apache.directory.fortress.core.rbac.OrgUnit}s.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @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 Permission 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 PSO context [" + inHier.getContextId() + "]" );
+        List<Graphable> descendants = null;
+        try
+        {
+            OrgUnit orgUnit = new OrgUnit();
+            orgUnit.setType( OrgUnit.Type.PERM );
+            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.PSO ) )
+        {
+            graph = HierUtil.buildGraph( hier );
+        }
+        psoCache.put( getKey( contextId ), graph );
+        return graph;
+    }
+
+
+    /**
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return
+     */
+    private static SimpleDirectedGraph<String, Relationship> getGraph( String contextId )
+    {
+        SimpleDirectedGraph<String, Relationship> graph = ( SimpleDirectedGraph<String, Relationship> ) psoCache
+            .get( getKey( contextId ) );
+        if ( graph == null )
+        {
+            graph = loadGraph( contextId );
+        }
+        return graph;
+    }
+
+
+    /**
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return
+     */
+    private static String getKey( String contextId )
+    {
+        String key = HierUtil.Type.PSO.toString();
+        if ( VUtil.isNotNullOrEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL ) )
+        {
+            key += ":" + contextId;
+        }
+        return key;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/PwMessage.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/PwMessage.java b/src/main/java/org/apache/directory/fortress/core/rbac/PwMessage.java
new file mode 100755
index 0000000..e866749
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/PwMessage.java
@@ -0,0 +1,136 @@
+/*
+ *   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;
+
+/**
+ * Interface is implemented by {@link org.apache.directory.fortress.core.rbac.Session} and prescribes methods used to return Fortress
+ * password messages to the caller.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public interface PwMessage
+{
+    /**
+     * Return the {@link org.apache.directory.fortress.core.rbac.User#userId} from entity.
+     *
+     * @param userId maps to {@code uid} attribute on inetOrgPerson object class.
+     */
+    public void setUserId(String userId);
+
+    /**
+     * Set the {@link org.apache.directory.fortress.core.rbac.User#userId} in entity.
+     *
+     * @return userId maps to {@code uid} attribute on inetOrgPerson object class.
+     */
+    public String getUserId();
+
+    /**
+     * Contains the message that corresponds to password.  These messages map to {@link GlobalPwMsgIds#pwMsgs}
+     *
+     * @param message
+     */
+    public void setMsg(String message);
+
+    /**
+     * Return the message that corresponds to last password check.
+     *
+     * @return message maps to {@link GlobalPwMsgIds#pwMsgs}
+     */
+    public String getMsg();
+
+    /**
+     * If set to true the user's password check out good.
+     *
+     * @param isAuthenticated
+     */
+    public void setAuthenticated(boolean isAuthenticated);
+
+    /**
+     * If set to true the user's password check out good.
+     *
+     * @return param isAuthenticated
+     */
+    public boolean isAuthenticated();
+
+    /**
+     * Return the warning id that pertain to User's password. This attribute maps to values between 0 and 100 contained within here {@link GlobalPwMsgIds}
+     *
+     * @param warning contains warning id.
+     */
+    public void setWarning(Warning warning);
+    public void setWarnings(List<Warning> warnings);
+    //public void setWarningId(int warning);
+
+
+    /**
+     * Set the warning id that pertain to User's password. This attribute maps to values between 0 and 100 contained within here {@link GlobalPwMsgIds}
+     *
+     * @return warning contains warning id.
+     */
+    public List<Warning> getWarnings();
+    //public int getWarningId();
+
+    /**
+     * Set the error id that pertain to User's password. This attribute maps to values greater than or equal to 100 contained within here {@link GlobalPwMsgIds}
+     *
+     * @param error contains error id that maps to {@link GlobalPwMsgIds#pwIds}
+     */
+    public void setErrorId(int error);
+
+    /**
+     * Return the error id that pertain to User's password. This attribute maps to values greater than or equal to 100 contained within here {@link GlobalPwMsgIds}
+     *
+     * @return error contains error id that maps to {@link GlobalPwMsgIds#pwIds}
+     */
+    public int getErrorId();
+
+    /**
+     * Grace count indicates how many binds User can perform before password slips into expired state.
+     *
+     * @param grace integer containing number of binds allowed for user.
+     */
+    public void setGraceLogins(int grace);
+
+    /**
+     * Get the grace count which indicates how many binds User can perform before password slips into expired state.
+     *
+     * @return grace integer containing number of binds allowed for user.
+     */
+    public int getGraceLogins();
+
+    /**
+     * The number of seconds until the User's password expires.
+     *
+     * @param expire value is computed by ldap server and contains the number of seconds until password will expire.
+     */
+    public void setExpirationSeconds(int expire);
+
+    /**
+     * Get the number of seconds until the User's password expires.
+     *
+     * @return expire value is computed by ldap server and contains the number of seconds until password will expire.
+     */
+    public int getExpirationSeconds();
+}
+


[39/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cli/CmdLineParser.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cli/CmdLineParser.java b/src/main/java/org/apache/directory/fortress/core/cli/CmdLineParser.java
new file mode 100755
index 0000000..8be4a45
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cli/CmdLineParser.java
@@ -0,0 +1,690 @@
+/**
+ * Copyright (c) 2001-2012 Steve Purcell.
+ * Copyright (c) 2002      Vidar Holen.
+ * Copyright (c) 2002      Michal Ceresna.
+ * Copyright (c) 2005      Ewan Mellor.
+ * Copyright (c) 2010-2012 penSec.IT UG (haftungsbeschränkt).
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. Redistributions in binary
+ * form must reproduce the above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or other materials provided
+ * with the distribution. Neither the name of the copyright holder nor the names
+ * of its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.apache.directory.fortress.core.cli;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Locale;
+
+/**
+ * Largely GNU-compatible command-line options parser. Has short (-v) and
+ * long-form (--verbose) option support, and also allows options with
+ * associated values (-d 2, --debug 2, --debug=2). Option processing
+ * can be explicitly terminated by the argument '--'.
+ *
+ * @author Steve Purcell
+ * @version $Revision: 1.10 $
+ * @see CommandLineInterpreter
+ */
+public class CmdLineParser
+{
+
+    /**
+     * Base class for exceptions that may be thrown when options are parsed
+     */
+    public static abstract class OptionException extends Exception
+    {
+        OptionException( String msg )
+        {
+            super( msg );
+        }
+    }
+
+    /**
+     * Thrown when the parsed command-line contains an option that is not
+     * recognised. <code>getMessage()</code> returns
+     * an error string suitable for reporting the error to the user (in
+     * English).
+     */
+    public static class UnknownOptionException extends OptionException
+    {
+        UnknownOptionException( String optionName )
+        {
+            this( optionName, "Unknown option '" + optionName + "'" );
+        }
+
+        UnknownOptionException( String optionName, String msg )
+        {
+            super( msg );
+            this.optionName = optionName;
+        }
+
+        /**
+         * @return the name of the option that was unknown (e.g. "-u")
+         */
+        public String getOptionName()
+        {
+            return this.optionName;
+        }
+
+        private String optionName = null;
+    }
+
+    /**
+     * Thrown when the parsed commandline contains multiple concatenated
+     * short options, such as -abcd, where one is unknown.
+     * <code>getMessage()</code> returns an english human-readable error
+     * string.
+     *
+     * @author Vidar Holen
+     */
+    public static class UnknownSuboptionException extends UnknownOptionException
+    {
+        private final char suboption;
+
+        UnknownSuboptionException( String option, char suboption )
+        {
+            super( option, "Illegal option: '" + suboption + "' in '" + option + "'" );
+            this.suboption = suboption;
+        }
+
+        public char getSuboption()
+        {
+            return suboption;
+        }
+    }
+
+    /**
+     * Thrown when the parsed commandline contains multiple concatenated
+     * short options, such as -abcd, where one or more requires a value.
+     * <code>getMessage()</code> returns an english human-readable error
+     * string.
+     *
+     * @author Vidar Holen
+     */
+    public static class NotFlagException extends UnknownOptionException
+    {
+        private final char notflag;
+
+        NotFlagException( String option, char unflaggish )
+        {
+            super( option, "Illegal option: '" + option + "', '" +
+                unflaggish + "' requires a value" );
+            notflag = unflaggish;
+        }
+
+        /**
+         * @return the first character which wasn't a boolean (e.g 'c')
+         */
+        public char getOptionChar()
+        {
+            return notflag;
+        }
+    }
+
+    /**
+     * Thrown when an illegal or missing value is given by the user for
+     * an option that takes a value. <code>getMessage()</code> returns
+     * an error string suitable for reporting the error to the user (in
+     * English).
+     */
+    public static class IllegalOptionValueException extends OptionException
+    {
+        public IllegalOptionValueException( Option opt, String value )
+        {
+            super( "Illegal value '" + value + "' for option " +
+                ( opt.shortForm() != null ? "-" + opt.shortForm() + "/" : "" ) +
+                "--" + opt.longForm() );
+            this.option = opt;
+            this.value = value;
+        }
+
+        /**
+         * @return the name of the option whose value was illegal (e.g. "-u")
+         */
+        public Option getOption()
+        {
+            return this.option;
+        }
+
+        /**
+         * @return the illegal value
+         */
+        public String getValue()
+        {
+            return this.value;
+        }
+
+        private final Option option;
+        private final String value;
+    }
+
+    /**
+     * Representation of a command-line option
+     */
+    public static abstract class Option
+    {
+
+        Option( String longForm, boolean wantsValue )
+        {
+            this( null, longForm, wantsValue );
+        }
+
+        Option( char shortForm, String longForm, boolean wantsValue )
+        {
+            this( new String( new char[]{shortForm} ), longForm, wantsValue );
+        }
+
+        private Option( String shortForm, String longForm, boolean wantsValue )
+        {
+            if ( longForm == null )
+            {
+                throw new IllegalArgumentException( "Null longForm not allowed" );
+            }
+            this.shortForm = shortForm;
+            this.longForm = longForm;
+            this.wantsValue = wantsValue;
+        }
+
+        public String shortForm()
+        {
+            return this.shortForm;
+        }
+
+        public String longForm()
+        {
+            return this.longForm;
+        }
+
+        /**
+         * Tells whether or not this option wants a value
+         */
+        public boolean wantsValue()
+        {
+            return this.wantsValue;
+        }
+
+        public final Object getValue( String arg, Locale locale ) throws IllegalOptionValueException
+        {
+            if ( this.wantsValue )
+            {
+                if ( arg == null )
+                {
+                    throw new IllegalOptionValueException( this, "arg is null" );
+                }
+                return this.parseValue( arg, locale );
+            }
+            else
+            {
+                return Boolean.TRUE;
+            }
+        }
+
+        /**
+         * Override to extract and convert an option value passed on the
+         * command-line
+         */
+        Object parseValue( String arg, Locale locale ) throws IllegalOptionValueException
+        {
+            return null;
+        }
+
+        private String shortForm = null;
+        private String longForm = null;
+        private boolean wantsValue = false;
+
+        public static class BooleanOption extends Option
+        {
+            public BooleanOption( char shortForm, String longForm )
+            {
+                super( shortForm, longForm, false );
+            }
+
+            public BooleanOption( String longForm )
+            {
+                super( longForm, false );
+            }
+        }
+
+        /**
+         * An option that expects an integer value
+         */
+        public static class IntegerOption extends Option
+        {
+            public IntegerOption( char shortForm, String longForm )
+            {
+                super( shortForm, longForm, true );
+            }
+
+            public IntegerOption( String longForm )
+            {
+                super( longForm, true );
+            }
+
+            protected Object parseValue( String arg, Locale locale ) throws IllegalOptionValueException
+            {
+                try
+                {
+                    return new Integer( arg );
+                }
+                catch ( NumberFormatException e )
+                {
+                    throw new IllegalOptionValueException( this, arg );
+                }
+            }
+        }
+
+        /**
+         * An option that expects a long integer value
+         */
+        public static class LongOption extends Option
+        {
+            public LongOption( char shortForm, String longForm )
+            {
+                super( shortForm, longForm, true );
+            }
+
+            public LongOption( String longForm )
+            {
+                super( longForm, true );
+            }
+
+            protected Object parseValue( String arg, Locale locale ) throws IllegalOptionValueException
+            {
+                try
+                {
+                    return new Long( arg );
+                }
+                catch ( NumberFormatException e )
+                {
+                    throw new IllegalOptionValueException( this, arg );
+                }
+            }
+        }
+
+        /**
+         * An option that expects a floating-point value
+         */
+        public static class DoubleOption extends Option
+        {
+            public DoubleOption( char shortForm, String longForm )
+            {
+                super( shortForm, longForm, true );
+            }
+
+            public DoubleOption( String longForm )
+            {
+                super( longForm, true );
+            }
+
+            protected Object parseValue( String arg, Locale locale ) throws IllegalOptionValueException
+            {
+                try
+                {
+                    NumberFormat format = NumberFormat.getNumberInstance( locale );
+                    Number num = format.parse( arg );
+                    return num.doubleValue();
+                }
+                catch ( ParseException e )
+                {
+                    throw new IllegalOptionValueException( this, arg );
+                }
+            }
+        }
+
+        /**
+         * An option that expects a string value
+         */
+        public static class StringOption extends Option
+        {
+            public StringOption( char shortForm, String longForm )
+            {
+                super( shortForm, longForm, true );
+            }
+
+            public StringOption( String longForm )
+            {
+                super( longForm, true );
+            }
+
+            protected Object parseValue( String arg, Locale locale )
+            {
+                return arg;
+            }
+        }
+    }
+
+    /**
+     * Add the specified Option to the list of accepted options
+     */
+    final Option addOption( Option opt )
+    {
+        if ( opt.shortForm() != null )
+        {
+            this.options.put( "-" + opt.shortForm(), opt );
+        }
+        this.options.put( "--" + opt.longForm(), opt );
+        return opt;
+    }
+
+    /**
+     * Convenience method for adding a string option.
+     *
+     * @return the new Option
+     */
+    public final Option addStringOption( char shortForm, String longForm )
+    {
+        return addOption( new Option.StringOption( shortForm, longForm ) );
+    }
+
+    /**
+     * Convenience method for adding a string option.
+     *
+     * @return the new Option
+     */
+    public final Option addStringOption( String longForm )
+    {
+        return addOption( new Option.StringOption( longForm ) );
+    }
+
+    /**
+     * Convenience method for adding an integer option.
+     *
+     * @return the new Option
+     */
+    public final Option addIntegerOption( char shortForm, String longForm )
+    {
+        return addOption( new Option.IntegerOption( shortForm, longForm ) );
+    }
+
+    /**
+     * Convenience method for adding an integer option.
+     *
+     * @return the new Option
+     */
+    public final Option addIntegerOption( String longForm )
+    {
+        return addOption( new Option.IntegerOption( longForm ) );
+    }
+
+    /**
+     * Convenience method for adding a long integer option.
+     *
+     * @return the new Option
+     */
+    public final Option addLongOption( char shortForm, String longForm )
+    {
+        return addOption( new Option.LongOption( shortForm, longForm ) );
+    }
+
+    /**
+     * Convenience method for adding a long integer option.
+     *
+     * @return the new Option
+     */
+    public final Option addLongOption( String longForm )
+    {
+        return addOption( new Option.LongOption( longForm ) );
+    }
+
+    /**
+     * Convenience method for adding a double option.
+     *
+     * @return the new Option
+     */
+    public final Option addDoubleOption( char shortForm, String longForm )
+    {
+        return addOption( new Option.DoubleOption( shortForm, longForm ) );
+    }
+
+    /**
+     * Convenience method for adding a double option.
+     *
+     * @return the new Option
+     */
+    public final Option addDoubleOption( String longForm )
+    {
+        return addOption( new Option.DoubleOption( longForm ) );
+    }
+
+    /**
+     * Convenience method for adding a boolean option.
+     *
+     * @return the new Option
+     */
+    public final Option addBooleanOption( char shortForm, String longForm )
+    {
+        return addOption( new Option.BooleanOption( shortForm, longForm ) );
+    }
+
+    /**
+     * Convenience method for adding a boolean option.
+     *
+     * @return the new Option
+     */
+    public final Option addBooleanOption( String longForm )
+    {
+        return addOption( new Option.BooleanOption( longForm ) );
+    }
+
+    /**
+     * Equivalent to {@link #getOptionValue(Option, Object) getOptionValue(o,
+     * null)}.
+     */
+    public final Object getOptionValue( Option o )
+    {
+        return getOptionValue( o, null );
+    }
+
+
+    /**
+     * @return the parsed value of the given Option, or null if the
+     * option was not set
+     */
+    final Object getOptionValue( Option o, Object def )
+    {
+        Vector v = ( Vector ) values.get( o.longForm() );
+
+        if ( v == null )
+        {
+            return def;
+        }
+        else if ( v.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            Object result = v.elementAt( 0 );
+            v.removeElementAt( 0 );
+            return result;
+        }
+    }
+
+
+    /**
+     * @return A Vector giving the parsed values of all the occurrences of the
+     * given Option, or an empty Vector if the option was not set.
+     */
+    public final Vector getOptionValues( Option option )
+    {
+        Vector result = new Vector();
+
+        while ( true )
+        {
+            Object o = getOptionValue( option, null );
+
+            if ( o == null )
+            {
+                return result;
+            }
+            else
+            {
+                result.addElement( o );
+            }
+        }
+    }
+
+
+    /**
+     * @return the non-option arguments
+     */
+    public final String[] getRemainingArgs()
+    {
+        return this.remainingArgs;
+    }
+
+    /**
+     * Extract the options and non-option arguments from the given
+     * list of command-line arguments. The default locale is used for
+     * parsing options whose values might be locale-specific.
+     */
+    public final void parse( String[] argv ) throws IllegalOptionValueException, UnknownOptionException
+    {
+
+        // It would be best if this method only threw OptionException, but for
+        // backwards compatibility with old user code we throw the two
+        // exceptions above instead.
+
+        parse( argv, Locale.getDefault() );
+    }
+
+    /**
+     * Extract the options and non-option arguments from the given
+     * list of command-line arguments. The specified locale is used for
+     * parsing options whose values might be locale-specific.
+     */
+    final void parse( String[] argv, Locale locale ) throws IllegalOptionValueException, UnknownOptionException
+    {
+
+        // It would be best if this method only threw OptionException, but for
+        // backwards compatibility with old user code we throw the two
+        // exceptions above instead.
+
+        Vector otherArgs = new Vector();
+        int position = 0;
+        this.values = new Hashtable( 10 );
+        while ( position < argv.length )
+        {
+            String curArg = argv[position];
+            if ( curArg.startsWith( "-" ) )
+            {
+                if ( curArg.equals( "--" ) )
+                { // end of options
+                    position += 1;
+                    break;
+                }
+                String valueArg = null;
+                if ( curArg.startsWith( "--" ) )
+                { // handle --arg=value
+                    int equalsPos = curArg.indexOf( "=" );
+                    if ( equalsPos != -1 )
+                    {
+                        valueArg = curArg.substring( equalsPos + 1 );
+                        curArg = curArg.substring( 0, equalsPos );
+                    }
+                }
+                else if ( curArg.length() > 2 )
+                {  // handle -abcd
+                    for ( int i = 1; i < curArg.length(); i++ )
+                    {
+                        Option opt = ( Option ) this.options.get( "-" + curArg.charAt( i ) );
+                        if ( opt == null )
+                        {
+                            throw new UnknownSuboptionException( curArg, curArg.charAt( i ) );
+                        }
+                        if ( opt.wantsValue() )
+                        {
+                            throw new NotFlagException( curArg, curArg.charAt( i ) );
+                        }
+                        addValue( opt, opt.getValue( null, locale ) );
+
+                    }
+                    position++;
+                    continue;
+                }
+
+                Option opt = ( Option ) this.options.get( curArg );
+                if ( opt == null )
+                {
+                    throw new UnknownOptionException( curArg );
+                }
+                Object value;
+                if ( opt.wantsValue() )
+                {
+                    if ( valueArg == null )
+                    {
+                        position += 1;
+                        if ( position < argv.length )
+                        {
+                            valueArg = argv[position];
+                        }
+                    }
+                    value = opt.getValue( valueArg, locale );
+                }
+                else
+                {
+                    value = opt.getValue( null, locale );
+                }
+
+                addValue( opt, value );
+
+                position += 1;
+            }
+            else
+            {
+                otherArgs.addElement( curArg );
+                position += 1;
+            }
+        }
+        for (; position < argv.length; ++position )
+        {
+            otherArgs.addElement( argv[position] );
+        }
+
+        this.remainingArgs = new String[otherArgs.size()];
+        otherArgs.copyInto( remainingArgs );
+    }
+
+
+    private void addValue( Option opt, Object value )
+    {
+        String lf = opt.longForm();
+
+        Vector v = ( Vector ) values.get( lf );
+
+        if ( v == null )
+        {
+            v = new Vector();
+            values.put( lf, v );
+        }
+
+        v.addElement( value );
+    }
+
+
+    private String[] remainingArgs = null;
+    private final Hashtable options = new Hashtable( 10 );
+    private Hashtable values = new Hashtable( 10 );
+}
\ 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/cli/CommandLineInterpreter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cli/CommandLineInterpreter.java b/src/main/java/org/apache/directory/fortress/core/cli/CommandLineInterpreter.java
new file mode 100755
index 0000000..9870eae
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cli/CommandLineInterpreter.java
@@ -0,0 +1,1435 @@
+/*
+ *   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.cli;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.directory.fortress.core.*;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.ldap.group.Group;
+import org.apache.directory.fortress.core.ldap.group.GroupMgr;
+import org.apache.directory.fortress.core.ldap.group.GroupMgrFactory;
+import org.apache.directory.fortress.core.rbac.Address;
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.SDSet;
+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 org.slf4j.LoggerFactory;
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+import org.apache.directory.fortress.core.rbac.Relationship;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.time.Constraint;
+
+
+/**
+ * Main program for Fortress Command Line Interpreter..
+ *
+ * @author Shawn McKinney
+ */
+public class CommandLineInterpreter
+{
+    private static final String CLS_NM = CommandLineInterpreter.class.getName();
+    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private AdminMgr adminMgr;
+    private ReviewMgr reviewMgr;
+    private AccessMgr accessMgr;
+    private DelAdminMgr delAdminMgr;
+    private GroupMgr groupMgr;
+    //private DelReviewMgr delReviewMgr;
+    //private DelAccessMgr delAccessMgr;
+    //private PwPolicyMgr pwPolicyMgr;
+
+    /* THESE ARE THE HIGH LEVEL COMMANDS: */
+    private static final String ADMIN = "admin";
+    private static final String REVIEW = "review";
+    private static final String SYSTEM = "system";
+    private static final String DELEGATED_ADMIN = "dadmin";
+    private static final String DELEGATED_REVIEW = "dreview";
+    private static final String DELEGATED_SYSTEM = "dsystem";
+    private static final String GROUP = "group";
+
+    /* THESE ARE THE 2ND LEVEL COMMANDS: */
+    private static final String ADD_USER = "auser";
+    private static final String UPDATE_USER = "uuser";
+    private static final String DELETE_USER = "duser";
+    private static final String READ_USER = "ruser";
+    private static final String FIND_USERS = "fuser";
+    private static final String ASSIGNED_USERS = "asgnuser";
+
+    private static final String CHANGE_PASSWORD = "change";
+    private static final String LOCK_USER_ACCOUNT = "lock";
+    private static final String UNLOCK_USER_ACCOUNT = "unlock";
+    private static final String RESET_PASSWORD = "reset";
+
+    private static final String ADD_ROLE = "arole";
+    private static final String UPDATE_ROLE = "urole";
+    private static final String DELETE_ROLE = "drole";
+    private static final String READ_ROLE = "rrole";
+    private static final String FIND_ROLES = "frole";
+    private static final String ASSIGN_ROLE = "asgnrole";
+    private static final String DEASSIGN_ROLE = "dsgnrole";
+    private static final String ADD_ROLE_INHERITANCE = "arel";
+    private static final String DELETE_ROLE_INHERITANCE = "drel";
+    private static final String CREATE_SSD_SET = "asset";
+    private static final String DELETE_SSD_SET = "dsset";
+    private static final String CREATE_DSD_SET = "adset";
+    private static final String DELETE_DSD_SET = "ddset";
+
+    private static final String ADD_POBJ = "aobj";
+    private static final String UPDATE_POBJ = "uobj";
+    private static final String DELETE_POBJ = "dobj";
+    private static final String READ_POBJ = "robj";
+    private static final String FIND_POBJS = "fobj";
+
+    private static final String ADD_PERM = "aperm";
+    private static final String UPDATE_PERM = "uperm";
+    private static final String DELETE_PERM = "dperm";
+    private static final String READ_PERM = "rperm";
+    private static final String FIND_PERMS = "fperm";
+    private static final String GRANT = "grant";
+    private static final String REVOKE = "revoke";
+
+    private static final String ADD_GROUP = "agroup";
+    private static final String UPDATE_GROUP = "ugroup";
+    private static final String DELETE_GROUP = "dgroup";
+    private static final String READ_GROUP = "rgroup";
+    private static final String FIND_GROUP = "fgroup";
+    private static final String ASSIGN_GROUP = "asgngroup";
+    private static final String DEASSIGN_GROUP = "dsgngroup";
+    private static final String ADD_GROUP_PROP = "agprop";
+    private static final String DELETE_GROUP_PROP = "dgprop";
+
+    private static final String ADD_USERORG = "auou";
+    private static final String UPDATE_USERORG = "uuou";
+    private static final String DELETE_USERORG = "duou";
+    private static final String ADD_USERORG_INHERITANCE = "aurel";
+    private static final String DELETE_USERORG_INHERITANCE = "durel";
+    private static final String ADD_PERMORG = "apou";
+    private static final String UPDATE_PERMORG = "upou";
+    private static final String DELETE_PERMORG = "dpou";
+    private static final String ADD_PERMORG_INHERITANCE = "aprel";
+    private static final String DELETE_PERMORG_INHERITANCE = "dprel";
+
+    private static final String CREATE_SESSION = "createsession";
+    private static final String AUTHENTICATE = "authenticate";
+    private static final String ASSIGNED_ROLES = "assignedroles";
+    private static final String CHECK_ACCESS = "checkaccess";
+
+    /**
+     * @param args
+     */
+    public static void main(String[] args)
+    {
+        CommandLineInterpreter cli = new CommandLineInterpreter();
+        cli.runInteractiveMode();
+    }
+
+    /**
+     *
+     */
+    private void runInteractiveMode()
+    {
+        if (!constructManagers())
+        {
+            String error = "Startup to interactive mode failed, goodbye.";
+            LOG.error(error);
+            return;
+        }
+
+        LOG.info("Startup to interactive mode success...");
+        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+        String input;
+        while (true)
+        {
+            try
+            {
+                LOG.info("CLI function groups include " + ADMIN + ", " + REVIEW + ", " + SYSTEM + ", " + DELEGATED_ADMIN + ", " + GROUP);
+                LOG.info("Enter one from above or 'q' to quit");
+                input = br.readLine();
+                if (VUtil.isNotNullOrEmpty(input))
+                {
+                    if ("Q".equalsIgnoreCase(input))
+                    {
+                        LOG.info("Goodbye");
+                        break;
+                    }
+
+                    String[] options = parseUserInput(input);
+                    processUserInput(options);
+                }
+            }
+            catch (Exception e)
+            {
+                String error = "runInteractiveMode caught Exception=" + e.toString();
+                LOG.error(error);
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private static void printUsage()
+    {
+        LOG.error("Usage: group function options");
+        LOG.error("where group is: admin, review, system, dadmin or group");
+        LOG.error("Check out the Command Line Reference manual for what the valid function and option combinations are.");
+    }
+
+    /**
+     * @param commands
+     * @param options
+     */
+    private void processCommand(Set<String> commands, Options options)
+    {
+        if (commands.contains(ADMIN))
+        {
+            processAdminCommand(commands, options);
+        }
+        else if (commands.contains(REVIEW))
+        {
+            processReviewCommand(commands, options);
+        }
+        else if (commands.contains(SYSTEM))
+        {
+            processSystemCommand(commands, options);
+        }
+        else if (commands.contains(DELEGATED_ADMIN))
+        {
+            processDelegatedAdminCommand(commands, options);
+        }
+        else if (commands.contains(GROUP))
+        {
+            processGroupCommand(commands, options);
+        }
+        else if (commands.contains(DELEGATED_REVIEW))
+        {
+            //processDelegatedReviewCommand(commands, options);
+        }
+        else if (commands.contains(DELEGATED_SYSTEM))
+        {
+            //processDelegatedSystemCommand(commands, options);
+        }
+        else
+        {
+            LOG.warn("unknown admin operation detected");
+        }
+    }
+
+    private void processDelegatedAdminCommand(Set<String> commands, Options options)
+    {
+        String command;
+        try
+        {
+            if (commands.contains(ADD_ROLE))
+            {
+                command = ADD_ROLE;
+                LOG.info(command);
+                AdminRole role = options.getAdminRole();
+                delAdminMgr.addRole(role);
+            }
+            else if (commands.contains(UPDATE_ROLE))
+            {
+                command = UPDATE_ROLE;
+                LOG.info(command);
+                AdminRole role = options.getAdminRole();
+                delAdminMgr.updateRole(role);
+            }
+            else if (commands.contains(DELETE_ROLE))
+            {
+                command = DELETE_ROLE;
+                LOG.info(command);
+                AdminRole role = options.getAdminRole();
+                delAdminMgr.deleteRole(role);
+            }
+            else if (commands.contains(ASSIGN_ROLE))
+            {
+                command = ASSIGN_ROLE;
+                LOG.info(command);
+                Role role = options.getRole();
+                String userId = options.getUserId();
+                delAdminMgr.assignUser(new UserAdminRole(userId, role));
+            }
+            else if (commands.contains(DEASSIGN_ROLE))
+            {
+                command = DEASSIGN_ROLE;
+                LOG.info(command);
+                Role role = options.getRole();
+                String userId = options.getUserId();
+                delAdminMgr.deassignUser(new UserAdminRole(userId, role));
+            }
+            else if (commands.contains(ADD_ROLE_INHERITANCE))
+            {
+                command = ADD_ROLE_INHERITANCE;
+                LOG.info(command);
+                Relationship relationship = options.getRelationship();
+                delAdminMgr.addInheritance(new AdminRole(relationship.getParent()), new AdminRole(relationship.getChild()));
+            }
+            else if (commands.contains(DELETE_ROLE_INHERITANCE))
+            {
+                command = DELETE_ROLE_INHERITANCE;
+                LOG.info(command);
+                Relationship relationship = options.getRelationship();
+                delAdminMgr.deleteInheritance(new AdminRole(relationship.getParent()), new AdminRole(relationship.getChild()));
+            }
+            else if (commands.contains(ADD_POBJ))
+            {
+                command = ADD_POBJ;
+                LOG.info(command);
+                PermObj permObj = options.getPermObj();
+                delAdminMgr.addPermObj(permObj);
+            }
+            else if (commands.contains(UPDATE_POBJ))
+            {
+                command = UPDATE_POBJ;
+                LOG.info(command);
+                PermObj permObj = options.getPermObj();
+                delAdminMgr.updatePermObj(permObj);
+            }
+            else if (commands.contains(DELETE_POBJ))
+            {
+                command = DELETE_POBJ;
+                LOG.info(command);
+                PermObj permObj = options.getPermObj();
+                delAdminMgr.deletePermObj(permObj);
+            }
+            else if (commands.contains(ADD_PERM))
+            {
+                command = ADD_PERM;
+                LOG.info(command);
+                Permission perm = options.getPermission();
+                delAdminMgr.addPermission(perm);
+            }
+            else if (commands.contains(UPDATE_PERM))
+            {
+                command = UPDATE_PERM;
+                LOG.info(command);
+                Permission perm = options.getPermission();
+                delAdminMgr.updatePermission(perm);
+            }
+            else if (commands.contains(DELETE_PERM))
+            {
+                command = DELETE_PERM;
+                LOG.info(command);
+                Permission permObj = options.getPermission();
+                delAdminMgr.deletePermission(permObj);
+            }
+            else if (commands.contains(GRANT))
+            {
+                command = GRANT;
+                LOG.info(command);
+                Permission perm = options.getPermission();
+                AdminRole role = options.getAdminRole();
+                role.setName(options.getRoleNm());
+                delAdminMgr.grantPermission(perm, role);
+            }
+            else if (commands.contains(REVOKE))
+            {
+                command = REVOKE;
+                LOG.info(command);
+                Permission perm = options.getPermission();
+                AdminRole role = options.getAdminRole();
+                role.setName(options.getRoleNm());
+                delAdminMgr.revokePermission(perm, role);
+            }
+            else if (commands.contains(ADD_USERORG))
+            {
+                command = ADD_USERORG;
+                LOG.info(command);
+                OrgUnit orgUnit = options.getOrgUnit();
+                orgUnit.setType(OrgUnit.Type.USER);
+                delAdminMgr.add(orgUnit);
+            }
+            else if (commands.contains(UPDATE_USERORG))
+            {
+                command = UPDATE_USERORG;
+                LOG.info(command);
+                OrgUnit orgUnit = options.getOrgUnit();
+                orgUnit.setType(OrgUnit.Type.USER);
+                delAdminMgr.update(orgUnit);
+            }
+            else if (commands.contains(DELETE_USERORG))
+            {
+                command = DELETE_USERORG;
+                LOG.info(command);
+                OrgUnit orgUnit = options.getOrgUnit();
+                orgUnit.setType(OrgUnit.Type.USER);
+                delAdminMgr.delete(orgUnit);
+            }
+            else if (commands.contains(ADD_USERORG_INHERITANCE))
+            {
+                command = ADD_USERORG_INHERITANCE;
+                LOG.info(command);
+                Relationship relationship = options.getRelationship();
+                delAdminMgr.addInheritance(new OrgUnit(relationship.getParent(), OrgUnit.Type.USER), new OrgUnit(relationship.getChild(), OrgUnit.Type.USER));
+            }
+            else if (commands.contains(DELETE_USERORG_INHERITANCE))
+            {
+                command = DELETE_USERORG_INHERITANCE;
+                LOG.info(command);
+                Relationship relationship = options.getRelationship();
+                delAdminMgr.deleteInheritance(new OrgUnit(relationship.getParent(), OrgUnit.Type.USER), new OrgUnit(relationship.getChild(), OrgUnit.Type.USER));
+            }
+            else if (commands.contains(ADD_PERMORG))
+            {
+                command = ADD_PERMORG;
+                LOG.info(command);
+                OrgUnit orgUnit = options.getOrgUnit();
+                orgUnit.setType(OrgUnit.Type.PERM);
+                delAdminMgr.add(orgUnit);
+            }
+            else if (commands.contains(UPDATE_PERMORG))
+            {
+                command = UPDATE_PERMORG;
+                LOG.info(command);
+                OrgUnit orgUnit = options.getOrgUnit();
+                orgUnit.setType(OrgUnit.Type.PERM);
+                delAdminMgr.update(orgUnit);
+            }
+            else if (commands.contains(DELETE_PERMORG))
+            {
+                command = DELETE_PERMORG;
+                LOG.info(command);
+                OrgUnit orgUnit = options.getOrgUnit();
+                orgUnit.setType(OrgUnit.Type.PERM);
+                delAdminMgr.delete(orgUnit);
+            }
+            else if (commands.contains(ADD_PERMORG_INHERITANCE))
+            {
+                command = ADD_PERMORG_INHERITANCE;
+                LOG.info(command);
+                Relationship relationship = options.getRelationship();
+                delAdminMgr.addInheritance(new OrgUnit(relationship.getParent(), OrgUnit.Type.PERM), new OrgUnit(relationship.getChild(), OrgUnit.Type.PERM));
+            }
+            else if (commands.contains(DELETE_PERMORG_INHERITANCE))
+            {
+                command = DELETE_PERMORG_INHERITANCE;
+                LOG.info(command);
+                Relationship relationship = options.getRelationship();
+                delAdminMgr.deleteInheritance(new OrgUnit(relationship.getParent(), OrgUnit.Type.PERM), new OrgUnit(relationship.getChild(), OrgUnit.Type.PERM));
+            }
+            else
+            {
+                LOG.warn("unknown delegated admin operation detected");
+                return;
+            }
+            LOG.info("command:" + command + " was successful");
+        }
+        catch ( org.apache.directory.fortress.core.SecurityException se)
+        {
+            String error = "processDelegatedAdminCommand caught SecurityException=" + se + ", return code=" + se.getErrorId();
+            LOG.error(error);
+        }
+    }
+
+    /**
+     * @param commands
+     * @param options
+     */
+    private void processAdminCommand(Set<String> commands, Options options)
+    {
+        String command;
+        try
+        {
+            if (commands.contains(ADD_USER))
+            {
+                command = ADD_USER;
+                LOG.info(command);
+                User user = options.getUser();
+                adminMgr.addUser(user);
+            }
+            else if (commands.contains(UPDATE_USER))
+            {
+                command = UPDATE_USER;
+                LOG.info(command);
+                User user = options.getUser();
+                adminMgr.updateUser(user);
+            }
+            else if (commands.contains(DELETE_USER))
+            {
+                command = DELETE_USER;
+                LOG.info(command);
+                User user = options.getUser();
+                adminMgr.deleteUser(user);
+            }
+            else if (commands.contains(ADD_ROLE))
+            {
+                command = ADD_ROLE;
+                LOG.info(command);
+                Role role = options.getRole();
+                adminMgr.addRole(role);
+            }
+            else if (commands.contains(UPDATE_ROLE))
+            {
+                command = UPDATE_ROLE;
+                LOG.info(command);
+                Role role = options.getRole();
+                adminMgr.updateRole(role);
+            }
+            else if (commands.contains(DELETE_ROLE))
+            {
+                command = DELETE_ROLE;
+                LOG.info(command);
+                Role role = options.getRole();
+                adminMgr.deleteRole(role);
+            }
+            else if (commands.contains(ASSIGN_ROLE))
+            {
+                command = ASSIGN_ROLE;
+                LOG.info(command);
+                Role role = options.getRole();
+                String userId = options.getUserId();
+                adminMgr.assignUser(new UserRole(userId, role));
+            }
+            else if (commands.contains(DEASSIGN_ROLE))
+            {
+                command = DEASSIGN_ROLE;
+                LOG.info(command);
+                Role role = options.getRole();
+                String userId = options.getUserId();
+                adminMgr.deassignUser(new UserRole(userId, role));
+            }
+            else if (commands.contains(ADD_ROLE_INHERITANCE))
+            {
+                command = ADD_ROLE_INHERITANCE;
+                LOG.info(command);
+                Relationship relationship = options.getRelationship();
+                adminMgr.addInheritance(new Role(relationship.getParent()), new Role(relationship.getChild()));
+            }
+            else if (commands.contains(DELETE_ROLE_INHERITANCE))
+            {
+                command = DELETE_ROLE_INHERITANCE;
+                LOG.info(command);
+                Relationship relationship = options.getRelationship();
+                adminMgr.deleteInheritance(new Role(relationship.getParent()), new Role(relationship.getChild()));
+            }
+            else if (commands.contains(ADD_POBJ))
+            {
+                command = ADD_POBJ;
+                LOG.info(command);
+                PermObj permObj = options.getPermObj();
+                adminMgr.addPermObj(permObj);
+            }
+            else if (commands.contains(UPDATE_POBJ))
+            {
+                command = UPDATE_POBJ;
+                LOG.info(command);
+                PermObj permObj = options.getPermObj();
+                adminMgr.updatePermObj(permObj);
+            }
+            else if (commands.contains(DELETE_POBJ))
+            {
+                command = DELETE_POBJ;
+                LOG.info(command);
+                PermObj permObj = options.getPermObj();
+                adminMgr.deletePermObj(permObj);
+            }
+            else if (commands.contains(ADD_PERM))
+            {
+                command = ADD_PERM;
+                LOG.info(command);
+                Permission perm = options.getPermission();
+                adminMgr.addPermission(perm);
+            }
+            else if (commands.contains(UPDATE_PERM))
+            {
+                command = UPDATE_PERM;
+                LOG.info(command);
+                Permission perm = options.getPermission();
+                adminMgr.updatePermission(perm);
+            }
+            else if (commands.contains(DELETE_PERM))
+            {
+                command = DELETE_PERM;
+                LOG.info(command);
+                Permission permObj = options.getPermission();
+                adminMgr.deletePermission(permObj);
+            }
+            else if (commands.contains(GRANT))
+            {
+                command = GRANT;
+                LOG.info(command);
+                Permission perm = options.getPermission();
+                Role role = options.getRole();
+                role.setName(options.getRoleNm());
+                adminMgr.grantPermission(perm, role);
+            }
+            else if (commands.contains(REVOKE))
+            {
+                command = REVOKE;
+                LOG.info(command);
+                Permission perm = options.getPermission();
+                Role role = options.getRole();
+                role.setName(options.getRoleNm());
+                adminMgr.revokePermission(perm, role);
+            }
+            else if (commands.contains(CREATE_SSD_SET))
+            {
+                command = CREATE_SSD_SET;
+                LOG.info(command);
+                SDSet ssd = options.getSdSet();
+                ssd.setType(SDSet.SDType.STATIC);
+                adminMgr.createSsdSet(ssd);
+            }
+            else if (commands.contains(DELETE_SSD_SET))
+            {
+                command = DELETE_SSD_SET;
+                LOG.info(command);
+                SDSet ssd = options.getSdSet();
+                ssd.setType(SDSet.SDType.STATIC);
+                adminMgr.deleteSsdSet(ssd);
+            }
+            else if (commands.contains(CREATE_DSD_SET))
+            {
+                command = CREATE_DSD_SET;
+                LOG.info(command);
+                SDSet ssd = options.getSdSet();
+                ssd.setType(SDSet.SDType.DYNAMIC);
+                adminMgr.createDsdSet(ssd);
+            }
+            else if (commands.contains(DELETE_DSD_SET))
+            {
+                command = DELETE_DSD_SET;
+                LOG.info(command);
+                SDSet ssd = options.getSdSet();
+                ssd.setType(SDSet.SDType.DYNAMIC);
+                adminMgr.deleteDsdSet(ssd);
+            }
+            else if (commands.contains(CHANGE_PASSWORD))
+            {
+                command = CHANGE_PASSWORD;
+                LOG.info(command);
+                User user = options.getUser();
+                char[] newPassword = options.getNewPassword();
+                adminMgr.changePassword(user, newPassword);
+            }
+            else if (commands.contains(RESET_PASSWORD))
+            {
+                command = RESET_PASSWORD;
+                LOG.info(command);
+                User user = options.getUser();
+                char[] newPassword = options.getNewPassword();
+                adminMgr.resetPassword(user, newPassword);
+            }
+            else if (commands.contains(LOCK_USER_ACCOUNT))
+            {
+                command = LOCK_USER_ACCOUNT;
+                LOG.info(command);
+                User user = options.getUser();
+                adminMgr.lockUserAccount(user);
+            }
+            else if (commands.contains(UNLOCK_USER_ACCOUNT))
+            {
+                command = UNLOCK_USER_ACCOUNT;
+                LOG.info(command);
+                User user = options.getUser();
+                adminMgr.unlockUserAccount(user);
+            }
+            else
+            {
+                LOG.warn("unknown admin operation detected");
+                return;
+            }
+            LOG.info("command:" + command + " was successful");
+        }
+        catch ( SecurityException se)
+        {
+            String error = "processAdminCommand caught SecurityException=" + se + ", return code=" + se.getErrorId();
+            LOG.error(error);
+        }
+    }
+
+    /**
+     * @param commands
+     * @param options
+     */
+    private void processReviewCommand(Set<String> commands, Options options)
+    {
+        String command;
+        try
+        {
+            if (commands.contains(READ_USER))
+            {
+                command = READ_USER;
+                LOG.info(READ_USER);
+                User inUser = options.getUser();
+                User outUser = reviewMgr.readUser(inUser);
+                printUser(outUser);
+            }
+            else if (commands.contains(FIND_USERS))
+            {
+                command = FIND_USERS;
+                LOG.info(command);
+                User user = options.getUser();
+                List<User> outUsers = reviewMgr.findUsers(user);
+                if (VUtil.isNotNullOrEmpty(outUsers))
+                {
+                    int ctr = 0;
+                    for (User outUser : outUsers)
+                    {
+                        printRow("U", "CTR ", "" + ctr++);
+                        printUser(outUser);
+                    }
+                }
+            }
+            else if (commands.contains(ASSIGNED_USERS))
+            {
+                command = ASSIGNED_USERS;
+                LOG.info(command);
+                Role inRole = options.getRole();
+                List<User> outUsers = reviewMgr.assignedUsers(inRole);
+                if (VUtil.isNotNullOrEmpty(outUsers))
+                {
+                    for (User outUser : outUsers)
+                    {
+                        printUser(outUser);
+                    }
+                }
+            }
+            else if (commands.contains(READ_ROLE))
+            {
+                command = READ_ROLE;
+                LOG.info(command);
+                Role inRole = options.getRole();
+                Role outRole = reviewMgr.readRole(inRole);
+                printRole(outRole);
+            }
+            else if (commands.contains(FIND_ROLES))
+            {
+                command = FIND_ROLES;
+                LOG.info(command);
+                String inRoleNm = options.getName();
+                List<Role> outRoles = reviewMgr.findRoles(inRoleNm);
+                if (VUtil.isNotNullOrEmpty(outRoles))
+                {
+                    int ctr = 0;
+                    for (Role outRole : outRoles)
+                    {
+                        printSeparator();
+                        printRow("R", "ROLE[" + ++ctr + "]", outRole.getName());
+                        printRole(outRole);
+                    }
+                }
+            }
+            else if (commands.contains(ASSIGNED_ROLES))
+            {
+                command = ASSIGNED_ROLES;
+                LOG.info(command);
+                String userId = options.getUserId();
+                List<UserRole> uRoles = reviewMgr.assignedRoles(new User(userId));
+                if (uRoles != null)
+                {
+                    for (UserRole ur : uRoles)
+                    {
+                        printTemporal("R", ur, "RBACROLE");
+                        printSeparator();
+                    }
+                }
+            }
+            else if (commands.contains(READ_POBJ))
+            {
+                command = READ_POBJ;
+                LOG.info(command);
+                PermObj inPermObj = options.getPermObj();
+                PermObj outPermObj = reviewMgr.readPermObj(inPermObj);
+                printPermObj(outPermObj);
+            }
+            else if (commands.contains(FIND_POBJS))
+            {
+                command = FIND_POBJS;
+                LOG.info(command);
+                PermObj inPermObj = options.getPermObj();
+                List<PermObj> outPermObjs = reviewMgr.findPermObjs(inPermObj);
+                if (VUtil.isNotNullOrEmpty(outPermObjs))
+                {
+                    int ctr = 0;
+                    for (PermObj outPermObj : outPermObjs)
+                    {
+                        printSeparator();
+                        printRow("PO", "POBJ[" + ++ctr + "]", outPermObj.getObjName());
+                        printPermObj(outPermObj);
+                    }
+                }
+            }
+            else if (commands.contains(READ_PERM))
+            {
+                command = READ_PERM;
+                LOG.info(command);
+                Permission inPerm = options.getPermission();
+                Permission outPerm = reviewMgr.readPermission(inPerm);
+                printPermission(outPerm);
+            }
+            else if (commands.contains(FIND_PERMS))
+            {
+                command = FIND_PERMS;
+                LOG.info(command);
+                Permission inPerm = options.getPermission();
+                List<Permission> outPerms = reviewMgr.findPermissions(inPerm);
+                if (VUtil.isNotNullOrEmpty(outPerms))
+                {
+                    int ctr = 0;
+                    for (Permission outPerm : outPerms)
+                    {
+                        printSeparator();
+                        printRow("P", "PERM[" + ++ctr + "]", outPerm.getAbstractName());
+                        printPermission(outPerm);
+                    }
+                }
+            }
+            else
+            {
+                LOG.warn("unknown review operation detected");
+                return;
+            }
+            LOG.info("command:" + command + " was successful");
+        }
+        catch ( SecurityException se)
+        {
+            String error = "processReviewCommand caught SecurityException=" + se + ", return code=" + se.getErrorId();
+            LOG.error(error);
+        }
+    }
+
+    /**
+     * @param commands
+     * @param options
+     */
+    private void processSystemCommand(Set<String> commands, Options options)
+    {
+        String command;
+        try
+        {
+            if (commands.contains(CREATE_SESSION))
+            {
+                command = CREATE_SESSION;
+                LOG.info(READ_USER);
+                User inUser = options.getUser();
+                Session session = accessMgr.createSession(inUser, false);
+                printSession(session);
+            }
+            else if (commands.contains(AUTHENTICATE))
+            {
+                command = AUTHENTICATE;
+                LOG.info(command);
+                User inUser = options.getUser();
+                Session session = accessMgr.authenticate(inUser.getUserId(), inUser.getPassword());
+                printSession(session);
+            }
+            else if (commands.contains(ASSIGNED_ROLES))
+            {
+                command = ASSIGNED_ROLES;
+                LOG.info(command);
+                User inUser = options.getUser();
+                Session session = accessMgr.createSession(inUser, true);
+                List<UserRole> uRoles = accessMgr.sessionRoles(session);
+                if (uRoles != null)
+                {
+                    for (UserRole ur : uRoles)
+                    {
+                        printTemporal("R", ur, "RBACROLE");
+                        printSeparator();
+                    }
+                }
+            }
+            else if (commands.contains(CHECK_ACCESS))
+            {
+                command = CHECK_ACCESS;
+                LOG.info(command);
+                Permission inPerm = options.getPermission();
+                User inUser = options.getUser();
+                Session session = accessMgr.createSession(inUser, true);
+                boolean result = accessMgr.checkAccess(session, inPerm);
+                printRow("CA", "PERM", "" + result);
+            }
+            else
+            {
+                LOG.warn("unknown system operation detected");
+                return;
+            }
+            LOG.info("command:" + command + " was successful");
+        }
+        catch ( SecurityException se)
+        {
+            String error = "processSystemCommand caught SecurityException=" + se + ", return code=" + se.getErrorId();
+            LOG.error(error);
+        }
+    }
+
+    /**
+     * @param commands
+     * @param options
+     */
+    private void processGroupCommand(Set<String> commands, Options options)
+    {
+        String command;
+        try
+        {
+            if (commands.contains(ADD_GROUP))
+            {
+                command = ADD_GROUP;
+                LOG.info(command);
+                Group group = options.getGroup();
+                groupMgr.add( group );
+            }
+            else if (commands.contains(UPDATE_GROUP))
+            {
+                command = UPDATE_GROUP;
+                LOG.info(command);
+                Group group = options.getGroup();
+                groupMgr.update( group );
+            }
+            else if (commands.contains(DELETE_GROUP))
+            {
+                command = DELETE_GROUP;
+                LOG.info(command);
+                Group group = options.getGroup();
+                groupMgr.delete( group );
+            }
+            else if (commands.contains(READ_GROUP))
+            {
+                command = READ_GROUP;
+                LOG.info(command);
+                Group group = options.getGroup();
+                Group outGroup = groupMgr.read( group );
+                printGroup(outGroup);
+            }
+            else if (commands.contains(FIND_GROUP))
+            {
+                command = FIND_GROUP;
+                LOG.info(command);
+                Group inGroup = options.getGroup();
+                List<Group> groups = groupMgr.find( inGroup );
+                if(VUtil.isNotNullOrEmpty( groups ))
+                {
+                    for(Group outGroup : groups)
+                    {
+                        printGroup(outGroup);
+                    }
+                }
+            }
+            else if (commands.contains(ASSIGN_GROUP))
+            {
+                command = ASSIGN_GROUP;
+                LOG.info(command);
+                Group group = options.getGroup();
+                if(VUtil.isNotNullOrEmpty( group.getMembers() ) )
+                {
+                    for( String member : group.getMembers())
+                    {
+                        groupMgr.assign( group, member );
+                    }
+                }
+            }
+            else if (commands.contains(DEASSIGN_GROUP))
+            {
+                command = DEASSIGN_GROUP;
+                LOG.info(command);
+                Group group = options.getGroup();
+                if(VUtil.isNotNullOrEmpty( group.getMembers() ) )
+                {
+                    for( String member : group.getMembers())
+                    {
+                        groupMgr.deassign( group, member );
+                    }
+                }
+            }
+            else if (commands.contains(ADD_GROUP_PROP))
+            {
+                command = ADD_GROUP_PROP;
+                LOG.info(command);
+                Group group = options.getGroup();
+                if(VUtil.isNotNullOrEmpty( group.getProperties() ))
+                {
+                    for (Enumeration e = group.getProperties().propertyNames(); e.hasMoreElements(); )
+                    {
+                        String key = (String) e.nextElement();
+                        String val = group.getProperty(key);
+                        groupMgr.add( group, key, val  );
+                    }
+                }
+            }
+            else if (commands.contains(DELETE_GROUP_PROP))
+            {
+                command = DELETE_GROUP_PROP;
+                LOG.info(command);
+                Group group = options.getGroup();
+                if(VUtil.isNotNullOrEmpty( group.getProperties() ))
+                {
+                    for (Enumeration e = group.getProperties().propertyNames(); e.hasMoreElements(); )
+                    {
+                        String key = (String) e.nextElement();
+                        String val = group.getProperty(key);
+                        groupMgr.delete( group, key, val );
+                    }
+                }
+            }
+            else
+            {
+                LOG.warn("unknown group operation detected");
+                return;
+            }
+            LOG.info("command:" + command + " was successful");
+        }
+        catch ( SecurityException se)
+        {
+            String error = "processGroupCommand caught SecurityException=" + se + ", return code=" + se.getErrorId();
+            LOG.error(error);
+        }
+    }
+
+    /**
+     * @param parser
+     * @return entity containing user options
+     */
+    private Options loadOptions(CmdLineParser parser)
+    {
+        return new Options(parser);
+    }
+
+    /**
+     *
+     * @param input
+     * @return array of strings
+     */
+    private String[] parseUserInput(String input)
+    {
+        List<String> options = new ArrayList<>();
+        // Break into separate tokens Strings that are delimited by "", '', or white space:
+        Pattern regex = Pattern.compile("[^\\s\"']+|\"([^\"]*)\"|'([^']*)'");
+        Matcher regexMatcher = regex.matcher(input);
+
+        boolean isPassword = false;
+        while (regexMatcher.find())
+        {
+            String arg;
+            if (regexMatcher.group(1) != null)
+            {
+                // Add double-quoted string without the quotes
+                arg = regexMatcher.group(1);
+            }
+            else if (regexMatcher.group(2) != null)
+            {
+                // Add single-quoted string without the quotes
+                arg = regexMatcher.group(2);
+            }
+            else
+            {
+                // Add unquoted word
+                arg = regexMatcher.group();
+            }
+            options.add(arg);
+            if (!isPassword)
+            {
+                LOG.info("arg:" + arg);
+            }
+            else
+            {
+                isPassword = false;
+            }
+            if ("-p".equalsIgnoreCase(arg))
+            {
+                isPassword = true;
+            }
+        }
+        return options.toArray(new String[options.size()]);
+    }
+
+    /**
+     * @param args
+     */
+    private void processUserInput(String[] args)
+    {
+        CmdLineParser parser = new CmdLineParser();
+        Options options = loadOptions(parser);
+        Set<String> commands = null;
+        try
+        {
+            parser.parse(args);
+            commands = loadCommandSet(parser.getRemainingArgs());
+        }
+        catch (CmdLineParser.OptionException e)
+        {
+            String error = "processUserInput caught OptionException=" + e.toString();
+            LOG.error(error);
+            printUsage();
+            //System.exit(2);
+        }
+        if (commands != null && commands.size() > 0)
+        {
+            processCommand(commands, options);
+        }
+    }
+
+    /**
+     * @param otherArgs
+     */
+    private Set<String> loadCommandSet(String[] otherArgs)
+    {
+        Set<String> commands = null;
+        if (VUtil.isNotNullOrEmpty(otherArgs))
+        {
+            commands = new HashSet<>();
+            Collections.addAll(commands, otherArgs);
+        }
+        return commands;
+    }
+
+    /**
+     * @param role
+     */
+    private void printRole(Role role)
+    {
+        String type = "R";
+        if (role != null)
+        {
+            printRow(type, "NAME", role.getName());
+            printRow(type, "IID ", role.getId());
+            if (VUtil.isNotNullOrEmpty(role.getParents()))
+            {
+                for (String parentRole : role.getParents())
+                {
+                    printRow(type, "PRLE", parentRole);
+                }
+            }
+            if (VUtil.isNotNullOrEmpty(role.getChildren()))
+            {
+                for (String childRole : role.getChildren())
+                {
+                    printRow(type, "CRLE", childRole);
+                }
+            }
+            printTemporal(type, role, "ROLE");
+        }
+    }
+
+    private void printPermission(Permission perm)
+    {
+        String type = "P";
+        if (perm != null)
+        {
+            printRow(type, "POBJ", perm.getObjName());
+            printRow(type, "OPER", perm.getOpName());
+            printRow(type, "IID", perm.getInternalId());
+            printRow(type, "TYPE", perm.getType());
+        }
+        if (VUtil.isNotNullOrEmpty(perm != null ? perm.getRoles() : null))
+        {
+            for (String roleName : perm.getRoles())
+            {
+                printRow("R", "ROLE", roleName);
+            }
+        }
+        if (VUtil.isNotNullOrEmpty(perm.getUsers()))
+        {
+            for (String userId : perm.getUsers())
+            {
+                printRow("U", "USER", userId);
+            }
+        }
+        if (VUtil.isNotNullOrEmpty(perm.getProperties()))
+        {
+            printSeparator();
+            int ctr = 0;
+            for (Enumeration e = perm.getProperties().propertyNames(); e.hasMoreElements(); )
+            {
+                String key = (String) e.nextElement();
+                String val = perm.getProperty(key);
+                LOG.info(type + "   KEY" + ++ctr + " [" + key + "]");
+                LOG.info(type + "   VAL" + ctr + " [" + val + "]");
+            }
+        }
+    }
+
+    private void printPermObj(PermObj permObj)
+    {
+        String type = "O";
+        if (permObj != null)
+        {
+            printRow(type, "NAME", permObj.getObjName());
+            printRow(type, "IID ", permObj.getInternalId());
+            printRow(type, "TYPE", permObj.getType());
+            printRow(type, "OU  ", permObj.getOu());
+        }
+        if (VUtil.isNotNullOrEmpty(permObj != null ? permObj.getProperties() : null))
+        {
+            printSeparator();
+            int ctr = 0;
+            for (Enumeration e = permObj.getProperties().propertyNames(); e.hasMoreElements(); )
+            {
+                String key = (String) e.nextElement();
+                String val = permObj.getProperty(key);
+                LOG.info(type + "   KEY" + ++ctr + " [" + key + "]");
+                LOG.info(type + "   VAL" + ctr + " [" + val + "]");
+            }
+        }
+    }
+
+    private void printSession(Session session)
+    {
+        String type = "S";
+        printRow(type, "UID ", session.getUserId());
+        printRow(type, "IID ", session.getInternalUserId());
+        printRow(type, "ERR ", "" + session.getErrorId());
+        printRow(type, "WARN", "" + session.getWarnings());
+        printRow(type, "MSG ", session.getMsg());
+        printRow(type, "EXP ", "" + session.getExpirationSeconds());
+        printRow(type, "GRAC", "" + session.getGraceLogins());
+        printRow(type, "AUTH", "" + session.isAuthenticated());
+        printRow(type, "LAST", "" + session.getLastAccess());
+        printRow(type, "SID ", session.getSessionId());
+        printSeparator();
+        User user = session.getUser();
+        if (user != null)
+        {
+            printUser(user);
+        }
+    }
+
+    /**
+     * @param user
+     */
+    private void printUser(User user)
+    {
+        String type = "U";
+        if (user != null)
+        {
+            printRow(type, "UID ", user.getUserId());
+            printRow(type, "IID ", user.getInternalId());
+            printRow(type, "CN  ", user.getCn());
+            printRow(type, "DESC", user.getDescription());
+            printRow(type, "OU  ", user.getOu());
+            printRow(type, "SN  ", user.getSn());
+            printRow(type, "BDTE", user.getBeginDate());
+            printRow(type, "EDTE", user.getEndDate());
+            printRow(type, "BLDT", user.getBeginLockDate());
+            printRow(type, "ELDT", user.getEndLockDate());
+            printRow(type, "DMSK", user.getDayMask());
+            printRow(type, "TO  ", "" + user.getTimeout());
+            printRow(type, "REST", "" + user.isReset());
+            printTemporal(type, user, "USER");
+            printAddress(type, user.getAddress(), "ADDR");
+            printPhone(type, user.getPhones(), "PHNE");
+            printPhone(type, user.getPhones(), "MOBL");
+
+            if (VUtil.isNotNullOrEmpty(user.getRoles()))
+            {
+                for (UserRole ur : user.getRoles())
+                {
+                    printSeparator();
+                    printTemporal("R", ur, "RBACROLE");
+                    if (VUtil.isNotNullOrEmpty(ur.getParents()))
+                    {
+                        for (String parentRole : ur.getParents())
+                        {
+                            printRow("R", "PRLE", parentRole);
+                        }
+                    }
+                }
+            }
+            if (VUtil.isNotNullOrEmpty(user.getAdminRoles()))
+            {
+                for (UserAdminRole ur : user.getAdminRoles())
+                {
+                    printSeparator();
+                    printTemporal("A", ur, "ADMINROLE");
+                    printAdminRole("A", ur);
+                }
+            }
+            if (VUtil.isNotNullOrEmpty(user.getProperties()))
+            {
+                printSeparator();
+                int ctr = 0;
+                for (Enumeration e = user.getProperties().propertyNames(); e.hasMoreElements(); )
+                {
+                    String key = (String) e.nextElement();
+                    String val = user.getProperty(key);
+                    LOG.info(type + "   KEY" + ++ctr + " [" + key + "]");
+                    LOG.info(type + "   VAL" + ctr + " [" + val + "]");
+                }
+            }
+        }
+    }
+
+    private void printGroup(Group group)
+    {
+        String type = "G";
+        if (group != null)
+        {
+            printSeparator();
+            printRow(type, "GROUP DATA" , group.getName());
+            printRow(type, "NAME ", group.getName());
+            printRow(type, "DESC", group.getDescription());
+            printRow(type, "PROT", group.getProtocol());
+            if (VUtil.isNotNullOrEmpty(group.getMembers()))
+            {
+                int memctr = 0;
+                for (String member : group.getMembers())
+                {
+                    printRow(type, "MEMBER[" + ++memctr + "]", member);
+                }
+            }
+            if (VUtil.isNotNullOrEmpty(group.getProperties()))
+            {
+                int propctr = 0;
+                for (Enumeration e = group.getProperties().propertyNames(); e.hasMoreElements(); )
+                {
+                    String key = (String) e.nextElement();
+                    String val = group.getProperty(key);
+                    printRow(type, "PROP[" + ++ propctr + "]", key + "=" + val);
+                }
+            }
+        }
+    }
+
+    /**
+     * @param constraint
+     * @param label
+     */
+    private void printTemporal(String type, Constraint constraint, String label)
+    {
+        if (constraint != null)
+        {
+            printRow(type, "TYPE", label);
+            printRow(type, "NAME", constraint.getName());
+            printRow(type, "BTME", constraint.getBeginTime());
+            printRow(type, "ETME", constraint.getEndTime());
+            printRow(type, "BDTE", constraint.getBeginDate());
+            printRow(type, "EDTE", constraint.getEndDate());
+            printRow(type, "BLDT", constraint.getBeginLockDate());
+            printRow(type, "ELDT", constraint.getEndLockDate());
+            printRow(type, "DMSK", constraint.getDayMask());
+            printRow(type, "TO  ", "" + constraint.getTimeout());
+        }
+    }
+
+    private void printAddress(String type, Address address, String label)
+    {
+        if (address != null)
+        {
+            printRow(type, "TYPE", label);
+            System.out.println(label);
+            if (VUtil.isNotNullOrEmpty(address.getAddresses()))
+            {
+                for (String addr : address.getAddresses())
+                {
+                    printRow(type, "LINE", addr);
+                }
+            }
+            printRow(type, "CITY", address.getCity());
+            printRow(type, "PROV", address.getState());
+            printRow(type, "ZIPC", address.getPostalCode());
+            printRow(type, "PBOX", address.getPostOfficeBox());
+        }
+    }
+
+    private void printPhone(String type, List<String> phones, String label)
+    {
+        if (phones != null)
+        {
+            printRow(type, "TYPE", label);
+            for (String phone : phones)
+            {
+                printRow(type, "TELE", phone);
+            }
+        }
+    }
+
+    /**
+     * @param ur
+     */
+    private void printAdminRole(String type, UserAdminRole ur)
+    {
+        if (ur != null)
+        {
+            printRow(type, "BEGR", ur.getBeginRange());
+            printRow(type, "ENDR", ur.getEndRange());
+            if (VUtil.isNotNullOrEmpty(ur.getOsP()))
+            {
+                printRow(type, "POUS", "" + ur.getOsP());
+            }
+            if (VUtil.isNotNullOrEmpty(ur.getOsU()))
+            {
+                printRow(type, "UOUS", "" + ur.getOsU());
+            }
+        }
+    }
+
+    /**
+     * @param type
+     * @param name
+     * @param value
+     */
+    private void printRow(String type, String name, String value)
+    {
+        LOG.info(type + "   " + name + " [" + value + "]");
+    }
+
+    /**
+     *
+     */
+    private void printSeparator()
+    {
+        LOG.info("------------------------------------------");
+    }
+
+    /**
+     */
+    private boolean constructManagers()
+    {
+        String contextId = GlobalIds.HOME;
+        boolean success = false;
+        // This property can be overriden with system property:
+        String tenant = System.getProperty(GlobalIds.TENANT);
+        if(VUtil.isNotNullOrEmpty(tenant) && !tenant.equals("${tenant}"))
+        {
+            contextId = tenant;
+        }
+        try
+        {
+            adminMgr = AdminMgrFactory.createInstance(contextId);
+            reviewMgr = ReviewMgrFactory.createInstance(contextId);
+            accessMgr = AccessMgrFactory.createInstance(contextId);
+            accessMgr = AccessMgrFactory.createInstance(contextId);
+            groupMgr = GroupMgrFactory.createInstance( contextId );
+            //delReviewMgr = DelReviewMgrFactory.createInstance(contextId);
+            //delAccessMgr = DelAccessMgrFactory.createInstance(contextId);
+            //pwPolicyMgr = PwPolicyMgrFactory.createInstance(contextId);
+            success = true;
+        }
+        catch ( SecurityException se)
+        {
+            String error = "constructManagers caught SecurityException=" + se;
+            LOG.error(error);
+        }
+        return success;
+    }
+}
\ No newline at end of file


[09/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/package.html b/src/main/java/org/apache/directory/fortress/core/rbac/package.html
new file mode 100755
index 0000000..70488a4
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/package.html
@@ -0,0 +1,52 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.core.rbac</title>
+   </head>
+   <body>
+      <p>
+      <ol>
+      <li>This package provides data entities and apis that adhere to standards like <a href="http://csrc.nist.gov/groups/SNS/rbac/documents/draft-rbac-implementation-std-v01.pdf">RBAC</a></li>
+      <li>This package provides data entities and APIs that adhere to <a href="http://profsandhu.com/journals/tissec/p113-oh.pdf">ARBAC02</a> model to provide delegated administration capabilities.</li>
+      <li>This package provides data entities and APIs to interrogate <a href="http://openldap.org/">OpenLDAP</a>'s slapd access log to obtain fortress audit trail and historical events.</li>
+      <li>This package uses <a href="http://www.jgrapht.org/">JGraphT</a> to provide hierarchical functionality that is reused within several other packages in the fortress system.</li>
+      </ol>
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress.core.rbac</b> package data entities may be manipulated by outside
+          programs but the apis contained within this package are for fortress use only.
+          The entities include {@link org.apache.directory.fortress.core.rbac.User User},{@link org.apache.directory.fortress.core.rbac.Role Role}, {@link org.apache.directory.fortress.core.rbac.PermObj PermObj}, {@link org.apache.directory.fortress.core.rbac.Permission Permission}, and more.
+          See the corresponding javadoc contained with this package for more info.
+      </p>
+      <h3>Fortress Manager APIs implemented in this package</h3>
+       <ol>
+       <li><a href="AccessMgrImpl.html">AccessMgrImpl</a> - This implements using LDAP the runtime access control operations on objects that are provisioned <a href="http://csrc.nist.gov/groups/SNS/rbac/documents/draft-rbac-implementation-std-v01.pdf">RBAC</a> entities that reside in LDAP directory.</li>
+       <li><a href="AdminMgrImpl.html">AdminMgrImpl</a> - This implements using LDAP the administrative functions to provision Fortress <a href="http://csrc.nist.gov/groups/SNS/rbac/documents/draft-rbac-implementation-std-v01.pdf">RBAC</a> entities into the LDAP directory.</li>
+       <li><a href="ReviewMgrImpl.html">ReviewMgrImpl</a> - This implements using LDAP the administrative review functions on already provisioned Fortress <a href="http://csrc.nist.gov/groups/SNS/rbac/documents/draft-rbac-implementation-std-v01.pdf">RBAC</a> entities that reside in LDAP directory.</li>
+       <li><a href="DelegatedAccessMgrImpl.html">DelegatedAccessMgrImpl</a> - This implements using LDAP the APIs for performing runtime delegated access control operations on objects that are provisioned Fortress <a href="http://profsandhu.com/journals/tissec/p113-oh.pdf">ARBAC02</a> entities that reside in LDAP directory.</li>
+       <li><a href="DelegatedAdminMgrImpl.html">DelegatedAdminMgrImpl</a> - This implements using LDAP the <a href="http://profsandhu.com/journals/tissec/p113-oh.pdf">ARBAC02</a> DelegatedAdminMgr interface for performing policy administration of Fortress ARBAC entities that reside in LDAP directory.</li>
+       <li><a href="DelegatedReviewMgrImpl.html">DelegatedReviewMgrImpl</a> - This implements using LDAP the <a href="http://profsandhu.com/journals/tissec/p113-oh.pdf">ARBAC02</a> DelegatedReviewMgr interface for performing policy interrogation of provisioned Fortress ARBAC02 entities that reside in LDAP directory.</li>
+       <li><a href="PwPolicyMgrImpl.html">PwPolicyMgrImpl</a> - Performs CRUD on OpenLDAP password policies stored in directory.</li>
+       <li><a href="AuditMgrImpl.html">AuditMgrImpl</a> - Interrogates Fortress audit data stored in OpenLDAP.</li>
+       </ol>
+   </body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rest/AccessMgrRestImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rest/AccessMgrRestImpl.java b/src/main/java/org/apache/directory/fortress/core/rest/AccessMgrRestImpl.java
new file mode 100644
index 0000000..744eb72
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rest/AccessMgrRestImpl.java
@@ -0,0 +1,525 @@
+/*
+ *   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.rest;
+
+import org.apache.directory.fortress.core.AccessMgr;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.AccessMgrImpl;
+import org.apache.directory.fortress.core.rbac.Manageable;
+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 org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Implementation class that performs runtime access control operations on data objects of type Fortress entities
+ * This object performs runtime access control operations on objects that are provisioned RBAC entities
+ * using HTTP access to En Masse REST server.  These APIs map directly to similar named APIs specified by ANSI and NIST
+ * RBAC system functions.
+ * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
+ * The RBAC Functional specification describes administrative operations for the creation
+ * and maintenance of RBAC element sets and relations; administrative review functions for
+ * performing administrative queries; and system functions for creating and managing
+ * RBAC attributes on user sessions and making access control decisions.
+ * <p/>
+ * <hr>
+ * <h4>RBAC0 - Core</h4>
+ * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
+ * <p/>
+ * <img src="../doc-files/RbacCore.png">
+ * <hr>
+ * <h4>RBAC1 - General Hierarchical Roles</h4>
+ * Simplifies role engineering tasks using inheritance of one or more parent roles.
+ * <p/>
+ * <img src="../doc-files/RbacHier.png">
+ * <hr>
+ * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+ * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
+ * <p/>
+ * <img src="../doc-files/RbacSSD.png">
+ * <hr>
+ * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+ * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+ * <p/>
+ * <img src="../doc-files/RbacDSD.png">
+ * <hr>
+ * <p/>
+ * This class is thread safe and may be used in servlet or other multi-threaded environment.
+ * <p/>
+ *
+ *
+ * @author Shawn McKinney
+ */
+public class AccessMgrRestImpl extends Manageable implements AccessMgr
+{
+    private static final String CLS_NM = AccessMgrImpl.class.getName();
+
+    /**
+     * Perform user authentication only.  It does not activate RBAC roles in session but will evaluate
+     * password policies.
+     *
+     * @param userId   Contains the userid of the user signing on.
+     * @param password Contains the user's 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.
+     */
+    @Override
+    public Session authenticate(String userId, char[] password)
+        throws SecurityException
+    {
+        VUtil.assertNotNullOrEmpty(userId, GlobalErrIds.USER_ID_NULL, CLS_NM + ".authenticate");
+        VUtil.assertNotNullOrEmpty(password, GlobalErrIds.USER_PW_NULL, ".authenticate");
+        Session retSession;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(new User(userId, password));
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.RBAC_AUTHN);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSession = response.getSession();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSession;
+    }
+
+    /**
+     * Perform user authentication {@link User#password} and role activations.<br />
+     * This method must be called once per user prior to calling other methods within this class.
+     * The successful result is {@link Session} that contains target user's RBAC {@link User#roles} and Admin role {@link User#adminRoles}.<br />
+     * In addition to checking user password validity it will apply configured password policy checks {@link User#pwPolicy}..<br />
+     * Method may also store parms passed in for audit trail {@link org.apache.directory.fortress.core.rbac.FortEntity}.
+     * <h4> This API will...</h4>
+     * <ul>
+     * <li> authenticate user password if trusted == false.
+     * <li> perform <a href="http://www.openldap.org/">OpenLDAP</a> <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10">password policy evaluation</a>, see {@link org.apache.directory.fortress.core.ldap.openldap.OLPWControlImpl}.
+     * <li> fail for any user who is locked by OpenLDAP's policies {@link User#isLocked()}, regardless of trusted flag being set as parm on API.
+     * <li> evaluate temporal {@link org.apache.directory.fortress.core.util.time.Constraint}(s) on {@link User}, {@link UserRole} and {@link org.apache.directory.fortress.core.rbac.UserAdminRole} entities.
+     * <li> process selective role activations into User RBAC Session {@link User#roles}.
+     * <li> check Dynamic Separation of Duties {@link org.apache.directory.fortress.core.rbac.DSDChecker#validate(Session, org.apache.directory.fortress.core.util.time.Constraint, org.apache.directory.fortress.core.util.time.Time)} on {@link User#roles}.
+     * <li> process selective administrative role activations {@link User#adminRoles}.
+     * <li> return a {@link Session} containing {@link Session#getUser()}, {@link Session#getRoles()} and (if admin user) {@link Session#getAdminRoles()} if everything checks out good.
+     * <li> throw a checked exception that will be {@link org.apache.directory.fortress.core.SecurityException} or its derivation.
+     * <li> throw a {@link SecurityException} for system failures.
+     * <li> throw a {@link org.apache.directory.fortress.core.PasswordException} for authentication and password policy violations.
+     * <li> throw a {@link org.apache.directory.fortress.core.ValidationException} for data validation errors.
+     * <li> throw a {@link org.apache.directory.fortress.core.FinderException} if User id not found.
+     * </ul>
+     * <h4>
+     * The function is valid if and only if:
+     * </h4>
+     * <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>
+     * <h4>
+     * The following attributes may be set when calling this method
+     * </h4>
+     * <ul>
+     * <li> {@link User#userId} - required
+     * <li> {@link User#password}
+     * <li> {@link User#roles} contains a list of RBAC role names authorized for user and targeted for activation within this session.  Default is all authorized RBAC roles will be activated into this Session.
+     * <li> {@link User#adminRoles} contains a list of Admin role names authorized for user and targeted for activation.  Default is all authorized ARBAC roles will be activated into this Session.
+     * <li> {@link User#props} collection of name value pairs collected on behalf of User during signon.  For example hostname:myservername or ip:192.168.1.99
+     * </ul>
+     * <h4>
+     * Notes:
+     * </h4>
+     * <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, see {@link User#setRole(String)}.
+     * </ul>
+     * </p>
+     *
+     * @param user Contains {@link User#userId}, {@link User#password} (optional if {@code isTrusted} is 'true'), optional {@link User#roles}, optional {@link User#adminRoles}
+     * @param isTrusted if true password is not required.
+     * @return Session object will contain authentication result code {@link Session#errorId}, RBAC role activations {@link Session#getRoles()}, Admin Role activations {@link Session#getAdminRoles()},OpenLDAP pw policy codes {@link Session#warningId}, {@link Session#expirationSeconds}, {@link Session#graceLogins} and more.
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    @Override
+    public Session createSession(User user, boolean isTrusted)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(user, GlobalErrIds.USER_NULL, CLS_NM + ".createSession");
+        Session retSession;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setEntity(user);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse;
+        if(isTrusted)
+        {
+            szResponse = RestUtils.post(szRequest, HttpIds.RBAC_CREATE_TRUSTED);
+        }
+        else
+        {
+            szResponse = RestUtils.post(szRequest, HttpIds.RBAC_CREATE);
+        }
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retSession = response.getSession();
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retSession;
+    }
+
+    /**
+     * Perform user rbac authorization.  This function returns a Boolean value meaning whether the subject of a given session is
+     * allowed or not to perform a given operation on a given object. The function is valid if and
+     * only if the session is a valid Fortress session, the object is a member of the OBJS data set,
+     * and the operation is a member of the OPS data set. The session's subject has the permission
+     * to perform the operation on that object if and only if that permission is assigned to (at least)
+     * one of the session's active roles. This implementation will verify the roles or userId correspond
+     * to the subject's active roles are registered in the object's access control list.
+     *
+     * @param perm  must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, of permission User is trying to access.
+     * @param session This object must be instantiated by calling {@link AccessMgrImpl#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return True if user has access, false otherwise.
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    @Override
+    public boolean checkAccess(Session session, Permission perm)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(perm, GlobalErrIds.PERM_NULL, CLS_NM + ".checkAccess");
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, CLS_NM + ".checkAccess");
+        boolean result;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        request.setEntity(perm);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.RBAC_AUTHZ);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            result = response.getAuthorized();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return result;
+    }
+
+    /**
+     * This function returns the permissions of the session, i.e., the permissions assigned
+     * to its authorized roles. The function is valid if and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return List<Permission> containing permissions (op, obj) active for user's session.
+     * @throws SecurityException in the event runtime error occurs with system.
+     */
+    @Override
+    public List<Permission> sessionPermissions(Session session)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, CLS_NM + ".sessionPermissions");
+        List<Permission> retPerms;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.RBAC_PERMS);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retPerms = response.getEntities();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retPerms;
+    }
+
+    /**
+     * This function returns the active roles associated with a session. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return List<UserRole> containing all roles active in user's session.  This will NOT contain inherited roles.
+     * @throws SecurityException
+     *          is thrown if session invalid or system. error.
+     */
+    @Override
+    public List<UserRole> sessionRoles(Session session)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, CLS_NM + ".sessionRoles");
+        List<UserRole> retRoles;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.RBAC_ROLES);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retRoles = response.getEntities();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRoles;
+    }
+
+    /**
+     * This function returns the authorized roles associated with a session. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return Set<String> containing all roles active in user's session.  This will contain inherited roles.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    @Override
+    public Set<String> authorizedRoles(Session session)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, CLS_NM + ".sessionRoles");
+        Set<String> retRoleNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.RBAC_AUTHZ_ROLES);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Set<String> tempNames = response.getValueSet();
+            // This is done to use a case insensitive TreeSet for returned names.
+            retRoleNames.addAll(tempNames);
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retRoleNames;
+    }
+
+    /**
+     * This function adds a role as an active role of a session whose owner is a given user.
+     * <p>
+     * The function is valid if and only if:
+     * <ul>
+     * <li> the user is a member of the USERS data set
+     * <li> the role is a member of the ROLES data set
+     * <li> the role inclusion does not violate Dynamic Separation of Duty Relationships
+     * <li> the session is a valid Fortress session
+     * <li> the user is authorized to that role
+     * <li> the session is owned by that user.
+     * </ul>
+     * </p>
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @param role object contains the role name, {@link UserRole#name}, to be activated into session.
+     * @throws SecurityException is thrown if user is not allowed to activate or runtime error occurs with system.
+     */
+    @Override
+    public void addActiveRole(Session session, UserRole role)
+        throws SecurityException
+    {
+        String fullMethodName = CLS_NM + ".addActiveRole";
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, fullMethodName);
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, fullMethodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        request.setEntity(role);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.RBAC_ADD);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This function deletes a role from the active role set of a session owned by a given user.
+     * The function is valid if and only if the user is a member of the USERS data set, the
+     * session object contains a valid Fortress session, the session is owned by the user,
+     * and the role is an active role of that session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @param role object contains the role name, {@link UserRole#name}, to be deactivated.
+     * @throws SecurityException is thrown if user is not allowed to deactivate or runtime error occurs with system.
+     */
+    @Override
+    public void dropActiveRole(Session session, UserRole role)
+        throws SecurityException
+    {
+        String fullMethodName = ".dropActiveRole";
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, CLS_NM + fullMethodName);
+        VUtil.assertNotNull(role, GlobalErrIds.ROLE_NULL, CLS_NM + fullMethodName);
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        request.setEntity(role);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.RBAC_DROP);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+    }
+
+    /**
+     * This function returns the userId value that is contained within the session object.
+     * The function is valid if and only if the session object contains a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return The userId value
+     * @throws SecurityException is thrown if user session not active or runtime error occurs with system.
+     */
+    @Override
+    public String getUserId(Session session)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, CLS_NM + ".getUserId");
+        String userId;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.RBAC_USERID);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            User outUser = (User) response.getEntity();
+            userId = outUser.getUserId();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return userId;
+    }
+
+    /**
+     * This function returns the user object that is contained within the session object.
+     * The function is valid if and only if the session object contains a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return The user value
+     *         Sample User data contained in Session object:
+     *         <ul> <code>Session</code>
+     *         <li> <code>session.getUserId() => demoUser4</code>
+     *         <li> <code>session.getInternalUserId() => be2dd2e:12a82ba707e:-7fee</code>
+     *         <li> <code>session.getMessage() => Fortress checkPwPolicies userId <demouser4> VALIDATION GOOD</code>
+     *         <li> <code>session.getErrorId() => 0</code>
+     *         <li> <code>session.getWarningId() => 11</code>
+     *         <li> <code>session.getExpirationSeconds() => 469831</code>
+     *         <li> <code>session.getGraceLogins() => 0</code>
+     *         <li> <code>session.getIsAuthenticated() => true</code>
+     *         <li> <code>session.getLastAccess() => 1283623680440</code>
+     *         <li> <code>session.getSessionId() => -7410986f:12addeea576:-7fff</code>
+     *         <li>  ------------------------------------------
+     *         <li> <code>User user = session.getUser();</code>
+     *         <ul> <li> <code>user.getUserId() => demoUser4</code>
+     *         <li> <code>user.getInternalId() => be2dd2e:12a82ba707e:-7fee</code>
+     *         <li> <code>user.getCn() => JoeUser4</code>
+     *         <li> <code>user.getDescription() => Demo Test User 4</code>
+     *         <li> <code>user.getOu() => test</code>
+     *         <li> <code>user.getSn() => User4</code>
+     *         <li> <code>user.getBeginDate() => 20090101</code>
+     *         <li> <code>user.getEndDate() => none</code>
+     *         <li> <code>user.getBeginLockDate() => none</code>
+     *         <li> <code>user.getEndLockDate() => none</code>
+     *         <li> <code>user.getDayMask() => 1234567</code>
+     *         <li> <code>user.getTimeout() => 60</code>
+     *         <li> <code>List<UserRole> roles = session.getRoles();</code>
+     *         <ul> <li><code>UserRole userRole = roles.get(i);</code>
+     *         <li> <code>userRole.getName() => role1</code>
+     *         <li> <code>userRole.getBeginTime() => 0000</code>
+     *         <li> <code>userRole.getEndTime() => 0000</code>
+     *         <li> <code>userRole.getBeginDate() => none</code>
+     *         <li> <code>userRole.getEndDate() => none</code>
+     *         <li> <code>userRole.getBeginLockDate() => null</code>
+     *         <li> <code>userRole.getEndLockDate() => null</code>
+     *         <li> <code>userRole.getDayMask() => null</code>
+     *         <li> <code>userRole.getTimeout() => 0</code>
+     *         </ul>
+     *         </ul>
+     *         </ul>
+     * @throws SecurityException is thrown if user session not active or runtime error occurs with system.
+     */
+    @Override
+    public User getUser(Session session)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(session, GlobalErrIds.USER_SESS_NULL, CLS_NM + ".getUser");
+        User retUser;
+        FortRequest request = new FortRequest();
+        request.setContextId(this.contextId);
+        request.setSession(session);
+        String szRequest = RestUtils.marshal(request);
+        String szResponse = RestUtils.post(szRequest, HttpIds.RBAC_USER);
+        FortResponse response = RestUtils.unmarshall(szResponse);
+        if (response.getErrorCode() == 0)
+        {
+            retUser = (User) response.getEntity();
+            Session outSession = response.getSession();
+            session.copy(outSession);
+        }
+        else
+        {
+            throw new SecurityException(response.getErrorCode(), response.getErrorMessage());
+        }
+        return retUser;
+    }
+}


[22/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/ReviewMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/ReviewMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/rbac/ReviewMgrImpl.java
new file mode 100755
index 0000000..43314aa
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/ReviewMgrImpl.java
@@ -0,0 +1,937 @@
+/*
+ *   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 org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.ReviewMgr;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class performs administrative review functions on already provisioned Fortress RBAC entities
+ * that reside in LDAP directory.  These APIs map directly to similar named APIs specified by ANSI and NIST RBAC models.
+ * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
+ * The RBAC Functional specification describes administrative operations for the creation
+ * and maintenance of RBAC element sets and relations; administrative review functions for
+ * performing administrative queries; and system functions for creating and managing
+ * RBAC attributes on user sessions and making access control decisions.
+ * <p/>
+ * <hr>
+ * <h4>RBAC0 - Core</h4>
+ * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
+ * <p/>
+ * <img src="../doc-files/RbacCore.png">
+ * <hr>
+ * <h4>RBAC1 - General Hierarchical Roles</h4>
+ * Simplifies role engineering tasks using inheritance of one or more parent roles.
+ * <p/>
+ * <img src="../doc-files/RbacHier.png">
+ * <hr>
+ * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+ * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
+ * <p/>
+ * <img src="../doc-files/RbacSSD.png">
+ * <hr>
+ * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+ * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+ * <p/>
+ * <img src="../doc-files/RbacDSD.png">
+ * <hr>
+ * <p/>
+ * This class is NOT thread safe if parent instance variables ({@link #contextId} or {@link #adminSess}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public class ReviewMgrImpl extends Manageable implements ReviewMgr
+{
+    private static final String CLS_NM = ReviewMgrImpl.class.getName();
+    private static final UserP userP = new UserP();
+    private static final RoleP roleP = new RoleP();
+    private static final PermP permP = new PermP();
+    private static final SdP ssdP = new SdP();
+
+    // package private constructor ensures outside classes cannot use:
+    ReviewMgrImpl()
+    {}
+
+    /**
+     * This method returns a matching permission entity to caller.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param permission must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, and optionally object id of targeted permission entity.
+     * @return Permission entity that is loaded with data.
+     * @throws SecurityException if permission not found or system error occurs.
+     */
+    @Override
+    public Permission readPermission(Permission permission)
+        throws SecurityException
+    {
+        String methodName = "readPermission";
+        assertContext(CLS_NM, methodName, permission, GlobalErrIds.PERM_OPERATION_NULL);
+        VUtil.assertNotNullOrEmpty(permission.getObjName(), GlobalErrIds.PERM_OBJECT_NM_NULL, CLS_NM + "." + methodName);
+        VUtil.assertNotNullOrEmpty(permission.getOpName(), GlobalErrIds.PERM_OPERATION_NM_NULL, CLS_NM + "." + methodName);
+        checkAccess(CLS_NM, methodName);
+        return permP.read(permission);
+    }
+
+    /**
+     * Method reads permission object from perm container in directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#objName} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param permObj entity contains the {@link org.apache.directory.fortress.core.rbac.PermObj#objName} of target record.
+     * @return PermObj loaded with perm object data.
+     * @throws SecurityException is thrown if object not found or system error.
+     */
+    @Override
+    public PermObj readPermObj(PermObj permObj)
+        throws SecurityException
+    {
+        String methodName = "readPermObj";
+        assertContext(CLS_NM, methodName, permObj, GlobalErrIds.PERM_OBJECT_NULL);
+        VUtil.assertNotNull(permObj.getObjName(), GlobalErrIds.PERM_OBJECT_NM_NULL, CLS_NM + "." + methodName);
+        checkAccess(CLS_NM, methodName);
+        return permP.read(permObj);
+    }
+
+    /**
+     * Method returns a list of type Permission that match the perm object search string.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains one or more characters of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains one or more characters of existing permission operation</li>
+     * </ul>
+     *
+     * @param permission contains object and operation name search strings.  Each contains 1 or more leading chars that correspond to object or op name.
+     * @return List of type Permission.  Fortress permissions are object->operation mappings.  The permissions may contain
+     *         assigned user, role or group entities as well.
+     * @throws SecurityException thrown in the event of system error.
+     */
+    @Override
+    public List<Permission> findPermissions(Permission permission)
+        throws SecurityException
+    {
+        String methodName = "findPermissions";
+        assertContext(CLS_NM, methodName, permission, GlobalErrIds.PERM_OPERATION_NULL);
+        checkAccess(CLS_NM, methodName);
+        return permP.search(permission);
+    }
+
+    /**
+     * Method returns a list of type PermObj that match the perm object search string.
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains one or more characters of existing object being targeted</li>
+     * </ul>
+     *
+     * @param permObj contains object name search string.  The search val contains 1 or more leading chars that correspond to object name.
+     * @return List of type PermObj.  Fortress permissions are object->operation mappings.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of system error.
+     */
+    @Override
+    public List<PermObj> findPermObjs(PermObj permObj)
+        throws SecurityException
+    {
+        String methodName = "findPermObjs";
+        assertContext(CLS_NM, methodName, permObj, GlobalErrIds.PERM_OBJECT_NULL);
+        checkAccess(CLS_NM, methodName);
+        return permP.search(permObj);
+    }
+
+    /**
+     * Method returns a list of type Permission that match the perm object search string.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.OrgUnit#name} - contains one or more characters of org unit associated with existing object being targeted</li>
+     * </ul>
+     *
+     * @param ou contains org unit name {@link org.apache.directory.fortress.core.rbac.OrgUnit#name}.  The search val contains the full name of matching ou in OS-P data set.
+     * @return List of type PermObj.  Fortress permissions are object->operation mappings.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of system error.
+     */
+    @Override
+    public List<PermObj> findPermObjs(OrgUnit ou)
+        throws SecurityException
+    {
+        String methodName = "findPermObjs";
+        assertContext(CLS_NM, methodName, ou, GlobalErrIds.ORG_NULL_PERM);
+        checkAccess(CLS_NM, methodName);
+        // pass a "false" which places no restrictions on how many records server returns.
+        return permP.search(ou, false);
+    }
+
+    /**
+     * Method reads Role entity from the role container in directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#name} - contains the name to use for the Role to read.</li>
+     * </ul>
+     *
+     * @param role contains role name, {@link org.apache.directory.fortress.core.rbac.Role#name}, to be read.
+     * @return Role entity that corresponds with role name.
+     * @throws SecurityException will be thrown if role not found or system error occurs.
+     */
+    @Override
+    public Role readRole(Role role)
+        throws SecurityException
+    {
+        String methodName = "readRole";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL);
+        VUtil.assertNotNullOrEmpty(role.getName(), GlobalErrIds.ROLE_NM_NULL, CLS_NM + "." + methodName);
+        checkAccess(CLS_NM, methodName);
+        return roleP.read(role);
+    }
+
+    /**
+     * Method will return a list of type Role matching all or part of Role name, {@link Role#name}.
+     *
+     * @param searchVal contains all or some of the chars corresponding to role entities stored in directory.
+     * @return List of type Role containing role entities that match the search criteria.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of system error.
+     */
+    @Override
+    public List<Role> findRoles(String searchVal)
+        throws SecurityException
+    {
+        String methodName = "findRoles";
+        VUtil.assertNotNull(searchVal, GlobalErrIds.ROLE_NM_NULL, CLS_NM + "." + methodName);
+        checkAccess(CLS_NM, methodName);
+        Role role = new Role(searchVal);
+        role.setContextId(this.contextId);
+        return roleP.search(role);
+    }
+
+    /**
+     * Method returns a list of roles of type String.  This method can be limited by integer value that indicates max
+     * number of records that may be contained in the result set.  This number can further limit global default but can
+     * not increase the max.  This method is called by the Websphere Realm impl.
+     *
+     * @param searchVal contains all or some leading chars that correspond to roles stored in the role container in the directory.
+     * @param limit     integer value specifies the max records that may be returned in the result set.
+     * @return List of type String containing names of the role entities that match the inbound search criteria.
+     * @throws SecurityException in the event of system error.
+     */
+    @Override
+    public List<String> findRoles(String searchVal, int limit)
+        throws SecurityException
+    {
+        String methodName = "findRoles";
+        VUtil.assertNotNull(searchVal, GlobalErrIds.ROLE_NM_NULL, CLS_NM + "." + methodName);
+        checkAccess(CLS_NM, methodName);
+        Role role = new Role(searchVal);
+        role.setContextId(this.contextId);
+        return roleP.search(role, limit);
+    }
+
+    /**
+     * Method returns matching User entity that is contained within the people container in the directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#userId} - contains the userId associated with the User object targeted for read.</li>
+     * </ul>
+     *
+     * @param user entity contains a value {@link org.apache.directory.fortress.core.rbac.User#userId} that matches record in the directory.  userId is globally unique in
+     *             people container.
+     * @return entity containing matching user data.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          if record not found or system error occurs.
+     */
+    @Override
+    public final User readUser(User user)
+        throws SecurityException
+    {
+        String methodName = "readUser";
+        assertContext(CLS_NM, methodName, user, GlobalErrIds.USER_NULL);
+        VUtil.assertNotNullOrEmpty(user.getUserId(), GlobalErrIds.USER_ID_NULL, CLS_NM + "." + methodName);
+        checkAccess(CLS_NM, methodName);
+        return userP.read(user, true);
+    }
+
+    /**
+     * Return a list of type User of all users in the people container that match all or part of the {@link User#userId} field passed in User entity.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains all or some leading chars that match userId(s) stored in the directory.</li>
+     * </ul>
+     *
+     * @param user contains all or some leading chars that match userIds stored in the directory.
+     * @return List of type User.
+     * @throws SecurityException In the event of system error.
+     */
+    @Override
+    public final List<User> findUsers(User user)
+        throws SecurityException
+    {
+        String methodName = "findUsers";
+        assertContext(CLS_NM, methodName, user, GlobalErrIds.USER_NULL);
+        checkAccess(CLS_NM, methodName);
+        return userP.search(user);
+    }
+
+    /**
+     * Return a list of type User of all users in the people container that match the name field passed in OrgUnit entity.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link OrgUnit#name} - contains one or more characters of org unit associated with existing object(s) being targeted</li>
+     * </ul>
+     *
+     * @param ou contains name of User OU, {@link OrgUnit#name} that match ou attribute associated with User entity in the directory.
+     * @return List of type User.
+     * @throws SecurityException In the event of system error.
+     */
+    @Override
+    public List<User> findUsers(OrgUnit ou)
+        throws SecurityException
+    {
+        String methodName = "findUsers";
+        assertContext(CLS_NM, methodName, ou, GlobalErrIds.ORG_NULL_USER);
+        checkAccess(CLS_NM, methodName);
+        // pass a "false" which places no restrictions on how many records server returns.
+        return userP.search(ou, false);
+    }
+
+    /**
+     * Return a list of type String of all users in the people container that match the userId field passed in User entity.
+     * This method is used by the Websphere realm component.  The max number of returned users may be set by the integer limit arg.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for read.</li>
+     * <li>limit - max number of objects to return.</li>
+     * </ul>
+     *
+     * @param user  contains all or some leading chars that correspond to users stored in the directory.
+     * @param limit integer value sets the max returned records.
+     * @return List of type String containing matching userIds.
+     * @throws SecurityException in the event of system error.
+     */
+    @Override
+    public final List<String> findUsers(User user, int limit)
+        throws SecurityException
+    {
+        String methodName = "findUsers";
+        assertContext(CLS_NM, methodName, user, GlobalErrIds.USER_NULL);
+        checkAccess(CLS_NM, methodName);
+        return userP.search(user, limit);
+    }
+
+    /**
+     * This function returns the set of users assigned to a given role. The function is valid if and
+     * only if the role is a member of the ROLES data set.
+     * The max number of users returned is constrained by limit argument.
+     * This method is used by the Websphere realm component.  This method does NOT use hierarchical rbac.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * <li>limit - max number of objects to return.</li>
+     * </ul>
+     *
+     * @param role  Contains {@link Role#name} of Role entity assigned to user.
+     * @param limit integer value sets the max returned records.
+     * @return List of type String containing userIds assigned to a particular role.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public List<String> assignedUsers(Role role, int limit)
+        throws SecurityException
+    {
+        String methodName = "assignedUsers";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL);
+        checkAccess(CLS_NM, methodName);
+        Role entity = roleP.read(role);
+        // this one retrieves from the role itself.
+        List<String> users = entity.getOccupants();
+        if (users != null && users.size() > limit)
+        {
+            users = users.subList(0, limit);
+        }
+        // No users found for this role.
+        // return empty list to caller:
+        else if (users == null)
+        {
+            users = new ArrayList<>();
+        }
+        return users;
+        // this one does a search across all users:
+        //return userP.getAuthorizedUsers(role, limit);
+    }
+
+    /**
+     * This method returns the data set of all users who are assigned the given role.  This searches the User data set for
+     * Role relationship.  This method does NOT search for hierarchical RBAC Roles relationships.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role contains the role name, {@link Role#name} used to search the User data set.
+     * @return List of type User containing the users assigned data.
+     * @throws SecurityException If system error occurs.
+     */
+    @Override
+    public List<User> assignedUsers(Role role)
+        throws SecurityException
+    {
+        String methodName = "assignedUsers";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL);
+        checkAccess(CLS_NM, methodName);
+        return userP.getAssignedUsers(role);
+    }
+
+    /**
+     * This function returns the set of roles assigned to a given user. The function is valid if and
+     * only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains {@link User#userId} matching User entity targeted in the directory.
+     * @return List of type UserRole containing the Roles assigned to User.
+     * @throws SecurityException If user not found or system error occurs.
+     */
+    @Override
+    public List<UserRole> assignedRoles(User user)
+        throws SecurityException
+    {
+        String methodName = "assignedRoles";
+        assertContext(CLS_NM, methodName, user, GlobalErrIds.USER_NULL);
+        checkAccess(CLS_NM, methodName);
+        User ue = userP.read(user, true);
+        return ue.getRoles();
+    }
+
+    /**
+     * This function returns the set of roles assigned to a given user. The function is valid if and
+     * only if the user is a member of the USERS data set.
+     *
+     * @param userId matches userId stored in the directory.
+     * @return List of type String containing the role names of all roles assigned to user.
+     * @throws SecurityException If user not found or system error occurs.
+     */
+    @Override
+    public List<String> assignedRoles(String userId)
+        throws SecurityException
+    {
+        String methodName = "assignedRoles";
+        VUtil.assertNotNullOrEmpty(userId, GlobalErrIds.USER_NULL, CLS_NM + "." + methodName);
+        checkAccess(CLS_NM, methodName);
+        User user = new User(userId);
+        user.setContextId(this.contextId);
+        return userP.getAssignedRoles(user);
+    }
+
+    /**
+     * This function returns the set of users authorized to a given role, i.e., the users that are assigned to a role that
+     * inherits the given role. The function is valid if and only if the given role is a member of the ROLES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role Contains role name, {@link Role#name} of Role entity assigned to User.
+     * @return List of type User containing all user's that having matching role assignment.
+     * @throws SecurityException In the event the role is not present in directory or system error occurs.
+     */
+    @Override
+    public List<User> authorizedUsers(Role role)
+        throws SecurityException
+    {
+        String methodName = "authorizedUsers";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL);
+        checkAccess(CLS_NM, methodName);
+        return userP.getAuthorizedUsers(role);
+    }
+
+    /**
+     * This function returns the set of roles authorized for a given user. The function is valid if
+     * and only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains the {@link User#userId} matching User entity stored in the directory.
+     * @return Set of type String containing the roles assigned and roles inherited.
+     * @throws SecurityException If user not found or system error occurs.
+     */
+    @Override
+    public Set<String> authorizedRoles(User user)
+        throws SecurityException
+    {
+        String methodName = "authorizedRoles";
+        assertContext(CLS_NM, methodName, user, GlobalErrIds.USER_NULL);
+        checkAccess(CLS_NM, methodName);
+        User ue = userP.read(user, true);
+        List<UserRole> roles = ue.getRoles();
+        Set<String> iRoles = null;
+        if (VUtil.isNotNullOrEmpty(roles))
+        {
+            iRoles = RoleUtil.getInheritedRoles( roles, this.contextId );
+        }
+        return iRoles;
+    }
+
+    /**
+     * This function returns the set of all permissions (op, obj), granted to or inherited by a
+     * given role. The function is valid if and only if the role is a member of the ROLES data
+     * set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role contains role name, {@link Role#name} of Role entity Permission is granted to.
+     * @return List of type Permission that contains all perms granted to a role.
+     * @throws SecurityException In the event system error occurs.
+     */
+    @Override
+    public List<Permission> rolePermissions(Role role)
+        throws SecurityException
+    {
+        String methodName = "rolePermissions";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL);
+        checkAccess(CLS_NM, methodName);
+        return permP.search(role);
+    }
+
+    /**
+     * This function returns the set of permissions a given user gets through his/her authorized
+     * roles. The function is valid if and only if the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - contains the userId associated with the User object targeted for search.</li>
+     * </ul>
+     *
+     * @param user contains the {@link User#userId} of User targeted for search.
+     * @return List of type Permission containing matching permission entities.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *
+     */
+    @Override
+    public List<Permission> userPermissions(User user)
+        throws SecurityException
+    {
+        String methodName = "userPermissions";
+        assertContext(CLS_NM, methodName, user, GlobalErrIds.USER_NULL);
+        checkAccess(CLS_NM, methodName);
+        user = readUser(user);
+        user.setContextId(this.contextId);
+        return permP.search(user);
+    }
+
+    /**
+     * Return a list of type String of all roles that have granted a particular permission.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return List of type string containing the role names that have the matching perm granted.
+     * @throws SecurityException in the event permission not found or system error occurs.
+     */
+    @Override
+    public List<String> permissionRoles(Permission perm)
+        throws SecurityException
+    {
+        String methodName = "permissionRoles";
+        assertContext(CLS_NM, methodName, perm, GlobalErrIds.PERM_OBJECT_NULL);
+        checkAccess(CLS_NM, methodName);
+        Permission pe = permP.read(perm);
+        List<String> retVals;
+        if(pe != null && VUtil.isNotNullOrEmpty(pe.getRoles()))
+        {
+            retVals = new ArrayList<>(pe.getRoles());
+        }
+        else
+        {
+            retVals =  new ArrayList<>();
+        }
+        return retVals;
+    }
+
+    /**
+     * Return all role names that have been authorized for a given permission.  This will process role hierarchies to determine set of all Roles who have access to a given permission.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return Set of type String containing all roles names that have been granted a particular permission.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of validation or system error.
+     */
+    @Override
+    public Set<String> authorizedPermissionRoles(Permission perm)
+        throws SecurityException
+    {
+        Set<String> authorizedRoles;
+        String methodName = "authorizedPermissionRoles";
+        assertContext(CLS_NM, methodName, perm, GlobalErrIds.PERM_OPERATION_NULL);
+        checkAccess(CLS_NM, methodName);
+        // Pull the permission from ldap:
+        Permission pe = permP.read(perm);
+
+        // Get all roles that this permission is authorized for:
+        authorizedRoles = authorizeRoles(pe.getRoles());
+        return authorizedRoles;
+    }
+
+    /**
+     * Return all userIds that have been granted (directly) a particular permission.  This will not consider assigned or authorized Roles.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return List of type String containing all userIds that have been granted a particular permission.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of validation or system error.
+     */
+    @Override
+    public List<String> permissionUsers(Permission perm)
+        throws SecurityException
+    {
+        String methodName = "permissionUsers";
+        assertContext(CLS_NM, methodName, perm, GlobalErrIds.PERM_OPERATION_NULL);
+        checkAccess(CLS_NM, methodName);
+        Permission pe = permP.read(perm);
+        List<String> retVals;
+        if(pe != null && VUtil.isNotNullOrEmpty(pe.getUsers()))
+        {
+            retVals = new ArrayList<>(pe.getUsers());
+        }
+        else
+        {
+            retVals =  new ArrayList<>();
+        }
+        return retVals;
+    }
+
+    /**
+     * Return all userIds that have been authorized for a given permission.  This will process role hierarchies to determine set of all Users who have access to a given permission.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, and optionally object id of targeted permission entity.
+     * @return Set of type String containing all userIds that have been granted a particular permission.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of validation or system error.
+     */
+    @Override
+    public Set<String> authorizedPermissionUsers(Permission perm)
+        throws SecurityException
+    {
+        Set<String> authorizedUsers = null;
+        String methodName = "authorizedPermissionUsers";
+        assertContext(CLS_NM, methodName, perm, GlobalErrIds.PERM_OPERATION_NULL);
+        checkAccess(CLS_NM, methodName);
+        // Pull the permission from ldap:
+        Permission pe = permP.read(perm);
+
+        // Get all roles that this permission is authorized for:
+        Set<String> authorizedRoles = authorizeRoles(pe.getRoles());
+        if (authorizedRoles != null)
+        {
+            // Pull the set of users assigned to descendant or assigned roles from ldap:
+            authorizedUsers = userP.getAssignedUsers(authorizedRoles, this.contextId);
+        }
+        // Now add any users who have been directly assigned to this permission entity:
+        Set<String> assignedUsers = pe.getUsers();
+        if (assignedUsers != null)
+        {
+            // It is possible this dataset has not yet been instantiated (if perm has no assigned roles):
+            if (authorizedUsers == null)
+            {
+                authorizedUsers = new HashSet<>();
+            }
+            authorizedUsers.addAll(assignedUsers);
+        }
+        // The returned list includes all assigned users plus any users assigned via authorized roles.
+        return authorizedUsers;
+    }
+
+    /**
+     * @param assignedRoles
+     * @return Set contains both assigned and descendant role names
+     * @throws SecurityException
+     */
+    private Set<String> authorizeRoles(Set<String> assignedRoles)
+    {
+        Set<String> authorizedRoles = null;
+        if (assignedRoles != null)
+        {
+            // Get the descendant roles of all assigned roles from jgrapht hierarchical roles data set:
+            authorizedRoles = RoleUtil.getDescendantRoles(assignedRoles, this.contextId);
+        }
+        return authorizedRoles;
+    }
+
+    /**
+     * This function returns the list of all SSD role sets that have a particular Role as member or Role's
+     * parent as a member.  If the Role parameter is left blank, function will return all SSD role sets.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role Will contain the role name, {@link Role#name}, for targeted SSD set or null to return all
+     * @return List containing all matching SSD's.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data or system error.
+     */
+    @Override
+    public List<SDSet> ssdRoleSets(Role role)
+        throws SecurityException
+    {
+        String methodName = "ssdRoleSets";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL);
+        checkAccess(CLS_NM, methodName);
+        return ssdP.search(role, SDSet.SDType.STATIC);
+    }
+
+    /**
+     * This function returns the list of SSDs that match a given ssd name value.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param ssd contains the name for the SSD set targeted, {@link SDSet#name}.
+     * @return List containing all SSDSets that match a given SSDSet name.
+     * @throws SecurityException in the event of data or system error.
+     */
+    public List<SDSet> ssdSets(SDSet ssd)
+        throws SecurityException
+    {
+        String methodName = "ssdSets";
+        ssd.setType(SDSet.SDType.STATIC);
+        assertContext(CLS_NM, methodName, ssd, GlobalErrIds.SSD_NULL);
+        checkAccess(CLS_NM, methodName);
+        return ssdP.search(ssd);
+    }
+
+    /**
+     * This function returns the SSD data set that matches a particular set name.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param set Will contain the name for existing SSD data set
+     * @return SDSet containing all attributes from matching SSD name.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data or system error.
+     */
+    @Override
+    public SDSet ssdRoleSet(SDSet set)
+        throws SecurityException
+    {
+        String methodName = "ssdRoleSet";
+        assertContext(CLS_NM, methodName, set, GlobalErrIds.SSD_NULL);
+        checkAccess(CLS_NM, methodName);
+        set.setType(SDSet.SDType.STATIC);
+        return ssdP.read(set);
+    }
+
+    /**
+     * This function returns the set of roles of a SSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param ssd contains the name for the SSD set targeted.
+     * @return Map containing all Roles that are members of SSD data set.
+     * @throws SecurityException in the event of data or system error.
+     */
+    @Override
+    public Set<String> ssdRoleSetRoles(SDSet ssd)
+        throws SecurityException
+    {
+        String methodName = "ssdRoleSetRoles";
+        assertContext(CLS_NM, methodName, ssd, GlobalErrIds.SSD_NULL);
+        checkAccess(CLS_NM, methodName);
+        ssd.setType(SDSet.SDType.STATIC);
+        SDSet se = ssdP.read(ssd);
+        return se.getMembers();
+    }
+
+    /**
+     * This function returns the cardinality associated with a SSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param ssd contains the name of the SSD set targeted, {@link SDSet#name}.
+     * @return int value containing cardinality of SSD set.
+     * @throws SecurityException in the event of data or system error.
+     */
+    @Override
+    public int ssdRoleSetCardinality(SDSet ssd)
+        throws SecurityException
+    {
+        String methodName = "ssdRoleSetCardinality";
+        assertContext(CLS_NM, methodName, ssd, GlobalErrIds.SSD_NULL);
+        checkAccess(CLS_NM, methodName);
+        SDSet se = ssdP.read(ssd);
+        return se.getCardinality();
+    }
+
+    /**
+     * This function returns the list of all dSD role sets that have a particular Role as member or Role's
+     * parent as a member.  If the Role parameter is left blank, function will return all dSD role sets.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role targeted for search.</li>
+     * </ul>
+     *
+     * @param role Will contain the role name, {@link Role#name}, for targeted dSD set or null to return all
+     * @return List containing all matching dSD's.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data or system error.
+     */
+    @Override
+    public List<SDSet> dsdRoleSets(Role role)
+        throws SecurityException
+    {
+        String methodName = "dsdRoleSets";
+        assertContext(CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL);
+        checkAccess(CLS_NM, methodName);
+        return ssdP.search(role, SDSet.SDType.DYNAMIC);
+    }
+
+    /**
+     * This function returns the DSD data set that matches a particular set name.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param set Will contain the name for existing DSD data set, {@link SDSet#name}.
+     * @return SDSet containing all attributes from matching DSD name.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data or system error.
+     */
+    @Override
+    public SDSet dsdRoleSet(SDSet set)
+        throws SecurityException
+    {
+        String methodName = "dsdRoleSet";
+        assertContext(CLS_NM, methodName, set, GlobalErrIds.DSD_NULL);
+        checkAccess(CLS_NM, methodName);
+        set.setType(SDSet.SDType.DYNAMIC);
+        return ssdP.read(set);
+    }
+
+    /**
+     * This function returns the list of DSDs that match a given dsd name value.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param ssd contains the name for the SSD set targeted, {@link SDSet#name}.
+     * @return List containing all DSDSets that match a given DSDSet name.
+     * @throws SecurityException in the event of data or system error.
+     */
+    public List<SDSet> dsdSets(SDSet ssd)
+        throws SecurityException
+    {
+        String methodName = "dsdSets";
+        ssd.setType(SDSet.SDType.DYNAMIC);
+        assertContext(CLS_NM, methodName, ssd, GlobalErrIds.DSD_NULL);
+        checkAccess(CLS_NM, methodName);
+        return ssdP.search(ssd);
+    }
+
+    /**
+     * This function returns the set of roles of a DSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param dsd contains the name for the DSD set targeted, {@link SDSet#name}.
+     * @return List containing all Roles that are members of DSD data set.
+     * @throws SecurityException in the event of data or system error.
+     */
+    @Override
+    public Set<String> dsdRoleSetRoles(SDSet dsd)
+        throws SecurityException
+    {
+        String methodName = "dsdRoleSetRoles";
+        assertContext(CLS_NM, methodName, dsd, GlobalErrIds.DSD_NULL);
+        checkAccess(CLS_NM, methodName);
+        dsd.setType(SDSet.SDType.DYNAMIC);
+        SDSet se = ssdP.read(dsd);
+        return se.getMembers();
+    }
+
+    /**
+     * This function returns the cardinality associated with a DSD role set. The function is valid if and only if the
+     * role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing object being targeted</li>
+     * </ul>
+     *
+     * @param dsd contains the name of the DSD set targeted, {@link SDSet#name}.
+     * @return int value containing cardinality of DSD set.
+     * @throws SecurityException in the event of data or system error.
+     */
+    @Override
+    public int dsdRoleSetCardinality(SDSet dsd)
+        throws SecurityException
+    {
+        String methodName = "dsdRoleSetCardinality";
+        assertContext(CLS_NM, methodName, dsd, GlobalErrIds.DSD_NULL);
+        checkAccess(CLS_NM, methodName);
+        SDSet se = ssdP.read(dsd);
+        return se.getCardinality();
+    }
+}
\ 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/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
new file mode 100755
index 0000000..0d9c20a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Role.java
@@ -0,0 +1,798 @@
+/*
+ *   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 java.util.UUID;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+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;
+
+
+/**
+ * All entities ({@link User}, {@link Role}, {@link Permission},
+ * {@link PwPolicy} {@link SDSet} etc...) are used to carry data between three Fortress
+ * layers.starting with the (1) Manager layer down thru middle (2) Process layer and it's processing rules into
+ * (3) DAO layer where persistence with the OpenLDAP server occurs.
+ * <h4>Fortress Processing Layers</h4>
+ * <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>
+ * </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 />
+ * For example, this entity requires {@link #setName} attribute set before passing into {@link AdminMgrImpl} APIs.
+ * Create methods sometimes require more attributes (than Read) due to constraints enforced between entities although only {@link Role#setName} is required for {@link Role}.
+ * <p/>
+ * <h4>Role entity attribute usages include</h4>
+ * <ul>
+ * <li>{@link #setName} attribute must be set before calling {@link AdminMgrImpl#addRole(Role)}, {@link AdminMgrImpl#updateRole(Role)} or  {@link AdminMgrImpl#deleteRole(Role)}
+ * <li>{@link org.apache.directory.fortress.core.util.time.Constraint} may be set <b>before</b> calling method {@link AdminMgrImpl#addRole(Role)}.
+ * <li>{@link org.apache.directory.fortress.core.util.time.Constraint} will be <b>returned</b> to caller on methods like {@link ReviewMgrImpl#readRole(Role)} or {@link ReviewMgrImpl#findRoles(String)} iff persisted to entity prior to call.
+ * </ul>
+ * <p/>
+ * This entity is used to store the RBAC Role assignments that comprise the many-to-many relationships between {@link User}s and {@link Permission}s.
+ * <br />The unique key to locate a Role entity (which is subsequently assigned both to Users and Permissions) is 'Role.name'.<br />
+ * <p/>
+ * There is a many-to-many relationship between User's, RBAC Roles and Permissions.
+ * <h3>{@link User}*<->*{@link Role}*<->*{@link Permission}</h3>
+ * <p/>
+ * <img src="../doc-files/RbacCore.png">
+ * <p/>
+ * Example to create new RBAC Role:
+ * <pre>
+ * try
+ * {
+ *  // Instantiate the AdminMgr first
+ *  AdminMgr adminMgr = AdminMgrFactory.createInstance();
+ *
+ *  Role myRole = new Role("MyRoleName");
+ *  myRole.setDescription("This is a test role");
+ *  adminMgr.addRole(myRole);
+ * }
+ * catch (SecurityException ex)
+ * {
+ *  // log or throw
+ * }</pre>
+ * The above code will persist to LDAP a Role object that can be used as a target for User-Role assignments and Role-Permission grants.
+ * <p/>
+ * <h4>Role Schema</h4>
+ * The Fortress Role entity is a composite of the following other Fortress structural and aux object classes:
+ * <p/>
+ * 1. organizationalRole Structural Object Class is used to store basic attributes like cn and description.
+ * <pre>
+ * ------------------------------------------
+ * objectclass ( 2.5.6.8 NAME 'organizationalRole'
+ *  DESC 'RFC2256: an organizational role'
+ *  SUP top STRUCTURAL
+ *  MUST cn
+ *  MAY (
+ *      x121Address $ registeredAddress $ destinationIndicator $
+ *      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
+ *      telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
+ *      seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $
+ *      postOfficeBox $ postalCode $ postalAddress $
+ *      physicalDeliveryOfficeName $ ou $ st $ l $ description
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 2. ftRls Structural objectclass is used to store the Role information like name and temporal constraint attributes.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Roles Structural Object Class
+ * objectclass	( 1.3.6.1.4.1.38088.2.1
+ *  NAME 'ftRls'
+ *  DESC 'Fortress Role Structural Object Class'
+ *  SUP organizationalrole
+ *  STRUCTURAL
+ *  MUST (
+ *      ftId $
+ *      ftRoleName
+ *  )
+ *  MAY (
+ *      description $
+ *      ftCstr $
+ *      ftParents
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 3. ftProperties AUXILIARY Object Class is used to store client specific name/value pairs on target entity.<br />
+ * <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 />
+ * <pre>
+ * ------------------------------------------
+ * AC2: Fortress Properties Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.2
+ *  NAME 'ftProperties'
+ *  DESC 'Fortress Properties AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftProps
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 4. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Audit Modification Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.4
+ *  NAME 'ftMods'
+ *  DESC 'Fortress Modifiers AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftModifier $
+ *      ftModCode $
+ *      ftModId
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortRole")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "role", propOrder =
+    {
+        "name",
+        "id",
+        "description",
+        "parents",
+        "children",
+        "beginDate",
+        "beginLockDate",
+        "beginTime",
+        "dayMask",
+        "endDate",
+        "endLockDate",
+        "endTime",
+        "timeout",
+        "rawData"
+})
+@XmlSeeAlso(
+    {
+        AdminRole.class
+})
+public class Role extends FortEntity
+implements Constraint, Graphable, java.io.Serializable
+{
+private String id; // this maps to ftId
+private String name; // this is ftRoleName
+private String description; // this is description
+@XmlTransient
+private String dn; // this attribute is automatically saved to each ldap record.
+@XmlTransient
+private List<String> occupants;
+private Set<String> parents;
+private Set<String> children;
+private String beginTime; // this attribute is ftCstr
+private String endTime; // this attribute is ftCstr
+private String beginDate; // this attribute is ftCstr
+private String endDate; // this attribute is ftCstr
+private String beginLockDate;// this attribute is ftCstr
+private String endLockDate; // this attribute is ftCstr
+private String dayMask; // this attribute is ftCstr
+private int timeout; // this attribute is ftCstr
+
+
+/**
+ * Default constructor is used by internal Fortress classes.
+ */
+public Role()
+{
+}
+
+
+/**
+ * Construct a Role entity with a given name.
+ *
+ * @param name maps to 'cn' attribute on 'organizationalrole' object class.
+ */
+public Role( String name )
+{
+    this.name = name;
+}
+
+
+/**
+ * Construct an RBAC Role with a given temporal constraint.
+ *
+ * @param con maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+public Role( Constraint con )
+{
+    CUtil.copy( con, this );
+}
+
+
+/**
+ * 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 'ftCstr' attribute in 'ftRls' object class.
+ */
+public String getRawData()
+{
+    return rawData;
+}
+
+
+/**
+ * Required on DAO classes convert Temporal from raw ldap data to entity attributes.  For internal use only.
+ *
+ * @param rawData maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+public void setRawData( String rawData )
+{
+    this.rawData = rawData;
+}
+
+private String rawData;
+
+
+/**
+ * Gets the name required attribute of the Role object
+ *
+ * @return attribute maps to 'cn' attribute on 'organizationalrole' object class.
+ */
+public String getName()
+{
+    return name;
+}
+
+
+/**
+ * Sets the required name attribute on the Role object
+ *
+ */
+public void setName( String name )
+{
+    this.name = name;
+}
+
+
+/**
+ * Set the occupant attribute with the contents of the User dn.
+ * @param occupant maps to 'roleOccupant' attribute on 'organizationalrole' object class.
+ */
+public void setOccupant( String occupant )
+{
+    if ( this.occupants == null )
+    {
+        this.occupants = new ArrayList<>();
+    }
+    this.occupants.add( occupant );
+}
+
+
+/**
+ * Return list of occupants for a particular Role entity.
+ * @return List of type String containing User dn that maps to 'roleOccupant' attribute on 'organizationalrole' object class.
+ */
+public List<String> getOccupants()
+{
+    return occupants;
+}
+
+
+/**
+ * Set a list of occupants for a particular Role entity.
+ * @param occupants contains a List of type String which maps to 'roleOccupant' attribute on 'organizationalrole' object class.
+ */
+public void setOccupants( List<String> occupants )
+{
+    this.occupants = occupants;
+}
+
+
+/**
+ * Returns optional description that is associated with Role.  This attribute is validated but not constrained by Fortress.
+ *
+ * @return value that is mapped to 'description' in 'organizationalrole' object class.
+ */
+public String getDescription()
+{
+    return this.description;
+}
+
+
+/**
+ * Sets the optional description that is associated with Role.  This attribute is validated but not constrained by Fortress.
+ *
+ * @param description that is mapped to same name in 'organizationalrole' object class.
+ */
+public void setDescription( String description )
+{
+    this.description = description;
+}
+
+
+/**
+ * Return the internal id that is associated with Role.  This attribute is generated automatically
+ * by Fortress when new Role is added to directory and is not known or changeable by external client.
+ *
+ * @return attribute maps to 'ftId' in 'ftRls' object class.
+ */
+public String getId()
+{
+    return id;
+}
+
+
+/**
+ * Generate an internal Id that is associated with Role.  This method is used by DAO class and
+ * is not available to outside classes.   The generated attribute maps to 'ftId' in 'ftRls' object class.
+ */
+public void setId()
+{
+    // generate a unique id that will be used as the rDn for this entry:
+    UUID uuid = UUID.randomUUID();
+    this.id = uuid.toString();
+}
+
+
+/**
+ * Set the internal Id that is associated with Role.  This method is used by DAO class and
+ * is generated automatically by Fortress.  Attribute stored in LDAP cannot be changed by external caller.
+ * This method can be used by client for search purposes only.
+ *
+ * @param id maps to 'ftId' in 'ftRls' object class.
+ */
+public void setId( String id )
+{
+    this.id = id;
+}
+
+
+/**
+ * temporal boolean flag is used by internal Fortress components.
+ *
+ * @return boolean indicating if temporal constraints are placed on Role.
+ */
+@Override
+public boolean isTemporalSet()
+{
+    return ( beginTime != null || endTime != null || beginDate != null || endDate != null || beginLockDate != null
+        || endLockDate != null || dayMask != null );
+}
+
+
+/**
+ * Contains the begin time of day Role is allowed to be activated in session.  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 attribute maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public String getBeginTime()
+{
+    return this.beginTime;
+}
+
+
+/**
+ * Set the begin time of day Role is allowed to be activated in session.  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 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public void setBeginTime( String beginTime )
+{
+    this.beginTime = beginTime;
+}
+
+
+/**
+ * Contains the end time of day Role is allowed to be activated in session.  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 attribute maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public String getEndTime()
+{
+    return this.endTime;
+}
+
+
+/**
+ * Set the end time of day Role is allowed to be activated in session.  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 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public void setEndTime( String endTime )
+{
+    this.endTime = endTime;
+}
+
+
+/**
+ * Contains the begin date when Role is allowed to be activated in session.  The format is - YYYYMMDD, i.e. 20100101 (January 1. 2010).
+ * This attribute is optional but if set will be validated for reasonableness.
+ *
+ * @return attribute maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public String getBeginDate()
+{
+    return this.beginDate;
+}
+
+
+/**
+ * Set the beginDate when Role is allowed to be activated in session.  The format is - YYYYMMDD, i.e. 20100101 (January 1. 2010).
+ * This attribute is optional but if set will be validated for reasonableness.
+ *
+ * @param beginDate maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public void setBeginDate( String beginDate )
+{
+    this.beginDate = beginDate;
+}
+
+
+/**
+ * Contains the end date when Role is allowed to be activated in session.  The format is - YYYYMMDD, i.e. 20101231 (December 31, 2010).
+ * This attribute is optional but if set will be validated for reasonableness.
+ *
+ * @return attribute maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public String getEndDate()
+{
+    return this.endDate;
+}
+
+
+/**
+ * Set the end date when Role is not allowed to be activated in session.  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 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public void setEndDate( String endDate )
+{
+    this.endDate = endDate;
+}
+
+
+/**
+ * Contains the begin lock date when Role is temporarily not allowed to be activated in session.  The format is - YYMMDD, i.e. 20100101 (January 1. 2010).
+ * This attribute is optional but if set will be validated for reasonableness.
+ *
+ * @return attribute maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public String getBeginLockDate()
+{
+    return this.beginLockDate;
+}
+
+
+/**
+ * Set the begin lock date when Role is temporarily not allowed to be activated in session.  The format is - YYYYMMDD, i.e. 20100101 (January 1. 2010).
+ * This attribute is optional but if set will be validated for reasonableness.
+ *
+ * @param beginLockDate maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public void setBeginLockDate( String beginLockDate )
+{
+    this.beginLockDate = beginLockDate;
+}
+
+
+/**
+ * Contains the end lock date when Role is allowed to be activated in session 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 attribute maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public String getEndLockDate()
+{
+    return this.endLockDate;
+}
+
+
+/**
+ * Set the end lock date when Role is allowed to be activated in session 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 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public void setEndLockDate( String endLockDate )
+{
+    this.endLockDate = endLockDate;
+}
+
+
+/**
+ * Get the daymask that indicates what days of week Role is allowed to be activated in session.  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 attribute maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public String getDayMask()
+{
+    return this.dayMask;
+}
+
+
+/**
+ * Set the daymask that specifies what days of week Role is allowed to be activated in session.  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 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public void setDayMask( String dayMask )
+{
+    this.dayMask = dayMask;
+}
+
+
+/**
+ * Return the integer timeout that contains total time (in seconds) that Role may remain inactive in User's session before it is deactivated.
+ * This attribute is optional but if set will be validated for reasonableness.
+ *
+ * @return int maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public Integer getTimeout()
+{
+    return this.timeout;
+}
+
+
+/**
+ * Set the integer timeout that contains max time (in seconds) that Role may remain inactive in User's session before it is deactivated.
+ * This attribute is optional but if set will be validated for reasonableness.
+ *
+ * @param timeout maps to 'ftCstr' attribute in 'ftRls' object class.
+ */
+@Override
+public void setTimeout( Integer timeout )
+{
+    this.timeout = timeout;
+}
+
+
+/**
+ * Get the names of roles that are parents (direct ascendants) of this role.
+ * @return Set of parent role names assigned to this role.
+ */
+@Override
+public Set<String> getParents()
+{
+    if ( this.parents == null )
+    {
+        this.parents = new HashSet<>();
+    }
+    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.
+ */
+@Override
+public void setParents( Set<String> parents )
+{
+    this.parents = parents;
+}
+
+
+/**
+ * Set the occupant attribute with the contents of the User dn.
+ * @param parent maps to 'ftParents' attribute on 'ftRls' object class.
+ */
+@Override
+public void setParent( String parent )
+{
+    if ( this.parents == null )
+    {
+        this.parents = new HashSet<>();
+    }
+    this.parents.add( parent );
+}
+
+
+/**
+ * Set the occupant attribute with the contents of the User dn.
+ * @param parent maps to 'ftParents' attribute on 'ftRls' object class.
+ */
+@Override
+public void delParent( String parent )
+{
+    if ( this.parents != null )
+    {
+        this.parents.remove( parent );
+    }
+}
+
+
+/**
+ * Return the Set of child role names (direct descendants) of this role.
+ * @return Set of child role names assigned to this role.
+ */
+public Set<String> getChildren()
+{
+    return children;
+}
+
+
+/**
+ * Set the Set of child role names (direct descendants) of this role
+ * @param children contains the Set of child role names assigned to this role.
+ */
+public void setChildren( Set<String> children )
+{
+    this.children = children;
+}
+
+
+/**
+ * Matches the name from two Role entities.
+ *
+ * @param thatObj contains a Role entity.
+ * @return boolean indicating both objects contain matching Role names.
+ */
+public boolean equals( Object thatObj )
+{
+    if ( this == thatObj )
+    {
+        return true;
+    }
+
+    if ( name == null )
+    {
+        return false;
+    }
+
+    if ( !( thatObj instanceof Role ) )
+    {
+        return false;
+    }
+
+    Role thatRole = ( Role ) thatObj;
+
+    if ( thatRole.getName() == null )
+    {
+        return false;
+    }
+
+    return thatRole.getName().equalsIgnoreCase( name );
+}
+
+
+/**
+ * @see Object#toString()
+ */
+public String toString()
+{
+    StringBuilder sb = new StringBuilder();
+
+    sb.append( "Role[" );
+
+    // The name
+    sb.append( name ).append( ", " );
+
+    if ( ( description != null ) && ( description.length() > 0 ) )
+    {
+        sb.append( description ).append( ", " );
+    }
+
+    // the date
+    sb.append( "date : <" ).append( beginDate ).append( ", " ).append( endDate ).append( ">, " );
+
+    // The time
+    sb.append( "time : <" ).append( beginTime ).append( ", " ).append( endTime ).append( ">, " );
+
+    // The lock date
+    sb.append( "lock date : <" ).append( beginLockDate ).append( ", " ).append( endLockDate ).append( ">, " );
+
+    // The timeout
+    sb.append( "timeout : " ).append( timeout ).append( ", " );
+
+    // The day mask
+    sb.append( "daymask : " ).append( dayMask );
+
+    // The parents if any
+    if ( ( parents != null ) && ( parents.size() > 0 ) )
+    {
+        sb.append( ", parents : {" );
+
+        boolean isFirst = true;
+
+        for ( String parent : parents )
+        {
+            if ( isFirst )
+            {
+                isFirst = false;
+            }
+            else
+            {
+                sb.append( '|' );
+            }
+
+            sb.append( parent );
+        }
+
+        sb.append( '}' );
+    }
+
+    // The children if any
+    if ( ( children != null ) && ( children.size() > 0 ) )
+    {
+        sb.append( ", children : {" );
+
+        boolean isFirst = true;
+
+        for ( String child : children )
+        {
+            if ( isFirst )
+            {
+                isFirst = false;
+            }
+            else
+            {
+                sb.append( '|' );
+            }
+
+            sb.append( child );
+        }
+
+        sb.append( '}' );
+    }
+
+    sb.append( ']' );
+
+    return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/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
new file mode 100755
index 0000000..56e4a13
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/RoleP.java
@@ -0,0 +1,307 @@
+/*
+ *   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 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.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;
+
+
+/**
+ * Process module for the Role 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.Role}, validate its contents and forward on to it's corresponding DAO class {@link RoleDAO}.
+ * <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 Kevin McKinney
+ */
+public final class RoleP
+{
+    private static RoleDAO rDao = DaoFactory.createRoleDAO();
+
+    /**
+     * Package private
+     */
+    RoleP()
+    {
+    }
+
+
+    /**
+     * Return a fully populated Role entity for a given RBAC role name.  If matching record not found a
+     * SecurityException will be thrown.
+     *
+     * @param role contains full role name for RBAC role in directory.
+     * @return Role entity containing all attributes associated with Role in directory.
+     * @throws SecurityException in the event Role not found or DAO search error.
+     */
+    final Role read( Role role ) throws SecurityException
+    {
+        return rDao.getRole( role );
+    }
+
+
+    /**
+     * Takes a search string that contains full or partial RBAC Role name in directory.
+     *
+     * @param role contains full or partial RBAC role name.
+     * @return List of type Role containing fully populated matching RBAC Role entities.  If no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<Role> search( Role role ) throws SecurityException
+    {
+        return rDao.findRoles( role );
+    }
+
+
+    /**
+     * Takes a search string that contains full or partial RBAC Role name in directory.
+     * This search is used by RealmMgr for Websphere.
+     *
+     * @param role contains full or partial RBAC role name.
+     * @param limit     specify the max number of records to return in result set.
+     * @return List of type String containing RBAC Role name 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( Role role, int limit ) throws SecurityException
+    {
+        return rDao.findRoles( role, limit );
+    }
+
+
+    /**
+     * Return all Roles that have a parent assignment.  This used for hierarchical processing.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return List of type Role containing {@link Role#name} and {@link Role#parents} populated.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<Graphable> getAllDescendants( String contextId ) throws SecurityException
+    {
+        return rDao.getAllDescendants( contextId );
+    }
+
+
+    /**
+     * Adds a new Role entity to directory.  The Role entity input object will be validated to ensure that:
+     * role name is present, and reasonability checks on all of the other populated values.
+     *
+     * @param entity Role entity contains data targeted for insertion.
+     * @return Role 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 Role add( Role entity ) throws SecurityException
+    {
+        validate( entity );
+        return rDao.create( entity );
+    }
+
+
+    /**
+     * Updates existing Role entity in directory.  For example the Role description and temporal constraints
+     * updated.
+     *
+     * @param entity Role entity contains data targeted for updating.
+     * @return Role entity contains fully populated updated entity.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final Role update( Role entity ) throws SecurityException
+    {
+        validate( entity );
+        return rDao.update( entity );
+    }
+
+
+    /**
+     * Removes parent role assignments from Role entity in directory.
+     * updated.
+     *
+     * @param entity Role entity contains data targeted for updating.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final void deleteParent( Role entity ) throws SecurityException
+    {
+        validate( entity );
+        rDao.deleteParent( entity );
+    }
+
+
+    /**
+     * Method will add the "roleOccupant" attribute on OpenLDAP entry which represents an RBAC Role assignment in Fortress.
+     *
+     * @param entity contains the role name targeted.
+     * @param userDn String contains the dn for the user entry that is being assigned the RBAC Role.
+     * @return Role containing copy of input data.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final Role assign( Role entity, String userDn ) throws SecurityException
+    {
+        return rDao.assign( entity, userDn );
+    }
+
+
+    /**
+     * Method will remove the "roleOccupant" attribute on OpenLDAP entry which represents an RBAC Role assignment in Fortress.
+     *
+     * @param entity contains the role name targeted.
+     * @param userDn String contains the dn for the user entry that is being assigned the RBAC Role.
+     * @return Role containing copy of input data.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final Role deassign( Role entity, String userDn ) throws SecurityException
+    {
+        entity = rDao.deassign( entity, userDn );
+        return entity;
+    }
+
+
+    /**
+     * Add the User dn occupant attribute to the OrganizationalRole entity in ldap.  This method is called by AdminMgrImpl
+     * when the User is being added.
+     *
+     * @param uRoles contains a collection of UserRole being targeted for assignment.
+     * @param userDn contains the userId targeted for addition.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final void addOccupant( List<UserRole> uRoles, String userDn, String contextId ) throws SecurityException
+    {
+        if ( VUtil.isNotNullOrEmpty( uRoles ) )
+        {
+            for ( UserRole uRole : uRoles )
+            {
+                Role role = new Role( uRole.getName() );
+                role.setContextId( contextId );
+                assign( role, userDn );
+            }
+        }
+    }
+
+
+    /**
+     * Remove the User dn occupant attribute from the OrganizationalRole entity in ldap.  This method is called by AdminMgrImpl
+     * when the User is being deleted.
+     *
+     * @param userDn contains the userId targeted for attribute removal.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final void removeOccupant( String userDn, String contextId ) throws SecurityException
+    {
+        List<String> list;
+        try
+        {
+            list = rDao.findAssignedRoles( userDn, contextId );
+            for ( String roleNm : list )
+            {
+                Role role = new Role( roleNm );
+                role.setContextId( contextId );
+                deassign( role, userDn );
+            }
+        }
+        catch ( FinderException fe )
+        {
+            String error = "removeOccupant userDn [" + userDn + "] caught FinderException=" + fe;
+            throw new SecurityException( GlobalErrIds.ROLE_REMOVE_OCCUPANT_FAILED, error, fe );
+        }
+    }
+
+
+    /**
+     * This method performs a "hard" delete.  It completely the RBAC Role node from the ldap directory.
+     * RBAC Role entity must exist in directory prior to making this call else exception will be thrown.
+     *
+     * @param entity Contains the name of the RBAC Role targeted for deletion.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    void delete( Role entity ) throws SecurityException
+    {
+        rDao.remove( entity );
+    }
+
+
+    /**
+     * Method will perform simple validations to ensure the integrity of the RBAC Role entity targeted for insertion
+     * or updating in directory.  For example the Role temporal constraints will be validated.  Data reasonability
+     * checks will be performed on all non-null attributes.
+     *
+     * @param entity contains data targeted for insertion or update.
+     * @throws org.apache.directory.fortress.core.ValidationException in the event of data validation error or Org validation.
+     */
+    private void validate( Role entity )
+        throws ValidationException
+    {
+        VUtil.safeText( entity.getName(), GlobalIds.ROLE_LEN );
+        if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+        {
+            VUtil.description( entity.getDescription() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getTimeout() ) )
+        {
+            VUtil.timeout( entity.getTimeout() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getBeginTime() ) )
+        {
+            VUtil.beginTime( entity.getBeginTime() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getEndTime() ) )
+        {
+            VUtil.endTime( entity.getEndTime() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getBeginDate() ) )
+        {
+            VUtil.beginDate( entity.getBeginDate() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getEndDate() ) )
+        {
+            VUtil.endDate( entity.getEndDate() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getDayMask() ) )
+        {
+            VUtil.dayMask( entity.getDayMask() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getBeginLockDate() ) )
+        {
+            VUtil.beginDate( entity.getBeginDate() );
+        }
+        if ( VUtil.isNotNullOrEmpty( entity.getEndLockDate() ) )
+        {
+            VUtil.endDate( entity.getEndLockDate() );
+        }
+    }
+}
\ 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/RolePerm.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/RolePerm.java b/src/main/java/org/apache/directory/fortress/core/rbac/RolePerm.java
new file mode 100755
index 0000000..ecb7de3
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/RolePerm.java
@@ -0,0 +1,63 @@
+/*
+ *   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.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * This entity is used by en masse to communicate {@link org.apache.directory.fortress.core.rbac.Role}, {@link Permission} and {@link org.apache.directory.fortress.core.rbac.Session} information to the server for access control decisions.
+ * <p/>
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortRolePerm")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "rolePerm", propOrder = {
+    "role",
+    "perm"
+})
+public class RolePerm extends FortEntity
+    implements java.io.Serializable
+{
+    private Role role;
+    private Permission perm;
+
+    public Role getRole()
+    {
+        return role;
+    }
+
+    public void setRole(Role role)
+    {
+        this.role = role;
+    }
+
+    public Permission getPerm()
+    {
+        return perm;
+    }
+
+    public void setPerm(Permission perm)
+    {
+        this.perm = perm;
+    }
+}
\ 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/RoleRelationship.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/RoleRelationship.java b/src/main/java/org/apache/directory/fortress/core/rbac/RoleRelationship.java
new file mode 100755
index 0000000..626beb2
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/RoleRelationship.java
@@ -0,0 +1,63 @@
+/*
+ *   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.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * This entity is used by en masse to communicate parent and child {@link org.apache.directory.fortress.core.rbac.Role} information to the server.
+ * <p/>
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortRoleRelationship")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "roleRelationship", propOrder = {
+    "child",
+    "parent"
+})
+public class RoleRelationship extends FortEntity
+    implements java.io.Serializable
+{
+    private Role parent;
+    private Role child;
+
+    public Role getParent()
+    {
+        return parent;
+    }
+
+    public void setParent(Role parent)
+    {
+        this.parent = parent;
+    }
+
+    public Role getChild()
+    {
+        return child;
+    }
+
+    public void setChild(Role child)
+    {
+        this.child = child;
+    }
+}


[49/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/AccelMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/AccelMgr.java b/src/main/java/org/apache/directory/fortress/core/AccelMgr.java
new file mode 100644
index 0000000..0b66270
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/AccelMgr.java
@@ -0,0 +1,215 @@
+/*
+ *   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;
+
+import java.util.List;
+
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rbac.UserRole;
+
+/**
+ * This object performs runtime access control operations on objects that are provisioned RBAC entities
+ * that reside in LDAP directory.  These APIs map directly to similar named APIs specified by ANSI and NIST
+ * RBAC system functions.
+ * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
+ * The RBAC Functional specification describes administrative operations for the creation
+ * and maintenance of RBAC element sets and relations; administrative review functions for
+ * performing administrative queries; and system functions for creating and managing
+ * RBAC attributes on user sessions and making access control decisions.
+ * <p/>
+ * <hr>
+ * <h4>RBAC0 - Core</h4>
+ * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
+ * <p/>
+ * <img src="./doc-files/RbacCore.png">
+ * <hr>
+ * <h4>RBAC1 - General Hierarchical Roles</h4>
+ * Simplifies role engineering tasks using inheritance of one or more parent roles.
+ * <p/>
+ * <img src="./doc-files/RbacHier.png">
+ * <hr>
+ * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+ * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
+ * <p/>
+ * <img src="./doc-files/RbacSSD.png">
+ * <hr>
+ * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+ * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+ * <p/>
+ * <img src="./doc-files/RbacDSD.png">
+ * <hr>
+ * <p/>
+ * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.apache.directory.fortress.core.rbac.Session)}) are set.
+ * @author Shawn McKinney
+ */
+public interface AccelMgr extends Manageable
+{
+
+    /**
+     * Perform user authentication {@link User#password} and role activations.<br />
+     * This method must be called once per user prior to calling other methods within this class.
+     * The successful result is {@link org.apache.directory.fortress.core.rbac.Session} that contains target user's RBAC {@link User#roles} and Admin role {@link User#adminRoles}.<br />
+     * In addition to checking user password validity it will apply configured password policy checks {@link org.apache.directory.fortress.core.rbac.User#pwPolicy}..<br />
+     * Method may also store parms passed in for audit trail {@link org.apache.directory.fortress.core.rbac.FortEntity}.
+     * <h4> This API will...</h4>
+     * <ul>
+     * <li> authenticate user password if trusted == false.
+     * <li> perform <a href="http://www.openldap.org/">OpenLDAP</a> <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10">password policy evaluation</a>, see {@link org.apache.directory.fortress.core.ldap.openldap.OLPWControlImpl}.
+     *
+     * <li> fail for any user who is locked by OpenLDAP's policies {@link org.apache.directory.fortress.core.rbac.User#isLocked()}, regardless of trusted flag being set as parm on API.
+     * <li> evaluate temporal {@link org.apache.directory.fortress.core.util.time.Constraint}(s) on {@link User}, {@link UserRole} and {@link org.apache.directory.fortress.core.rbac.UserAdminRole} entities.
+     * <li> process selective role activations into User RBAC Session {@link User#roles}.
+     * <li> check Dynamic Separation of Duties {@link org.apache.directory.fortress.core.rbac.DSDChecker#validate(org.apache.directory.fortress.core.rbac.Session, org.apache.directory.fortress.core.util.time.Constraint, org.apache.directory.fortress.core.util.time.Time)} on {@link org.apache.directory.fortress.core.rbac.User#roles}.
+     * <li> process selective administrative role activations {@link User#adminRoles}.
+     * <li> return a {@link org.apache.directory.fortress.core.rbac.Session} containing {@link org.apache.directory.fortress.core.rbac.Session#getUser()}, {@link org.apache.directory.fortress.core.rbac.Session#getRoles()} and (if admin user) {@link org.apache.directory.fortress.core.rbac.Session#getAdminRoles()} if everything checks out good.
+     * <li> throw a checked exception that will be {@link SecurityException} or its derivation.
+     * <li> throw a {@link SecurityException} for system failures.
+     * <li> throw a {@link PasswordException} for authentication and password policy violations.
+     * <li> throw a {@link ValidationException} for data validation errors.
+     * <li> throw a {@link FinderException} if User id not found.
+     * </ul>
+     * <h4>
+     * The function is valid if and only if:
+     * </h4>
+     * <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>
+     * <h4>
+     * The following attributes may be set when calling this method
+     * </h4>
+     * <ul>
+     * <li> {@link User#userId} - required
+     * <li> {@link org.apache.directory.fortress.core.rbac.User#password}
+     * <li> {@link org.apache.directory.fortress.core.rbac.User#roles} contains a list of RBAC role names authorized for user and targeted for activation within this session.  Default is all authorized RBAC roles will be activated into this Session.
+     * <li> {@link org.apache.directory.fortress.core.rbac.User#adminRoles} contains a list of Admin role names authorized for user and targeted for activation.  Default is all authorized ARBAC roles will be activated into this Session.
+     * <li> {@link User#props} collection of name value pairs collected on behalf of User during signon.  For example hostname:myservername or ip:192.168.1.99
+     * </ul>
+     * <h4>
+     * Notes:
+     * </h4>
+     * <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, see {@link User#setRole(String)}.
+     * </ul>
+     * </p>
+     *
+     * @param user      Contains {@link User#userId}, {@link org.apache.directory.fortress.core.rbac.User#password} (optional if {@code isTrusted} is 'true'), optional {@link User#roles}, optional {@link org.apache.directory.fortress.core.rbac.User#adminRoles}
+     * @param isTrusted if true password is not required.
+     * @return Session object will contain authentication result code {@link org.apache.directory.fortress.core.rbac.Session#errorId}, RBAC role activations {@link org.apache.directory.fortress.core.rbac.Session#getRoles()}, Admin Role activations {@link org.apache.directory.fortress.core.rbac.Session#getAdminRoles()},OpenLDAP pw policy codes {@link org.apache.directory.fortress.core.rbac.Session#warningId}, {@link org.apache.directory.fortress.core.rbac.Session#expirationSeconds}, {@link org.apache.directory.fortress.core.rbac.Session#graceLogins} and more.
+     * @throws SecurityException
+     *          in the event of data validation failure, security policy violation or DAO error.
+     */
+    public Session createSession(User user, boolean isTrusted)
+        throws SecurityException;
+
+
+    /**
+     * This function deletes a fortress session from the RBAC Policy Decision Point inside OpenLDAP RBAC Accelerator.  The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    public void deleteSession(Session session)
+        throws SecurityException;
+
+    /**
+     * This function returns the active roles associated with a session. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return List<UserRole> containing all roles active in user's session.  This will NOT contain inherited roles.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    public List<UserRole> sessionRoles(Session session)
+        throws SecurityException;
+
+
+    /**
+     * Perform user RBAC authorization.  This function returns a Boolean value meaning whether the subject of a given session is
+     * allowed or not to perform a given operation on a given object. The function is valid if and
+     * only if the session is a valid Fortress session, the object is a member of the OBJS data set,
+     * and the operation is a member of the OPS data set. The session's subject has the permission
+     * to perform the operation on that object if and only if that permission is assigned to (at least)
+     * one of the session's active roles. This implementation will verify the roles or userId correspond
+     * to the subject's active roles are registered in the object's access control list.
+     *
+     * @param perm    must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, of permission User is trying to access.
+     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return True if user has access, false otherwise.
+     * @throws SecurityException
+     *          in the event of data validation failure, security policy violation or DAO error.
+     */
+    public boolean checkAccess(Session session, Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the permissions of the session, i.e., the permissions assigned
+     * to its authorized roles. The function is valid if and only if the session is a valid Fortress session.
+     *
+     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return List<Permission> containing permissions (op, obj) active for user's session.
+     * @throws SecurityException is thrown if runtime error occurs with system.
+     */
+    public List<Permission> sessionPermissions(Session session)
+        throws SecurityException;
+
+
+    /**
+     * This function adds a role as an active role of a session whose owner is a given user.
+     * <p>
+     * The function is valid if and only if:
+     * <ul>
+     * <li> the user is a member of the USERS data set
+     * <li> the role is a member of the ROLES data set
+     * <li> the role inclusion does not violate Dynamic Separation of Duty Relationships
+     * <li> the session is a valid Fortress session
+     * <li> the user is authorized to that role
+     * <li> the session is owned by that user.
+     * </ul>
+     * </p>
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @param role    object contains the role name, {@link UserRole#name}, to be activated into session.
+     * @throws SecurityException is thrown if user is not allowed to activate or runtime error occurs with system.
+     */
+    public void addActiveRole(Session session, UserRole role)
+        throws SecurityException;
+
+
+    /**
+     * This function deletes a role from the active role set of a session owned by a given user.
+     * The function is valid if and only if the user is a member of the USERS data set, the
+     * session object contains a valid Fortress session, the session is owned by the user,
+     * and the role is an active role of that session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @param role    object contains the role name, {@link org.apache.directory.fortress.core.rbac.UserRole#name}, to be deactivated.
+     * @throws SecurityException is thrown if user is not allowed to deactivate or runtime error occurs with system.
+     */
+    public void dropActiveRole(Session session, UserRole role)
+        throws SecurityException;
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/AccelMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/AccelMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/AccelMgrFactory.java
new file mode 100644
index 0000000..032cc8a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/AccelMgrFactory.java
@@ -0,0 +1,74 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.AccelMgrImpl;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Creates an instance of the AccelMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link AccelMgrImpl} but can be overridden by
+ * adding the {@link GlobalIds#ACCEL_IMPLEMENTATION} config property.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class AccelMgrFactory
+{
+    private static String accelClassName = Config.getProperty(GlobalIds.ACCEL_IMPLEMENTATION);
+    private static final String CLS_NM = AccelMgrFactory.class.getName();
+
+    /**
+     * Create and return a reference to {@link AccelMgr} object using HOME context.
+     *
+     * @return instance of {@link AccelMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AccelMgr createInstance()
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME );
+    }
+
+    /**
+     * Create and return a reference to {@link AccelMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return instance of {@link AccelMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AccelMgr createInstance(String contextId)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance");
+        if (!VUtil.isNotNullOrEmpty(accelClassName))
+        {
+                accelClassName = AccelMgrImpl.class.getName();
+        }
+
+        AccelMgr accelMgr = (AccelMgr) ClassUtil.createInstance(accelClassName);
+        accelMgr.setContextId(contextId);
+        return accelMgr;
+    }
+}
\ 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/AccessMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/AccessMgr.java b/src/main/java/org/apache/directory/fortress/core/AccessMgr.java
new file mode 100755
index 0000000..7c616db
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/AccessMgr.java
@@ -0,0 +1,295 @@
+/*
+ *   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;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rbac.UserRole;
+
+/**
+ * This object performs runtime access control operations on objects that are provisioned RBAC entities
+ * that reside in LDAP directory.  These APIs map directly to similar named APIs specified by ANSI and NIST
+ * RBAC system functions.
+ * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
+ * The RBAC Functional specification describes administrative operations for the creation
+ * and maintenance of RBAC element sets and relations; administrative review functions for
+ * performing administrative queries; and system functions for creating and managing
+ * RBAC attributes on user sessions and making access control decisions.
+ * <p/>
+ * <hr>
+ * <h4>RBAC0 - Core</h4>
+ * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
+ * <p/>
+ * <img src="./doc-files/RbacCore.png">
+ * <hr>
+ * <h4>RBAC1 - General Hierarchical Roles</h4>
+ * Simplifies role engineering tasks using inheritance of one or more parent roles.
+ * <p/>
+ * <img src="./doc-files/RbacHier.png">
+ * <hr>
+ * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+ * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
+ * <p/>
+ * <img src="./doc-files/RbacSSD.png">
+ * <hr>
+ * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+ * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+ * <p/>
+ * <img src="./doc-files/RbacDSD.png">
+ * <hr>
+ * <p/>
+ * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.apache.directory.fortress.core.rbac.Session)}) are set.
+ * @author Shawn McKinney
+ */
+public interface AccessMgr extends Manageable
+{
+
+    /**
+     * Perform user authentication only.  It does not activate RBAC roles in session but will evaluate
+     * password policies.
+     *
+     * @param userId   Contains the userid of the user signing on.
+     * @param password Contains the user's 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.
+     */
+    public Session authenticate(String userId, char[] password)
+        throws SecurityException;
+
+
+    /**
+     * Perform user authentication {@link User#password} and role activations.<br />
+     * This method must be called once per user prior to calling other methods within this class.
+     * The successful result is {@link org.apache.directory.fortress.core.rbac.Session} that contains target user's RBAC {@link User#roles} and Admin role {@link User#adminRoles}.<br />
+     * In addition to checking user password validity it will apply configured password policy checks {@link org.apache.directory.fortress.core.rbac.User#pwPolicy}..<br />
+     * Method may also store parms passed in for audit trail {@link org.apache.directory.fortress.core.rbac.FortEntity}.
+     * <h4> This API will...</h4>
+     * <ul>
+     * <li> authenticate user password if trusted == false.
+     * <li> perform <a href="http://www.openldap.org/">OpenLDAP</a> <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10">password policy evaluation</a>, see {@link org.apache.directory.fortress.core.ldap.openldap.OLPWControlImpl}.
+     *
+     * <li> fail for any user who is locked by OpenLDAP's policies {@link org.apache.directory.fortress.core.rbac.User#isLocked()}, regardless of trusted flag being set as parm on API.
+     * <li> evaluate temporal {@link org.apache.directory.fortress.core.util.time.Constraint}(s) on {@link User}, {@link UserRole} and {@link org.apache.directory.fortress.core.rbac.UserAdminRole} entities.
+     * <li> process selective role activations into User RBAC Session {@link User#roles}.
+     * <li> check Dynamic Separation of Duties {@link org.apache.directory.fortress.core.rbac.DSDChecker#validate(org.apache.directory.fortress.core.rbac.Session, org.apache.directory.fortress.core.util.time.Constraint, org.apache.directory.fortress.core.util.time.Time)} on {@link org.apache.directory.fortress.core.rbac.User#roles}.
+     * <li> process selective administrative role activations {@link User#adminRoles}.
+     * <li> return a {@link org.apache.directory.fortress.core.rbac.Session} containing {@link org.apache.directory.fortress.core.rbac.Session#getUser()}, {@link org.apache.directory.fortress.core.rbac.Session#getRoles()} and (if admin user) {@link org.apache.directory.fortress.core.rbac.Session#getAdminRoles()} if everything checks out good.
+     * <li> throw a checked exception that will be {@link SecurityException} or its derivation.
+     * <li> throw a {@link SecurityException} for system failures.
+     * <li> throw a {@link PasswordException} for authentication and password policy violations.
+     * <li> throw a {@link ValidationException} for data validation errors.
+     * <li> throw a {@link FinderException} if User id not found.
+     * </ul>
+     * <h4>
+     * The function is valid if and only if:
+     * </h4>
+     * <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>
+     * <h4>
+     * The following attributes may be set when calling this method
+     * </h4>
+     * <ul>
+     * <li> {@link User#userId} - required
+     * <li> {@link org.apache.directory.fortress.core.rbac.User#password}
+     * <li> {@link org.apache.directory.fortress.core.rbac.User#roles} contains a list of RBAC role names authorized for user and targeted for activation within this session.  Default is all authorized RBAC roles will be activated into this Session.
+     * <li> {@link org.apache.directory.fortress.core.rbac.User#adminRoles} contains a list of Admin role names authorized for user and targeted for activation.  Default is all authorized ARBAC roles will be activated into this Session.
+     * <li> {@link User#props} collection of name value pairs collected on behalf of User during signon.  For example hostname:myservername or ip:192.168.1.99
+     * </ul>
+     * <h4>
+     * Notes:
+     * </h4>
+     * <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, see {@link User#setRole(String)}.
+     * </ul>
+     * </p>
+     *
+     * @param user      Contains {@link User#userId}, {@link org.apache.directory.fortress.core.rbac.User#password} (optional if {@code isTrusted} is 'true'), optional {@link User#roles}, optional {@link org.apache.directory.fortress.core.rbac.User#adminRoles}
+     * @param isTrusted if true password is not required.
+     * @return Session object will contain authentication result code {@link org.apache.directory.fortress.core.rbac.Session#errorId}, RBAC role activations {@link org.apache.directory.fortress.core.rbac.Session#getRoles()}, Admin Role activations {@link org.apache.directory.fortress.core.rbac.Session#getAdminRoles()},OpenLDAP pw policy codes {@link org.apache.directory.fortress.core.rbac.Session#warningId}, {@link org.apache.directory.fortress.core.rbac.Session#expirationSeconds}, {@link org.apache.directory.fortress.core.rbac.Session#graceLogins} and more.
+     * @throws SecurityException
+     *          in the event of data validation failure, security policy violation or DAO error.
+     */
+    public Session createSession(User user, boolean isTrusted)
+        throws SecurityException;
+
+
+    /**
+     * Perform user RBAC authorization.  This function returns a Boolean value meaning whether the subject of a given session is
+     * allowed or not to perform a given operation on a given object. The function is valid if and
+     * only if the session is a valid Fortress session, the object is a member of the OBJS data set,
+     * and the operation is a member of the OPS data set. The session's subject has the permission
+     * to perform the operation on that object if and only if that permission is assigned to (at least)
+     * one of the session's active roles. This implementation will verify the roles or userId correspond
+     * to the subject's active roles are registered in the object's access control list.
+     *
+     * @param perm    must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, of permission User is trying to access.
+     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return True if user has access, false otherwise.
+     * @throws SecurityException
+     *          in the event of data validation failure, security policy violation or DAO error.
+     */
+    public boolean checkAccess(Session session, Permission perm)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the permissions of the session, i.e., the permissions assigned
+     * to its authorized roles. The function is valid if and only if the session is a valid Fortress session.
+     *
+     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return List<Permission> containing permissions (op, obj) active for user's session.
+     * @throws SecurityException is thrown if runtime error occurs with system.
+     */
+    public List<Permission> sessionPermissions(Session session)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the active roles associated with a session. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return List<UserRole> containing all roles active in user's session.  This will NOT contain inherited roles.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    public List<UserRole> sessionRoles(Session session)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the authorized roles associated with a session based on hierarchical relationships. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return Set<String> containing all roles active in user's session.  This will contain inherited roles.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    public Set<String> authorizedRoles(Session session)
+        throws SecurityException;
+
+
+    /**
+     * This function adds a role as an active role of a session whose owner is a given user.
+     * <p>
+     * The function is valid if and only if:
+     * <ul>
+     * <li> the user is a member of the USERS data set
+     * <li> the role is a member of the ROLES data set
+     * <li> the role inclusion does not violate Dynamic Separation of Duty Relationships
+     * <li> the session is a valid Fortress session
+     * <li> the user is authorized to that role
+     * <li> the session is owned by that user.
+     * </ul>
+     * </p>
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @param role    object contains the role name, {@link UserRole#name}, to be activated into session.
+     * @throws SecurityException is thrown if user is not allowed to activate or runtime error occurs with system.
+     */
+    public void addActiveRole(Session session, UserRole role)
+        throws SecurityException;
+
+
+    /**
+     * This function deletes a role from the active role set of a session owned by a given user.
+     * The function is valid if and only if the user is a member of the USERS data set, the
+     * session object contains a valid Fortress session, the session is owned by the user,
+     * and the role is an active role of that session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @param role    object contains the role name, {@link org.apache.directory.fortress.core.rbac.UserRole#name}, to be deactivated.
+     * @throws SecurityException is thrown if user is not allowed to deactivate or runtime error occurs with system.
+     */
+    public void dropActiveRole(Session session, UserRole role)
+        throws SecurityException;
+
+
+    /**
+     * This function returns the userId value that is contained within the session object.
+     * The function is valid if and only if the session object contains a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return The userId value
+     * @throws SecurityException is thrown if user session not active or runtime error occurs with system.
+     */
+    public String getUserId(Session session)
+        throws SecurityException;
+
+    /**
+     * This function returns the user object that is contained within the session object.
+     * The function is valid if and only if the session object contains a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return The user value
+     *         Sample User data contained in Session object:
+     *         <ul> <code>Session</code>
+     *         <li> <code>session.getUserId() => demoUser4</code>
+     *         <li> <code>session.getInternalUserId() => be2dd2e:12a82ba707e:-7fee</code>
+     *         <li> <code>session.getMessage() => Fortress checkPwPolicies userId <demouser4> VALIDATION GOOD</code>
+     *         <li> <code>session.getErrorId() => 0</code>
+     *         <li> <code>session.getWarningId() => 11</code>
+     *         <li> <code>session.getExpirationSeconds() => 469831</code>
+     *         <li> <code>session.getGraceLogins() => 0</code>
+     *         <li> <code>session.getIsAuthenticated() => true</code>
+     *         <li> <code>session.getLastAccess() => 1283623680440</code>
+     *         <li> <code>session.getSessionId() => -7410986f:12addeea576:-7fff</code>
+     *         <li>  ------------------------------------------
+     *         <li> <code>User user = session.getUser();</code>
+     *         <ul> <li> <code>user.getUserId() => demoUser4</code>
+     *         <li> <code>user.getInternalId() => be2dd2e:12a82ba707e:-7fee</code>
+     *         <li> <code>user.getCn() => JoeUser4</code>
+     *         <li> <code>user.getDescription() => Demo Test User 4</code>
+     *         <li> <code>user.getOu() => test</code>
+     *         <li> <code>user.getSn() => User4</code>
+     *         <li> <code>user.getBeginDate() => 20090101</code>
+     *         <li> <code>user.getEndDate() => none</code>
+     *         <li> <code>user.getBeginLockDate() => none</code>
+     *         <li> <code>user.getEndLockDate() => none</code>
+     *         <li> <code>user.getDayMask() => 1234567</code>
+     *         <li> <code>user.getTimeout() => 60</code>
+     *         <li> <code>List<UserRole> roles = session.getRoles();</code>
+     *         <ul> <li><code>UserRole userRole = roles.get(i);</code>
+     *         <li> <code>userRole.getName() => role1</code>
+     *         <li> <code>userRole.getBeginTime() => 0000</code>
+     *         <li> <code>userRole.getEndTime() => 0000</code>
+     *         <li> <code>userRole.getBeginDate() => none</code>
+     *         <li> <code>userRole.getEndDate() => none</code>
+     *         <li> <code>userRole.getBeginLockDate() => null</code>
+     *         <li> <code>userRole.getEndLockDate() => null</code>
+     *         <li> <code>userRole.getDayMask() => null</code>
+     *         <li> <code>userRole.getTimeout() => 0</code>
+     *         </ul>
+     *         </ul>
+     *         </ul>
+     * @throws SecurityException is thrown if user session not active or runtime error occurs with system.
+     */
+    public User getUser(Session session)
+        throws SecurityException;
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/AccessMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/AccessMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/AccessMgrFactory.java
new file mode 100755
index 0000000..5a74567
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/AccessMgrFactory.java
@@ -0,0 +1,82 @@
+/*
+ *   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;
+
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.AccessMgrImpl;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.rest.AccessMgrRestImpl;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * Creates an instance of the AccessMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link AccessMgrImpl} but can be overridden by
+ * adding the {@link GlobalIds#ACCESS_IMPLEMENTATION} config property.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class AccessMgrFactory
+{
+    private static String accessClassName = Config.getProperty(GlobalIds.ACCESS_IMPLEMENTATION);
+    private static final String CLS_NM = AccessMgrFactory.class.getName();
+
+    /**
+     * Create and return a reference to {@link AccessMgr} object using HOME context.
+     *
+     * @return instance of {@link AccessMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AccessMgr createInstance()
+        throws SecurityException
+    {
+        return createInstance( GlobalIds.HOME );
+    }
+
+    /**
+     * Create and return a reference to {@link AccessMgr} object.
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return instance of {@link AccessMgr}.
+     * @throws SecurityException in the event of failure during instantiation.
+     */
+    public static AccessMgr createInstance(String contextId)
+        throws SecurityException
+    {
+        VUtil.assertNotNull(contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance");
+        if (!VUtil.isNotNullOrEmpty(accessClassName))
+        {
+            if(GlobalIds.IS_REST)
+            {
+                accessClassName = AccessMgrRestImpl.class.getName();
+            }
+            else
+            {
+                accessClassName = AccessMgrImpl.class.getName();
+            }
+        }
+
+        AccessMgr accessMgr = (AccessMgr) ClassUtil.createInstance(accessClassName);
+        accessMgr.setContextId(contextId);
+        return accessMgr;
+    }
+}
\ No newline at end of file


[33/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/openldap/OLPWControlImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/openldap/OLPWControlImpl.java b/src/main/java/org/apache/directory/fortress/core/ldap/openldap/OLPWControlImpl.java
new file mode 100755
index 0000000..853d906
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/openldap/OLPWControlImpl.java
@@ -0,0 +1,417 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.openldap;
+
+
+import java.util.Arrays;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.ObjectFactory;
+import org.apache.directory.fortress.core.rbac.GlobalPwMsgIds;
+import org.apache.directory.fortress.core.rbac.PwMessage;
+import org.apache.directory.fortress.core.rbac.PwPolicyControl;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPControl;
+import org.apache.directory.fortress.core.rbac.Warning;
+
+
+/**
+ * This class reads the OpenLDAP password policy control and translates into data entity for Fortress.  In order for these checks
+ * to be successful the OpenLDAP server must have enabled the pw policy overlay.  Read the OpenLDAP man pages for how this overlay works.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class OLPWControlImpl implements PwPolicyControl
+{
+    private static final String CLS_NM = OLPWControlImpl.class.getName();
+    private final static Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+
+    /**
+     * Reads the OpenLDAP password policy control and sets the PwMessage with what it finds.
+     *
+     * <p/>This function will use the password policy control that is contained within the ldap connection object.
+     * Ber encoding:
+     * <ul>
+     * <li>  ------------------------------------------
+     * <li>  PasswordPolicyResponseValue ::= SEQUENCE {
+     * <li>  warning [0] CHOICE {
+     * <li>  timeBeforeExpiration [0] INTEGER (0 .. maxInt),
+     * <li>  graceLoginsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL
+     * <li>  error [1] ENUMERATED {
+     * <li>  passwordExpired        (0),
+     * <li>  accountLocked          (1),
+     * <li>  changeAfterReset       (2),
+     * <li>  passwordModNotAllowed  (3),
+     * <li>  mustSupplyOldPassword  (4),
+     * <li>  invalidPasswordSyntax  (5),
+     * <li>  passwordTooShort       (6),
+     * <li>  passwordTooYoung       (7),
+     * <li>  passwordInHistory      (8) } OPTIONAL }
+     * <li>  ---
+     * <li>  Old Encoding Scheme:
+     * <li>  PPOLICY_WARNING    0xa0
+     * <li>  PPOLICY_ERROR      0xa1
+     * <li>  PPOLICY_EXPIRE     0xa0
+     * <li>  PPOLICY_GRACE      0xa1
+     * <li>  New Encoding Scheme:
+     * <li>  PPOLICY_WARNING 0xa0
+     * <li>  PPOLICY_ERROR 0x81
+     * <li>  PPOLICY_EXPIRE 0x80
+     * <li>  PPOLICY_GRACE  0x81
+     * </ul>
+     *
+     * @param controls ldap controls object.
+     * @param isAuthenticated set to 'true' if password checks pass.
+     * @param pwMsg describes the outcome of the policy checks.
+     */
+    @Override
+    public void checkPasswordPolicy( LDAPControl[] controls, boolean isAuthenticated, PwMessage pwMsg )
+    {
+        String methodName = "checkPasswordPolicy";
+        pwMsg.setErrorId( GlobalPwMsgIds.GOOD );
+        //pwMsg.setWarningId( GlobalPwMsgIds.PP_NOWARNING );
+        pwMsg.setAuthenticated( isAuthenticated );
+
+        if ( controls == null )
+        {
+            pwMsg.setWarning( new ObjectFactory().createWarning( GlobalPwMsgIds.NO_CONTROLS_FOUND, "PW CONTROLS NOT FOUND", Warning.Type.PASSWORD ) );
+        }
+        else if ( controls.length >= 1 )
+        {
+            for ( int i = 0; i < controls.length; i++ )
+            {
+                if ( LOG.isDebugEnabled() )
+                {
+                    LOG.debug( "{} controls[{}]={}", methodName, i, controls[i] );
+                }
+
+                LDAPControl con = controls[i];
+                String id = con.getID();
+
+                if ( id.compareTo( GlobalIds.OPENLDAP_PW_RESPONSE_CONTROL ) == 0 )
+                {
+                    byte[] rB = con.getValue();
+
+                    if ( LOG.isDebugEnabled() )
+                    {
+                        LOG.debug( "{} control value length={}", methodName, rB.length );
+
+                        String bytes = "";
+
+                        for ( byte aRB : rB )
+                        {
+                            bytes = bytes + printRawData( aRB );
+                        }
+
+                        LOG.debug( "{} printRawData numbytes: {}", methodName, bytes );
+                    }
+
+                    if ( rB == null || rB[1] == 0 )
+                    {
+                        LOG.debug( methodName + " no password policy for user" );
+                        pwMsg.setWarning( new ObjectFactory().createWarning( GlobalPwMsgIds.NOT_PW_POLICY_ENABLED, "NO PW POLICY ENABLED FOR USER", Warning.Type.PASSWORD ) );
+                    }
+
+                    if ( LOG.isDebugEnabled() )
+                    {
+                        LOG.debug( "{} byte[]={}", methodName, Arrays.toString( rB ) );
+                        LOG.debug( "control.toString()={}", con.toString() );
+                    }
+
+                    int indx = 0;
+                    int lBerObjType = getInt( rB[indx++] );
+
+                    if ( LOG.isDebugEnabled() )
+                    {
+                        LOG.debug( "{} BER encoded object type={}", methodName, lBerObjType );
+                    }
+
+                    int msgLen = getInt( rB[indx++] );
+
+                    while ( indx < msgLen )
+                    {
+                        switch ( rB[indx++] )
+                        {
+                            case ( byte ) 0xa0:
+                                // BER Encoded byte array:
+                                //client: 00110000 00000101 10100000
+                                //  			     		^
+                                //		PPOLICY_WARNING  0xa0
+                                int policyWarnLen = getInt( rB[indx++] );
+
+                                switch ( rB[indx++] )
+                                {
+                                    case ( byte ) 0xa0:
+                                    case ( byte ) 0x80:
+                                        //pwMsg.setWarningId( GlobalPwMsgIds.PASSWORD_EXPIRATION_WARNING );
+                                        pwMsg.setWarning( new ObjectFactory().createWarning( GlobalPwMsgIds.PASSWORD_EXPIRATION_WARNING, "PASSWORD HAS EXPIRED", Warning.Type.PASSWORD ) );
+                                        // BER Encoded byte array:
+                                        // client: 00110000 00000110 10100000 00000100 10100000 00000010 00000010 00100100
+                                        //							 ^                  ^                   ^
+                                        //       PPOLICY_WARNING  0xa0 PPOLICY_EXPIRE 0xa0       EXP int==(decimal 548) 1000100100
+                                        int expLength = getInt( rB[indx++] );
+                                        int expire = getInt( rB[indx++] );
+
+                                        for ( int k = 1; k < expLength; k++ )
+                                        {
+                                            expire = expire << 8;
+                                            int next = getInt( rB[indx++] );
+                                            expire = expire | next;
+                                        }
+
+                                        pwMsg.setExpirationSeconds( expire );
+
+                                        if ( LOG.isDebugEnabled() )
+                                        {
+                                            LOG.debug( "{} User:{}, password expires in: {} seconds.", methodName, pwMsg.getUserId(), expire );
+                                        }
+
+                                        break;
+
+                                    case ( byte ) 0xa1:
+                                    case ( byte ) 0x81:
+                                        pwMsg.setWarning( new ObjectFactory().createWarning( GlobalPwMsgIds.PASSWORD_GRACE_WARNING, "PASSWORD IN GRACE", Warning.Type.PASSWORD ) );
+                                        // BER Encoded byte array:
+                                        //client: 00110000 00000101 10100000 00000011 10100001 00000001 01100100
+                                        //  			     		^                 ^                 ^
+                                        //			PPOLICY_WARNING  0xa0   PPOLICY_GRACE 0xa1       grace integer value
+                                        int graceLen = getInt( rB[indx++] );
+                                        int grace = getInt( rB[indx++] );
+
+                                        for ( int k = 1; k < graceLen; k++ )
+                                        {
+                                            grace = grace << 8;
+                                            int next = getInt( rB[indx++] );
+                                            grace = grace | next;
+                                        }
+
+                                        pwMsg.setGraceLogins( grace );
+
+                                        if ( LOG.isDebugEnabled() )
+                                        {
+                                            LOG.debug( "{} UserId:{}, # logins left={}", methodName, pwMsg.getUserId() + grace );
+                                        }
+
+                                        break;
+
+                                    default:
+                                        pwMsg.setWarning( new ObjectFactory().createWarning( GlobalPwMsgIds.INVALID_PASSWORD_MESSAGE, "INVALID PASSWORD", Warning.Type.PASSWORD ) );
+
+                                        if ( LOG.isDebugEnabled() )
+                                        {
+                                            LOG.debug( "{} UserId:{}, Invalid PPOlicy Type", methodName, pwMsg.getUserId() );
+                                        }
+
+                                        break;
+                                }
+
+                                break;
+
+                            case ( byte ) 0xa1:
+                            case ( byte ) 0x81:
+                                // BER Encoded byte array:
+                                //client: 00110000 00001011 10100000 00000110 10100000 00000100 00000001 11100001 00110011 01111101 10100001 00000001 00000010
+                                //							 ^                  ^                 ^                                   ^                     ^
+                                //		   PPOLICY_WARNING  0xa0 PPOLICY_EXPIRE 0xa0      expire int==(decimal 100)     PPOLICY_ERR 0xa1             ERR #==2
+                                int errLen = getInt( rB[indx++] );
+                                int err = getInt( rB[indx++] );
+
+                                if ( LOG.isDebugEnabled() )
+                                {
+                                    LOG.debug( "{} UserId:{}, PPOLICY_ERROR={}", methodName, pwMsg.getUserId(), err);
+                                }
+
+                                switch ( err )
+                                {
+                                    case 0:
+                                        pwMsg.setErrorId( GlobalPwMsgIds.PASSWORD_HAS_EXPIRED );
+                                        break;
+
+                                    case 1:
+                                        pwMsg.setErrorId( GlobalPwMsgIds.ACCOUNT_LOCKED );
+                                        break;
+
+                                    case 2:
+                                        pwMsg.setErrorId( GlobalPwMsgIds.CHANGE_AFTER_RESET );
+                                        break;
+
+                                    case 3:
+                                        pwMsg.setErrorId( GlobalPwMsgIds.NO_MODIFICATIONS );
+                                        break;
+
+                                    case 4:
+                                        pwMsg.setErrorId( GlobalPwMsgIds.MUST_SUPPLY_OLD );
+                                        break;
+
+                                    case 5:
+                                        pwMsg.setErrorId( GlobalPwMsgIds.INSUFFICIENT_QUALITY );
+                                        break;
+
+                                    case 6:
+                                        pwMsg.setErrorId( GlobalPwMsgIds.PASSWORD_TOO_SHORT );
+                                        break;
+
+                                    case 7:
+                                        pwMsg.setErrorId( GlobalPwMsgIds.PASSWORD_TOO_YOUNG );
+                                        break;
+
+                                    case 8:
+                                        pwMsg.setErrorId( GlobalPwMsgIds.HISTORY_VIOLATION );
+                                        break;
+
+                                    case 65535:
+                                        pwMsg.setErrorId( GlobalPwMsgIds.GOOD );
+                                        break;
+
+                                    default:
+                                        pwMsg.setErrorId( GlobalPwMsgIds.INVALID_PASSWORD_MESSAGE );
+                                        break;
+                                }
+
+                                break;
+
+                            default:
+                                pwMsg.setWarning( new ObjectFactory().createWarning( GlobalPwMsgIds.INVALID_PASSWORD_MESSAGE, "INVALID POLICY MESSAGE TYPE", Warning.Type.PASSWORD ) );
+
+                                if ( LOG.isDebugEnabled() )
+                                {
+                                    LOG.debug( "{} userId:{}, Invalid PPOlicy Message Type", methodName, pwMsg.getUserId());
+                                }
+
+                                break;
+                        }
+                    }
+                }
+                else
+                {
+                    pwMsg.setWarning( new ObjectFactory().createWarning( GlobalPwMsgIds.INVALID_PASSWORD_MESSAGE, "CANNOT PROCESS OPENLDAP POLICY CONTROL", Warning.Type.PASSWORD ) );
+
+                    if ( LOG.isDebugEnabled() )
+                    {
+                        LOG.debug( "{} UserId:{},  Can't process LDAP control.", methodName, pwMsg.getUserId() );
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @param bte
+     * @return int
+     */
+    private static int getInt( byte bte )
+    {
+        return bte & 0xff;
+    }
+
+
+    /**
+     * Description of the Method
+     *
+     * @param ch Description of the Parameter
+     * @return Description of the Return Value
+     */
+    private static String printRawData( byte ch )
+    {
+        int B0 = 0x01;
+        int B1 = 0x02;
+        int B2 = 0x04;
+        int B3 = 0x08;
+        int B4 = 0x10;
+        int B5 = 0x20;
+        int B6 = 0x40;
+        int B7 = 0x80;
+
+        String byteString;
+        if ( ( ch & B7 ) != 0 )
+        {
+            byteString = "1";
+        }
+        else
+        {
+            byteString = "0";
+        }
+        if ( ( ch & B6 ) != 0 )
+        {
+            byteString += "1";
+        }
+        else
+        {
+            byteString += "0";
+        }
+        if ( ( ch & B5 ) != 0 )
+        {
+            byteString += "1";
+        }
+        else
+        {
+            byteString += "0";
+        }
+        if ( ( ch & B4 ) != 0 )
+        {
+            byteString += "1";
+        }
+        else
+        {
+            byteString += "0";
+        }
+        if ( ( ch & B3 ) != 0 )
+        {
+            byteString += "1";
+        }
+        else
+        {
+            byteString += "0";
+        }
+        if ( ( ch & B2 ) != 0 )
+        {
+            byteString += "1";
+        }
+        else
+        {
+            byteString += "0";
+        }
+        if ( ( ch & B1 ) != 0 )
+        {
+            byteString += "1";
+        }
+        else
+        {
+            byteString += "0";
+        }
+        if ( ( ch & B0 ) != 0 )
+        {
+            byteString += "1";
+        }
+        else
+        {
+            byteString += "0";
+        }
+        byteString += " ";
+        return byteString;
+    }
+}
\ 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/ldap/openldap/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/openldap/package.html b/src/main/java/org/apache/directory/fortress/core/ldap/openldap/package.html
new file mode 100755
index 0000000..ee649fc
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/openldap/package.html
@@ -0,0 +1,33 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.ldap.openldap</title>
+   </head>
+   <body>
+      <p>
+         This package contains openldap password policy mappings.
+      </p>
+      <p>
+          This package stores and retrieves data elements in OpenLDAP ldap object class <b>pwdPolicy</b>.  In addition this package
+          contains processing to interrogate the OpenLDAP password policy control <b>1.3.6.1.4.1.42.2.27.8.5.1</b>.
+      </p>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/package.html b/src/main/java/org/apache/directory/fortress/core/ldap/package.html
new file mode 100755
index 0000000..cffad11
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/package.html
@@ -0,0 +1,33 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.ldap</title>
+   </head>
+   <body>
+      <p>
+         This package uses <a href="http://www.unboundid.com/products/ldap-sdk/">UnboundID LDAP SDK for Java</a> to provide ldap data access along with a custom, hybrid connection pooling mechanism to maintain connections with the ldap server.
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress.ldap</b> package provides ldap system functionality for the fortress DAO classes.  The apis contained within this package are for fortress use only.
+          See the corresponding javadoc contained with this package for more info.
+      </p>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/suffix/Suffix.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/suffix/Suffix.java b/src/main/java/org/apache/directory/fortress/core/ldap/suffix/Suffix.java
new file mode 100755
index 0000000..08876da
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/suffix/Suffix.java
@@ -0,0 +1,134 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.suffix;
+
+
+public class Suffix
+{
+    private String dc;
+    private String dc2;
+    private String name;
+    private String description;
+
+
+    /**
+     * Generate instance of suffix to be loaded as domain component ldap object.
+     *
+     * @param dc          top level domain component maps to 'dc' (i.e. 'com') attribute in 'dcObject' object class.
+     * @param name        second level domain component name maps to attribute in 'dcObject' object class.
+     * @param description maps to 'o' attribute in 'dcObject' object class.
+     */
+    public Suffix(String dc, String name, String description)
+    {
+        this.dc = dc;
+        this.name = name;
+        this.description = description;
+    }
+
+    /**
+     * Default constructor used by {@link org.apache.directory.fortress.core.ant.FortressAntTask}
+     */
+    public Suffix()
+    {
+    }
+
+    /**
+     * Get the second level qualifier on the domain component.  This attribute is required.
+     *
+     * @return name maps to 'dcObject' object class.
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * Set the second level qualifier on the domain component.  This attribute is required.
+     *
+     * @param name maps to 'dcObject' object class.
+     */
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    /**
+     * Get the description for the domain component.  This value is not required or constrained
+     * but is validated on reasonability.
+     *
+     * @return field maps to 'o' attribute on 'dcObject'.
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+    /**
+     * Set the description for the domain component.  This value is not required or constrained
+     * but is validated on reasonability.
+     *
+     * @param description maps to 'o' attribute on 'dcObject'.
+     */
+    public void setDescription(String description)
+    {
+        this.description = description;
+    }
+
+    /**
+     * Get top level domain component specifier, i.e. dc=com.  This attribute is required.
+     *
+     * @return dc maps to 'dc' in 'dcObject' object class.
+     */
+    public String getDc()
+    {
+        return dc;
+    }
+
+    /**
+     * Set top level domain component specifier, i.e. dc=com.  This attribute is required.
+     *
+     * @param dc maps to 'dc' in 'dcObject' object class.
+     */
+    public void setDc(String dc)
+    {
+        this.dc = dc;
+    }
+
+    /**
+     * Get top level domain component specifier, i.e. dc=com for a three part dc structure.  This attribute is optional.
+     *
+     * @return dc maps to 'dc' in 'dcObject' object class.
+     */
+    public String getDc2()
+    {
+        return dc2;
+    }
+
+    /**
+     * Get top level domain component specifier, i.e. dc=com for three part dc structure.  This attribute is optional.
+     *
+     * @return dc maps to 'dc' in 'dcObject' object class.
+     */
+    public void setDc2( String dc2 )
+    {
+        this.dc2 = dc2;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/suffix/SuffixDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/suffix/SuffixDAO.java b/src/main/java/org/apache/directory/fortress/core/ldap/suffix/SuffixDAO.java
new file mode 100755
index 0000000..ba181fc
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/suffix/SuffixDAO.java
@@ -0,0 +1,178 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.suffix;
+
+
+import org.apache.directory.api.ldap.model.cursor.CursorException;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * This class contains the Suffix node for OpenLDAP Directory Information Tree.
+ * <br />The domain component object class is 'dcObject' <br />
+ * <p/>
+ * dcObject Auxiliary Object Class is used to store basic attributes like domain component names and description.
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code># RFC 2247</code>
+ * <li> <code>objectclass ( 1.3.6.1.4.1.1466.344 NAME 'dcObject'</code>
+ * <li> <code>SUP top AUXILIARY MUST dc )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <p/>
+ * Following wikipedia excerpt describes usage of this object <a href="http://http://en.wikipedia.org/wiki/LDAP/">Wikipedia LDAP</a>
+ * <font size="2" color="blue">
+ * <blockquote>
+ * <h3>
+ * Naming structure
+ * </h3>
+ * Since an LDAP server can return referrals to other servers for requests the server itself will not/can not serve, a naming structure for LDAP entries is needed so one can find a server holding a given DN. Since such a structure already exists in the Domain name system (DNS), servers' top level names often mimic DNS names, as they do in X.500.
+ * If an organization has domain name example.org, its top level LDAP entry will typically have the DN dc=example,dc=org (where dc means domain component). If the LDAP server is also named ldap.example.org, the organization's top level LDAP URL becomes ldap://ldap.example.org/dc=example,dc=org.
+ * Below the top level, the entry names will typically reflect the organization's internal structure or needs rather than DNS names.
+ * </blockquote>
+ * </font>
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+final class SuffixDAO extends ApacheDsDataProvider
+{
+    private static final String CLS_NM = SuffixDAO.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final String DC = "dc";
+    private static final String O = "o";
+    private static final String[] SUFFIX_OBJ_CLASS =
+        {
+            GlobalIds.SUFFIX_CLASS, GlobalIds.ORGANIZATION_CLASS
+    };
+
+
+    /**
+     * Package private default constructor.
+     */
+    SuffixDAO()
+    {
+    }
+
+
+    /**
+     * @param se
+     * @throws org.apache.directory.fortress.core.CreateException
+     */
+    final void create( Suffix se )
+        throws CreateException
+    {
+        LdapConnection ld = null;
+        String nodeDn = getDn( se );
+        try
+        {
+            LOG.info( "create suffix dn [" + nodeDn + "]" );
+            Entry myEntry = new DefaultEntry( nodeDn );
+            myEntry.add( GlobalIds.OBJECT_CLASS, SUFFIX_OBJ_CLASS );
+            myEntry.add( DC, se.getName() );
+            myEntry.add( O, se.getDescription() );
+            ld = getAdminConnection();
+            add( ld, myEntry );
+        }
+        catch ( LdapException e )
+        {
+            String error = "create container node dn [" + nodeDn + "] caught LDAPException="
+                + e.getMessage();
+            throw new CreateException( GlobalErrIds.SUFX_CREATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * <p/>
+     * <font size="4" color="red">
+     * This method is destructive as it will remove all nodes below the suffix using recursive delete function.<BR>
+     * Extreme care should be taken during execution to ensure target directory is correct and permanent removal of data is intended.  There is no
+     * 'undo' for this operation.
+     * </font>
+     * <p/>
+     *
+     * @param se
+     * @throws org.apache.directory.fortress.core.RemoveException
+     */
+    final void remove( Suffix se )
+        throws RemoveException
+    {
+        LdapConnection ld = null;
+        String nodeDn = getDn( se );
+        LOG.info( "remove suffix dn [" + nodeDn + "]" );
+        try
+        {
+            ld = getAdminConnection();
+            deleteRecursive( ld, nodeDn );
+        }
+        catch ( CursorException e )
+        {
+            String error = "remove suffix node dn [" + nodeDn + "] caught CursorException="
+                + e.getMessage();
+            throw new RemoveException( GlobalErrIds.SUFX_DELETE_FAILED, error, e );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove suffix node dn [" + nodeDn + "] caught LDAPException="
+                + e.getMessage();
+            throw new RemoveException( GlobalErrIds.SUFX_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     *
+     * @param se
+     * @return
+     */
+    private String getDn( Suffix se )
+    {
+        String dn = DC + "=" + se.getName() + "," + DC + "=" + se.getDc();
+        // only use this domain component variable if it has been set in the build.properties file:
+        if( VUtil.isNotNullOrEmpty( se.getDc2() ) && !se.getDc2().equals( "${suffix.dc2}" ))
+        {
+            dn += "," + DC + "=" + se.getDc2();
+        }
+        LOG.debug( "suffix=" + dn );
+        return dn;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/suffix/SuffixP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/suffix/SuffixP.java b/src/main/java/org/apache/directory/fortress/core/ldap/suffix/SuffixP.java
new file mode 100755
index 0000000..f9f7f6d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/suffix/SuffixP.java
@@ -0,0 +1,146 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ldap.suffix;
+
+
+import org.apache.directory.fortress.core.ValidationException;
+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.SecurityException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * Process module for the suffix or root node of Fortress directory structure. The suffix represents the topmost node in a directory information
+ * tree.  For example dc=companyName,dc=com.  The suffix data is passed using {@link Suffix} class.  This class does perform simple data validations.
+ * The {@link org.apache.directory.fortress.core.ant.FortressAntTask#addSuffixes()} method calls the {@link #add} from this class during initial base loads.
+ * Removal {@link org.apache.directory.fortress.core.ant.FortressAntTask#deleteSuffixes()} is performed during regression tests and should never
+ * be executed targeting production directory systems.<BR>
+ * This class will accept {@link Suffix}, and forward on to it's corresponding DAO class {@link SuffixDAO} for add/delete of suffix.
+ * <p>
+ * Class will throw {@link org.apache.directory.fortress.core.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 org.apache.directory.fortress.core.SecurityException}s with appropriate
+ * error id from {@link GlobalErrIds}.
+ * <p>
+ * <font size="3" color="red">
+ * The {@link #delete} method in this class is destructive as it will remove all nodes below the suffix using recursive delete function.<BR>
+ * Extreme care should be taken during execution to ensure target dn is correct and permanent removal of data is intended.  There is no
+ * 'undo' for this operation.
+ * </font>
+ * <p/>
+ * Simple error mapping is performed in {@link #validate} class.
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+public class SuffixP
+{
+    private static final String CLS_NM = SuffixP.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+
+    /**
+     * Add a new suffix to the Directory Information Tree (DIT).  After added the
+     * node will be listed in domain component format, i.e. dc=companyName, dc=com, or dc=orgName, dc=org.
+     *
+     * @param suffix contains the dc name and top level dc for target node.
+     * @throws org.apache.directory.fortress.core.SecurityException in event of validation or system error.
+     */
+    public final void add( Suffix suffix )
+        throws SecurityException
+    {
+        validate( suffix );
+        SuffixDAO sDao = new SuffixDAO();
+        sDao.create( suffix );
+    }
+
+
+    /**
+     * Remove the suffix along with descendant nodes.  This is a destructive method which will remove all DIT nodes under
+     * the specified.
+     * <p/>
+     * <font size="2" color="red">
+     * This method is destructive and will remove all nodes below.<BR>
+     * Extreme care should be taken during execution to ensure target dn is correct and permanent removal of data is intended.  There is no
+     * 'undo' for this operation.
+     * </font>
+     * <p/>
+     *
+     * @param suffix contains the dc name and top level dc for target node.
+     * @throws SecurityException in event of validation or system error.
+     */
+    public final void delete( Suffix suffix )
+        throws SecurityException
+    {
+        validate( suffix );
+        SuffixDAO sDao = new SuffixDAO();
+        sDao.remove( suffix );
+    }
+
+
+    /**
+     * Method will perform simple validations to ensure the integrity of the {@link Suffix} entity targeted for insertion
+     * or deletion in directory.
+     *
+     * @param entity contains the enum type to validate
+     * @throws org.apache.directory.fortress.core.SecurityException thrown in the event the attribute is null.
+     */
+    private void validate( Suffix entity )
+        throws SecurityException
+    {
+        if ( entity.getName().length() > GlobalIds.OU_LEN )
+        {
+            String name = entity.getName();
+            String error = "validate name [" + name + "] invalid length [" + entity.getName().length() + "]";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.SUFX_NAME_INVLD, error );
+        }
+        if ( !VUtil.isNotNullOrEmpty( entity.getName() ) )
+        {
+            String error = "validate name validation failed, null or empty value";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.SUFX_NAME_NULL, error );
+        }
+        if ( entity.getDc().length() > GlobalIds.OU_LEN )
+        {
+            String name = entity.getName();
+            String error = "validate dc [" + name + "] invalid length [" + entity.getName().length() + "]";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.SUFX_DCTOP_INVLD, error );
+        }
+        if ( !VUtil.isNotNullOrEmpty( entity.getDc() ) )
+        {
+            String error = "validate dc validation failed, null or empty value";
+            LOG.warn( error );
+            throw new ValidationException( GlobalErrIds.SUFX_DCTOP_NULL, error );
+        }
+        VUtil.safeText( entity.getDescription(), GlobalIds.DESC_LEN );
+        if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+        {
+            VUtil.description( entity.getDescription() );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ldap/suffix/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/suffix/package.html b/src/main/java/org/apache/directory/fortress/core/ldap/suffix/package.html
new file mode 100755
index 0000000..a5d398c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/suffix/package.html
@@ -0,0 +1,38 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.ldap.suffix</title>
+   </head>
+   <body>
+      <p>
+         This package contains APIs to perform create and teardown the ldap suffix node.
+      </p>
+      <p>
+         Care must be taken when performing the delete api as it is destructive and will attempt to
+          recursively remove all nodes below the suffix.  This delete is not intended as safe for
+          teardown on large, production data sets.  The delete is safe for teardown of smaller directory as in initial base loads and/or regression
+          testing operations.
+          The <b>org.apache.directory.fortress.ldap.suffix</b> package provides apis to add and remove suffix node, <b>dcObject</b>.
+          The suffix node is also called 'root' or 'baseDn' and is the uppermost node within a particular Directory Information Tree.
+          Example of valid suffix nodes is <b>dc=example,dc=com</b>.  The container nodes will be located as direct descendants of the suffix.
+      </p>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/overview.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/overview.html b/src/main/java/org/apache/directory/fortress/core/overview.html
new file mode 100755
index 0000000..49ccc8f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/overview.html
@@ -0,0 +1,68 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Overview of the org.apache.fortress component</title>
+   </head>
+   <body>
+       A standards based and open source Identity Access Management Java SDK for LDAP v3 compliant systems.
+       <hr>
+      <h2>What can Fortress SDK do?</h2>
+       Contained within this SDK are APIs and utilities to perform authentication, authorization, administration, audit and password policies.
+       The most important package in this system is <A HREF="org/openldap/fortress/package-summary.html">org.apache.directory.fortress</A> which contains all of the public APIs that are called by outside programs.
+      <h3>Fortress Manager APIs</h3>
+       <ol>
+       <li><a href="org/openldap/fortress/AccessMgr.html">AccessMgr</a> - This class performs runtime access control operations on objects that are provisioned <a href="http://csrc.nist.gov/groups/SNS/rbac/documents/draft-rbac-implementation-std-v01.pdf">RBAC</a> entities that reside in LDAP directory.</li>
+       <li><a href="org/openldap/fortress/AdminMgr.html">AdminMgr</a> - This class performs administrative functions to provision Fortress <a href="http://csrc.nist.gov/groups/SNS/rbac/documents/draft-rbac-implementation-std-v01.pdf">RBAC</a> entities into the LDAP directory.</li>
+       <li><a href="org/openldap/fortress/AuditMgr.html">AuditMgr</a> - This interface prescribes methods used to search OpenLDAP's slapd access log.</li>
+       <li><a href="org/openldap/fortress/DelAccessMgr.html">DelAccessMgr</a> - This interface prescribes the API for performing runtime delegated access control operations on objects that are provisioned Fortress <a href="http://profsandhu.com/journals/tissec/p113-oh.pdf">ARBAC02</a> entities that reside in LDAP directory.</li>
+       <li><a href="org/openldap/fortress/DelAdminMgr.html">DelAdminMgr</a> - This class prescribes the <a href="http://profsandhu.com/journals/tissec/p113-oh.pdf">ARBAC02</a> DelegatedAdminMgr interface for performing policy administration of Fortress ARBAC entities that reside in LDAP directory.</li>
+       <li><a href="org/openldap/fortress/DelReviewMgr.html">DelReviewMgr</a> - This class prescribes the <a href="http://profsandhu.com/journals/tissec/p113-oh.pdf">ARBAC02</a> DelegatedReviewMgr interface for performing policy interrogation of provisioned Fortress ARBAC02 entities that reside in LDAP directory.</li>
+       <li><a href="org/openldap/fortress/PwPolicyMgr.html">PwPolicyMgr</a> - This class adheres to <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10">IETF PW policy draft</a> and is used to perform administrative and review functions on the <a href="org/openldap/fortress/rbac/PwPolicy.html">PWPOLICIES</a> and <a href="org/openldap/fortress/rbac/User.html">USERS</a> data sets within Fortress.</li>
+       <li><a href="org/openldap/fortress/ReviewMgr.html">ReviewMgr</a> - This interface prescribes the administrative review functions on already provisioned Fortress <a href="http://csrc.nist.gov/groups/SNS/rbac/documents/draft-rbac-implementation-std-v01.pdf">RBAC</a> entities that reside in LDAP directory.</li>
+       </ol>
+       <h5>Error Handling</h5>
+       These APIs throw checked exceptions defined in <a href="org/openldap/fortress/SecurityException.html">SecurityException</a>
+       <hr>
+      <h2>What technologies are used?</h2>
+      <p>
+         Fortress SDK runs on any platform that supports Java technology and LDAP v3 protocols.  Functionality that extends beyond
+          LDAP v3 is provided via <a href="http://openldap.org/">OpenLDAP</a> specific features.  In other words Fortress was optimized to run on OpenLDAP but works on any directory.
+      </p>
+       <hr>
+      <h2>What are the conditions of use?</h2>
+      <p>
+         This software development kit is open source, thus free to use and distribute via the <a href="http://www.OpenLDAP.org/license.html">OpenLDAP Public License</a>.
+         It was developed and tested on open systems like <a href="http://www.ubuntu.com/">Ubuntu</a> and <a href="http://www.centos.org/">Centos</a> and was helped along
+         by the following open source products:
+          <ol>
+          <li><a href="http://www.openldap.org/project/">The OpenLDAP Project</a></li>
+          <li><a href="http://www.apache.org/">The Apache Software Foundation</a></li>
+          <li><a href="http://www.unboundid.com/">UnboundID</a></li>
+          <li><a href="http://www.eigenbase.org/">The Eigenbase Project</a></li>
+          <li><a href="http://ehcache.org/">Ehcache</a></li>
+          </ol>
+      </p>
+      <p>
+         Check out these <A HREF="../samples/overview-summary.html">samples</A> in the <b>org.apache.directory.fortress.core.samples</b> package to show how Fortress APIs can be used by outside clients.  The
+         <b>dist</b> target in build.xml creates the samples package in the /dist folder of this project and is intended to be used for experimentation.
+      </p>
+   </body>
+</html>
\ 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/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/package.html b/src/main/java/org/apache/directory/fortress/core/package.html
new file mode 100755
index 0000000..770d6ee
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/package.html
@@ -0,0 +1,148 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress</title>
+   </head>
+   <body>
+      <p>
+         This package contains public APIs that are used by Java programs to provide Identity and Access Management functionality.  The APIs
+         are organized into categories or 'Managers'.  Each manager controls a specific area of functionality.
+      <h3>Managers</h3>
+          <ol>
+          <li>{@link org.apache.directory.fortress.AccessMgr} is used for RBAC runtime security checking</li>
+          <li>{@link org.apache.directory.fortress.AdminMgr} is for RBAC provisioning</li>
+          <li>{@link org.apache.directory.fortress.AuditMgr} is for interrogating OpenLDAP audit and historical logs</li>
+          <li>{@link org.apache.directory.fortress.DelAccessMgr} is used for ARBAC runtime security checking</li>
+          <li>{@link org.apache.directory.fortress.DelAdminMgr} is for ARBAC provisioning</li>
+          <li>{@link org.apache.directory.fortress.DelReviewMgr} is used to interrogate ARBAC policy</li>
+          <li>{@link org.apache.directory.fortress.PwPolicyMgr} is for performing OpenLDAP pwpolicy provisioning and interrogation</li>
+          <li>{@link org.apache.directory.fortress.ReviewMgr} is used to interrogate RBAC policy</li>
+          </ol>
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress</b> package provides managers, factories and exception classes that can be thrown when
+          fortress needs to report an error status code back to caller.  The fortress manager APIs are based on standards like <a href="http://csrc.nist.gov/groups/SNS/rbac/documents/draft-rbac-implementation-std-v01.pdf">RBAC</a>,
+          <a href="http://profsandhu.com/journals/tissec/p113-oh.pdf">ARBAC02</a> and <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10/">Password Policy for LDAP Directories</a>.
+          A {@link org.apache.directory.fortress.util.time.Constraint} mechanism is used by fortress to control the {@link org.apache.directory.fortress.util.time.Time}, {@link org.apache.directory.fortress.util.time.Date} and {@link org.apache.directory.fortress.util.time.Day} of week for when a
+          {@link org.apache.directory.fortress.core.rbac.User} or {@link org.apache.directory.fortress.core.rbac.UserRole} entity can be activated within a {@link org.apache.directory.fortress.core.rbac.Session}.
+          There is also a lockout mechanism to temporarily bar entities from activating.  AuditMgr may be used to interrogate OpenLDAP audit and historical information.
+      </p>
+      <hr>
+      <h2>Description of Package Contents</h2>
+      This package contains APIs to do the following
+      <ol>
+      <li>Role Based Access Control (RBAC)</li>
+      <li>Administrative Role Based Access Control (ARBAC)</li>
+      <li>Password Policies</li>
+      <li>Audit Trail</li>
+      </ol>
+      The following sections provides more info on each.
+      <hr>
+      <h3>1. Role Based Access Control description</h3>
+      <p>
+      Many of the method names and signatures within this package were taken directly from ANSI INCITS 359-2004.
+      The RBAC Functional specification describes administrative operations for the creation
+      and maintenance of RBAC element sets and relations; administrative review functions for
+      performing administrative queries; and system functions for creating and managing
+      RBAC attributes on user sessions and making access control decisions.
+      <p/>
+      <h4>RBAC0 - Core</h4>
+      Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
+      <p/>
+      <img src="./doc-files/RbacCore.png">
+      <h4>RBAC1 - General Hierarchical Roles</h4>
+      Simplifies role engineering tasks using inheritance of one or more parent roles.
+      <p/>
+      <img src="./doc-files/RbacHier.png">
+      <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+      Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
+      <p/>
+      <img src="./doc-files/RbacSSD.png">
+      <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+      Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+      <p/>
+      <img src="./doc-files/RbacDSD.png">
+      <p/>
+      <hr>
+      <h3>2. Administrative Role Based Access Control (ARBAC) description</h3>
+      These APIs map directly to similar named APIs specified by ARBAC02 functions.  The ARBAC Functional specification describes delegated administrative
+      operations for the creation and maintenance of ARBAC element sets and relations.  Delegated administrative review functions for performing administrative queries
+      and system functions for creating and managing ARBAC attributes on user sessions and making delegated administrative access control decisions.
+      <h4>ARBAC02 Diagram</h4>
+      <img src="./doc-files/ARbac.png">
+      <p/>
+      Fortress fully supports the Oh/Sandhu/Zhang ARBAC02 model for delegated administration.  ARBAC provides large enterprises the capability to delegate administrative authority to users that reside outside of the security admin group.
+      Decentralizing administration helps because it provides security provisioning capability to work groups without sacrificing regulations for accountability or traceability.
+      <p/>
+      <hr>
+      <h3>3. Password Policy description</h3>
+      Fortress APIs store and interrogate policies on <a href="http://www.openldap.org/">OpenLDAP</a> which supports the IETF <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10/">Password Policies LDAP directories</a></li> draft.  Policies may be applied at the user, group or global level.
+      Password enforcement options include:
+      <ul>
+      <li>A configurable limit on failed authentication attempts.</li>
+      <li>A counter to track the number of failed authentication attempts.</li>
+      <li>A time frame in which the limit of consecutive failed authentication attempts must happen before action is taken.</li>
+      <li>The action to be taken when the limit is reached. The action will either be nothing, or the account will be locked.</li>
+      <li>An amount of time the account is locked (if it is to be locked) This can be indefinite.</li>
+      <li>Password expiration.</li>
+      <li>Expiration warning</li>
+      <li>Grace authentications</li>
+      <li>Password history</li>
+      <li>Password minimum age</li>
+      <li>Password minimum length</li>
+      <li>Password Change after Reset</li>
+      <li>Safe Modification of Password</li>
+      </ul>
+      <h4>Password Policy diagram</h4>
+      The following is an example of policies that can be configured. There is no limit to the number of different policies that can be created and enforced.
+      <p/>
+      <img src="./doc-files/PasswordPolicy.png">
+      <p/>
+      <hr>
+      <h3>4. History and Audit trail using OpenLDAP</h3>
+      Provides an OpenLDAP access log retrieval mechanism that enables security event monitoring.
+      <ol>
+      <li>Authentication events:
+      <li>Session enablement events
+      <li>Authorization events
+      <li>Entity mods and deletes
+      </li>
+      </ol>
+      <h4>Diagram of Audit Events</h4>
+      <img src="./doc-files/Audit.png">
+      <p/>
+      All events include Fortress context, see {@code FortEntity}.
+      <p/>
+      <h4>
+      The following APIs generate events subsequently stored in this access log:
+      </h4>
+      <ul>
+      <li> {@link org.apache.directory.fortress.AccessMgr}
+      <li> {@link org.apache.directory.fortress.AdminMgr}
+      <li> {@link org.apache.directory.fortress.AdminMgr}
+      <li> {@link org.apache.directory.fortress.DelAdminMgr}
+      <li> {@link org.apache.directory.fortress.cfg.ConfigMgr}
+      <li> {@link org.apache.directory.fortress.PwPolicyMgr}
+      </ul>
+      </p>
+   </body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/AccelMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AccelMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/rbac/AccelMgrImpl.java
new file mode 100644
index 0000000..f9e017c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AccelMgrImpl.java
@@ -0,0 +1,282 @@
+/*
+ *   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 org.apache.directory.fortress.core.AccelMgr;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rbac.dao.AcceleratorDAO;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * Implementation class that performs runtime access control operations on data objects of type Fortress entities
+ * This class performs runtime access control operations on objects that are provisioned RBAC entities
+ * that reside in LDAP directory.  These APIs map directly to similar named APIs specified by ANSI and NIST
+ * RBAC system functions.
+ * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
+ * The RBAC Functional specification describes administrative operations for the creation
+ * and maintenance of RBAC element sets and relations; administrative review functions for
+ * performing administrative queries; and system functions for creating and managing
+ * RBAC attributes on user sessions and making access control decisions.
+ * <p/>
+ * <hr>
+ * <h4>RBAC0 - Core</h4>
+ * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
+ * <p/>
+ * <img src="../doc-files/RbacCore.png">
+ * <hr>
+ * <h4>RBAC1 - General Hierarchical Roles</h4>
+ * Simplifies role engineering tasks using inheritance of one or more parent roles.
+ * <p/>
+ * <img src="../doc-files/RbacHier.png">
+ * <hr>
+ * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+ * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
+ * <p/>
+ * <img src="../doc-files/RbacSSD.png">
+ * <hr>
+ * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+ * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+ * <p/>
+ * <img src="../doc-files/RbacDSD.png">
+ * <hr>
+ * <p/>
+ * This class is NOT thread safe if parent instance variables ({@link #contextId} or {@link #adminSess}) are set.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class AccelMgrImpl extends Manageable implements AccelMgr
+{
+    private static final String CLS_NM = AccessMgrImpl.class.getName();
+    private static final AcceleratorDAO aDao = new org.apache.directory.fortress.core.rbac.dao.apache.AcceleratorDAO();
+
+
+    /**
+     * package private constructor ensures outside classes must use factory: {@link org.apache.directory.fortress.core.AccelMgrFactory}
+     */
+    public AccelMgrImpl()
+    {
+    }
+
+
+    /**
+     * Perform user authentication {@link org.apache.directory.fortress.core.rbac.User#password} and role activations.<br />
+     * This method must be called once per user prior to calling other methods within this class.
+     * The successful result is {@link org.apache.directory.fortress.core.rbac.Session} that contains target user's RBAC {@link org.apache.directory.fortress.core.rbac.User#roles} and Admin role {@link org.apache.directory.fortress.core.rbac.User#adminRoles}.<br />
+     * In addition to checking user password validity it will apply configured password policy checks {@link org.apache.directory.fortress.core.rbac.User#pwPolicy}..<br />
+     * Method may also store parms passed in for audit trail {@link org.apache.directory.fortress.core.rbac.FortEntity}.
+     * <h4> This API will...</h4>
+     * <ul>
+     * <li> authenticate user password if trusted == false.
+     * <li> perform <a href="http://www.openldap.org/">OpenLDAP</a> <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10">password policy evaluation</a>, see {@link org.apache.directory.fortress.core.ldap.openldap.OLPWControlImpl}.
+     * <li> fail for any user who is locked by OpenLDAP's policies {@link org.apache.directory.fortress.core.rbac.User#isLocked()}, regardless of trusted flag being set as parm on API.
+     * <li> evaluate temporal {@link org.apache.directory.fortress.core.util.time.Constraint}(s) on {@link org.apache.directory.fortress.core.rbac.User}, {@link org.apache.directory.fortress.core.rbac.UserRole} and {@link UserAdminRole} entities.
+     * <li> process selective role activations into User RBAC Session {@link org.apache.directory.fortress.core.rbac.User#roles}.
+     * <li> check Dynamic Separation of Duties {@link org.apache.directory.fortress.core.rbac.DSDChecker#validate(org.apache.directory.fortress.core.rbac.Session, org.apache.directory.fortress.core.util.time.Constraint, org.apache.directory.fortress.core.util.time.Time)} on {@link org.apache.directory.fortress.core.rbac.User#roles}.
+     * <li> process selective administrative role activations {@link org.apache.directory.fortress.core.rbac.User#adminRoles}.
+     * <li> return a {@link org.apache.directory.fortress.core.rbac.Session} that contains a reference to an object stored on the RBAC server..
+     * <li> throw a checked exception that will be {@link org.apache.directory.fortress.core.SecurityException} or its derivation.
+     * <li> throw a {@link SecurityException} for system failures.
+     * <li> throw a {@link org.apache.directory.fortress.core.PasswordException} for authentication and password policy violations.
+     * <li> throw a {@link org.apache.directory.fortress.core.ValidationException} for data validation errors.
+     * <li> throw a {@link org.apache.directory.fortress.core.FinderException} if User id not found.
+     * </ul>
+     * <h4>
+     * The function is valid if and only if:
+     * </h4>
+     * <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>
+     * <h4>
+     * The following attributes may be set when calling this method
+     * </h4>
+     * <ul>
+     * <li> {@link org.apache.directory.fortress.core.rbac.User#userId} - required
+     * <li> {@link org.apache.directory.fortress.core.rbac.User#password}
+     * <li> {@link org.apache.directory.fortress.core.rbac.User#roles} contains a list of RBAC role names authorized for user and targeted for activation within this session.  Default is all authorized RBAC roles will be activated into this Session.
+     * <li> {@link org.apache.directory.fortress.core.rbac.User#adminRoles} contains a list of Admin role names authorized for user and targeted for activation.  Default is all authorized ARBAC roles will be activated into this Session.
+     * <li> {@link org.apache.directory.fortress.core.rbac.User#props} collection of name value pairs collected on behalf of User during signon.  For example hostname:myservername or ip:192.168.1.99
+     * </ul>
+     * <h4>
+     * Notes:
+     * </h4>
+     * <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, see {@link org.apache.directory.fortress.core.rbac.User#setRole(String)}.
+     * </ul>
+     * </p>
+     *
+     * @param user Contains {@link org.apache.directory.fortress.core.rbac.User#userId}, {@link org.apache.directory.fortress.core.rbac.User#password} (optional if {@code isTrusted} is 'true'), optional {@link org.apache.directory.fortress.core.rbac.User#roles}, optional {@link org.apache.directory.fortress.core.rbac.User#adminRoles}
+     * @param isTrusted if true password is not required.
+     * @return Session object will contain authentication result code {@link org.apache.directory.fortress.core.rbac.Session#errorId},
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    @Override
+    public Session createSession( User user, boolean isTrusted )
+        throws SecurityException
+    {
+        String methodName = "createSession";
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        return aDao.createSession( user );
+    }
+
+
+    /**
+     * This function requests the RBAC server to delete the session from cache.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @throws SecurityException in the event runtime error occurs with system.
+     */
+    @Override
+    public void deleteSession( Session session )
+        throws SecurityException
+    {
+        String methodName = "deleteSession";
+        assertContext( CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL );
+        aDao.deleteSession( session );
+    }
+
+
+    /**
+     * This function returns the active roles associated with a session. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return List<UserRole> containing all roles active in user's session.  This will NOT contain inherited roles.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    public List<UserRole> sessionRoles(Session session)
+        throws SecurityException
+    {
+        String methodName = "sessionRoles";
+        assertContext( CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL );
+        return aDao.sessionRoles( session );
+    }
+
+
+    /**
+     * Perform user rbac authorization.  This function returns a Boolean value meaning whether the subject of a given session is
+     * allowed or not to perform a given operation on a given object. The function is valid if and
+     * only if the session is a valid Fortress session, the object is a member of the OBJS data set,
+     * and the operation is a member of the OPS data set. The session's subject has the permission
+     * to perform the operation on that object if and only if that permission is assigned to (at least)
+     * one of the session's active roles. This implementation will verify the roles or userId correspond
+     * to the subject's active roles are registered in the object's access control list.
+     *
+     * @param perm  must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, of permission User is trying to access.
+     * @param session This object must be instantiated by calling {@link AccessMgrImpl#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return True if user has access, false otherwise.
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    @Override
+    public boolean checkAccess( Session session, Permission perm )
+        throws SecurityException
+    {
+        String methodName = "checkAccess";
+        assertContext( CLS_NM, methodName, perm, GlobalErrIds.PERM_NULL );
+        assertContext( CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL );
+        VUtil.assertNotNullOrEmpty( perm.getOpName(), GlobalErrIds.PERM_OPERATION_NULL, getFullMethodName( CLS_NM,
+            methodName ) );
+        VUtil.assertNotNullOrEmpty( perm.getObjName(), GlobalErrIds.PERM_OBJECT_NULL, getFullMethodName( CLS_NM,
+            methodName ) );
+        return aDao.checkAccess( session, perm );
+    }
+
+
+    /**
+     * This function returns the permissions of the session, i.e., the permissions assigned
+     * to its authorized roles. The function is valid if and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return List<Permission> containing permissions (op, obj) active for user's session.
+     * @throws SecurityException in the event runtime error occurs with system.
+     */
+    @Override
+    public List<Permission> sessionPermissions( Session session )
+        throws SecurityException
+    {
+        throw new java.lang.UnsupportedOperationException();
+    }
+
+
+    /**
+     * This function adds a role as an active role of a session whose owner is a given user.
+     * <p>
+     * The function is valid if and only if:
+     * <ul>
+     * <li> the user is a member of the USERS data set
+     * <li> the role is a member of the ROLES data set
+     * <li> the role inclusion does not violate Dynamic Separation of Duty Relationships
+     * <li> the session is a valid Fortress session
+     * <li> the user is authorized to that role
+     * <li> the session is owned by that user.
+     * </ul>
+     * </p>
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @param role object contains the role name, {@link UserRole#name}, to be activated into session.
+     * @throws SecurityException is thrown if user is not allowed to activate or runtime error occurs with system.
+     */
+    @Override
+    public void addActiveRole( Session session, UserRole role )
+        throws SecurityException
+    {
+        String methodName = "addActiveRole";
+        assertContext( CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL );
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        VUtil.assertNotNullOrEmpty( role.getUserId(), GlobalErrIds.USER_ID_NULL,
+            getFullMethodName( CLS_NM, methodName ) );
+        VUtil.assertNotNullOrEmpty( role.getName(), GlobalErrIds.ROLE_NM_NULL, getFullMethodName( CLS_NM,
+            methodName ) );
+        aDao.addActiveRole( session, role );
+    }
+
+
+    /**
+     * This function deletes a role from the active role set of a session owned by a given user.
+     * The function is valid if and only if the user is a member of the USERS data set, the
+     * session object contains a valid Fortress session, the session is owned by the user,
+     * and the role is an active role of that session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @param role object contains the role name, {@link UserRole#name}, to be deactivated.
+     * @throws SecurityException is thrown if user is not allowed to deactivate or runtime error occurs with system.
+     */
+    @Override
+    public void dropActiveRole( Session session, UserRole role )
+        throws SecurityException
+    {
+        String methodName = "dropActiveRole";
+        assertContext( CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL );
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        VUtil.assertNotNullOrEmpty( role.getUserId(), GlobalErrIds.USER_ID_NULL,
+            getFullMethodName( CLS_NM, methodName ) );
+        VUtil.assertNotNullOrEmpty( role.getName(), GlobalErrIds.ROLE_NM_NULL, getFullMethodName( CLS_NM,
+            methodName ) );
+        aDao.dropActiveRole( session, role );
+    }
+}
\ No newline at end of file


[32/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/AccessMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AccessMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/rbac/AccessMgrImpl.java
new file mode 100755
index 0000000..5001b33
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AccessMgrImpl.java
@@ -0,0 +1,439 @@
+/*
+ *   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 org.apache.directory.fortress.core.AccessMgr;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.time.CUtil;
+
+
+/**
+ * Implementation class that performs runtime access control operations on data objects of type Fortress entities
+ * This class performs runtime access control operations on objects that are provisioned RBAC entities
+ * that reside in LDAP directory.  These APIs map directly to similar named APIs specified by ANSI and NIST
+ * RBAC system functions.
+ * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
+ * The RBAC Functional specification describes administrative operations for the creation
+ * and maintenance of RBAC element sets and relations; administrative review functions for
+ * performing administrative queries; and system functions for creating and managing
+ * RBAC attributes on user sessions and making access control decisions.
+ * <p/>
+ * <hr>
+ * <h4>RBAC0 - Core</h4>
+ * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
+ * <p/>
+ * <img src="../doc-files/RbacCore.png">
+ * <hr>
+ * <h4>RBAC1 - General Hierarchical Roles</h4>
+ * Simplifies role engineering tasks using inheritance of one or more parent roles.
+ * <p/>
+ * <img src="../doc-files/RbacHier.png">
+ * <hr>
+ * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+ * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
+ * <p/>
+ * <img src="../doc-files/RbacSSD.png">
+ * <hr>
+ * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+ * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+ * <p/>
+ * <img src="../doc-files/RbacDSD.png">
+ * <hr>
+ * <p/>
+ * This class is NOT thread safe if parent instance variables ({@link #contextId} or {@link #adminSess}) are set.
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class AccessMgrImpl extends Manageable implements AccessMgr
+{
+    private static final String CLS_NM = AccessMgrImpl.class.getName();
+    private static final UserP userP = new UserP();
+    private static final PermP permP = new PermP();
+
+
+    // package private constructor ensures outside classes cannot use:
+    public AccessMgrImpl()
+    {
+    }
+
+
+    /**
+     * Perform user authentication only.  It does not activate RBAC roles in session but will evaluate
+     * password policies.
+     *
+     * @param userId   Contains the userid of the user signing on.
+     * @param password Contains the user's 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.
+     */
+    @Override
+    public Session authenticate( String userId, char[] password )
+        throws SecurityException
+    {
+        String methodName = "authenticate";
+        VUtil.assertNotNullOrEmpty( userId, GlobalErrIds.USER_ID_NULL, getFullMethodName( CLS_NM, methodName ) );
+        VUtil.assertNotNullOrEmpty( password, GlobalErrIds.USER_PW_NULL, getFullMethodName( CLS_NM, methodName ) );
+        User inUser = new User( userId );
+        inUser.setContextId( contextId );
+        // false tells the User Read not to fetch roles.
+        User user = userP.read( inUser, false );
+        user.setPassword( password );
+        user.setContextId( contextId );
+        Session ftSess = userP.authenticate( user );
+        ftSess.setUser( user );
+
+        return ftSess;
+    }
+
+
+    /**
+     * Perform user authentication {@link User#password} and role activations.<br />
+     * This method must be called once per user prior to calling other methods within this class.
+     * The successful result is {@link Session} that contains target user's RBAC {@link User#roles} and Admin role {@link User#adminRoles}.<br />
+     * In addition to checking user password validity it will apply configured password policy checks {@link User#pwPolicy}..<br />
+     * Method may also store parms passed in for audit trail {@link org.apache.directory.fortress.core.rbac.FortEntity}.
+     * <h4> This API will...</h4>
+     * <ul>
+     * <li> authenticate user password if trusted == false.
+     * <li> perform <a href="http://www.openldap.org/">OpenLDAP</a> <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10">password policy evaluation</a>, see {@link org.apache.directory.fortress.core.ldap.openldap.OLPWControlImpl}.
+     * <li> fail for any user who is locked by OpenLDAP's policies {@link User#isLocked()}, regardless of trusted flag being set as parm on API.
+     * <li> evaluate temporal {@link org.apache.directory.fortress.core.util.time.Constraint}(s) on {@link User}, {@link org.apache.directory.fortress.core.rbac.UserRole} and {@link UserAdminRole} entities.
+     * <li> process selective role activations into User RBAC Session {@link User#roles}.
+     * <li> check Dynamic Separation of Duties {@link org.apache.directory.fortress.core.rbac.DSDChecker#validate(Session, org.apache.directory.fortress.core.util.time.Constraint, org.apache.directory.fortress.core.util.time.Time)} on {@link User#roles}.
+     * <li> process selective administrative role activations {@link User#adminRoles}.
+     * <li> return a {@link Session} containing {@link Session#getUser()}, {@link Session#getRoles()} and (if admin user) {@link Session#getAdminRoles()} if everything checks out good.
+     * <li> throw a checked exception that will be {@link org.apache.directory.fortress.core.SecurityException} or its derivation.
+     * <li> throw a {@link SecurityException} for system failures.
+     * <li> throw a {@link org.apache.directory.fortress.core.PasswordException} for authentication and password policy violations.
+     * <li> throw a {@link org.apache.directory.fortress.core.ValidationException} for data validation errors.
+     * <li> throw a {@link org.apache.directory.fortress.core.FinderException} if User id not found.
+     * </ul>
+     * <h4>
+     * The function is valid if and only if:
+     * </h4>
+     * <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>
+     * <h4>
+     * The following attributes may be set when calling this method
+     * </h4>
+     * <ul>
+     * <li> {@link User#userId} - required
+     * <li> {@link User#password}
+     * <li> {@link User#roles} contains a list of RBAC role names authorized for user and targeted for activation within this session.  Default is all authorized RBAC roles will be activated into this Session.
+     * <li> {@link User#adminRoles} contains a list of Admin role names authorized for user and targeted for activation.  Default is all authorized ARBAC roles will be activated into this Session.
+     * <li> {@link User#props} collection of name value pairs collected on behalf of User during signon.  For example hostname:myservername or ip:192.168.1.99
+     * </ul>
+     * <h4>
+     * Notes:
+     * </h4>
+     * <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, see {@link User#setRole(String)}.
+     * </ul>
+     * </p>
+     *
+     * @param user Contains {@link User#userId}, {@link User#password} (optional if {@code isTrusted} is 'true'), optional {@link User#roles}, optional {@link User#adminRoles}
+     * @param isTrusted if true password is not required.
+     * @return Session object will contain authentication result code {@link Session#errorId}, RBAC role activations {@link Session#getRoles()}, Admin Role activations {@link Session#getAdminRoles()},OpenLDAP pw policy codes {@link Session#warningId}, {@link Session#expirationSeconds}, {@link Session#graceLogins} and more.
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    @Override
+    public Session createSession( User user, boolean isTrusted )
+        throws SecurityException
+    {
+        String methodName = "createSession";
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+
+        return userP.createSession( user, isTrusted );
+    }
+
+
+    /**
+     * Perform user rbac authorization.  This function returns a Boolean value meaning whether the subject of a given session is
+     * allowed or not to perform a given operation on a given object. The function is valid if and
+     * only if the session is a valid Fortress session, the object is a member of the OBJS data set,
+     * and the operation is a member of the OPS data set. The session's subject has the permission
+     * to perform the operation on that object if and only if that permission is assigned to (at least)
+     * one of the session's active roles. This implementation will verify the roles or userId correspond
+     * to the subject's active roles are registered in the object's access control list.
+     *
+     * @param perm  must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation, {@link org.apache.directory.fortress.core.rbac.Permission#opName}, of permission User is trying to access.
+     * @param session This object must be instantiated by calling {@link AccessMgrImpl#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
+     * @return True if user has access, false otherwise.
+     * @throws SecurityException in the event of data validation failure, security policy violation or DAO error.
+     */
+    @Override
+    public boolean checkAccess( Session session, Permission perm )
+        throws SecurityException
+    {
+        String methodName = "checkAccess";
+        assertContext( CLS_NM, methodName, perm, GlobalErrIds.PERM_NULL );
+        assertContext( CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL );
+        VUtil.assertNotNullOrEmpty( perm.getOpName(), GlobalErrIds.PERM_OPERATION_NULL,
+            getFullMethodName( CLS_NM, methodName ) );
+        VUtil.assertNotNullOrEmpty( perm.getObjName(), GlobalErrIds.PERM_OBJECT_NULL,
+            getFullMethodName( CLS_NM, methodName ) );
+        CUtil.validateConstraints( session, CUtil.ConstraintType.USER, false );
+        CUtil.validateConstraints( session, CUtil.ConstraintType.ROLE, false );
+        return permP.checkPermission( session, perm );
+    }
+
+
+    /**
+     * This function returns the permissions of the session, i.e., the permissions assigned
+     * to its authorized roles. The function is valid if and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return List<Permission> containing permissions (op, obj) active for user's session.
+     * @throws SecurityException in the event runtime error occurs with system.
+     */
+    @Override
+    public List<Permission> sessionPermissions( Session session )
+        throws SecurityException
+    {
+        String methodName = "sessionPermissions";
+        assertContext( CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL );
+        CUtil.validateConstraints( session, CUtil.ConstraintType.USER, false );
+        CUtil.validateConstraints( session, CUtil.ConstraintType.ROLE, false );
+        return permP.search( session );
+    }
+
+
+    /**
+     * This function returns the active roles associated with a session. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return List<UserRole> containing all roles active in user's session.  This will NOT contain inherited roles.
+     * @throws SecurityException
+     *          is thrown if session invalid or system. error.
+     */
+    @Override
+    public List<UserRole> sessionRoles( Session session )
+        throws SecurityException
+    {
+        String methodName = "sessionRoles";
+        assertContext( CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL );
+        CUtil.validateConstraints( session, CUtil.ConstraintType.USER, false );
+        CUtil.validateConstraints( session, CUtil.ConstraintType.ROLE, false );
+        return session.getRoles();
+    }
+
+
+    /**
+     * This function returns the authorized roles associated with a session based on hierarchical relationships. The function is valid if
+     * and only if the session is a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return Set<String> containing all roles active in user's session.  This will contain inherited roles.
+     * @throws SecurityException is thrown if session invalid or system. error.
+     */
+    @Override
+    public Set<String> authorizedRoles( Session session )
+        throws SecurityException
+    {
+        String methodName = "authorizedRoles";
+        assertContext( CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL );
+        VUtil.assertNotNull( session.getUser(), GlobalErrIds.USER_NULL, CLS_NM + ".authorizedRoles" );
+        CUtil.validateConstraints( session, CUtil.ConstraintType.USER, false );
+        CUtil.validateConstraints( session, CUtil.ConstraintType.ROLE, false );
+        return RoleUtil.getInheritedRoles( session.getRoles(), this.contextId );
+    }
+
+
+    /**
+     * This function adds a role as an active role of a session whose owner is a given user.
+     * <p>
+     * The function is valid if and only if:
+     * <ul>
+     * <li> the user is a member of the USERS data set
+     * <li> the role is a member of the ROLES data set
+     * <li> the role inclusion does not violate Dynamic Separation of Duty Relationships
+     * <li> the session is a valid Fortress session
+     * <li> the user is authorized to that role
+     * <li> the session is owned by that user.
+     * </ul>
+     * </p>
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @param role object contains the role name, {@link UserRole#name}, to be activated into session.
+     * @throws SecurityException is thrown if user is not allowed to activate or runtime error occurs with system.
+     */
+    @Override
+    public void addActiveRole( Session session, UserRole role )
+        throws SecurityException
+    {
+        String methodName = "addActiveRole";
+        assertContext( CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL );
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        role.setUserId( session.getUserId() );
+        List<UserRole> uRoles;
+        List<UserRole> sRoles = session.getRoles();
+        // If session already has role activated log an error and throw an exception:
+        if ( sRoles != null && sRoles.contains( role ) )
+        {
+            String info = getFullMethodName( CLS_NM, methodName ) + " User [" + session.getUserId() + "] Role ["
+                + role.getName() + "] role already activated.";
+            throw new SecurityException( GlobalErrIds.URLE_ALREADY_ACTIVE, info );
+        }
+
+        User inUser = new User( session.getUserId() );
+        inUser.setContextId( this.contextId );
+        User ue = userP.read( inUser, true );
+        uRoles = ue.getRoles();
+        int indx;
+        // Is the role activation target valid for this user?
+        if ( !VUtil.isNotNullOrEmpty( uRoles ) || ( ( indx = uRoles.indexOf( role ) ) == -1 ) )
+        {
+            String info = getFullMethodName( CLS_NM, methodName ) + " Role [" + role.getName() + "] User ["
+                + session.getUserId() + "] role not authorized for user.";
+            throw new SecurityException( GlobalErrIds.URLE_ACTIVATE_FAILED, info );
+        }
+
+        // validate Dynamic Separation of Duty Relations:
+        SDUtil.validateDSD( session, role );
+
+        // set the role to the session:
+        session.setRole( uRoles.get( indx ) );
+
+        // Check role temporal constraints & DSD:
+        CUtil.validateConstraints( session, CUtil.ConstraintType.ROLE, false );
+    }
+
+
+    /**
+     * This function deletes a role from the active role set of a session owned by a given user.
+     * The function is valid if and only if the user is a member of the USERS data set, the
+     * session object contains a valid Fortress session, the session is owned by the user,
+     * and the role is an active role of that session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @param role object contains the role name, {@link UserRole#name}, to be deactivated.
+     * @throws SecurityException is thrown if user is not allowed to deactivate or runtime error occurs with system.
+     */
+    @Override
+    public void dropActiveRole( Session session, UserRole role )
+        throws SecurityException
+    {
+        String methodName = "dropActiveRole";
+        assertContext( CLS_NM, methodName, session, GlobalErrIds.USER_SESS_NULL );
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        role.setUserId( session.getUserId() );
+        List<UserRole> roles = session.getRoles();
+        VUtil
+            .assertNotNull( roles, GlobalErrIds.URLE_DEACTIVE_FAILED, CLS_NM + getFullMethodName( CLS_NM, methodName ) );
+        int indx = roles.indexOf( role );
+        if ( indx != -1 )
+        {
+            roles.remove( role );
+        }
+        else
+        {
+            String info = getFullMethodName( CLS_NM, methodName ) + " Role [" + role.getName() + "] User ["
+                + session.getUserId() + "], not previously activated";
+            throw new SecurityException( GlobalErrIds.URLE_NOT_ACTIVE, info );
+        }
+    }
+
+
+    /**
+     * This function returns the userId value that is contained within the session object.
+     * The function is valid if and only if the session object contains a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return The userId value
+     * @throws SecurityException is thrown if user session not active or runtime error occurs with system.
+     */
+    @Override
+    public String getUserId( Session session )
+        throws SecurityException
+    {
+        assertContext( CLS_NM, "getUserId", session, GlobalErrIds.USER_SESS_NULL );
+        return session.getUserId();
+    }
+
+
+    /**
+     * This function returns the user object that is contained within the session object.
+     * The function is valid if and only if the session object contains a valid Fortress session.
+     *
+     * @param session object contains the user's returned RBAC session from the createSession method.
+     * @return The user value
+     *         Sample User data contained in Session object:
+     *         <ul> <code>Session</code>
+     *         <li> <code>session.getUserId() => demoUser4</code>
+     *         <li> <code>session.getInternalUserId() => be2dd2e:12a82ba707e:-7fee</code>
+     *         <li> <code>session.getMessage() => Fortress checkPwPolicies userId <demouser4> VALIDATION GOOD</code>
+     *         <li> <code>session.getErrorId() => 0</code>
+     *         <li> <code>session.getWarningId() => 11</code>
+     *         <li> <code>session.getExpirationSeconds() => 469831</code>
+     *         <li> <code>session.getGraceLogins() => 0</code>
+     *         <li> <code>session.getIsAuthenticated() => true</code>
+     *         <li> <code>session.getLastAccess() => 1283623680440</code>
+     *         <li> <code>session.getSessionId() => -7410986f:12addeea576:-7fff</code>
+     *         <li>  ------------------------------------------
+     *         <li> <code>User user = session.getUser();</code>
+     *         <ul> <li> <code>user.getUserId() => demoUser4</code>
+     *         <li> <code>user.getInternalId() => be2dd2e:12a82ba707e:-7fee</code>
+     *         <li> <code>user.getCn() => JoeUser4</code>
+     *         <li> <code>user.getDescription() => Demo Test User 4</code>
+     *         <li> <code>user.getOu() => test</code>
+     *         <li> <code>user.getSn() => User4</code>
+     *         <li> <code>user.getBeginDate() => 20090101</code>
+     *         <li> <code>user.getEndDate() => none</code>
+     *         <li> <code>user.getBeginLockDate() => none</code>
+     *         <li> <code>user.getEndLockDate() => none</code>
+     *         <li> <code>user.getDayMask() => 1234567</code>
+     *         <li> <code>user.getTimeout() => 60</code>
+     *         <li> <code>List<UserRole> roles = session.getRoles();</code>
+     *         <ul> <li><code>UserRole userRole = roles.get(i);</code>
+     *         <li> <code>userRole.getName() => role1</code>
+     *         <li> <code>userRole.getBeginTime() => 0000</code>
+     *         <li> <code>userRole.getEndTime() => 0000</code>
+     *         <li> <code>userRole.getBeginDate() => none</code>
+     *         <li> <code>userRole.getEndDate() => none</code>
+     *         <li> <code>userRole.getBeginLockDate() => null</code>
+     *         <li> <code>userRole.getEndLockDate() => null</code>
+     *         <li> <code>userRole.getDayMask() => null</code>
+     *         <li> <code>userRole.getTimeout() => 0</code>
+     *         </ul>
+     *         </ul>
+     *         </ul>
+     * @throws SecurityException is thrown if user session not active or runtime error occurs with system.
+     */
+    @Override
+    public User getUser( Session session )
+        throws SecurityException
+    {
+        assertContext( CLS_NM, "getUser", session, GlobalErrIds.USER_SESS_NULL );
+
+        return session.getUser();
+    }
+}
\ 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/Address.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Address.java b/src/main/java/org/apache/directory/fortress/core/rbac/Address.java
new file mode 100644
index 0000000..150ac76
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Address.java
@@ -0,0 +1,469 @@
+/*
+ *   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.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+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.XmlType;
+
+
+/**
+ * This entity is stored on {@link org.apache.directory.fortress.core.rbac.User} and is used to store postal address information in LDAP.
+ * <p/>
+ * Contains data retrieved from the following LDAP attributes:
+ * <p/>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>postalAddress</code>
+ * <li> <code>st</code>
+ * <li> <code>postalCode</code>
+ * <li> <code>postOfficeBox</code>
+ * <li> <code>c</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortAddress")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "address", propOrder =
+    {
+        "addresses",
+        "city",
+        "state",
+        "country",
+        "postalCode",
+        "postOfficeBox",
+        "building",
+        "departmentNumber",
+        "roomNumber"
+})
+public class Address implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(nillable = true)
+    private List<String> addresses;
+    private String city;
+    private String state;
+    private String country;
+    private String postalCode;
+    private String postOfficeBox;
+    private String building;
+    private String departmentNumber;
+    private String roomNumber;
+
+
+    /**
+     * This attribute is bound for {@code postalAddress} attribute on {@code organizationalPerson} object class.
+     *
+     * @param address contains a String value containing address line that is bound for multi-occurring {@code postalAddress} attribute.
+     */
+    public void setAddress( String address )
+    {
+        if ( addresses == null )
+        {
+            addresses = new ArrayList<>();
+        }
+
+        addresses.add( address );
+    }
+
+
+    /**
+     * Return an ArrayList of type String that contains zero or more values retrieved from {@code postalAddress} attribute from {@code organizationalPerson} object class.
+     *
+     * @return a non-null ArrayList of type String that contains zero or more address lines associated with the user.
+     */
+    public List<String> getAddresses()
+    {
+        if ( addresses == null )
+        {
+            addresses = new ArrayList<>();
+        }
+
+        return addresses;
+    }
+
+
+    /**
+     * Set an ArrayList of type String that contains one or more values bound for {@code postalAddress} attribute on {@code organizationalPerson} object class.
+     *
+     * @param addresses contains ArrayList of type String with one or more address lines associated with the user.
+     */
+    public void setAddresses( List<String> addresses )
+    {
+        this.addresses = addresses;
+    }
+
+
+    /**
+     * Return a String that contains a value retrieved from {@code l} (location) attribute from {@code organizationalPerson} object class.
+     *
+     * @return a String that contains city associated with the user.
+     */
+    public String getCity()
+    {
+        return city;
+    }
+
+
+    /**
+     * Accept a String that contains a value {@code l} (location) bound for {@code organizationalPerson} object class.
+     *
+     * @param city associated with the user.
+     */
+    public void setCity( String city )
+    {
+        this.city = city;
+    }
+
+
+    /**
+     * Return a String that contains a value retrieved from {@code st} (state) attribute from {@code organizationalPerson} object class.
+     *
+     * @return a String that contains state associated with the user.
+     */
+    public String getState()
+    {
+        return state;
+    }
+
+
+    /**
+     * Accept a String that contains a value {@code st} (state) bound for {@code organizationalPerson} object class.
+     *
+     * @param state associated with the user.
+     */
+    public void setState( String state )
+    {
+        this.state = state;
+    }
+
+
+    /**
+     * TODO: Add support for this attribute:
+     * Return a String that contains a value retrieved from {@code c} (country) attribute from {@code c} object class.
+     *
+     * @return a String that contains country associated with the user.
+     */
+    public String getCountry()
+    {
+        return country;
+    }
+
+
+    /**
+     * TODO: Add support for this attribute:
+     * Accept a String that contains a value {@code c} (country) bound for {@code c} object class.
+     *
+     * @param country associated with the user.
+     */
+    public void setCountry( String country )
+    {
+        this.country = country;
+    }
+
+
+    /**
+     * Return a String that contains a value retrieved from {@code postalCode} attribute from {@code organizationalPerson} object class.
+     *
+     * @return a String that contains postalCode associated with the user.
+     */
+    public String getPostalCode()
+    {
+        return postalCode;
+    }
+
+
+    /**
+     * Accept a String that contains a value {@code postalCode} bound for {@code organizationalPerson} object class.
+     *
+     * @param postalCode associated with the user.
+     */
+    public void setPostalCode( String postalCode )
+    {
+        this.postalCode = postalCode;
+    }
+
+
+    /**
+     * Return a String that contains a value retrieved from {@code postOfficeBox} attribute from {@code organizationalPerson} object class.
+     *
+     * @return a String that contains postOfficeBox associated with the user.
+     */
+    public String getPostOfficeBox()
+    {
+        return postOfficeBox;
+    }
+
+
+    /**
+     * Accept a String that contains a value {@code postOfficeBox} bound for {@code organizationalPerson} object class.
+     *
+     * @param postOfficeBox associated with the user.
+     */
+    public void setPostOfficeBox( String postOfficeBox )
+    {
+        this.postOfficeBox = postOfficeBox;
+    }
+
+
+    /**
+     * Return a String that contains a value retrieved from {@code building} attribute from {@code organizationalPerson} object class.
+     *
+     * @return a String that contains building associated with the user.
+     */
+    public String getBuilding()
+    {
+        return building;
+    }
+
+
+    /**
+     * Accept a String that contains a value {@code building} bound for {@code organizationalPerson} object class.
+     *
+     * @param postOfficeBox associated with the user.
+     */
+    public void setBuilding( String building )
+    {
+        this.building = building;
+    }
+
+
+    /**
+     * Return a String that contains a value retrieved from {@code departmentNumber} attribute from {@code organizationalPerson} object class.
+     *
+     * @return a String that contains departmentNumber associated with the user.
+     */
+    public String getDepartmentNumber()
+    {
+        return departmentNumber;
+    }
+
+
+    /**
+     * Accept a String that contains a value {@code departmentNumber} bound for {@code inetOrgperson} object class.
+     *
+     * @param departmentNumber associated with the user.
+     */
+    public void setDepartmentNumber( String departmentNumber )
+    {
+        this.departmentNumber = departmentNumber;
+    }
+
+
+    /**
+     * Return a String that contains a value retrieved from {@code roomNumber} attribute from {@code organizationalPerson} object class.
+     *
+     * @return a String that contains roomNumber associated with the user.
+     */
+    public String getRoomNumber()
+    {
+        return roomNumber;
+    }
+
+
+    /**
+     * Accept a String that contains a value {@code roomNumber} bound for {@code inetOrgperson} object class.
+     *
+     * @param roomNumber associated with the user.
+     */
+    public void setRoomNumber( String roomNumber )
+    {
+        this.roomNumber = roomNumber;
+    }
+
+
+    /**
+     * Override the standard equals on object to use the attributes of this class.
+     *
+     * @param o
+     * @return boolean value
+     */
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o )
+        {
+            return true;
+        }
+
+        if ( ( o == null ) || ( getClass() != o.getClass() ) )
+        {
+            return false;
+        }
+
+        Address address = ( Address ) o;
+
+        if ( addresses != null ? !addresses.equals( address.addresses ) : address.addresses != null )
+        {
+            return false;
+        }
+
+        if ( building != null ? !building.equals( address.building ) : address.building != null )
+        {
+            return false;
+        }
+
+        if ( city != null ? !city.equals( address.city ) : address.city != null )
+        {
+            return false;
+        }
+
+        if ( country != null ? !country.equals( address.country ) : address.country != null )
+        {
+            return false;
+        }
+
+        if ( departmentNumber != null ? !departmentNumber.equals( address.departmentNumber )
+            : address.departmentNumber != null )
+        {
+            return false;
+        }
+
+        if ( postOfficeBox != null ? !postOfficeBox.equals( address.postOfficeBox ) : address.postOfficeBox != null )
+        {
+            return false;
+        }
+
+        if ( postalCode != null ? !postalCode.equals( address.postalCode ) : address.postalCode != null )
+        {
+            return false;
+        }
+
+        if ( roomNumber != null ? !roomNumber.equals( address.roomNumber ) : address.roomNumber != null )
+        {
+            return false;
+        }
+
+        if ( state != null ? !state.equals( address.state ) : address.state != null )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Override the standard hashCode on object to use attributes of class.
+     *
+     * @return int
+     */
+    @Override
+    public int hashCode()
+    {
+        int result = addresses != null ? addresses.hashCode() : 0;
+        result = 31 * result + ( city != null ? city.hashCode() : 0 );
+        result = 31 * result + ( state != null ? state.hashCode() : 0 );
+        result = 31 * result + ( country != null ? country.hashCode() : 0 );
+        result = 31 * result + ( postalCode != null ? postalCode.hashCode() : 0 );
+        result = 31 * result + ( postOfficeBox != null ? postOfficeBox.hashCode() : 0 );
+        result = 31 * result + ( building != null ? building.hashCode() : 0 );
+        result = 31 * result + ( departmentNumber != null ? departmentNumber.hashCode() : 0 );
+        result = 31 * result + ( roomNumber != null ? roomNumber.hashCode() : 0 );
+
+        return result;
+    }
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append( "Address object: \n" );
+
+        if ( roomNumber != null )
+        {
+            sb.append( "    roomNumber :" ).append( roomNumber ).append( '\n' );
+        }
+
+        if ( departmentNumber != null )
+        {
+            sb.append( "    departmentNumber :" ).append( departmentNumber ).append( '\n' );
+        }
+
+        if ( building != null )
+        {
+            sb.append( "    building :" ).append( building ).append( '\n' );
+        }
+
+        if ( addresses != null )
+        {
+            sb.append( "    addresses : " );
+
+            boolean isFirst = true;
+
+            for ( String addr : addresses )
+            {
+                if ( isFirst )
+                {
+                    isFirst = false;
+                }
+                else
+                {
+                    sb.append( ", " );
+                }
+
+                sb.append( addr );
+            }
+
+            sb.append( '\n' );
+        }
+
+        if ( city != null )
+        {
+            sb.append( "    city :" ).append( city ).append( '\n' );
+        }
+
+        if ( postalCode != null )
+        {
+            sb.append( "    postalCode :" ).append( postalCode ).append( '\n' );
+        }
+
+        if ( postOfficeBox != null )
+        {
+            sb.append( "    postOfficeBox :" ).append( postOfficeBox ).append( '\n' );
+        }
+
+        if ( state != null )
+        {
+            sb.append( "    state :" ).append( state ).append( '\n' );
+        }
+
+        if ( country != null )
+        {
+            sb.append( "    country :" ).append( country ).append( '\n' );
+        }
+
+        return sb.toString();
+    }
+}
\ No newline at end of file


[38/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cli/Options.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cli/Options.java b/src/main/java/org/apache/directory/fortress/core/cli/Options.java
new file mode 100755
index 0000000..58dcbdd
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cli/Options.java
@@ -0,0 +1,698 @@
+/*
+ *   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.cli;
+
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.ldap.group.Group;
+import org.apache.directory.fortress.core.rbac.Address;
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.PermObj;
+import org.apache.directory.fortress.core.rbac.Permission;
+import org.apache.directory.fortress.core.rbac.Relationship;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.SDSet;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.time.Constraint;
+
+import java.util.Vector;
+
+/**
+ * This converts between Fortress entities and the JArg Options.  It contains attributes passed from JArgs command interpreter.
+ *
+ * @author Shawn McKinney
+ */
+public class Options implements java.io.Serializable
+{
+    final CmdLineParser parser;
+    final CmdLineParser.Option userId;
+    final CmdLineParser.Option password;
+    final CmdLineParser.Option newPassword;
+    final CmdLineParser.Option ou;
+    final CmdLineParser.Option pwPolicy;
+    final CmdLineParser.Option cn;
+    final CmdLineParser.Option sn;
+    final CmdLineParser.Option description;
+    final CmdLineParser.Option title;
+    final CmdLineParser.Option employeeType;
+    final CmdLineParser.Option beginTime;
+    final CmdLineParser.Option endTime;
+    final CmdLineParser.Option beginDate;
+    final CmdLineParser.Option endDate;
+    final CmdLineParser.Option beginLockDate;
+    final CmdLineParser.Option endLockDate;
+    final CmdLineParser.Option dayMask;
+    final CmdLineParser.Option name;
+    final CmdLineParser.Option timeout;
+    final CmdLineParser.Option properties;
+    final CmdLineParser.Option roleAssigns;
+    final CmdLineParser.Option role;
+    final CmdLineParser.Option adminRoleAssigns;
+    final CmdLineParser.Option type;
+    final CmdLineParser.Option opName;
+    final CmdLineParser.Option ascendant;
+    final CmdLineParser.Option descendant;
+    final CmdLineParser.Option cardinality;
+    final CmdLineParser.Option osPs;
+    final CmdLineParser.Option osUs;
+    final CmdLineParser.Option beginRange;
+    final CmdLineParser.Option endRange;
+    final CmdLineParser.Option beginInclusive;
+    final CmdLineParser.Option endInclusive;
+    final CmdLineParser.Option phones;
+    final CmdLineParser.Option mobiles;
+    final CmdLineParser.Option emails;
+    final CmdLineParser.Option address;
+    final CmdLineParser.Option state;
+    final CmdLineParser.Option city;
+    final CmdLineParser.Option postalCode;
+    final CmdLineParser.Option postalOfficeBox;
+    final CmdLineParser.Option protocol;
+    final CmdLineParser.Option member;
+
+
+    /**
+     * @param parser
+     */
+    public Options(CmdLineParser parser)
+    {
+        this.parser = parser;
+        this.userId = parser.addStringOption('u', "userId");
+        this.password = parser.addStringOption('p', "password");
+        this.newPassword = parser.addStringOption('V', "newpassword");
+        this.ou = parser.addStringOption('o', "orgUnit");
+        this.pwPolicy = parser.addStringOption('w', "pwPolicy");
+        this.cn = parser.addStringOption('c', "cn");
+        this.sn = parser.addStringOption('s', "sn");
+        this.description = parser.addStringOption('d', "description");
+        this.beginTime = parser.addStringOption('b', "beginTime");
+        this.endTime = parser.addStringOption('e', "endTime");
+        this.beginDate = parser.addStringOption('B', "beginDate");
+        this.endDate = parser.addStringOption('E', "endDate");
+        this.beginLockDate = parser.addStringOption('l', "beginLockDate");
+        this.endLockDate = parser.addStringOption('N', "endLockDate");
+        this.dayMask = parser.addStringOption('m', "dayMask");
+        this.name = parser.addStringOption('n', "name");
+        this.timeout = parser.addStringOption('t', "timeout");
+        this.properties = parser.addStringOption('v', "properties");
+        this.roleAssigns = parser.addStringOption('r', "roles");
+        this.role = parser.addStringOption('R', "role");
+        this.adminRoleAssigns = parser.addStringOption('a', "adminRoles");
+        this.type = parser.addStringOption('T', "type");
+        this.opName = parser.addStringOption('O', "opName");
+        this.ascendant = parser.addStringOption('A', "ascendant");
+        this.descendant = parser.addStringOption('D', "descendant");
+        this.cardinality = parser.addStringOption('C', "cardinality");
+        this.osPs = parser.addStringOption('P', "osPs");
+        this.osUs = parser.addStringOption('U', "osUs");
+        this.beginRange = parser.addStringOption('x', "beginRange");
+        this.endRange = parser.addStringOption('w', "endRange");
+        this.beginInclusive = parser.addStringOption('y', "beginInclusive");
+        this.endInclusive = parser.addStringOption('z', "endInclusive");
+        this.phones = parser.addStringOption('y', "phones");
+        this.mobiles = parser.addStringOption('Y', "mobiles");
+        this.emails = parser.addStringOption('@', "emails");
+        this.address = parser.addStringOption('>', "address");
+        this.state = parser.addStringOption('<', "state");
+        this.city = parser.addStringOption('3', "city");
+        this.postalCode = parser.addStringOption('z', "postalCode");
+        this.postalOfficeBox = parser.addStringOption('2', "postalOfficeBox");
+        this.title = parser.addStringOption('3', "title");
+        this.employeeType = parser.addStringOption('4', "employeeType");
+        this.protocol = parser.addStringOption('X', "protocol");
+        this.member = parser.addStringOption('M', "member");
+    }
+
+    /**
+     */
+    public SDSet getSdSet()
+    {
+        SDSet sdSet = new SDSet();
+        sdSet.setName(getName());
+        sdSet.setDescription(getDescription());
+        updateRoleAssigns(sdSet);
+        try
+        {
+            Integer cardinality = new Integer(getCardinality());
+            sdSet.setCardinality(cardinality);
+        }
+        catch (NumberFormatException ne)
+        {
+            // default is '2'.
+            sdSet.setCardinality(2);
+        }
+        return sdSet;
+    }
+
+    /**
+     */
+    public OrgUnit getOrgUnit()
+    {
+        OrgUnit orgUnit = new OrgUnit();
+        orgUnit.setName(getName());
+        orgUnit.setDescription(getDescription());
+        return orgUnit;
+    }
+
+    /**
+     */
+    public Group getGroup()
+    {
+        Group group = new Group();
+        group.setName( getName() );
+        group.setDescription( getDescription() );
+        group.setProtocol( getProtocol() );
+        updateAssigns(group);
+        updateProperties(group);
+        return group;
+    }
+
+    /**
+     */
+    public Role getRole()
+    {
+        Role role = new Role();
+        role.setDescription(getDescription());
+        updateTemporal(role);
+        return role;
+    }
+
+    /**
+     */
+    public AdminRole getAdminRole()
+    {
+        AdminRole role = new AdminRole();
+        role.setDescription(getDescription());
+        role.setBeginRange(getBeginRange());
+        role.setEndRange(getEndRange());
+        Boolean bVal = Boolean.valueOf(getBeginInclusive());
+        role.setBeginInclusive(bVal);
+        bVal = Boolean.valueOf(getEndInclusive());
+        role.setEndInclusive(bVal);
+        updateOsPs(role);
+        updateOsUs(role);
+        updateTemporal(role);
+        return role;
+    }
+
+    /**
+     */
+    public Relationship getRelationship()
+    {
+        Relationship relationship = new Relationship();
+        relationship.setChild(getDescendant());
+        relationship.setParent(getAscendant());
+        return relationship;
+    }
+
+    /**
+     */
+    public PermObj getPermObj()
+    {
+        PermObj permObj = new PermObj();
+        permObj.setObjName( getName() );
+        permObj.setDescription(getDescription());
+        permObj.setOu(getOu());
+        permObj.setType(getType());
+        updateProperties(permObj);
+        return permObj;
+    }
+
+    public Permission getPermission()
+    {
+        Permission perm = new Permission();
+        perm.setObjName( getName() );
+        perm.setOpName(getOpName());
+        updateRoleAssigns(perm);
+        updateProperties(perm);
+        perm.setType(getType());
+        return perm;
+    }
+
+    /**
+     */
+    public User getUser()
+    {
+        User user = new User();
+        user.setUserId(getUserId());
+        user.setPassword(getPassword());
+        user.setOu(getOu());
+        user.setPwPolicy(getPwPolicy());
+        user.setCn(getCn());
+        user.setSn(getSn());
+        user.setDescription(getDescription());
+        user.setTitle(getTitle());
+        user.setEmployeeType(getEmployeeType());
+        updateTemporal(user);
+        updateProperties(user);
+        updateRoleAssigns(user);
+        updateAdminRoleAssigns(user);
+        updatePhones(user);
+        updateMobiles(user);
+        updateEmails(user);
+        updateAddress(user);
+        return user;
+    }
+
+    private void updateTemporal(Constraint constraint)
+    {
+        constraint.setBeginTime(getBeginTime());
+        constraint.setEndTime(getEndTime());
+        constraint.setBeginDate(getBeginDate());
+        constraint.setEndDate(getEndDate());
+        constraint.setBeginLockDate(getBeginLockDate());
+        constraint.setEndLockDate(getEndLockDate());
+        constraint.setDayMask(getDayMask());
+        constraint.setName(getName());
+        try
+        {
+            Integer to = new Integer(getTimeout());
+            constraint.setTimeout(to);
+        }
+        catch (NumberFormatException ne)
+        {
+            constraint.setTimeout(0);
+        }
+    }
+
+    public String getUserId()
+    {
+        return (String) parser.getOptionValue(userId);
+    }
+
+    public char[] getPassword()
+    {
+        char[] pw = null;
+        String szPw = (String) parser.getOptionValue(password);
+        if (VUtil.isNotNullOrEmpty(szPw))
+        {
+            pw = szPw.toCharArray();
+        }
+        return pw;
+    }
+
+    public char[] getNewPassword()
+    {
+        char[] pw = null;
+        String szPw = (String) parser.getOptionValue(newPassword);
+        if (VUtil.isNotNullOrEmpty(szPw))
+        {
+            pw = szPw.toCharArray();
+        }
+        return pw;
+    }
+
+    private void updateProperties(User user)
+    {
+        Vector fractionValues = parser.getOptionValues(properties);
+        if (fractionValues != null)
+        {
+            for (Object raw : fractionValues)
+            {
+                String szRaw = (String) raw;
+                int indx = szRaw.indexOf(GlobalIds.PROP_SEP);
+                if (indx >= 1)
+                {
+                    user.addProperty(szRaw.substring(0, indx), szRaw.substring(indx + 1));
+                }
+            }
+        }
+    }
+
+    private void updateProperties(PermObj permObj)
+    {
+        Vector fractionValues = parser.getOptionValues(properties);
+        if (fractionValues != null)
+        {
+            for (Object raw : fractionValues)
+            {
+                String szRaw = (String) raw;
+                int indx = szRaw.indexOf(GlobalIds.PROP_SEP);
+                if (indx >= 1)
+                {
+                    permObj.addProperty(szRaw.substring(0, indx), szRaw.substring(indx + 1));
+                }
+            }
+        }
+    }
+
+    private void updateProperties(Permission perm)
+    {
+        Vector fractionValues = parser.getOptionValues(properties);
+        if (fractionValues != null)
+        {
+            for (Object raw : fractionValues)
+            {
+                String szRaw = (String) raw;
+                int indx = szRaw.indexOf(GlobalIds.PROP_SEP);
+                if (indx >= 1)
+                {
+                    perm.addProperty(szRaw.substring(0, indx), szRaw.substring(indx + 1));
+                }
+            }
+        }
+    }
+
+    private void updateProperties(Group group)
+    {
+        Vector fractionValues = parser.getOptionValues(properties);
+        if (fractionValues != null)
+        {
+            for (Object raw : fractionValues)
+            {
+                String szRaw = (String) raw;
+                int indx = szRaw.indexOf("=");
+                if (indx >= 1)
+                {
+                    group.addProperty(szRaw.substring(0, indx), szRaw.substring(indx + 1));
+                }
+            }
+        }
+    }
+
+    private void updateAssigns(Group group)
+    {
+        Vector fractionValues = parser.getOptionValues(member);
+        if (fractionValues != null)
+        {
+            for (Object raw : fractionValues)
+            {
+                String szRaw = (String) raw;
+                group.setMember( szRaw );
+            }
+        }
+    }
+
+    private void updateRoleAssigns(User user)
+    {
+        Vector fractionValues = parser.getOptionValues(roleAssigns);
+        if (fractionValues != null)
+        {
+            for (Object raw : fractionValues)
+            {
+                String szRaw = (String) raw;
+                user.setRole(szRaw);
+            }
+        }
+    }
+
+    private void updateRoleAssigns(Permission perm)
+    {
+        Vector fractionValues = parser.getOptionValues(roleAssigns);
+        if (fractionValues != null)
+        {
+            for (Object raw : fractionValues)
+            {
+                String szRaw = (String) raw;
+                perm.setRole(szRaw);
+            }
+        }
+    }
+
+    private void updateAdminRoleAssigns(User user)
+    {
+        Vector fractionValues = parser.getOptionValues(adminRoleAssigns);
+        if (fractionValues != null)
+        {
+            for (Object raw : fractionValues)
+            {
+                String szRaw = (String) raw;
+                user.setAdminRole(szRaw);
+            }
+        }
+    }
+
+    private void updateRoleAssigns(SDSet sdSet)
+    {
+        Vector fractionValues = parser.getOptionValues(roleAssigns);
+        if (fractionValues != null)
+        {
+            for (Object raw : fractionValues)
+            {
+                String szRaw = (String) raw;
+                sdSet.addMember(szRaw);
+            }
+        }
+    }
+
+    private void updateOsPs(AdminRole role)
+    {
+        Vector fractionValues = parser.getOptionValues(osPs);
+        if (fractionValues != null)
+        {
+            for (Object raw : fractionValues)
+            {
+                String szRaw = (String) raw;
+                role.setOsP(szRaw);
+            }
+        }
+    }
+
+    private void updateOsUs(AdminRole role)
+    {
+        Vector fractionValues = parser.getOptionValues(osPs);
+        if (fractionValues != null)
+        {
+            for (Object raw : fractionValues)
+            {
+                String szRaw = (String) raw;
+                role.setOsU(szRaw);
+            }
+        }
+    }
+
+    private void updatePhones(User user)
+    {
+        Vector fractionValues = parser.getOptionValues(phones);
+        if (fractionValues != null)
+        {
+            for (Object val : fractionValues)
+            {
+                String number = (String) val;
+                user.setPhone(number);
+            }
+        }
+    }
+
+    private void updateMobiles(User user)
+    {
+        Vector fractionValues = parser.getOptionValues(mobiles);
+        if (fractionValues != null)
+        {
+            for (Object val : fractionValues)
+            {
+                String number = (String) val;
+                user.setMobile(number);
+            }
+        }
+    }
+
+    private void updateEmails(User user)
+    {
+        Vector fractionValues = parser.getOptionValues(emails);
+        if (fractionValues != null)
+        {
+            for (Object val : fractionValues)
+            {
+                String email = (String) val;
+                user.setPhone(email);
+            }
+        }
+    }
+
+    private void updateAddress(User user)
+    {
+        Address uAddr = user.getAddress();
+        Vector fractionValues = parser.getOptionValues(address);
+        if (fractionValues != null)
+        {
+            for (Object val : fractionValues)
+            {
+                String szAddress = (String) val;
+                uAddr.setAddress(szAddress);
+            }
+        }
+        uAddr.setCity(getCity());
+        uAddr.setState(getState());
+        uAddr.setPostalCode(getPostalCode());
+        uAddr.setPostOfficeBox(getPostOfficeBox());
+    }
+
+    String getState()
+    {
+        return (String) parser.getOptionValue(state);
+    }
+
+    String getCity()
+    {
+        return (String) parser.getOptionValue(city);
+    }
+
+    String getPostalCode()
+    {
+        return (String) parser.getOptionValue(postalCode);
+    }
+
+    String getPostOfficeBox()
+    {
+        return (String) parser.getOptionValue(postalOfficeBox);
+    }
+
+    String getOu()
+    {
+        return (String) parser.getOptionValue(ou);
+    }
+
+    String getPwPolicy()
+    {
+        return (String) parser.getOptionValue(pwPolicy);
+    }
+
+    String getCn()
+    {
+        return (String) parser.getOptionValue(cn);
+    }
+
+    String getSn()
+    {
+        return (String) parser.getOptionValue(sn);
+    }
+
+    String getDescription()
+    {
+        return (String) parser.getOptionValue(description);
+    }
+
+    String getTitle()
+    {
+        return (String) parser.getOptionValue(title);
+    }
+
+    String getEmployeeType()
+    {
+        return (String) parser.getOptionValue(employeeType);
+    }
+
+    String getBeginTime()
+    {
+        return (String) parser.getOptionValue(beginTime);
+    }
+
+    String getEndTime()
+    {
+        return (String) parser.getOptionValue(endTime);
+    }
+
+    String getBeginDate()
+    {
+        return (String) parser.getOptionValue(beginDate);
+    }
+
+    String getEndDate()
+    {
+        return (String) parser.getOptionValue(endDate);
+    }
+
+    String getBeginLockDate()
+    {
+        return (String) parser.getOptionValue(beginLockDate);
+    }
+
+    String getEndLockDate()
+    {
+        return (String) parser.getOptionValue(endLockDate);
+    }
+
+    String getDayMask()
+    {
+        return (String) parser.getOptionValue(dayMask);
+    }
+
+    String getRoleNm()
+    {
+        return (String) parser.getOptionValue(role);
+    }
+
+    String getName()
+    {
+        return (String) parser.getOptionValue(name);
+    }
+
+    String getTimeout()
+    {
+        return (String) parser.getOptionValue(timeout);
+    }
+
+    String getType()
+    {
+        return (String) parser.getOptionValue(type);
+    }
+
+    String getOpName()
+    {
+        return (String) parser.getOptionValue(opName);
+    }
+
+    String getAscendant()
+    {
+        return (String) parser.getOptionValue(ascendant);
+    }
+
+    String getDescendant()
+    {
+        return (String) parser.getOptionValue(descendant);
+    }
+
+    String getCardinality()
+    {
+        return (String) parser.getOptionValue(cardinality);
+    }
+
+    String getBeginRange()
+    {
+        return (String) parser.getOptionValue(beginRange);
+    }
+
+    String getEndRange()
+    {
+        return (String) parser.getOptionValue(endRange);
+    }
+
+    String getBeginInclusive()
+    {
+        return (String) parser.getOptionValue(beginInclusive);
+    }
+
+    String getEndInclusive()
+    {
+        return (String) parser.getOptionValue(endInclusive);
+    }
+
+    String getProtocol()
+    {
+        return (String) parser.getOptionValue(protocol);
+    }
+
+    String getMember()
+    {
+        return (String) parser.getOptionValue(member);
+    }
+}


[31/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/AdminMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AdminMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/rbac/AdminMgrImpl.java
new file mode 100755
index 0000000..c27318b
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AdminMgrImpl.java
@@ -0,0 +1,1638 @@
+/*
+ *   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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.AdminMgr;
+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.util.attr.VUtil;
+import org.apache.directory.fortress.core.util.time.CUtil;
+
+
+/**
+ * This class performs administrative functions to provision Fortress RBAC entities into the LDAP directory.  These APIs
+ * map directly to similar named APIs specified by ANSI and NIST RBAC models.
+ * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
+ * The RBAC Functional specification describes administrative operations for the creation
+ * and maintenance of RBAC element sets and relations; administrative review functions for
+ * performing administrative queries; and system functions for creating and managing
+ * RBAC attributes on user sessions and making access control decisions.
+ * <p/>
+ * <hr>
+ * <h4>RBAC0 - Core</h4>
+ * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to
+ * add, update, delete identity data and perform identity and access control decisions during runtime operations.
+ * <p/>
+ * <img src="../doc-files/RbacCore.png">
+ * <hr>
+ * <h4>RBAC1 - General Hierarchical Roles</h4>
+ * Simplifies role engineering tasks using inheritance of one or more parent roles.
+ * <p/>
+ * <img src="../doc-files/RbacHier.png">
+ * <hr>
+ * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
+ * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting
+ * which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which
+ * help enterprises meet strict compliance regulations.
+ * <p/>
+ * <img src="../doc-files/RbacSSD.png">
+ * <hr>
+ * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
+ * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies
+ * that facilitate authorization dual control and two man policy restrictions during runtime security checks.
+ * <p/>
+ * <img src="../doc-files/RbacDSD.png">
+ * <hr>
+ * <p/>
+ * This class is NOT thread safe if parent instance variables ({@link #contextId} or {@link #adminSess}) are set.
+ *
+ * @author Shawn McKinney
+ */
+public final class AdminMgrImpl extends Manageable implements AdminMgr
+{
+    private static final String CLS_NM = AdminMgrImpl.class.getName();
+    private static final AdminRoleP adminP = new AdminRoleP();
+    private static final PermP permP = new PermP();
+    private static final RoleP roleP = new RoleP();
+    private static final SdP sdP = new SdP();
+    private static final UserP userP = new UserP();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+
+    // package private constructor ensures outside classes cannot use:
+    AdminMgrImpl()
+    {
+    }
+
+
+    /**
+     * This command creates a new RBAC user. The command is valid only if the new user is
+     * not already a member of the USERS data set. The USER data set is updated. The new user
+     * does not own any session at the time of its creation.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#userId} - maps to INetOrgPerson uid</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#password} - used to authenticate the User</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#ou} - contains the name of an already existing User OU node</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#pwPolicy} - contains the name of an already existing OpenLDAP password policy node</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#cn} - maps to INetOrgPerson common name attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#sn} - maps to INetOrgPerson surname attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#description} - maps to INetOrgPerson description attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#title} - maps to INetOrgPerson title attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#employeeType} - maps to INetOrgPerson employeeType attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#phones} * - multi-occurring attribute maps to organizationalPerson telephoneNumber
+     * attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#mobiles} * - multi-occurring attribute maps to INetOrgPerson mobile attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#emails} * - multi-occurring attribute maps to INetOrgPerson mail attribute</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#address} * - multi-occurring attribute maps to organizationalPerson postalAddress, st, l,
+     * postalCode, postOfficeBox attributes</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#beginTime} - HHMM - determines begin hour user may activate session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#endTime} - HHMM - determines end hour user may activate session.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#beginDate} - YYYYMMDD - determines date when user may sign on</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#endDate} - YYYYMMDD - indicates latest date user may sign on</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of user may sign on</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#timeout} - number in seconds of session inactivity time allowed</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.User#props} * - multi-occurring attribute contains property key and values are separated with a ':'
+     * .  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param user User entity must contain {@link org.apache.directory.fortress.core.rbac.User#userId} and {@link org.apache.directory.fortress.core.rbac.User#ou} (required) and optional {@link
+     * org.apache.directory.fortress.core.rbac.User#description},{@link org.apache.directory.fortress.core.rbac.User#roles} and many others.
+     * @return Returns entity containing user data that was added.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public User addUser( User user ) throws SecurityException
+    {
+        String methodName = "addUser";
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        setEntitySession( CLS_NM, methodName, user );
+
+        // Add the User record to ldap.
+        return userP.add( user );
+    }
+
+
+    /**
+     * This command disables an existing user in the RBAC database. The command is valid
+     * if and only if the user to be disabled is a member of the USERS data set. The USERS and
+     * UA data sets and the assigned_users function are updated.
+     * Method performs a "soft" delete.  It performs the following:
+     * - sets the user status to "deleted"
+     * - deassigns all roles from the user
+     * - locks the user's password in LDAP
+     * - revokes all perms that have been granted to user entity.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user Contains the {@link User#userId} of the User targeted for deletion.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void disableUser( User user ) throws SecurityException
+    {
+        String methodName = "disableUser";
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        setEntitySession( CLS_NM, methodName, user );
+        // set the user's status to "deleted"
+        String userDn = userP.softDelete( user );
+        // lock the user out of ldap.
+        userP.lock( user );
+        // remove the userId attribute from any granted permission operations (if applicable).
+        permP.remove( user );
+        // remove the user dn occupant attribute from assigned ldap role entities.
+        roleP.removeOccupant( userDn, this.contextId );
+        // remove the user dn occupant attribute from assigned ldap adminRole entities.
+        adminP.removeOccupant( userDn, user.getContextId() );
+    }
+
+
+    /**
+     * This command deletes an existing user from the RBAC database. The command is valid
+     * if and only if the user to be deleted is a member of the USERS data set. The USERS and
+     * UA data sets and the assigned_users function are updated.
+     * 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.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user Contains the {@link User#userId} of the User targeted for deletion.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteUser( User user ) throws SecurityException
+    {
+        String methodName = "deleteUser";
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        setEntitySession( CLS_NM, methodName, user );
+        // remove the userId attribute from any granted permission operations (if applicable).
+        permP.remove( user );
+        // remove the user inetOrgPerson object from ldap.
+        String userDn = userP.delete( user );
+        // remove the user dn occupant attribute from assigned ldap role entities.
+        roleP.removeOccupant( userDn, this.contextId );
+        // remove the user dn occupant attribute from assigned ldap adminRole entities.
+        adminP.removeOccupant( userDn, user.getContextId() );
+    }
+
+
+    /**
+     * This method performs an update on User entity in directory.  Prior to making this call the entity must exist in
+     * directory.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link User#password} - used to authenticate the User</li>
+     * <li>{@link User#ou} - contains the name of an already existing User OU node</li>
+     * <li>{@link User#pwPolicy} - contains the name of an already existing OpenLDAP password policy node</li>
+     * <li>{@link User#cn} - maps to INetOrgPerson common name attribute</li>
+     * <li>{@link User#sn} - maps to INetOrgPerson surname attribute</li>
+     * <li>{@link User#description} - maps to INetOrgPerson description attribute</li>
+     * <li>{@link User#phones} * - multi-occurring attribute maps to organizationalPerson telephoneNumber
+     * attribute</li>
+     * <li>{@link User#mobiles} * - multi-occurring attribute maps to INetOrgPerson mobile attribute</li>
+     * <li>{@link User#emails} * - multi-occurring attribute maps to INetOrgPerson mail attribute</li>
+     * <li>{@link User#address} * - multi-occurring attribute maps to organizationalPerson postalAddress, st, l,
+     * postalCode, postOfficeBox attributes</li>
+     * <li>{@link User#beginTime} - HHMM - determines begin hour user may activate session</li>
+     * <li>{@link User#endTime} - HHMM - determines end hour user may activate session.</li>
+     * <li>{@link User#beginDate} - YYYYMMDD - determines date when user may sign on</li>
+     * <li>{@link User#endDate} - YYYYMMDD - indicates latest date user may sign on</li>
+     * <li>{@link User#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link User#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link User#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day of user may sign on</li>
+     * <li>{@link User#timeout} - number in seconds of session inactivity time allowed</li>
+     * <li>{@link User#props} * - multi-occurring attribute contains property key and values are separated with a ':'
+     * .  e.g. mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param user must contain {@link User#userId} and optional entity data to update i.e. desc, ou, properties,
+     *             all attributes that are not set will be ignored.
+     * @return Updated user entity data.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    @Override
+    public User updateUser( User user ) throws SecurityException
+    {
+        String methodName = "updateUser";
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        setEntitySession( CLS_NM, methodName, user );
+        return userP.update( user );
+    }
+
+
+    /**
+     * Method will change user's password.  This method will evaluate user's password policies.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * <li>{@link User#password} - contains the User's old password</li>
+     * <li>newPassword - contains the User's new password</li>
+     * </ul>
+     *
+     * @param user        contains {@link User#userId} and old user password {@link User#password}.
+     * @param newPassword contains new user password.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Will be thrown in the event of password policy violation or system error.
+     */
+    @Override
+    public void changePassword( User user, char[] newPassword ) throws SecurityException
+    {
+        String methodName = "changePassword";
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        setEntitySession( CLS_NM, methodName, user );
+        VUtil.assertNotNullOrEmpty( newPassword, GlobalErrIds.USER_PW_NULL, CLS_NM + methodName );
+        userP.changePassword( user, newPassword );
+    }
+
+
+    /**
+     * Method will lock user's password which will prevent the user from authenticating with directory.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user entity contains {@link User#userId} of User to be locked.
+     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
+     */
+    @Override
+    public void lockUserAccount( User user ) throws SecurityException
+    {
+        String methodName = "lockUserAccount";
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        setEntitySession( CLS_NM, methodName, user );
+        userP.lock( user );
+    }
+
+
+    /**
+     * Method will unlock user's password which will enable user to authenticate with directory.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * </ul>
+     *
+     * @param user entity contains {@link User#userId} of User to be unlocked.
+     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
+     */
+    @Override
+    public void unlockUserAccount( User user ) throws SecurityException
+    {
+        String methodName = "unlockUserAccount";
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        setEntitySession( CLS_NM, methodName, user );
+        userP.unlock( user );
+    }
+
+
+    /**
+     * Method will reset user's password which will require user to change password before successful authentication
+     * with directory.
+     * This method will not evaluate password policies on the new user password as it must be changed before use.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * <li>newPassword - contains the User's new password</li>
+     * </ul>
+     *
+     * @param user entity contains {@link User#userId} of User to be reset.
+     * @throws SecurityException will be thrown in the event of pw policy violation or system error.
+     */
+    @Override
+    public void resetPassword( User user, char[] newPassword ) throws SecurityException
+    {
+        String methodName = "resetPassword";
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        VUtil.assertNotNullOrEmpty( newPassword, GlobalErrIds.USER_PW_NULL, CLS_NM + "." + methodName );
+        setEntitySession( CLS_NM, methodName, user );
+        user.setPassword( newPassword );
+        userP.resetPassword( user );
+    }
+
+
+    /**
+     * Method will delete user's password policy designation.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link User#userId} - maps to INetOrgPerson uid</li>
+     * <li>newPassword - contains the User's new password</li>
+     * </ul>
+     *
+     * @param user contains {@link User#userId}.
+     * @throws SecurityException will be thrown in the event of password policy violation or system error.
+     */
+    @Override
+    public void deletePasswordPolicy( User user ) throws SecurityException
+    {
+        String methodName = "deletePasswordPolicy";
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        setEntitySession( CLS_NM, methodName, user );
+        userP.deletePwPolicy( user );
+    }
+
+
+    /**
+     * This command creates a new role. The command is valid if and only if the new role is not
+     * already a member of the ROLES data set. The ROLES data set is updated.
+     * Initially, no user or permission is assigned to the new role.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#name} - contains the name to use for the Role to be created.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#description} - maps to description attribute on organizationalRole object class</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated
+     * into user's RBAC session</li>
+     * </ul>
+     *
+     * @param role must contains {@link org.apache.directory.fortress.core.rbac.Role#name} (required) and optional {@link org.apache.directory.fortress.core.rbac.Role#description}.
+     * @return Role contains reference to entity operated on.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public Role addRole( Role role ) throws SecurityException
+    {
+        String methodName = "addRole";
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, role );
+        return roleP.add( role );
+    }
+
+
+    /**
+     * This command deletes an existing role from the RBAC database. The command is valid
+     * if and only if the role to be deleted is a member of the ROLES data set.  This command will
+     * also deassign role from all users.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role to be deleted.</li>
+     * </ul>
+     *
+     * @param role Contains {@link Role#name} for Role to delete.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteRole( Role role ) throws SecurityException
+    {
+        String methodName = "deleteRole";
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, role );
+        int numChildren = RoleUtil.numChildren( role.getName(), role.getContextId() );
+        if ( numChildren > 0 )
+        {
+            String error =  methodName + " role [" + role.getName() + "] must remove [" + numChildren +
+                "] descendants before deletion";
+            LOG.error( error );
+            throw new SecurityException( GlobalErrIds.HIER_DEL_FAILED_HAS_CHILD, error, null );
+        }
+        // search for all users assigned this role and deassign:
+        //role.setContextId(this.contextId);
+        List<User> users = userP.getAssignedUsers( role );
+        if ( users != null )
+        {
+            for ( User ue : users )
+            {
+                UserRole uRole = new UserRole( ue.getUserId(), role.getName() );
+                setAdminData( CLS_NM, methodName, uRole );
+                deassignUser( uRole );
+            }
+        }
+        permP.remove( role );
+        // remove all parent relationships from the role graph:
+        Set<String> parents = RoleUtil.getParents( role.getName(), this.contextId );
+        if ( parents != null )
+        {
+            for ( String parent : parents )
+            {
+                RoleUtil.updateHier( this.contextId, new Relationship( role.getName().toUpperCase(),
+                    parent.toUpperCase() ), Hier.Op.REM );
+            }
+        }
+        roleP.delete( role );
+    }
+
+
+    /**
+     * Method will update a Role entity in the directory.  The role must exist prior to this call.
+     * <p/>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Role#name} - contains the name to use for the Role to be updated.</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Role#description} - maps to description attribute on organizationalRole object class</li>
+     * <li>{@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+     * <li>{@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+     * <li>{@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC session</li>
+     * <li>{@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC session</li>
+     * <li>{@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be activated
+     * into user's RBAC session</li>
+     * </ul>
+     *
+     * @param role must contains {@link Role#name} and may contain new description or {@link org.apache.directory.fortress.util
+     * .time.Constraint}
+     * @return Role contains reference to entity operated on.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of validation or system error.
+     */
+    @Override
+    public Role updateRole( Role role ) throws SecurityException
+    {
+        String methodName = "updateRole";
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, role );
+        return roleP.update( role );
+    }
+
+
+    /**
+     * 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>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserRole#name} - contains the name for already existing Role to be assigned</li>
+     * <li>{@link UserRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link UserRole#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC session</li>
+     * <li>{@link UserRole#endTime} - HHMM - determines end hour role may be activated into user's RBAC session.</li>
+     * <li>{@link UserRole#beginDate} - YYYYMMDD - determines date when role may be activated into user's RBAC
+     * session</li>
+     * <li>{@link UserRole#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC
+     * session</li>
+     * <li>{@link UserRole#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status</li>
+     * <li>{@link UserRole#endLockDate} - YYYYMMDD - determines end of enforced inactive status</li>
+     * <li>{@link UserRole#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be
+     * activated into user's RBAC session</li>
+     * </ul>
+     *
+     * @param uRole must contain {@link UserRole#userId} and {@link UserRole#name} and optional {@code Constraints}.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of validation or system error.
+     */
+    @Override
+    public void assignUser( UserRole uRole ) throws SecurityException
+    {
+        String methodName = "assignUser";
+        assertContext( CLS_NM, methodName, uRole, GlobalErrIds.URLE_NULL );
+        Role role = new Role( uRole.getName() );
+        role.setContextId( contextId );
+        User user = new User( uRole.getUserId() );
+        user.setContextId( contextId );
+        setEntitySession( CLS_NM, methodName, uRole );
+        AdminUtil.canAssign( uRole.getAdminSession(), user, role, contextId );
+        SDUtil.validateSSD( user, role );
+
+        // Get the default constraints from role:
+        role.setContextId( this.contextId );
+        Role validRole = roleP.read( role );
+        // if the input role entity attribute doesn't have temporal constraints set, copy from the role declaration:
+        CUtil.validateOrCopy( validRole, uRole );
+
+        // Assign the Role data to User:
+        String dn = userP.assign( uRole );
+        setAdminData( CLS_NM, methodName, role );
+        // Assign user dn attribute to the role, this will add a single, standard attribute value,
+        // called "roleOccupant", directly onto the role node:
+        roleP.assign( role, dn );
+    }
+
+
+    /**
+     * 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.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link UserRole#name} - contains the name for already existing Role to be deassigned</li>
+     * <li>{@link UserRole#userId} - contains the userId for existing User</li>
+     * </ul>
+     *
+     * @param uRole must contain {@link UserRole#userId} and {@link UserRole#name}.
+     * @throws SecurityException - in the event data error in user or role objects or system error.
+     */
+    @Override
+    public void deassignUser( UserRole uRole ) throws SecurityException
+    {
+        String methodName = "deassignUser";
+        assertContext( CLS_NM, methodName, uRole, GlobalErrIds.URLE_NULL );
+        Role role = new Role( uRole.getName() );
+        role.setContextId( contextId );
+        User user = new User( uRole.getUserId() );
+        setEntitySession( CLS_NM, methodName, uRole );
+        AdminUtil.canDeassign( user.getAdminSession(), user, role, contextId );
+        String dn = userP.deassign( uRole );
+        setAdminData( CLS_NM, methodName, role );
+        // Now "deassign" user dn attribute, this will remove a single, standard attribute value,
+        // called "roleOccupant", from the node:
+        roleP.deassign( role, dn );
+    }
+
+
+    /**
+     * This method will add permission operation to an existing permission object which resides under {@code
+     * ou=Permissions,ou=RBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may have {@link org.apache.directory.fortress.core.rbac.Role} or {@link org.apache.directory.fortress.core.rbac.User}
+     * associations.  The target {@link org.apache.directory.fortress.core.rbac.Permission} must not exist prior to calling.
+     * A Fortress Permission instance exists in a hierarchical, one-many relationship between its parent and itself
+     * as stored in ldap tree: ({@link org.apache.directory.fortress.core.rbac.PermObj}*->{@link org.apache.directory.fortress.core.rbac.Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#objName} - contains the name of existing object being targeted for the permission
+     * add</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#opName} - contains the name of new permission operation being added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is
+     * being granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#users} * - multi occurring attribute contains Users that permission operation is being
+     * granted to</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g.
+     * mykey1:myvalue1</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link org.apache.directory.fortress.core.rbac.Permission#objName}, and operation,
+     * {@link org.apache.directory.fortress.core.rbac.Permission#opName}, that identifies target along with optional other attributes..
+     * @return copy of Permission entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public Permission addPermission( Permission perm ) throws SecurityException
+    {
+        String methodName = "addPermission";
+        assertContext( CLS_NM, methodName, perm, GlobalErrIds.PERM_OPERATION_NULL );
+        setEntitySession( CLS_NM, methodName, perm );
+        return permP.add( perm );
+    }
+
+
+    /**
+     * This method will update permission operation pre-existing in target directory under {@code ou=Permissions,
+     * ou=RBAC,dc=yourHostName,dc=com} container in directory information tree.
+     * The perm operation entity may also contain {@link org.apache.directory.fortress.core.rbac.Role} or {@link org.apache.directory.fortress.core.rbac
+     * .User} associations to add or remove using this function.
+     * The perm operation must exist before making this call.  Only non-null attributes will be updated.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission
+     * update</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link Permission#roles} * - multi occurring attribute contains RBAC Roles that permission operation is
+     * being granted to</li>
+     * <li>{@link Permission#users} * - multi occurring attribute contains Users that permission operation is being
+     * granted to</li>
+     * <li>{@link Permission#props} * - multi-occurring property key and values are separated with a ':'.  e.g.
+     * mykey1:myvalue1</li>
+     * <li>{@link Permission#type} - any safe text</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName},
+     *             that identifies target and any optional data to update.  Null or empty attributes will be ignored.
+     * @return copy of Permission entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public Permission updatePermission( Permission perm ) throws SecurityException
+    {
+        String methodName = "updatePermission";
+        assertContext( CLS_NM, methodName, perm, GlobalErrIds.PERM_OPERATION_NULL );
+        setEntitySession( CLS_NM, methodName, perm );
+        return permP.update( perm );
+    }
+
+
+    /**
+     * This method will remove permission operation entity from permission object. A Fortress permission is
+     * (object->operation).
+     * The perm operation must exist before making this call.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the name of existing object being targeted for the permission
+     * delete</li>
+     * <li>{@link Permission#opName} - contains the name of existing permission operation being removed</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName},
+     *             that identifies target.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public void deletePermission( Permission perm ) throws SecurityException
+    {
+        String methodName = "deletePermission";
+        assertContext( CLS_NM, methodName, perm, GlobalErrIds.PERM_OPERATION_NULL );
+        setEntitySession( CLS_NM, methodName, perm );
+        permP.delete( perm );
+    }
+
+
+    /**
+     * This method will add permission object to perms container in directory. The perm object must not exist before
+     * making this call.
+     * A {@link org.apache.directory.fortress.core.rbac.PermObj} instance exists in a hierarchical, one-many relationship between itself and children as
+     * stored in ldap tree: ({@link org.apache.directory.fortress.core.rbac.PermObj}*->{@link Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#objName} - contains the name of new object being added</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#description} - any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#type} - contains any safe text</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g.
+     * mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link org.apache.directory.fortress.core.rbac.PermObj#objName} and {@link org.apache.directory.fortress.core.rbac.PermObj#ou}.  The other attributes are
+     *             optional.
+     * @return copy of PermObj entity.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public PermObj addPermObj( PermObj pObj ) throws SecurityException
+    {
+        String methodName = "addPermObj";
+        assertContext( CLS_NM, methodName, pObj, GlobalErrIds.PERM_OBJECT_NULL );
+        setEntitySession( CLS_NM, methodName, pObj );
+        return permP.add( pObj );
+    }
+
+
+    /**
+     * This method will update permission object in perms container in directory.  The perm object must exist before
+     * making this call.
+     * A {@link PermObj} instance exists in a hierarchical, one-many relationship between itself and children as
+     * stored in ldap tree: ({@link PermObj}*->{@link Permission}).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of existing object being updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#ou} - contains the name of an existing PERMS OrgUnit this object is associated with</li>
+     * <li>{@link PermObj#description} - any safe text</li>
+     * <li>{@link PermObj#type} - contains any safe text</li>
+     * <li>{@link PermObj#props} * - multi-occurring property key and values are separated with a ':'.  e.g.
+     * mykey1:myvalue1</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link PermObj#objName}. Only non-null attributes will be updated.
+     * @return copy of newly updated PermObj entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public PermObj updatePermObj( PermObj pObj ) throws SecurityException
+    {
+        String methodName = "updatePermObj";
+        assertContext( CLS_NM, methodName, pObj, GlobalErrIds.PERM_OBJECT_NULL );
+        setEntitySession( CLS_NM, methodName, pObj );
+        return permP.update( pObj );
+    }
+
+
+    /**
+     * This method will remove permission object to perms container in directory.  This method will also remove
+     * in associated permission objects that are attached to this object.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link PermObj#objName} - contains the name of existing object targeted for removal</li>
+     * </ul>
+     *
+     * @param pObj must contain the {@link PermObj#objName} of object targeted for removal.
+     * @throws SecurityException - thrown in the event of perm object data or system error.
+     */
+    @Override
+    public void deletePermObj( PermObj pObj ) throws SecurityException
+    {
+        String methodName = "deletePermObj";
+        assertContext( CLS_NM, methodName, pObj, GlobalErrIds.PERM_OBJECT_NULL );
+        setEntitySession( CLS_NM, methodName, pObj );
+        permP.delete( pObj );
+    }
+
+
+    /**
+     * This command grants a role the permission to perform an operation on an object to a role.
+     * The command is implemented by granting permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * and the role is a member of the ROLES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link Role#name} - contains the role name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName},
+     *             that identifies target.
+     * @param role must contains {@link Role#name}.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void grantPermission( Permission perm, Role role ) throws SecurityException
+    {
+        String methodName = "grantPermission";
+        assertContext( CLS_NM, methodName, perm, GlobalErrIds.PERM_OPERATION_NULL );
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, perm );
+
+        // validate role
+        if ( perm.isAdmin() )
+        {
+            AdminRole adminRole = new AdminRole( role.getName() );
+            adminRole.setContextId( this.contextId );
+            adminP.read( adminRole );
+        }
+        else
+        {
+            AdminUtil.canGrant( perm.getAdminSession(), role, perm, contextId );
+            roleP.read( role );
+        }
+        permP.grant( perm, role );
+    }
+
+
+    /**
+     * This command revokes the permission to perform an operation on an object from the set
+     * of permissions assigned to a role. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * the role is a member of the ROLES data set, and the permission is assigned to that role.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link Role#name} - contains the role name</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName},
+     *             that identifies target.
+     * @param role must contains {@link Role#name}.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void revokePermission( Permission perm, Role role ) throws SecurityException
+    {
+        String methodName = "revokePermission";
+        assertContext( CLS_NM, methodName, perm, GlobalErrIds.PERM_OPERATION_NULL );
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, perm );
+        if ( !perm.isAdmin() )
+        {
+            AdminUtil.canRevoke( perm.getAdminSession(), role, perm, contextId );
+        }
+        permP.revoke( perm, role );
+    }
+
+
+    /**
+     * This command grants a user the permission to perform an operation on an object to a role.
+     * The command is implemented by granting permission by setting the access control list of
+     * the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * and the user is a member of the USERS data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName},
+     *             that identifies target.
+     * @param user must contain {@link User#userId} of target User entity.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void grantPermission( Permission perm, User user ) throws SecurityException
+    {
+        String methodName = "grantPermissionUser";
+        assertContext( CLS_NM, methodName, perm, GlobalErrIds.PERM_OPERATION_NULL );
+        setEntitySession( CLS_NM, methodName, perm );
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        // Ensure the user entity exists:
+        userP.read( user, false );
+        permP.grant( perm, user );
+    }
+
+
+    /**
+     * This command revokes the permission to perform an operation on an object from the set
+     * of permissions assigned to a user. The command is implemented by setting the access control
+     * list of the object involved.
+     * The command is valid if and only if the pair (operation, object) represents a permission,
+     * the user is a member of the USERS data set, and the permission is assigned to that user.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link Permission#objName} - contains the object name</li>
+     * <li>{@link Permission#opName} - contains the operation name</li>
+     * <li>{@link User#userId} - contains the userId</li>
+     * </ul>
+     *
+     * @param perm must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName},
+     *             that identifies target.
+     * @param user must contain {@link User#userId} of target User entity.
+     * @throws SecurityException Thrown in the event of data validation or system error.
+     */
+    @Override
+    public void revokePermission( Permission perm, User user ) throws SecurityException
+    {
+        String methodName = "revokePermissionUser";
+        assertContext( CLS_NM, methodName, perm, GlobalErrIds.PERM_OPERATION_NULL );
+        setEntitySession( CLS_NM, methodName, perm );
+        assertContext( CLS_NM, methodName, user, GlobalErrIds.USER_NULL );
+        permP.revoke( perm, user );
+    }
+
+
+    /**
+     * This command creates a new role childRole, and inserts it in the role hierarchy as an immediate descendant of
+     * the existing role parentRole. The command is valid if and only if childRole is not a member of the ROLES data
+     * set,
+     * and parentRole is a member of the ROLES data set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#name} - contains the name of existing Role to be parent</li>
+     * <li>childRole - {@link Role#name} - contains the name of new Role to be child</li>
+     * </ul>
+     * <h4>optional parameters childRole</h4>
+     * <ul>
+     * <li>childRole - {@link Role#description} - maps to description attribute on organizationalRole object class
+     * for new child</li>
+     * <li>childRole - {@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC
+     * session for new child</li>
+     * <li>childRole - {@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC
+     * session for new child</li>
+     * <li>childRole - {@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's
+     * RBAC session for new child</li>
+     * <li>childRole - {@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's RBAC
+     * session for new child</li>
+     * <li>childRole - {@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for
+     * new child</li>
+     * <li>childRole - {@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new
+     * child</li>
+     * <li>childRole - {@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be
+     * activated into user's RBAC session for new child</li>
+     * </ul>
+     *
+     * @param parentRole This entity must be present in ROLE data set.  Success will add role rel with childRole.
+     * @param childRole  This entity must not be present in ROLE data set.  Success will add the new role entity to
+     *                   ROLE data set.
+     *                   This method:
+     *                   1 - Adds new role.
+     *                   2 - Assigns role relationship between new childRole and pre-existing parentRole.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addDescendant( Role parentRole, Role childRole ) throws SecurityException
+    {
+        String methodName = "addDescendant";
+        assertContext( CLS_NM, methodName, parentRole, GlobalErrIds.PARENT_ROLE_NULL );
+        assertContext( CLS_NM, methodName, childRole, GlobalErrIds.CHILD_ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, childRole );
+        // make sure the parent role is already there:
+        Role role = new Role( parentRole.getName() );
+        role.setContextId( this.contextId );
+        roleP.read( role );
+        RoleUtil.validateRelationship( childRole, parentRole, false );
+        childRole.setParent( parentRole.getName() );
+        roleP.add( childRole );
+        RoleUtil.updateHier( this.contextId, new Relationship( childRole.getName().toUpperCase(),
+            parentRole.getName().toUpperCase() ), Hier.Op.ADD );
+    }
+
+
+    /**
+     * This command creates a new role parentRole, and inserts it in the role hierarchy as an immediate ascendant of
+     * the existing role childRole. The command is valid if and only if parentRole is not a member of the ROLES data
+     * set,
+     * and childRole is a member of the ROLES data set.
+     * This method:
+     * 1 - Adds new role.
+     * 2 - Assigns role relationship between new parentRole and pre-existing childRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>childRole - {@link Role#name} - contains the name of existing child Role</li>
+     * <li>parentRole - {@link Role#name} - contains the name of new Role to be parent</li>
+     * </ul>
+     * <h4>optional parameters parentRole</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#description} - maps to description attribute on organizationalRole object class
+     * for new parent</li>
+     * <li>parentRole - {@link Role#beginTime} - HHMM - determines begin hour role may be activated into user's RBAC
+     * session for new parent</li>
+     * <li>parentRole - {@link Role#endTime} - HHMM - determines end hour role may be activated into user's RBAC
+     * session for new parent</li>
+     * <li>parentRole - {@link Role#beginDate} - YYYYMMDD - determines date when role may be activated into user's
+     * RBAC session for new parent</li>
+     * <li>parentRole - {@link Role#endDate} - YYYYMMDD - indicates latest date role may be activated into user's
+     * RBAC session for new parent</li>
+     * <li>parentRole - {@link Role#beginLockDate} - YYYYMMDD - determines beginning of enforced inactive status for
+     * new parent</li>
+     * <li>parentRole - {@link Role#endLockDate} - YYYYMMDD - determines end of enforced inactive status for new
+     * parent</li>
+     * <li>parentRole - {@link Role#dayMask} - 1234567, 1 = Sunday, 2 = Monday, etc - specifies which day role may be
+     * activated into user's RBAC session for new parent</li>
+     * </ul>
+     *
+     * @param parentRole completion of op assigns new child relationship with childRole.
+     * @param childRole  completion of op assigns new parent relationship with parentRole.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addAscendant( Role childRole, Role parentRole ) throws SecurityException
+    {
+        String methodName = "addAscendant";
+        assertContext( CLS_NM, methodName, parentRole, GlobalErrIds.PARENT_ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, parentRole );
+        assertContext( CLS_NM, methodName, childRole, GlobalErrIds.CHILD_ROLE_NULL );
+        // make sure the child role is already there:
+        Role role = new Role( childRole.getName() );
+        role.setContextId( this.contextId );
+        role = roleP.read( role );
+        role.setContextId( this.contextId );
+        RoleUtil.validateRelationship( childRole, parentRole, false );
+        roleP.add( parentRole );
+        // Use cRole2 to update ONLY the parents attribute on the child role and nothing else:
+        Role cRole2 = new Role( childRole.getName() );
+        cRole2.setParents( role.getParents() );
+        cRole2.setParent( parentRole.getName() );
+        cRole2.setContextId( this.contextId );
+        setAdminData( CLS_NM, methodName, cRole2 );
+        roleP.update( cRole2 );
+        RoleUtil.updateHier( this.contextId, new Relationship( childRole.getName().toUpperCase(),
+            parentRole.getName().toUpperCase() ), Hier.Op.ADD );
+    }
+
+
+    /**
+     * This command establishes a new immediate inheritance relationship parentRole <<-- childRole between existing
+     * roles parentRole, childRole. The command is valid if and only if parentRole and childRole are members of the
+     * ROLES data
+     * set, parentRole is not an immediate ascendant of childRole, and childRole does not properly inherit parentRole
+     * (in order to
+     * avoid cycle creation).
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#name} - contains the name of existing Role to be parent</li>
+     * <li>childRole - {@link Role#name} - contains the name of existing Role to be child</li>
+     * </ul>
+     *
+     * @param parentRole completion of op deassigns child relationship with childRole.
+     * @param childRole  completion of op deassigns parent relationship with parentRole.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          thrown in the event of data validation or system error.
+     */
+    @Override
+    public void addInheritance( Role parentRole, Role childRole ) throws SecurityException
+    {
+        String methodName = "addInheritance";
+        assertContext( CLS_NM, methodName, parentRole, GlobalErrIds.PARENT_ROLE_NULL );
+        assertContext( CLS_NM, methodName, childRole, GlobalErrIds.CHILD_ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, parentRole );
+        // make sure the parent role is already there:
+        Role pRole = new Role( parentRole.getName() );
+        pRole.setContextId( this.contextId );
+        roleP.read( pRole );
+        // make sure the child role is already there:
+        Role cRole = new Role( childRole.getName() );
+        cRole.setContextId( this.contextId );
+        cRole = roleP.read( cRole );
+        RoleUtil.validateRelationship( childRole, parentRole, false );
+        RoleUtil.updateHier( this.contextId, new Relationship( childRole.getName().toUpperCase(),
+            parentRole.getName().toUpperCase() ), Hier.Op.ADD );
+        // Use cRole2 to update ONLY the parents attribute on the child role and nothing else:
+        Role cRole2 = new Role( childRole.getName() );
+        cRole2.setParents( cRole.getParents() );
+        cRole2.setParent( parentRole.getName() );
+        cRole2.setContextId( this.contextId );
+        setAdminData( CLS_NM, methodName, cRole2 );
+        roleP.update( cRole2 );
+    }
+
+
+    /**
+     * This command deletes an existing immediate inheritance relationship parentRole <<-- childRole. The command is
+     * valid if and only if the roles parentRole and childRole are members of the ROLES data set, and parentRole is an
+     * immediate ascendant of childRole. The new inheritance relation is computed as the reflexive-transitive
+     * closure of the immediate inheritance relation resulted after deleting the relationship parentRole <<-- childRole.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>parentRole - {@link Role#name} - contains the name of existing Role to remove parent relationship</li>
+     * <li>childRole - {@link Role#name} - contains the name of existing Role to remove child relationship</li>
+     * </ul>
+     *
+     * @param parentRole completion of op removes child relationship with childRole.
+     * @param childRole  completion of op removes parent relationship with parentRole.
+     * @throws SecurityException thrown in the event of data validation or system error.
+     */
+    @Override
+    public void deleteInheritance( Role parentRole, Role childRole ) throws SecurityException
+    {
+        String methodName = "deleteInheritance";
+        assertContext( CLS_NM, methodName, parentRole, GlobalErrIds.PARENT_ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, parentRole );
+        assertContext( CLS_NM, methodName, childRole, GlobalErrIds.CHILD_ROLE_NULL );
+        RoleUtil.validateRelationship( childRole, parentRole, true );
+        RoleUtil.updateHier( this.contextId, new Relationship( childRole.getName().toUpperCase(),
+            parentRole.getName().toUpperCase() ), Hier.Op.REM );
+        // need to remove the parent from the child role:
+        Role cRole = new Role( childRole.getName() );
+        cRole.setContextId( this.contextId );
+        cRole = roleP.read( cRole );
+        // Use cRole2 to update ONLY the parents attribute on the child role and nothing else:
+        Role cRole2 = new Role( childRole.getName() );
+        cRole2.setParents( cRole.getParents() );
+        cRole2.delParent( parentRole.getName() );
+        cRole2.setContextId( this.contextId );
+        setAdminData( CLS_NM, methodName, cRole2 );
+        // are there any parents left?
+        if ( !VUtil.isNotNullOrEmpty( cRole2.getParents() ) )
+        {
+            // The updates only update non-empty multi-occurring attributes
+            // so if last parent assigned, so must remove the attribute completely:
+            roleP.deleteParent( cRole2 );
+        }
+        else
+        {
+            roleP.update( cRole2 );
+        }
+    }
+
+
+    /**
+     * This command creates a named SSD set of roles and sets the cardinality n of its subsets
+     * that cannot have common users. The command is valid if and only if:
+     * 1 - the name of the SSD set is not already in use
+     * 2 - all the roles in the SSD set are members of the ROLES data set
+     * 3 - n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the SSD role
+     * set,
+     * 4 - the SSD constraint for the new role set is satisfied.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.SDSet#name} - contains the name of new SSD role set to be added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link org.apache.directory.fortress.core.rbac.SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be
+     * assigned to User from a particular set</li>
+     * <li>{@link org.apache.directory.fortress.core.rbac.SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to new SSD set containing, name, members,
+     *               and cardinality (default 2)
+     * @return reference to newly created SSDSet object.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public SDSet createSsdSet( SDSet ssdSet ) throws SecurityException
+    {
+        String methodName = "createSsdSet";
+        assertContext( CLS_NM, methodName, ssdSet, GlobalErrIds.SSD_NULL );
+        setEntitySession( CLS_NM, methodName, ssdSet );
+        ssdSet.setType( SDSet.SDType.STATIC );
+        if ( ssdSet.getCardinality() == null )
+        {
+            // default cardinality == 2
+            ssdSet.setCardinality( 2 );
+        }
+        clearSSDCache( ssdSet );
+        return sdP.add( ssdSet );
+    }
+
+
+    /**
+     * This command updates existing SSD set of roles and sets the cardinality n of its subsets
+     * that cannot have common users.
+     * <p/>
+     * The command is valid if and only if:
+     * <ul>
+     * <li>The name of the SSD set already exists.
+     * <li> All the roles in the SSD set are members of the ROLES data set.
+     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the SSD
+     * role set.
+     * <li> The SSD constraint for the new role set is satisfied.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing SSD role set to be updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be
+     * assigned to User from a particular set</li>
+     * <li>{@link SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to existing SSD set containing, name, members,
+     *               and cardinality (default 2)
+     * @return reference to SSDSet object targeted for update.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet updateSsdSet( SDSet ssdSet ) throws SecurityException
+    {
+        String methodName = "updateSsdSet";
+        assertContext( CLS_NM, methodName, ssdSet, GlobalErrIds.SSD_NULL );
+        setEntitySession( CLS_NM, methodName, ssdSet );
+        ssdSet.setType( SDSet.SDType.STATIC );
+        return sdP.update( ssdSet );
+    }
+
+
+    /**
+     * This command adds a role to a named SSD set of roles. The cardinality associated with the role set remains
+     * unchanged.
+     * The command is valid if and only if:
+     * 1 - the SSD role set exists, and
+     * 2 - the role to be added is a member of the ROLES data set but not of a member of the SSD role set, and
+     * 3 - the SSD constraint is satisfied after the addition of the role to the SSD role set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
+     * <li>{@link Role#name} - contains the name of new {@link SDSet#members} to be added</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to new SSD set containing, name
+     * @param role   contains instantiated Role object with role name field set.
+     * @return reference to updated SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public SDSet addSsdRoleMember( SDSet ssdSet, Role role ) throws SecurityException
+    {
+        String methodName = "addSsdRoleMember";
+        assertContext( CLS_NM, methodName, ssdSet, GlobalErrIds.SSD_NULL );
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, ssdSet );
+        SDSet entity = sdP.read( ssdSet );
+        entity.setContextId( this.contextId );
+        entity.setContextId( this.contextId );
+        entity.addMember( role.getName() );
+        setAdminData( CLS_NM, methodName, entity );
+        SDSet ssdOut = sdP.update( entity );
+        // remove any references to the old SSD from cache:
+        clearSSDCache( role );
+        return ssdOut;
+    }
+
+
+    /**
+     * This command removes a role from a named SSD set of roles. The cardinality associated with the role set
+     * remains unchanged.
+     * The command is valid if and only if:
+     * 1 - the SSD role set exists, and
+     * 2 - the role to be removed is a member of the SSD role set, and
+     * 3 - the cardinality associated with the SSD role set is less than the number of elements of the SSD role set.
+     * Note that the SSD constraint should be satisfied after the removal of the role from the SSD role set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
+     * <li>{@link Role#name} - contains the name of existing {@link SDSet#members} to be removed</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to new SSD set containing name.
+     * @param role   contains instantiated Role object with role name field set.
+     * @return reference to updated SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public SDSet deleteSsdRoleMember( SDSet ssdSet, Role role ) throws SecurityException
+    {
+        String methodName = "deleteSsdRoleMember";
+        assertContext( CLS_NM, methodName, ssdSet, GlobalErrIds.SSD_NULL );
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, ssdSet );
+        SDSet entity = sdP.read( ssdSet );
+        entity.setContextId( this.contextId );
+        entity.delMember( role.getName() );
+
+        // when removing last role member a placeholder must be left in data set:
+        if ( entity.getMembers().isEmpty() )
+        {
+            entity.addMember( GlobalIds.NONE );
+        }
+        setAdminData( CLS_NM, methodName, entity );
+        SDSet ssdOut = sdP.update( entity );
+        // remove any references to the old SSD from cache:
+        clearSSDCache( role );
+        return ssdOut;
+    }
+
+
+    /**
+     * This command deletes a SSD role set completely. The command is valid if and only if the SSD role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing SSD role set to be removed</li>
+     * </ul>
+     *
+     * @param ssdSet contains an instantiated reference to SSD set targeted for removal.
+     * @return reference to deleted SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public SDSet deleteSsdSet( SDSet ssdSet ) throws SecurityException
+    {
+        String methodName = "deleteSsdSet";
+        assertContext( CLS_NM, methodName, ssdSet, GlobalErrIds.SSD_NULL );
+        setEntitySession( CLS_NM, methodName, ssdSet );
+        ssdSet.setType( SDSet.SDType.STATIC );
+        // remove any references to the old SSD from cache:
+        clearSSDCache( ssdSet );
+        return sdP.delete( ssdSet );
+    }
+
+
+    /**
+     * Clear the SSD cache entries that correspond to this SSD
+     *
+     * @param ssdSet
+     * @throws SecurityException
+     */
+    private void clearSSDCache( SDSet ssdSet )
+    {
+        if ( ssdSet.getMembers() != null )
+        {
+            for ( String roleName : ssdSet.getMembers() )
+            {
+                SDUtil.clearSsdCacheEntry( roleName, contextId );
+            }
+        }
+    }
+
+
+    /**
+     * Clear the SSD cache entries that correspond to this Role.
+     *
+     * @param role
+     * @throws SecurityException
+     */
+    private void clearSSDCache( Role role )
+    {
+        SDUtil.clearSsdCacheEntry( role.getName(), contextId );
+    }
+
+
+    /**
+     * This command sets the cardinality associated with a given SSD role set. The command is valid if and only if:
+     * 1 - the SSD role set exists, and
+     * 2 - the new cardinality is a natural number greater than or equal to 2 and less than or equal to the number of
+     * elements of the SSD role set, and
+     * 3 - the SSD constraint is satisfied after setting the new cardinality.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
+     * <li>cardinality - contains new cardinality setting for SSD</li>
+     * </ul>
+     *
+     * @param ssdSet      contains an instantiated reference to new SSD set containing, name
+     * @param cardinality integer value contains new cardinality value for data set.
+     * @return reference to updated SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public SDSet setSsdSetCardinality( SDSet ssdSet, int cardinality ) throws SecurityException
+    {
+        String methodName = "setSsdSetCardinality";
+        assertContext( CLS_NM, methodName, ssdSet, GlobalErrIds.SSD_NULL );
+        setEntitySession( CLS_NM, methodName, ssdSet );
+        ssdSet.setType( SDSet.SDType.STATIC );
+        ssdSet.setCardinality( cardinality );
+        // remove any references to the old SSD from cache:
+        clearSSDCache( ssdSet );
+        return sdP.update( ssdSet );
+    }
+
+
+    /**
+     * This command creates a named DSD set of roles and sets an associated cardinality n.
+     * The DSD constraint stipulates that the DSD role set cannot contain n or more roles
+     * simultaneously active in the same session.  The command is valid if and only if:
+     * 1 - the name of the DSD set is not already in use
+     * 2 - all the roles in the DSD set are members of the ROLES data set
+     * 3 - n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the DSD role
+     * set,
+     * 4 - the DSD constraint for the new role set is satisfied.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of new DSD role set to be added</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be
+     * assigned to User from a particular set</li>
+     * <li>{@link SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to new DSD set containing, name, members,
+     *               and cardinality (default 2)
+     * @return reference to newly created SSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public SDSet createDsdSet( SDSet dsdSet ) throws SecurityException
+    {
+        String methodName = "createDsdSet";
+        assertContext( CLS_NM, methodName, dsdSet, GlobalErrIds.DSD_NULL );
+        setEntitySession( CLS_NM, methodName, dsdSet );
+        dsdSet.setType( SDSet.SDType.DYNAMIC );
+        if ( dsdSet.getCardinality() == null )
+        {
+            // default cardinality == 2
+            dsdSet.setCardinality( 2 );
+        }
+        return sdP.add( dsdSet );
+    }
+
+
+    /**
+     * This command updates existing DSD set of roles and sets the cardinality n of its subsets
+     * that cannot have common users.
+     * <p/>
+     * The command is valid if and only if:
+     * <ul>
+     * <li>The name of the DSD set already exists.
+     * <li> All the roles in the DSD set are members of the ROLES data set.
+     * <li> n is a natural number greater than or equal to 2 and less than or equal to the cardinality of the DSD
+     * role set.
+     * <li> The DSD constraint for the new role set is satisfied.
+     * </ul>
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of existing DSD role set to be updated</li>
+     * </ul>
+     * <h4>optional parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#members} * - multi-occurring attribute contains the RBAC Role names to be added to this set</li>
+     * <li>{@link SDSet#cardinality} - default is 2 which is one more than maximum number of Roles that may be
+     * assigned to User from a particular set</li>
+     * <li>{@link SDSet#description} - contains any safe text</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to existing DSD set containing, name, members,
+     *               and cardinality (default 2)
+     * @return reference to DSDSet object targeted for update.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    public SDSet updateDsdSet( SDSet dsdSet ) throws SecurityException
+    {
+        String methodName = "updateDsdSet";
+        assertContext( CLS_NM, methodName, dsdSet, GlobalErrIds.DSD_NULL );
+        setEntitySession( CLS_NM, methodName, dsdSet );
+        dsdSet.setType( SDSet.SDType.DYNAMIC );
+        return sdP.update( dsdSet );
+    }
+
+
+    /**
+     * This command adds a role to a named DSD set of roles. The cardinality associated with
+     * the role set remains unchanged. The command is valid if and only if:
+     * 1 - the DSD role set exists, and
+     * 2 - the role to be added is a member of the ROLES data set but not of a member of the DSD role set, and
+     * 3 - the DSD constraint is satisfied after the addition of the role to the SSD role set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of DSD role set to be modified</li>
+     * <li>{@link Role#name} - contains the name of new {@link SDSet#members} to be added</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to new DSD set containing, name
+     * @param role   contains instantiated Role object with role name field set.
+     * @return reference to updated DSDSet object.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public SDSet addDsdRoleMember( SDSet dsdSet, Role role ) throws SecurityException
+    {
+        String methodName = "addDsdRoleMember";
+        assertContext( CLS_NM, methodName, dsdSet, GlobalErrIds.DSD_NULL );
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, dsdSet );
+        SDSet entity = sdP.read( dsdSet );
+        entity.setContextId( this.contextId );
+        entity.addMember( role.getName() );
+        setAdminData( CLS_NM, methodName, entity );
+        entity.setContextId( contextId );
+        SDSet dsdOut = sdP.update( entity );
+        // remove any references to the old DSD from cache:
+        clearDSDCache( dsdSet );
+        return dsdOut;
+    }
+
+
+    /**
+     * This command removes a role from a named DSD set of roles. The cardinality associated
+     * with the role set remains unchanged. The command is valid if and only if:
+     * 1 - the DSD role set exists, and
+     * 2 - the role to be removed is a member of the DSD role set, and
+     * 3 - the cardinality associated with the DSD role set is less than the number of elements of the DSD role set.
+     * Note that the DSD constraint should be satisfied after the removal of the role from the DSD role set.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of DSD role set to be modified</li>
+     * <li>{@link Role#name} - contains the name of existing {@link SDSet#members} to be removed</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to new DSD set containing name.
+     * @param role   contains instantiated Role object with role name field set.
+     * @return reference to updated DSDSet object.
+     * @throws SecurityException in the event of data validation or system error.
+     */
+    @Override
+    public SDSet deleteDsdRoleMember( SDSet dsdSet, Role role ) throws SecurityException
+    {
+        String methodName = "deleteDsdRoleMember";
+        assertContext( CLS_NM, methodName, dsdSet, GlobalErrIds.DSD_NULL );
+        assertContext( CLS_NM, methodName, role, GlobalErrIds.ROLE_NULL );
+        setEntitySession( CLS_NM, methodName, dsdSet );
+        SDSet entity = sdP.read( dsdSet );
+        entity.setContextId( this.contextId );
+        entity.delMember( role.getName() );
+
+        // when removing last role member a placeholder must be left in data set:
+        if ( entity.getMembers().isEmpty() )
+        {
+            entity.addMember( GlobalIds.NONE );
+        }
+        setAdminData( CLS_NM, methodName, entity );
+        SDSet dsdOut = sdP.update( entity );
+        // remove any references to the old DSD from cache:
+        clearDSDCache( dsdSet );
+        return dsdOut;
+    }
+
+
+    /**
+     * This command deletes a DSD role set completely. The command is valid if and only if the DSD role set exists.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of DSD role set to be removed</li>
+     * </ul>
+     *
+     * @param dsdSet contains an instantiated reference to DSD set targeted for removal.
+     * @return reference to deleted DSDSet object.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public SDSet deleteDsdSet( SDSet dsdSet ) throws SecurityException
+    {
+        String methodName = "deleteDsdSet";
+        assertContext( CLS_NM, methodName, dsdSet, GlobalErrIds.DSD_NULL );
+        setEntitySession( CLS_NM, methodName, dsdSet );
+        dsdSet.setType( SDSet.SDType.DYNAMIC );
+        // remove any references to the old DSD from cache:
+        clearDSDCache( dsdSet );
+        return sdP.delete( dsdSet );
+    }
+
+
+    /**
+     * h     * This command sets the cardinality associated with a given DSD role set. The command is valid if and
+     * only if:
+     * 1 - the SSD role set exists, and
+     * 2 - the new cardinality is a natural number greater than or equal to 2 and less than or equal to the number of
+     * elements of the SSD role set, and
+     * 3 - the SSD constraint is satisfied after setting the new cardinality.
+     * <h4>required parameters</h4>
+     * <ul>
+     * <li>{@link SDSet#name} - contains the name of SSD role set to be modified</li>
+     * <li>cardinality - contains new cardinality setting for DSD</li>
+     * </ul>
+     *
+     * @param dsdSet      contains an instantiated reference to new DSD set containing, name
+     * @param cardinality integer value contains new cardinality value for data set.
+     * @return reference to updated DSDSet object.
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *          in the event of data validation or system error.
+     */
+    @Override
+    public SDSet setDsdSetCardinality( SDSet dsdSet, int cardinality ) throws SecurityException
+    {
+        String methodName = "setDsdSetCardinality";
+        assertContext( CLS_NM, methodName, dsdSet, GlobalErrIds.DSD_NULL );
+        setEntitySession( CLS_NM, methodName, dsdSet );
+        dsdSet.setType( SDSet.SDType.DYNAMIC );
+        dsdSet.setCardinality( cardinality );
+        // remove any references to the old DSD from cache:
+        clearDSDCache( dsdSet );
+        return sdP.update( dsdSet );
+    }
+
+
+    /**
+     * Clear the DSD cache entries that correspond to this DSD
+     *
+     * @param dsdSet
+     * @throws SecurityException
+     */
+    private void clearDSDCache( SDSet dsdSet )
+    {
+        SDUtil.clearDsdCacheEntry( dsdSet.getName(), contextId );
+    }
+}


[21/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/RoleUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/RoleUtil.java b/src/main/java/org/apache/directory/fortress/core/rbac/RoleUtil.java
new file mode 100755
index 0000000..67ce3c5
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/RoleUtil.java
@@ -0,0 +1,358 @@
+/*
+ *   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 org.apache.directory.fortress.core.rbac.HierUtil} methods to provide hierarchical functionality for the {@link org.apache.directory.fortress.core.rbac.Role} data set.
+ * The {@code cn=Hierarchies, ou=Roles} data is stored within a cache, {@link #roleCache}, contained within this class.  The parent-child edges are contained in LDAP,
+ * in {@code ftParents} attribute.  The ldap data is retrieved {@link org.apache.directory.fortress.core.rbac.RoleP#getAllDescendants(String)} 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 org.apache.directory.fortress.core.rbac.dao.UserDAO} and {@link org.apache.directory.fortress.core.rbac.dao.PermDAO}
+ * 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 RoleUtil
+{
+    private static final Cache roleCache;
+    private static final RoleP roleP = new RoleP();
+    private static final String CLS_NM = RoleUtil.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    /**
+     * Initialize the Role 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();
+        roleCache = cacheMgr.getCache( "fortress.roles" );
+    }
+
+
+    /**
+     * Used to determine if one {@link org.apache.directory.fortress.core.rbac.Role} is the parent of another.  This method
+     * will call recursive routine {@link #getAscendants(String, String)} to walk the {@code org.jgrapht.graph.SimpleDirectedGraph} data structure
+     * returning flag indicating if parent-child relationship is valid.
+     *
+     * @param child  maps to logical {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+     * @param parent maps to logical {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRels' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return boolean result, 'true' indicates parent/child relationship exists.
+     */
+    public static boolean isParent( String child, String parent, String contextId )
+    {
+        boolean result = false;
+        Set<String> parents = getAscendants( child, contextId );
+        if ( parents != null && parents.size() > 0 )
+        {
+            result = parents.contains( parent.toUpperCase() );
+        }
+        return result;
+    }
+
+
+    /**
+     * Recursively traverse the {@link org.apache.directory.fortress.core.rbac.Role} graph and return all of the descendants of a given node {@link org.apache.directory.fortress.core.rbac.Role#name}.
+     *
+     * @param roleName {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of Role names are descendants {@link org.apache.directory.fortress.core.rbac.Role}s of given parent.
+     */
+    public static Set<String> getDescendants( String roleName, String contextId )
+    {
+        return HierUtil.getDescendants( roleName.toUpperCase(), getGraph( contextId ) );
+    }
+
+
+    /**
+     * Traverse the {@link org.apache.directory.fortress.core.rbac.Role} graph and return all children (direct descendants) of a given parent node {@link org.apache.directory.fortress.core.rbac.Role#name}.
+     *
+     * @param roleName {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of Role names are children {@link org.apache.directory.fortress.core.rbac.Role}s of given parent.
+     */
+    public static Set<String> getChildren( String roleName, String contextId )
+    {
+        return HierUtil.getChildren( roleName.toUpperCase(), getGraph( contextId ) );
+    }
+
+
+    /**
+     * Recursively traverse the hierarchical role graph and return all of the ascendants of a given role.
+     *
+     * @param roleName maps to logical {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of Role names that are ascendants of given child.
+     */
+    public static Set<String> getAscendants( String roleName, String contextId )
+    {
+        return HierUtil.getAscendants( roleName.toUpperCase(), getGraph( contextId ) );
+    }
+
+
+    /**
+     * Traverse the hierarchical role graph and return all of the parents (direct ascendants) of a given role.
+     *
+     * @param roleName maps to logical {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of Role names that are parents of given child.
+     */
+    static Set<String> getParents( String roleName, String contextId )
+    {
+        return HierUtil.getParents( roleName.toUpperCase(), getGraph( contextId ) );
+    }
+
+
+    /**
+     * Determine the number of children (direct descendants) a given parent role has.
+     *
+     * @param roleName maps to logical {@link org.apache.directory.fortress.core.rbac.Role#name} on 'ftRls' object class.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return int value contains the number of children of a given parent nRole.
+     */
+    static int numChildren( String roleName, String contextId )
+    {
+        return HierUtil.numChildren( roleName.toUpperCase(), getGraph( contextId ) );
+    }
+
+
+    /**
+     * Return Set of RBAC {@link org.apache.directory.fortress.core.rbac.Role#name}s ascendants.  Used by {@link org.apache.directory.fortress.core.rbac.dao.PermDAO#checkPermission}
+     * for computing authorized {@link UserRole#name}s.
+     *
+     * @param uRoles contains list of Roles activated within a {@link org.apache.directory.fortress.core.rbac.User}'s {@link org.apache.directory.fortress.core.rbac.Session}.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return contains Set of all authorized RBAC Roles for a given User.
+     */
+    public static Set<String> getInheritedRoles( List<UserRole> uRoles, String contextId )
+    {
+        // create Set with case insensitive comparator:
+        Set<String> iRoles = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        if ( VUtil.isNotNullOrEmpty( uRoles ) )
+        {
+            for ( UserRole uRole : uRoles )
+            {
+                String rleName = uRole.getName();
+                iRoles.add( rleName );
+                Set<String> parents = HierUtil.getAscendants( rleName, getGraph( contextId ) );
+                if ( VUtil.isNotNullOrEmpty( parents ) )
+                    iRoles.addAll( parents );
+            }
+        }
+        return iRoles;
+    }
+
+
+    /**
+     *
+     * @param roles
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return
+     */
+    static Set<String> getAscendantRoles( List<String> roles, String contextId )
+    {
+        // create Set with case insensitive comparator:
+        Set<String> iRoles = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        if ( VUtil.isNotNullOrEmpty( roles ) )
+        {
+            for ( String role : roles )
+            {
+                iRoles.add( role );
+                Set<String> parents = HierUtil.getAscendants( role, getGraph( contextId ) );
+                if ( VUtil.isNotNullOrEmpty( parents ) )
+                    iRoles.addAll( parents );
+            }
+        }
+        return iRoles;
+    }
+
+
+    /**
+     *
+     * @param roles
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return
+     */
+    static Set<String> getDescendantRoles( Set<String> roles, String contextId )
+    {
+        // create Set with case insensitive comparator:
+        Set<String> iRoles = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
+        if ( VUtil.isNotNullOrEmpty( roles ) )
+        {
+            for ( String role : roles )
+            {
+                iRoles.add( role );
+                Set<String> children = HierUtil.getDescendants( role, getGraph( contextId ) );
+                if ( VUtil.isNotNullOrEmpty( children ) )
+                    iRoles.addAll( children );
+            }
+        }
+        return iRoles;
+    }
+
+
+    /**
+     * Recursively traverse the hierarchical graph and return all of the ascendants of a given child node.
+     *
+     * @param childName   maps to vertex to determine parentage.
+     * @param parentName  points to top most ascendant where traversal must stop.
+     * @param isInclusive if set to true will include the parentName in the result set.  False will not return specified parentName.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of names that are parents of given child.
+     */
+    static Set<String> getAscendants( String childName, String parentName, boolean isInclusive, String contextId )
+    {
+        return HierUtil.getAscendants( childName, parentName, isInclusive, getGraph( contextId ) );
+    }
+
+
+    /**
+     * This api is used by {@link AdminMgrImpl} to determine parentage for Hierarchical RBAC processing.
+     * It calls {@link HierUtil#validateRelationship(org.jgrapht.graph.SimpleDirectedGraph, String, String, boolean)} to evaluate three adminRole 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 childRole  contains {@link org.apache.directory.fortress.core.rbac.Role#name} of child.
+     * @param parentRole contains {@link org.apache.directory.fortress.core.rbac.Role#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( Role childRole, Role parentRole, boolean mustExist )
+        throws ValidationException
+    {
+        HierUtil.validateRelationship( getGraph( childRole.getContextId() ), childRole.getName(), parentRole.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 ROLE context [" + inHier.getContextId() + "]" );
+        List<Graphable> descendants = null;
+        try
+        {
+            descendants = roleP.getAllDescendants( inHier.getContextId() );
+        }
+        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.ROLE ) )
+        {
+            graph = HierUtil.buildGraph( hier );
+        }
+        roleCache.put( getKey( contextId ), graph );
+        return graph;
+    }
+
+
+    /**
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return
+     */
+    private static String getKey( String contextId )
+    {
+        String key = HierUtil.Type.ROLE.toString();
+        if ( VUtil.isNotNullOrEmpty( contextId ) && !contextId.equalsIgnoreCase( GlobalIds.NULL ) )
+        {
+            key += ":" + contextId;
+        }
+        return key;
+    }
+
+
+    /**
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return
+     */
+    private static SimpleDirectedGraph<String, Relationship> getGraph( String contextId )
+    {
+        SimpleDirectedGraph<String, Relationship> graph = ( SimpleDirectedGraph<String, Relationship> ) roleCache
+            .get( getKey( contextId ) );
+        if ( graph == null )
+        {
+            graph = loadGraph( contextId );
+        }
+        return graph;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/SDSet.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/SDSet.java b/src/main/java/org/apache/directory/fortress/core/rbac/SDSet.java
new file mode 100755
index 0000000..81889d3
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/SDSet.java
@@ -0,0 +1,413 @@
+/*
+ *   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.XmlElement;
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+
+/**
+ * <h4>Static Separation of Duties Schema</h4>
+ * The Fortress SDSet entity is a composite of the following other Fortress structural and aux object classes:
+ * <p/>
+ * 1. organizationalRole Structural Object Class is used to store basic attributes like cn and description.
+ * <pre>
+ * ------------------------------------------
+ * objectclass ( 2.5.6.8 NAME 'organizationalRole'
+ *  DESC 'RFC2256: an organizational role'
+ *  SUP top STRUCTURAL
+ *  MUST cn
+ *  MAY (
+ *      x121Address $ registeredAddress $ destinationIndicator $
+ *      preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
+ *      telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $
+ *      seeAlso $ roleOccupant $ preferredDeliveryMethod $ street $
+ *      postOfficeBox $ postalCode $ postalAddress $
+ *      physicalDeliveryOfficeName $ ou $ st $ l $ description
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 2. The RBAC Separation of14:14 Duties includes:
+ * <p/> Static Separation of Duties
+ * <img src="../doc-files/RbacSSD.png">
+ * <pre>
+ * ------------------------------------------
+ * Fortress Dynamic Separation of Duties Structural Object Class
+ *  objectclass	( 1.3.6.1.4.1.38088.2.5
+ *  NAME 'ftDSDSet'
+ *  DESC 'Fortress Role Dynamic Separation of Duty Set Structural Object Class'
+ *  SUP organizationalrole
+ *  STRUCTURAL
+ *  MUST (
+ *      ftId $
+ *      ftSetName $
+ *      ftSetCardinality
+ *  )
+ *  MAY (
+ *      ftRoles $
+ *      description
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * OR
+ * <p/> Dynamic Separation of Duties
+ * <img src="../doc-files/RbacDSD.png">
+ * <pre>
+ * ------------------------------------------
+ * Fortress Static Separation of Duties Structural Object Class
+ *  objectclass	( 1.3.6.1.4.1.38088.2.4
+ *  NAME 'ftSSDSet'
+ *  DESC 'Fortress Role Static Separation of Duty Set Structural Object Class'
+ *  SUP organizationalrole
+ *  STRUCTURAL
+ *  MUST (
+ *      ftId $
+ *      ftSetName $
+ *      ftSetCardinality
+ *  )
+ *  MAY (
+ *      ftRoles $
+ *      description
+ *  )
+ *)
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ * 3. ftMods AUXILIARY Object Class is used to store Fortress audit variables on target entity.
+ * <pre>
+ * ------------------------------------------
+ * Fortress Audit Modification Auxiliary Object Class
+ * objectclass ( 1.3.6.1.4.1.38088.3.4
+ *  NAME 'ftMods'
+ *  DESC 'Fortress Modifiers AUX Object Class'
+ *  AUXILIARY
+ *  MAY (
+ *      ftModifier $
+ *      ftModCode $
+ *      ftModId
+ *  )
+ * )
+ * ------------------------------------------
+ * </pre>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortSet")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "sdset", propOrder = {
+    "name",
+    "id",
+    "description",
+    "cardinality",
+    "members",
+    "type"
+})
+public class SDSet extends FortEntity
+    implements java.io.Serializable, Comparable
+{
+    private String id;
+    private String name;
+    private String description;
+    private Integer cardinality;
+    @XmlElement(nillable = true)
+    private Set<String> members;
+    private SDType type;
+
+
+    /**
+     * enum for SSD or DSD data sets.  Both nodes will be stored in the same LDAP container but use different
+     * object classes.
+     * SDType determines if 'ftSSDSet' or 'ftDSDSet' object class is used.
+     */
+    @XmlType(name = "sdtype")
+    @XmlEnum
+    public enum SDType
+    {
+        /**
+         * Static Separation of Duty data set.
+         */
+        STATIC,
+
+        /**
+         * Dynamic Separation of Duty data set.
+         */
+        DYNAMIC
+    }
+
+    /**
+     * Get the required type of SD Set - 'STATIC' Or 'DYNAMIC'.
+     *
+     * @return type that maps to either 'ftSSDSet' or 'ftDSDSet' object class is used.
+     */
+    public SDType getType()
+    {
+        return type;
+    }
+
+    /**
+     * Set the required type of SD Set - 'STATIC' Or 'DYNAMIC'.
+     *
+     * @param type maps to either 'ftSSDSet' or 'ftDSDSet' object class is used.
+     */
+    public void setType(SDType type)
+    {
+        this.type = type;
+    }
+
+    /**
+     * Create a new, empty map that is used to load Role members.  This method is called by any class
+     * that needs to create an SDSet set.
+     *
+     * @return Set that sorts members by alphabetical order.
+     */
+    private static Set<String> createMembers()
+    {
+        return new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+    }
+
+
+    /**
+     * Return the name of SDSet entity.  This field is required.
+     *
+     * @return attribute maps to 'cn' attribute on the 'organizationalRole' object class.
+     */
+    public String getName()
+    {
+        return this.name;
+    }
+
+
+    /**
+     * Set the name of SDSet entity.  This field is required.
+     *
+     * @param name maps to 'cn' attribute on the 'organizationalRole' object class.
+     */
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+
+    /**
+     * Returns optional description that is associated with SDSet.  This attribute is validated but not constrained by Fortress.
+     *
+     * @return value that is mapped to 'description' in 'organizationalrole' object class.
+     */
+    public String getDescription()
+    {
+        return this.description;
+    }
+
+
+    /**
+     * Sets the optional description that is associated with SDSet.  This attribute is validated but not constrained by Fortress.
+     *
+     * @param description that is mapped to same name in 'organizationalrole' object class.
+     */
+    public void setDescription(String description)
+    {
+        this.description = description;
+    }
+
+
+    /**
+     * Return the internal id that is associated with SDSet.  This attribute is generated automatically
+     * by Fortress when new SDSet is added to directory and is not known or changeable by external client.
+     *
+     * @return attribute maps to 'ftId' in either 'ftSSDSet' or 'ftDSDSet' object class.
+     */
+    public String getId()
+    {
+        return id;
+    }
+
+
+    /**
+     * Generate an internal Id that is associated with SDSet.  This method is used by DAO class and
+     * is not available to outside classes.   The generated attribute maps to 'ftId' in either 'ftSSDSet' or 'ftDSDSet' object class.
+     */
+    public void setId()
+    {
+        // generate a unique id that will be used as the rDn for this entry:
+        UUID uuid = UUID.randomUUID();
+        this.id = uuid.toString();
+    }
+
+
+    /**
+     * Set the internal Id that is associated with Role.  This method is used by DAO class and
+     * is generated automatically by Fortress.  Attribute stored in LDAP cannot be changed by external caller.
+     * This method can be used by client for search purposes only.
+     *
+     * @param id maps to 'ftId' in either 'ftSSDSet' or 'ftDSDSet' object class.
+     */
+    public void setId(String id)
+    {
+        this.id = id;
+    }
+
+
+    /**
+     * Return the numeric value that reflects the membership cardinality for SDSet.  A value of '2' indicates
+     * the Role membership is mutually exclusive amongst members.  A value of '3' indicates no more than two Roles
+     * in set can be assigned to a single User (SSD) or activated within a single Session (DSD).  A value of '4' indicates
+     * no more than three Roles may be used at a time, etc...
+     *
+     * @return attribute maps to 'ftSetCardinality' attribute in either 'ftSSDSet' or 'ftDSDSet' object class.
+     */
+    public Integer getCardinality()
+    {
+        return cardinality;
+    }
+
+    /**
+     * Set the numeric value that reflects the membership cardinality for SDSet.  A value of '2' indicates
+     * the Role membership is mutually exclusive amongst members.  A value of '3' indicates no more than two Roles
+     * in set can be assigned to a single User (SSD) or activated within a single Session (DSD).  A value of '4' indicates
+     * no more than three Roles may be used at a time, etc...
+     *
+     */
+    public void setCardinality(Integer cardinality)
+    {
+        this.cardinality = cardinality;
+    }
+
+    /**
+     * Return the alphabetically sorted Set containing Role membership to SDSet.
+     *
+     * @return attribute maps to 'ftRoles' attribute in either 'ftSSDSet' or 'ftDSDSet' object class.
+     */
+    //@XmlJavaTypeAdapter(SetAdapter.class)
+    public Set<String> getMembers()
+    {
+        return members;
+    }
+
+    /**
+     * Set an alphabetically sorted Set containing Role membership to SDSet.
+     *
+     * @param members attribute maps to 'ftRoles' attribute in either 'ftSSDSet' or 'ftDSDSet' object class.
+     */
+    public void setMembers(Set<String> members)
+    {
+        this.members = members;
+    }
+
+
+    /**
+     * Add a member to the set.
+     *
+     * @param member role name.
+     */
+    public void setMember(String member)
+    {
+        if(this.members == null)
+        {
+            this.members = new HashSet<>();
+        }
+        this.members.add(member);
+    }
+
+
+    /**
+     * Add a member to an alphabetically sorted Set containing Role membership to SDSet.
+     *
+     * @param role attribute maps to 'ftRoles' attribute in either 'ftSSDSet' or 'ftDSDSet' object class.
+     */
+    public void addMember(String role)
+    {
+        if (this.members == null)
+        {
+            this.members = createMembers();
+        }
+        this.members.add(role);
+    }
+
+    /**
+     * Remove a member from the alphabetically sorted Set containing Role membership to SDSet.
+     *
+     * @param role attribute maps to 'ftRoles' attribute in either 'ftSSDSet' or 'ftDSDSet' object class.
+     */
+    public void delMember(String role)
+    {
+        if (this.members == null)
+        {
+            return;
+        }
+        this.members.remove(role);
+    }
+
+    public int compareTo(Object o)
+    {
+        SDSet k1 = this;
+        SDSet k2 = (SDSet) o;
+        String s1 = k1.getName();
+        String s2 = k2.getName();
+        return s1.compareToIgnoreCase(s2);
+    }
+
+    /**
+     * Matches the name from two SDSet entities.
+     *
+     * @param thatObj contains an SDSet entity.
+     * @return boolean indicating both objects contain matching SDSet names.
+     */
+    public boolean equals(Object thatObj)
+    {
+        if (this == thatObj)
+        {
+            return true;
+        }
+        if (this.getName() == null)
+        {
+            return false;
+        }
+        if (!(thatObj instanceof Role ))
+        {
+            return false;
+        }
+        SDSet thatSet = (SDSet) thatObj;
+        if (thatSet.getName() == null)
+        {
+            return false;
+        }
+        return thatSet.getName().equalsIgnoreCase(this.getName());
+    }
+
+    @Override
+    public String toString()
+    {
+        return "SDSet{" +
+            "name='" + name + '\'' +
+            '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/SDUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/SDUtil.java b/src/main/java/org/apache/directory/fortress/core/rbac/SDUtil.java
new file mode 100755
index 0000000..0eb4c88
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/SDUtil.java
@@ -0,0 +1,533 @@
+/*
+ *   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 org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.ReviewMgrFactory;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.ReviewMgr;
+import org.apache.directory.fortress.core.cfg.Config;
+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;
+import org.apache.directory.fortress.core.util.cache.DsdCacheEntry;
+import org.apache.directory.fortress.core.util.time.Constraint;
+import net.sf.ehcache.search.Attribute;
+import net.sf.ehcache.search.Query;
+import net.sf.ehcache.search.Result;
+import net.sf.ehcache.search.Results;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This utilty provides functionality necessary for SSD and DSD processing and cannot be called by components outside fortress.
+ * This class also contains utility functions for maintaining the SSD and DSD cache.
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ * @created September 3, 2010
+ */
+final class SDUtil
+{
+    private static final Cache m_dsdCache;
+    private static final String FORTRESS_DSDS = "fortress.dsd";
+    private static final Cache m_ssdCache;
+    private static final String FORTRESS_SSDS = "fortress.ssd";
+    private static final SdP sp = new SdP();
+    private static final String IS_DSD_CACHE_DISABLED_PARM = "enable.dsd.cache";
+    private static final String MEMBER = "member";
+    private static final String DSD_NAME = "name";
+    private static final String EMPTY_ELEMENT = "empty";
+    private static final String CONTEXT_ID = "contextId";
+
+    static
+    {
+        // Get a reference to the CacheManager Singleton object:
+        CacheMgr cacheMgr = CacheMgr.getInstance();
+        // This cache contains a wrapper entry for DSD and is searchable by both DSD and Role name:
+        m_dsdCache = cacheMgr.getCache(FORTRESS_DSDS);
+        // This cache is not searchable and contains Lists of SSD objects by Role:
+        m_ssdCache = cacheMgr.getCache(FORTRESS_SSDS);
+    }
+
+    /**
+     * This method is called by AdminMgr.assignUser and is used to validate Static Separation of Duty
+     * constraints when assigning a role to user.
+     *
+     * @param uRole
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *
+     */
+    static void validateSSD(UserRole uRole)
+        throws SecurityException
+    {
+        validateSSD(new User(uRole.getUserId()), new Role(uRole.getName()));
+    }
+
+    /**
+     * This method is called by AdminMgr.assignUser and is used to validate Static Separation of Duty
+     * constraints when assigning a role to user.
+     *
+     * @param user
+     * @param role
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *
+     */
+    static void validateSSD(User user, Role role)
+        throws SecurityException
+    {
+        int matchCount;
+        // get all authorized roles for user
+        ReviewMgr rMgr = ReviewMgrFactory.createInstance(user.getContextId());
+        Set<String> rls = rMgr.authorizedRoles(user);
+        // Need to proceed?
+        if (!VUtil.isNotNullOrEmpty(rls))
+        {
+            return;
+        }
+
+        // get all SSD sets that contain the new role
+        List<SDSet> ssdSets = getSsdCache(role.getName(), user.getContextId());
+        for (SDSet ssd : ssdSets)
+        {
+            matchCount = 0;
+            Set<String> map = ssd.getMembers();
+            // iterate over every authorized role for user:
+            for (String authRole : rls)
+            {
+                // is there a match found between authorized role and SSD set's members?
+                if (map.contains(authRole))
+                {
+                    matchCount++;
+                    // does the match count exceed the cardinality allowed for this particular SSD set?
+                    if (matchCount >= ssd.getCardinality() - 1)
+                    {
+                        String error = "validateSSD new role [" + role.getName() + "] validates SSD Set Name:" + ssd.getName() + " Cardinality:" + ssd.getCardinality();
+                        throw new SecurityException(GlobalErrIds.SSD_VALIDATION_FAILED, error);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * This method is called by AccessMgr.addActiveRole and is used to validate Dynamic Separation of Duty
+     * constraints when activating a role one at a time.  For activation of multiple roles simultaneously use
+     * the DSD.validate API which is used during createSession sequence.
+     *
+     * @param session
+     * @param role
+     * @throws org.apache.directory.fortress.core.SecurityException
+     *
+     */
+    static void validateDSD(Session session, Constraint role)
+        throws SecurityException
+    {
+        // get all activated roles from user's session:
+        List<UserRole> rls = session.getRoles();
+        if (!VUtil.isNotNullOrEmpty(rls))
+        {
+            // An empty list of roles was passed in the session variable.
+            // No need to continue.
+            return;
+        }
+
+        // get all DSD sets that contain the target role
+        Set<SDSet> dsdSets = getDsdCache(role.getName(), session.getContextId());
+        for (SDSet dsd : dsdSets)
+        {
+            // Keeps the number of matched roles to a particular DSD set.
+            int matchCount = 0;
+
+            // Contains the list of roles assigned to a particular DSD set.
+            Set<String> map = dsd.getMembers();
+
+            // iterate over every role active in session for match wth DSD members:
+            for (UserRole actRole : rls)
+            {
+                // is there a match found between active role in session and DSD set members?
+                if (map.contains(actRole.getName()))
+                {
+                    // Yes, we found a match, increment the count.
+                    matchCount++;
+
+                    // Does the match count exceed the cardinality allowed for this particular DSD set?
+                    if (matchCount >= dsd.getCardinality() - 1)
+                    {
+                        // Yes, the target role violates DSD cardinality rule.
+                        String error = "validateDSD failed for role [" + role.getName() + "] DSD Set Name:" + dsd.getName() + " Cardinality:" + dsd.getCardinality();
+                        throw new SecurityException(GlobalErrIds.DSD_VALIDATION_FAILED, error);
+                    }
+                }
+                else // Check the parents of activated role for DSD match:
+                {
+                    // Now pull the activated role's list of parents.
+                    Set<String> parentSet = RoleUtil.getAscendants(actRole.getName(), session.getContextId());
+
+                    // Iterate over the list of parent roles:
+                    for (String parentRole : parentSet)
+                    {
+                        if (map.contains(parentRole)) // is there match between parent and DSD member?
+                        {
+                            matchCount++;
+                            if (matchCount >= dsd.getCardinality() - 1) // Does the counter exceed max per cardinality on this DSD set?
+                            {
+                                String error = "validateDSD failed for role [" + role.getName() + "] parent role [" + parentRole + "] DSD Set Name:" + dsd.getName() + " Cardinality:" + dsd.getCardinality();
+                                throw new SecurityException(GlobalErrIds.DSD_VALIDATION_FAILED, error);
+                            }
+                            // Breaking out of the loop here means the DSD algorithm will only match one
+                            // role per parent of active role candidate.
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Given DSD entry name, clear its corresponding object values from the cache.
+     *
+     * @param name contains the name of object to be cleared.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.     *
+     * @throws SecurityException in the event of system or rule violation.
+     */
+    static void clearDsdCacheEntry(String name, String contextId)
+    {
+        Attribute<String> context = m_dsdCache.getSearchAttribute(CONTEXT_ID);
+        Attribute<String> dsdName = m_dsdCache.getSearchAttribute(DSD_NAME);
+        Query query = m_dsdCache.createQuery();
+        query.includeKeys();
+        query.includeValues();
+        query.addCriteria(dsdName.eq(name).and(context.eq(contextId)));
+        Results results = query.execute();
+        for (Result result : results.all())
+        {
+            m_dsdCache.clear(result.getKey());
+        }
+    }
+
+    /**
+     * Given a role name, return the set of DSD's that have a matching member.
+     *
+     * @param name contains name of authorized Role used to search the cache.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return un-ordered set of matching DSD's.
+     * @throws SecurityException in the event of system or rule violation.
+     */
+    private static Set<SDSet> getDsdCache(String name, String contextId)
+        throws SecurityException
+    {
+        contextId = getContextId(contextId);
+        Set<SDSet> finalSet = new HashSet<>();
+        Attribute<String> context = m_dsdCache.getSearchAttribute(CONTEXT_ID);
+        Attribute<String> member = m_dsdCache.getSearchAttribute(MEMBER);
+        Query query = m_dsdCache.createQuery();
+        query.includeKeys();
+        query.includeValues();
+        query.addCriteria(member.eq(name).and(context.eq(contextId)));
+        Results results = query.execute();
+        boolean empty = false;
+        for (Result result : results.all())
+        {
+            DsdCacheEntry entry = (DsdCacheEntry) result.getValue();
+            if (!entry.isEmpty())
+            {
+                finalSet.add(entry.getSdSet());
+                finalSet = putDsdCache(name, contextId);
+            }
+            else
+            {
+                empty = true;
+            }
+            finalSet.add(entry.getSdSet());
+        }
+        // If nothing was found in the cache, determine if it needs to be seeded:
+        if (finalSet.size() == 0 && !empty)
+        {
+            finalSet = putDsdCache(name, contextId);
+        }
+        return finalSet;
+    }
+
+    /**
+     * Given a Set of authorized Roles, return the set of DSD's that have matching members.
+     *
+     * @param authorizedRoleSet contains an un-order Set of authorized Roles.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return un-ordered set of matching DSD's.
+     * @throws SecurityException in the event of system or rule violation.
+     */
+    static Set<SDSet> getDsdCache(Set<String> authorizedRoleSet, String contextId)
+        throws SecurityException
+    {
+        contextId = getContextId(contextId);
+        Set<SDSet> dsdRetSets = new HashSet<>();
+        // Need to proceed?
+        if (!VUtil.isNotNullOrEmpty(authorizedRoleSet))
+        {
+            return dsdRetSets;
+        }
+        // Was the DSD Cache switched off?
+        boolean isCacheDisabled = Config.getBoolean(IS_DSD_CACHE_DISABLED_PARM, false);
+        // If so, get DSD's from LDAP:
+        if (isCacheDisabled)
+        {
+            SDSet sdSet = new SDSet();
+            sdSet.setType(SDSet.SDType.DYNAMIC);
+            sdSet.setContextId(contextId);
+            dsdRetSets = sp.search(authorizedRoleSet, sdSet);
+        }
+        // Search the DSD cache for matching Role members:
+        else
+        {
+            // Search on roleName attribute which maps to 'member' attr on the cache record:
+            Attribute<String> member = m_dsdCache.getSearchAttribute(MEMBER);
+            Attribute<String> context = m_dsdCache.getSearchAttribute(CONTEXT_ID);
+            Query query = m_dsdCache.createQuery();
+            query.includeKeys();
+            query.includeValues();
+            // Add the passed in authorized Role names to this cache query:
+            Set<String> roles = new HashSet<>(authorizedRoleSet);
+            query.addCriteria(member.in(roles).and(context.eq(contextId)));
+            // Return all DSD cache entries that match roleName to the 'member' attribute in cache entry:
+            Results results = query.execute();
+            for (Result result : results.all())
+            {
+                DsdCacheEntry entry = (DsdCacheEntry) result.getValue();
+                // Do not add dummy DSD sets to the final list:
+                if (!entry.isEmpty())
+                {
+                    dsdRetSets.add(entry.getSdSet());
+                }
+                // Remove role member from authorizedRoleSet to preclude from upcoming DSD search:
+                authorizedRoleSet.remove(entry.getMember());
+            }
+            // Authorized roles remaining in this set correspond to missed cache hits from above:
+            if (authorizedRoleSet.size() > 0)
+            {
+                dsdRetSets = putDsdCache(authorizedRoleSet, contextId);
+            }
+        }
+        return dsdRetSets;
+    }
+
+    /**
+     * Get the matching DSD's from directory and add to the cache (if found).  If matching DSD not found,
+     * add dummy entry to cache to prevent repeated searches.
+     *
+     * @param authorizedRoleSet contains set of Roles used to search directory for matching DSD's.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return List of DSD's who have matching Role members.
+     * @throws SecurityException in the event of system or rule violation.
+     */
+    private static Set<SDSet> putDsdCache(Set<String> authorizedRoleSet, String contextId)
+        throws SecurityException
+    {
+        contextId = getContextId(contextId);
+        Set<SDSet> dsdSets = new HashSet<>();
+        // Search the DSD's iteratively to seed the DSD cache by Role name:
+        for (String roleName : authorizedRoleSet)
+        {
+            Role role = new Role(roleName);
+            role.setContextId(contextId);
+            List<SDSet> dsdList = sp.search(role, SDSet.SDType.DYNAMIC);
+            if (VUtil.isNotNullOrEmpty(dsdList))
+            {
+                for (SDSet dsd : dsdList)
+                {
+                    dsd.setContextId(contextId);
+                    Set<String> members = dsd.getMembers();
+                    if (members != null)
+                    {
+                        // Seed the cache with DSD objects mapped to role name:
+                        for (String member : members)
+                        {
+                            String key = buildKey(dsd.getName(), member);
+                            DsdCacheEntry entry = new DsdCacheEntry(member, dsd, false);
+                            entry.setName(dsd.getName());
+                            m_dsdCache.put(getKey(key, contextId), entry);
+                        }
+                    }
+                }
+                // Maintain the set of DSD's to be returned to the caller:
+                dsdSets.addAll(dsdList);
+            }
+            else
+            {
+                // Seed the cache with dummy entry for a Role that is not referenced by DSD:
+                String key = buildKey(EMPTY_ELEMENT, roleName);
+                SDSet sdSet = new SDSet();
+                sdSet.setType(SDSet.SDType.DYNAMIC);
+                sdSet.setName(key);
+                sdSet.setMember(roleName);
+                sdSet.setContextId(contextId);
+                DsdCacheEntry entry = new DsdCacheEntry(roleName, sdSet, true);
+                entry.setName(key);
+                m_dsdCache.put(getKey(sdSet.getName(), contextId), entry);
+            }
+        }
+        return dsdSets;
+    }
+
+    /**
+     * Get the matching DSD's from directory and add to the cache (if found).  If matching DSD not found,
+     * add dummy entry to cache to prevent repeated searches.
+     *
+     * @param roleName of Role is used to search directory for matching DSD's.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return Set of DSD's who have matching Role member.
+     * @throws SecurityException in the event of system or rule violation.
+     */
+    private static Set<SDSet> putDsdCache(String roleName, String contextId)
+        throws SecurityException
+    {
+        contextId = getContextId(contextId);
+        Role role = new Role(roleName);
+        role.setContextId(contextId);
+        List<SDSet> dsdList = sp.search(role, SDSet.SDType.DYNAMIC);
+        Set<SDSet> finalSet = new HashSet<>(dsdList);
+        if (VUtil.isNotNullOrEmpty(dsdList))
+        {
+            for (SDSet dsd : dsdList)
+            {
+                dsd.setContextId(contextId);
+                Set<String> members = dsd.getMembers();
+                if (members != null)
+                {
+                    // Seed the cache with DSD objects mapped to role name:
+                    for (String member : members)
+                    {
+                        String key = buildKey(dsd.getName(), member);
+                        DsdCacheEntry entry = new DsdCacheEntry(member, dsd, false);
+                        entry.setName(dsd.getName());
+                        m_dsdCache.put(getKey(key, contextId), entry);
+                    }
+                }
+            }
+        }
+        else
+        {
+            // Seed the cache with dummy entry for Role that does not have DSD:
+            String key = buildKey(EMPTY_ELEMENT, roleName);
+            SDSet sdSet = new SDSet();
+            sdSet.setType(SDSet.SDType.DYNAMIC);
+            sdSet.setName(key);
+            sdSet.setMember(roleName);
+            sdSet.setContextId(contextId);
+            DsdCacheEntry entry = new DsdCacheEntry(roleName, sdSet, true);
+            entry.setName(key);
+            m_dsdCache.put(getKey(sdSet.getName(), contextId), entry);
+        }
+        return finalSet;
+    }
+
+    /**
+     * Given entry name, clear its corresponding object value from the cache.
+     *
+     * @param name contains the name of object to be cleared.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @throws SecurityException in the event of system or rule violation.
+     */
+    static void clearSsdCacheEntry(String name, String contextId)
+    {
+        contextId = getContextId(contextId);
+        m_ssdCache.clear(getKey(name, contextId));
+    }
+
+    /**
+     * Get the matching SSD's from directory and add to the cache (if found).
+     *
+     * @param name of Role is used to search directory for matching SSD's.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return List of SSD's who have matching Role member.
+     * @throws SecurityException in the event of system or rule violation.
+     */
+    private static List<SDSet> putSsdCache(String name, String contextId)
+        throws SecurityException
+    {
+        Role role = new Role(name);
+        role.setContextId(contextId);
+        List<SDSet> ssdSets = sp.search(role, SDSet.SDType.STATIC);
+        m_ssdCache.put(getKey(name, contextId), ssdSets);
+        return ssdSets;
+    }
+
+    /**
+     * Look in cache for matching List of SSD's.
+     *
+     * @param name of Role is used to search directory for matching SSD's.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return List of SSD's who have matching Role member.
+     * @throws SecurityException in the event of system or rule violation.
+     */
+    private static List<SDSet> getSsdCache(String name, String contextId)
+        throws SecurityException
+    {
+        List<SDSet> ssdSets = (List<SDSet>) m_ssdCache.get(getKey(name, contextId));
+        if (ssdSets == null)
+        {
+            ssdSets = putSsdCache(name, contextId);
+        }
+        return ssdSets;
+    }
+
+    /**
+     *
+     * @param parm1
+     * @param parm2
+     * @return
+     */
+    private static String buildKey(String parm1, String parm2)
+    {
+        return parm1 + ":" + parm2;
+    }
+
+    /**
+     *
+     * @param name
+     * @param contextId
+     * @return
+     */
+    private static String getKey(String name, String contextId)
+    {
+        contextId = getContextId(contextId);
+        return name += ":" + contextId;
+    }
+
+    /**
+     *
+     * @param contextId
+     * @return
+     */
+    private static String getContextId(String contextId)
+    {
+        String szContextId = GlobalIds.HOME;
+        if(VUtil.isNotNullOrEmpty(contextId) && !contextId.equals(GlobalIds.NULL))
+        {
+            szContextId = contextId;
+        }
+        return szContextId;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/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
new file mode 100755
index 0000000..fa06867
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/SdP.java
@@ -0,0 +1,221 @@
+/*
+ *   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 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;
+
+
+/**
+ * Process module for Separation of Duty Relation data sets. The Fortress SD data set can be of two types:
+ * <ol>
+ * <li>Static Separation of Duties (SSD)</li>
+ * <li>Dynamic Separation of Duties (DSD)</li>
+ * </ol>
+ * The SDSet entity itself distinguishes which is being targeted by {@link SDSet.SDType} which is equal to {@link SDSet.SDType#STATIC} or {@link SDSet.SDType#DYNAMIC}.
+ * 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}.
+ * <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
+ * @created September 11, 2010
+ */
+public final class SdP
+{
+    /**
+     * Get the DAO created:
+     */
+    private static final SdDAO sdDao = new SdDAO();
+
+
+    /**
+     * Package private constructor.
+     */
+    SdP()
+    {
+    }
+
+
+    /**
+     * Adds a new SDSet to directory. The OrgUnit SDType enum will determine which data set insertion will
+     * occur - STATIC or DYNAMIC.  The SDSet entity input will be validated to ensure that:
+     * name is present, and reasonability checks on all of the other populated values.
+     *
+     * @param entity SDSet contains data targeted for insertion.
+     * @return SDSet 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 SDSet add( SDSet entity ) throws SecurityException
+    {
+        validate( entity );
+        return sdDao.create( entity );
+    }
+
+
+    /**
+     * Updates existing SDSet in directory. The SDSet type enum will determine which data set insertion will
+     * occur - STATIC or DYNAMIC.  The SDSet entity input will be validated to ensure that:
+     * name is present, and reasonability checks on all of the other populated values.
+     * Null or empty attributes are ignored.
+     *
+     * @param entity SDSet contains data targeted for updating.  Null attributes ignored.
+     * @return SDSet entity copy of input + additional attributes (internalId) that were updated by op.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final SDSet update( SDSet entity ) throws SecurityException
+    {
+        validate( entity );
+        return sdDao.update( entity );
+    }
+
+
+    /**
+     * This method performs a "hard" delete.  It completely the SDSet node from the ldap directory.
+     * The SDSet type enum will determine where deletion will occur - STATIC or DYNAMIC data sets.
+     * SDSet entity must exist in directory prior to making this call else exception will be thrown.
+     *
+     * @param entity Contains the name of the SDSet node targeted for deletion.
+     * @return SDSet is a copy of entity.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    final SDSet delete( SDSet entity ) throws SecurityException
+    {
+        return sdDao.remove( entity );
+    }
+
+
+    /**
+     * Return a fully populated SDSet entity for a given STATIC or DYNAMIC SDSet name.  If matching record not found a
+     * SecurityException will be thrown.
+     *
+     * @param entity contains full SDSet name used for STATIC or DYNAMIC data sets in directory.
+     * @return SDSet entity containing all attributes associated with ou in directory.
+     * @throws SecurityException in the event SDSet not found or DAO search error.
+     */
+    final SDSet read( SDSet entity ) throws SecurityException
+    {
+        SDSet sde;
+        // The assumption is this method is called from ReviewMgr.ssdRoleSetRoles or ReviewMgr.dsdRoleSetRoles.
+        // If called from ReviewMgr, the object class type will be passed in:
+        SDSet.SDType type = entity.getType();
+        sde = sdDao.getSD( entity );
+        // Load the previously saved type onto the return entity:
+        sde.setType( type );
+        return sde;
+    }
+
+
+    /**
+     * Will search using a single RBAC Role name either STATIC or DYNAMIC SDSet depending on which type is passed.
+     * The role entity contains full RBAC Role name associated with SDSet node in directory.
+     *
+     * @param sdSet contains sdset name or partial name along with sdset type of STATIC or DYNAMIC.
+     * @return List of SDSet entities found.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<SDSet> search( SDSet sdSet ) throws SecurityException
+    {
+        return sdDao.search( sdSet );
+    }
+
+
+    /**
+     * Will search using a single RBAC Role name either STATIC or DYNAMIC SDSet depending on which type is passed.
+     * The role entity contains full RBAC Role name associated with SDSet node in directory.
+     *
+     * @param role contains full role name associated with SDSet.
+     * @param type either STATIC or DYNAMIC depending on target search data set.
+     * @return List of SDSet entities found.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final List<SDSet> search( Role role, SDSet.SDType type ) throws SecurityException
+    {
+        return sdDao.search( role, type );
+    }
+
+
+    /**
+     * Will search using list of input RBAC role names either STATIC or DYNAMIC SDSet depending on which type is passed.
+     * The role entity contains full RBAC Role name associated with SDSet node in directory.
+     *
+     * @param rls  contains set of type String containing full role names associated with SDSet.
+     * @param sdSet contains type either STATIC or DYNAMIC depending on target search data set.
+     * @return List of SDSet entities found.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    final Set<SDSet> search( Set<String> rls, SDSet sdSet ) throws SecurityException
+    {
+        return sdDao.search( rls, sdSet );
+    }
+
+
+    /**
+     * Method will perform simple validations to ensure the integrity of the SDSet entity targeted for insertion
+     * or updating in directory.  This method will ensure the name and type enum are specified.  Method will
+     * also ensure every Role name set is valid RBAC role entity in directory.  It will also perform
+     * reasonability check on description if set.
+     *
+     * @param entity contains the enum type to validate
+     * @throws SecurityException thrown in the event the attribute is null.
+     */
+    private void validate( SDSet entity )
+        throws SecurityException
+    {
+        // TODO: Add more validations here:
+        VUtil.safeText( entity.getName(), GlobalIds.OU_LEN );
+        if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+        {
+            VUtil.description( entity.getDescription() );
+        }
+        Set<String> roles = entity.getMembers();
+        if ( roles != null )
+        {
+            RoleP rp = new RoleP();
+            for ( String key : roles )
+            {
+                // when removing last role member a placeholder must be left in data set:
+                if ( !key.equalsIgnoreCase( GlobalIds.NONE ) )
+                {
+                    // Ensure the name exists:
+                    Role role = new Role( key );
+                    role.setContextId( entity.getContextId() );
+                    rp.read( role );
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/Session.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/Session.java b/src/main/java/org/apache/directory/fortress/core/rbac/Session.java
new file mode 100755
index 0000000..3e95094
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/Session.java
@@ -0,0 +1,688 @@
+/*
+ *   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.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * This contains attributes related to a user's RBAC session.
+ * The following example shows the mapping to Session attributes on this entity:
+ * <p/>
+ * <ul> <li><code>Session</code>
+ * <li> <code>session.getUserId() => demoUser4</code>
+ * <li> <code>session.getInternalUserId() => be2dd2e:12a82ba707e:-7fee</code>
+ * <li> <code>session.getMessage() => Fortress checkPwPolicies userId <demouser4> VALIDATION GOOD</code>
+ * <li> <code>session.getErrorId() => 0</code>
+ * <li> <code>session.getWarningId() => 11</code>
+ * <li> <code>session.getExpirationSeconds() => 469831</code>
+ * <li> <code>session.getGraceLogins() => 0</code>
+ * <li> <code>session.getIsAuthenticated() => true</code>
+ * <li> <code>session.getLastAccess() => 1283623680440</code>
+ * <li> <code>session.getSessionId() => -7410986f:12addeea576:-7fff</code>
+ * <li>  ------------------------------------------
+ * <li> <code>User user = session.getUser();</code>
+ * <ul> <li> <code>user.getUserId() => demoUser4</code>
+ * <li> <code>user.getInternalId() => be2dd2e:12a82ba707e:-7fee</code>
+ * <li> <code>user.getCn() => JoeUser4</code>
+ * <li> <code>user.getDescription() => Demo Test User 4</code>
+ * <li> <code>user.getOu() => test</code>
+ * <li> <code>user.getSn() => User4</code>
+ * <li> <code>user.getBeginDate() => 20090101</code>
+ * <li> <code>user.getEndDate() => none</code>
+ * <li> <code>user.getBeginLockDate() => none</code>
+ * <li> <code>user.getEndLockDate() => none</code>
+ * <li> <code>user.getDayMask() => 1234567</code>
+ * <li> <code>user.getTimeout() => 60</code>
+ * <li> <code>List<UserRole> roles = session.getRoles();</code>
+ * <ul> <li><code>UserRole userRole = roles.get(i);</code>
+ * <li> <code>userRole.getName() => role1</code>
+ * <li> <code>userRole.getBeginTime() => 0000</code>
+ * <li> <code>userRole.getEndTime() => 0000</code>
+ * <li> <code>userRole.getBeginDate() => none</code>
+ * <li> <code>userRole.getEndDate() => none</code>
+ * <li> <code>userRole.getBeginLockDate() => null</code>
+ * <li> <code>userRole.getEndLockDate() => null</code>
+ * <li> <code>userRole.getDayMask() => null</code>
+ * <li> <code>userRole.getTimeout() => 0</code>
+ * <li> <code>List<UserAdminRole> adminRoles = session.getAdminRoles();</code>
+ * </ul>
+ * <ul> <li><code>UserAdminRole userAdminRole = adminRoles.get(i);</code>
+ * <li> <code>userAdminRole.getName() => DemoAdminUsers</code>
+ * <li> <code>userAdminRole.getBeginTime() => 0000</code>
+ * <li> <code>userAdminRole.getEndTime() => 0000</code>
+ * <li> <code>userAdminRole.getBeginDate() => none</code>
+ * <li> <code>userAdminRole.getEndDate() => none</code>
+ * <li> <code>userAdminRole.getBeginLockDate() => null</code>
+ * <li> <code>userAdminRole.getEndLockDate() => null</code>
+ * <li> <code>userAdminRole.getDayMask() => null</code>
+ * <li> <code>userAdminRole.getTimeout() => 0</code>
+ * <li> <code>userAdminRole.getOsPs() => [ftT3POrg10, ftT4POrg10]</code>
+ * <li> <code>userAdminRole.getOsUs() => [ftT1UOrg10, ftT2UOrg10]</code>
+ * <li> <code>userAdminRole.getBeginRange() => ftT14Role1</code>
+ * <li> <code>userAdminRole.getEndRange() => ftT14Role10</code>
+ * <li> <code>userAdminRole.getBeginInclusive() => true</code>
+ * <li> <code>userAdminRole.getEndInclusive() => false</code>
+ * </ul>
+ * </ul>
+ * <p/>
+ * Sample Data data contained within this Entity.
+ * <p/>
+ * Ses UID      [demoUser4]:<br />
+ * Ses IID      [ccbb2929-bf01-413d-b768-529de4d428e5]<br />
+ * Ses ERR      [0]<br />
+ * Ses WARN     [10]<br />
+ * Ses MSG      [checkPwPolicies for userId <demouser4> PASSWORD CHECK SUCCESS]<br />
+ * Ses EXP      [0]<br />
+ * Ses GRAC     [0]<br />
+ * Ses AUTH     [true]<br />
+ * Ses LAST     [1297408501356]<br />
+ * Ses SID      [fc228713-1242-4061-9d8a-d4860bf8d3d8]<br />
+ * ------------------------------------------<br />
+ * Usr UID      [demoUser4]<br />
+ * Usr IID      [ccbb2929-bf01-413d-b768-529de4d428e5]<br />
+ * Usr CN       [JoeUser4]<br />
+ * Usr DESC     [Demo Test User 4]<br />
+ * Usr OU       [demousrs1]<br />
+ * Usr SN       [User4]<br />
+ * Usr BDTE     [20090101]<br />
+ * Usr EDTE     [20990101]<br />
+ * Usr BLDT     [none]<br />
+ * Usr ELDT     [none]<br />
+ * Usr DMSK     [1234567]<br />
+ * Usr TO       [60]<br />
+ * Usr REST     [false]<br />
+ * Usr PROP1    [customerNumber, 3213432]<br />
+ * <p/>
+ * USER RBAC ROLE[0]:<br />
+ * Rle  role name       [role1]<br />
+ * Rle  begin time      [0000]<br />
+ * Rle  end time        [0000]<br />
+ * Rle  begin date      [20110101]<br />
+ * Rle  end date        [none]<br />
+ * Rle  begin lock      [none]<br />
+ * Rle  end lock        [none]<br />
+ * Rle  day mask        [all]<br />
+ * Rle  time out        [60]<br />
+ * <p/>
+ * USER ADMIN ROLE[0]:<br />
+ * Adm  admin role name [DemoAdminUsers]<br />
+ * Adm  OsU             [Dev1]<br />
+ * Adm  OsP             [App1]<br />
+ * Adm  begin range     [role1]<br />
+ * Adm  end range       [role3]<br />
+ * Adm  begin time      [0000]<br />
+ * Adm  end time        [0000]<br />
+ * Adm  begin date      [20110101]<br />
+ * Adm  end date        [none]<br />
+ * Adm  begin lock      [none]<br />
+ * Adm  end lock        [none]<br />
+ * Adm  day mask        [23456]<br />
+ * Adm  time out        [30]<br />
+ * <p/>
+ * @author Shawn McKinney
+ */
+@XmlRootElement(name = "fortSession")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "session", propOrder = {
+    "user",
+    "isAuthenticated",
+    "sessionId",
+    "lastAccess",
+    "timeout",
+    "errorId",
+    "expirationSeconds",
+    "graceLogins",
+    "message",
+    "warnings"
+/*    "warningId"*/
+})
+public class Session  extends FortEntity implements PwMessage, java.io.Serializable
+{
+    private User user;
+    private String sessionId;
+    private long lastAccess;
+    private int timeout;
+/*    private int warningId;*/
+    private int errorId;
+    private int graceLogins;
+    private int expirationSeconds;
+    private boolean isAuthenticated;
+    private String message;
+    @XmlElement(nillable = true)
+    private List<Warning> warnings;
+
+    /**
+     * A 'true' value here indicates user successfully authenticated with Fortress.
+     *
+     * @return boolean indicating successful authentication.
+     */
+    public boolean isAuthenticated()
+    {
+        return isAuthenticated;
+    }
+
+    private void init()
+    {
+        // generate a unique id that will be used as the id for this session:
+        UUID uuid = UUID.randomUUID();
+        this.sessionId = uuid.toString();
+    }
+
+    /**
+     * Copy values from incoming Session object.
+     *
+     * @param inSession contains Session values.
+     */
+    public void copy(Session inSession)
+    {
+        this.user = inSession.getUser();
+        // don't copy session id:
+        //this.sessionId = inSession.getSessionId();
+        this.lastAccess = inSession.getLastAccess();
+        this.timeout = inSession.getTimeout();
+/*        this.warningId = inSession.getWarningId();*/
+        this.errorId = inSession.getErrorId();
+        this.graceLogins = inSession.getGraceLogins();
+        this.expirationSeconds = inSession.expirationSeconds;
+        this.isAuthenticated = inSession.isAuthenticated();
+        this.message = inSession.getMsg();
+        this.warnings = inSession.getWarnings();
+    }
+
+    /**
+     * Default constructor for Fortress Session.
+     */
+    public Session()
+    {
+        init();
+        // this class will not check for null on user object.
+        this.user = new User();
+    }
+
+    /**
+     * Construct a new Session instance with given User entity.
+     *
+     * @param user contains the User attributes that are associated with the Session.
+     */
+    public Session(User user)
+    {
+        init();
+        this.user = user;
+    }
+
+    /**
+     * Construct a new Session instance with given User entity.
+     *
+     * @param user contains the User attributes that are associated with the Session.
+     */
+    public Session(User user, String sessionId)
+    {
+        this.sessionId = sessionId;
+        this.user = user;
+    }
+
+    /**
+     * Return the unique id that is associated with User.  This attribute is generated automatically
+     * by Fortress when new Session is created and is not known or changeable by external client.
+     *
+     * @return attribute maps to unique sessionId associated with user's session.
+     */
+    public String getSessionId()
+    {
+        return this.sessionId;
+    }
+
+
+    /**
+     * Return the User entity that is associated with this entity.
+     *
+     * Sample User data contained in Session object:
+     * <p/>
+     * ------------------------------------------<br />
+     * U   UID  [demoUser4]<br />
+     * U   IID  [ccbb2929-bf01-413d-b768-529de4d428e5]<br />
+     * U   CN   [JoeUser4]<br />
+     * U   DESC [Demo Test User 4]<br />
+     * U   OU   [demousrs1]<br />
+     * U   SN   [User4]<br />
+     * U   BDTE [20090101]<br />
+     * U   EDTE [20990101]<br />
+     * U   BLDT [none]<br />
+     * U   ELDT [none]<br />
+     * U   DMSK [1234567]<br />
+     * U   TO   [60]<br />
+     * U   REST [false]<br />
+     * U   PROP[0]=customerNumber VAL=3213432<br />
+     * <p/>
+     * USER ROLE[0]:<br />
+     * role name <role1><br />
+     * begin time <0000><br />
+     * end time <0000><br />
+     * begin date <none><br />
+     * end date <none><br />
+     * begin lock <none><br />
+     * end lock <none><br />
+     * day mask <all><br />
+     * time out <0><br />
+     * <p/>
+     * USER ADMIN ROLE[0]:<br />
+     * admin role name <DemoAdminUsers><br />
+     * OsU <null><br />
+     * OsP <null><br />
+     * begin range <null><br />
+     * end range <null><br />
+     * begin time <0000><br />
+     * end time <0000><br />
+     * begin date <none><br />
+     * end date <none><br />
+     * begin lock <none><br />
+     * end lock <none><br />
+     * day mask <all><br />
+     * time out <0><br />
+     * <p/>
+     * @return User entity that contains userid, roles and other attributes valid for Session.
+     */
+    public User getUser()
+    {
+        return this.user;
+    }
+
+    /**
+     * Return the userId that is associated with this Session object.
+     *
+     * @return userId maps to the 'uid' attribute on the 'inetOrgPerson' object class.
+     */
+    public String getUserId()
+    {
+        return this.user.getUserId();
+    }
+
+    /**
+     * Return the internal userId that is associated with User.  This attribute is generated automatically
+     * by Fortress when new User is added to directory and is not known or changeable by external client.
+     *
+     * @return attribute maps to 'ftId' in 'ftUserAttrs' object class.
+     */
+    public String getInternalUserId()
+    {
+        return this.user.getInternalId();
+    }
+
+    /**
+     * Return the list of User's RBAC Roles that have been activated into User's session.  This list will not include
+     * ascendant RBAC roles which may be retrieved using {@link AccessMgrImpl#authorizedRoles(Session)}.
+     *
+     * @return List containing User's RBAC roles.  This list may be empty if User not assigned RBAC.
+     */
+    public List<UserRole> getRoles()
+    {
+        List<UserRole> roles = null;
+
+        if (user != null)
+            roles = user.getRoles();
+
+        return roles;
+    }
+
+    /**
+     * Return a list of User's Admin Roles  that have been activated into User's session.  This list will not include
+     * ascendant ARBAC roles which may be retrieved using {@link org.apache.directory.fortress.core.DelAccessMgr#authorizedAdminRoles(Session)}.
+     *
+     * @return List containing User's Admin roles.  This list may be empty if User not assigned Administrative role.
+     */
+    public List<UserAdminRole> getAdminRoles()
+    {
+        List<UserAdminRole> roles = null;
+
+        if (user != null)
+            roles = user.getAdminRoles();
+
+        return roles;
+    }
+
+    /**
+     * Returns the last access time in milliseconds. Note that while the unit of time of the return value is a millisecond,
+     * the granularity of the value depends on the underlying operating system and may be larger. For example, many
+     * operating systems measure time in units of tens of milliseconds.
+     *
+     * @return the difference, measured in milliseconds, between the last access time and midnight, January 1, 1970 UTC.
+     */
+    public long getLastAccess()
+    {
+        return this.lastAccess;
+    }
+
+    /**
+     * Gets the message that is associated with the user's last authentication attempt.
+     *
+     * @return String contains text explaining result of user's last authentication.
+     */
+    public String getMsg()
+    {
+        return this.message;
+    }
+
+    /**
+     * Gets the attribute that specifies the number of times an expired password can
+     * be used to authenticate before failure.
+     *
+     * @return The number of logins the user has left before password fails.
+     */
+    public int getGraceLogins()
+    {
+        return this.graceLogins;
+    }
+
+    /**
+     * This attribute specifies the maximum number of seconds before a
+     * password is due to expire that expiration warning messages will be
+     * returned to an authenticating user.
+     * <p/>
+     * If this attribute is not present, or if the value is 0 no warnings
+     * will be returned.  If not 0, the value must be smaller than the value
+     * of the pwdMaxAge attribute.
+     *
+     * @return attribute is computed based on last time user has changed their password.
+     */
+    public int getExpirationSeconds()
+    {
+        return this.expirationSeconds;
+    }
+
+    /**
+     * Get the integer timeout that contains max time (in seconds) that User's session may remain inactive.
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @return int maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    private int getTimeout()
+    {
+        return this.timeout;
+    }
+
+    /**
+     * Get the value that will be set to 'true' if user has successfully authenticated with Fortress for this Session.  This value is set by
+     * the Fortress DAO object.
+     *
+     * @return value indicates result of authentication.
+     */
+    public boolean setAuthenticated()
+    {
+        return this.isAuthenticated;
+    }
+
+    /**
+     * Return the error id that is associated with the password policy checks.  a '0' indicates no errors.
+     * <ul>
+     * <li> <code>INVALID_PASSWORD_MESSAGE = -10;</code>
+     * <li> <code>GOOD = 0;</code>
+     * <li> <code>PASSWORD_HAS_EXPIRED = 100;</code>
+     * <li> <code>ACCOUNT_LOCKED = 101;</code>
+     * <li> <code>CHANGE_AFTER_RESET = 102;</code>
+     * <li> <code>NO_MODIFICATIONS = 103;</code>
+     * <li> <code>MUST_SUPPLY_OLD = 104;</code>
+     * <li> <code>INSUFFICIENT_QUALITY = 105;</code>
+     * <li> <code>PASSWORD_TOO_SHORT = 106;</code>
+     * <li> <code>PASSWORD_TOO_YOUNG = 107;</code>
+     * <li> <code>HISTORY_VIOLATION = 108;</code>
+     * <li> <code>ACCOUNT_LOCKED_CONSTRAINTS = 109;</code>
+     * </ul>
+     * <p/>
+     *
+     * @return int contains the error id that was generated on the user's last authentication.
+     */
+    public int getErrorId()
+    {
+        return this.errorId;
+    }
+
+    /**
+     * Set a User entity into the Session.
+     * Sample User data contained in Session object:
+     * <p/>
+     * ------------------------------------------<br />
+     * U   UID  [demoUser4]<br />
+     * U   IID  [ccbb2929-bf01-413d-b768-529de4d428e5]<br />
+     * U   CN   [JoeUser4]<br />
+     * U   DESC [Demo Test User 4]<br />
+     * U   OU   [demousrs1]<br />
+     * U   SN   [User4]<br />
+     * U   BDTE [20090101]<br />
+     * U   EDTE [20990101]<br />
+     * U   BLDT [none]<br />
+     * U   ELDT [none]<br />
+     * U   DMSK [1234567]<br />
+     * U   TO   [60]<br />
+     * U   REST [false]<br />
+     * U   PROP[0]=customerNumber VAL=3213432<br />
+     * <p/>
+     * USER ROLE[0]:<br />
+     * role name <role1><br />
+     * begin time <0000><br />
+     * end time <0000><br />
+     * begin date <none><br />
+     * end date <none><br />
+     * begin lock <none><br />
+     * end lock <none><br />
+     * day mask <all><br />
+     * time out <0><br />
+     * <p/>
+     * USER ADMIN ROLE[0]:<br />
+     * admin role name <DemoAdminUsers><br />
+     * OsU <null><br />
+     * OsP <null><br />
+     * begin range <null><br />
+     * end range <null><br />
+     * begin time <0000><br />
+     * end time <0000><br />
+     * begin date <none><br />
+     * end date <none><br />
+     * begin lock <none><br />
+     * end lock <none><br />
+     * day mask <all><br />
+     * time out <0><br />
+     * <p/>
+     * @param user Contains userId, roles and other security attributes used for access control.
+     */
+    public void setUser(User user)
+    {
+        this.user = user;
+    }
+
+    /**
+     * Set the internal userId that is associated with User.  This method is used by DAO class and
+     * is generated automatically by Fortress.  Attribute stored in LDAP cannot be changed by external caller.
+     * This method can be used by client for search purposes only.
+     *
+     * @param internalUserId maps to 'ftId' in 'ftUserAttrs' object class.
+     */
+    public void setInternalUserId(String internalUserId)
+    {
+        this.user.setInternalId(internalUserId);
+    }
+
+    /**
+     * Set the value to 'true' indicating that user has successfully authenticated with Fortress.  This value is set by
+     * the Fortress DAO object.
+     *
+     * @param authenticated indicates result of authentication.
+     */
+    public void setAuthenticated(boolean authenticated)
+    {
+        isAuthenticated = authenticated;
+    }
+
+    /**
+     * Set the userId that is associated with User.  UserId is required attribute and must be set on add, update, delete, createSession, authenticate, etc..
+     *
+     * @param userId maps to 'uid' attribute in 'inNetOrgPerson' object class.
+     */
+    public void setUserId(String userId)
+    {
+        this.user.setUserId(userId);
+    }
+
+
+    /**
+     * Add a list of RBAC Roles to this entity that have been activated into Session or are under consideration for activation.
+     *
+     * @param roles List of type UserRole that contains at minimum UserId and Role name.
+     */
+    public void setRoles(List<UserRole> roles)
+    {
+        this.user.setRoles(roles);
+    }
+
+    /**
+     * Add a single user-role object to the list of UserRoles for User.
+     *
+     * @param role UserRole contains at least userId and role name (activation) and additional constraints (assignment)
+     */
+    public void setRole(UserRole role)
+    {
+        user.setRole(role);
+    }
+
+    /**
+     * Set the integer timeout that contains max time (in seconds) that User's session may remain inactive.
+     * This attribute is optional but if set will be validated for reasonableness.
+     *
+     * @param timeout maps to 'ftCstr' attribute in 'ftUserAttrs' object class.
+     */
+    private void setTimeout(int timeout)
+    {
+        this.timeout = timeout;
+    }
+
+    /**
+     * Set the last access time in milliseconds. Note that while the unit of time of the return value is a millisecond,
+     * the granularity of the value depends on the underlying operating system and may be larger. For example, many
+     * operating systems measure time in units of tens of milliseconds.
+     */
+    public void setLastAccess()
+    {
+        this.lastAccess = System.currentTimeMillis();
+    }
+
+    /**
+     * Set the message that is associated with the user's last authentication attempt.
+     *
+     * @param message Contains text explaining result of user's last authentication.
+     */
+    public void setMsg(String message)
+    {
+        this.message = message;
+    }
+
+    /**
+     * Set the error id that is associated with the password policy checks.  a '0' indicates no errors.
+     * <ul>
+     * <li> <code>INVALID_PASSWORD_MESSAGE = -10;</code>
+     * <li> <code>GOOD = 0;</code>
+     * <li> <code>PASSWORD_HAS_EXPIRED = 100;</code>
+     * <li> <code>ACCOUNT_LOCKED = 101;</code>
+     * <li> <code>CHANGE_AFTER_RESET = 102;</code>
+     * <li> <code>NO_MODIFICATIONS = 103;</code>
+     * <li> <code>MUST_SUPPLY_OLD = 104;</code>
+     * <li> <code>INSUFFICIENT_QUALITY = 105;</code>
+     * <li> <code>PASSWORD_TOO_SHORT = 106;</code>
+     * <li> <code>PASSWORD_TOO_YOUNG = 107;</code>
+     * <li> <code>HISTORY_VIOLATION = 108;</code>
+     * <li> <code>ACCOUNT_LOCKED_CONSTRAINTS = 109;</code>
+     * </ul>
+     * <p/>
+     *
+     * @param error contains the error id that was generated on the user's last authentication.
+     */
+    public void setErrorId(int error)
+    {
+        this.errorId = error;
+    }
+
+    /**
+     * This attribute specifies the number of times an expired password can
+     * be used to authenticate.
+     *
+     * @param grace The number of logins the user has left before password fails.
+     */
+    public void setGraceLogins(int grace)
+    {
+        this.graceLogins = grace;
+    }
+
+    /**
+     * This attribute specifies the maximum number of seconds before a
+     * password is due to expire that expiration warning messages will be
+     * returned to an authenticating user.
+     * <p/>
+     * If this attribute is not present, or if the value is 0 no warnings
+     * will be returned.  If not 0, the value must be smaller than the value
+     * of the pwdMaxAge attribute.
+     *
+     * @param expire attribute is computed based on last time user has changed their password.
+     */
+    public void setExpirationSeconds(int expire)
+    {
+        this.expirationSeconds = expire;
+    }
+
+    /**
+     * Get the warnings attached to this Session.  Used for processing password policy scenarios, e.g.. password expiring message.
+     *
+     * @return null value, zero or more objects of type {@link Warning} will be returned.  Note: the caller of this method must ensure a not null condition before use.
+     */
+    public List<Warning> getWarnings()
+    {
+        return warnings;
+    }
+
+    /**
+     * Set the warnings on this Session.  Used for processing password policy scenarios, e.g.. password expiring message.
+     * Not intended for use outside of Fortress packages.
+     *
+     * @param warnings zero or more objects of type warning may be set on a Fortress session.
+     */
+    public void setWarnings( List<Warning> warnings )
+    {
+        this.warnings = warnings;
+    }
+
+    /**
+     * Add a warning to the collection into Fortress Session object.  Used for processing password policy scenarios, e.g.. password expiring message.
+     * Not intended for use outside of Fortress packages.
+     *
+     * @param warning one object of type warning will be added to Fortress session.
+     */
+    public void setWarning( Warning warning )
+    {
+        if ( warnings == null )
+        {
+            warnings = new ArrayList<>();
+        }
+        this.warnings.add( warning );
+    }
+}
\ No newline at end of file


[44/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/SecurityException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/SecurityException.java b/src/main/java/org/apache/directory/fortress/core/SecurityException.java
new file mode 100755
index 0000000..4fb79d7
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/SecurityException.java
@@ -0,0 +1,474 @@
+/*
+ *   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;
+
+/**
+ * This exception is declared to be thrown by all APIs within Fortress Manager interfaces: ({@link AdminMgr}, {@link AccessMgr},
+ * {@link ReviewMgr},{@link PwPolicyMgr},{@link AuditMgr},{@link DelAdminMgr},
+ * {@link DelAccessMgr},{@link DelReviewMgr},{@link org.apache.directory.fortress.core.cfg.ConfigMgr}).
+ * <h3>
+ * <p/>The original exception thrown may be of this type or one of its extensions
+ * </h3>
+ * <ul>
+ * <li>{@link AuthorizationException} in the event user fails administrative permission check..
+ * <li>{@link CfgException} in the event the runtime cfg system fails.
+ * <li>{@link CreateException} in the event DAO cannot create entity.
+ * <li>{@link FinderException} in the event DAO cannot find the entity.
+ * <li>{@link PasswordException} in the event user fails password checks or password policy exception occurs.
+ * <li>{@link RemoveException} in the event DAO cannot remove entity.
+ * <li>{@link RestException} during HTTP event failure.
+ * <li>{@link UpdateException} in the event DAO cannot update entity.
+ * <li>{@link ValidationException} in the event entity validation fails.
+ * </ul>
+ * <p/>
+ * For certain APIs, i.e., {@link AccessMgr#createSession(org.apache.directory.fortress.core.rbac.User, boolean)}, or {@link AccessMgr#authenticate(String, char[])}, the caller may need to differentiate by one of the above subclasses, e.g. {@link PasswordException}, to facilitate password expiring condition or allow user to retry authentication after entering it incorrectly.
+ * If specific exception processing is not the aim, or if differentiating conditions by {@link #errorId} is acceptable, callers are allowed to catch (or throw) as type {@link SecurityException}.
+ * <p/>
+ * All exceptions generated by Fortress will be set with error code {@link SecurityException#getErrorId()} indicating fault condition which is set via its constructor - ({@link #SecurityException(int, String)}, {@link #SecurityException(int, String, Exception)}).
+ * The error codes are declared in {@link GlobalErrIds} and are also listed below.
+ * <h3>
+ * <p/>100's - Configuration Errors
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#CONTEXT_NULL} = 101;</code>
+ * <li> <code>{@code CONTEXT_SERIALIZATION_FAILED} = 102;</code>*
+ * <li> <code>{@link GlobalErrIds#FT_MGR_CLASS_NOT_FOUND} = 103;</code>
+ * <li> <code>{@link GlobalErrIds#FT_MGR_INST_EXCEPTION} = 104;</code>
+ * <li> <code>{@link GlobalErrIds#FT_MGR_ILLEGAL_ACCESS} = 105;</code>
+ * <li> <code>{@link GlobalErrIds#FT_MGR_CLASS_NAME_NULL} = 106;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_NOT_FOUND} = 107;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_NAME_NULL} = 108;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_NAME_INVLD} = 109;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_PROPS_NULL} = 110;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_CREATE_FAILED} = 120;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_UPDATE_FAILED} = 121;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_DELETE_FAILED} = 122;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_DELETE_PROPS_FAILED} = 123;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_READ_FAILED} = 124;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_ALREADY_EXISTS} = 125;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_BOOTSTRAP_FAILED} = 126;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_INITIALIZE_FAILED} = 127;</code>
+ * <li> <code>{@link GlobalErrIds#FT_RESOURCE_NOT_FOUND} = 128;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CACHE_NOT_CONFIGURED} = 129;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CACHE_GET_ERR} = 130;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CACHE_PUT_ERR} = 131;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CACHE_CLEAR_ERR} = 132;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CACHE_FLUSH_ERR} = 133;</code>
+ * <li> <code>{@link GlobalErrIds#FT_NULL_CACHE} = 134;</code>
+ * <li> <code>{@link GlobalErrIds#FT_APACHE_LDAP_POOL_INIT_FAILED} = 135;</code>
+ * <li> <code>{@link GlobalErrIds#FT_CONFIG_JSSE_TRUSTSTORE_NULL} = 136;</code>
+ *
+ * </ul>
+ * <h3>
+ * <p/>1000's - User Entity Rule and LDAP Errors
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#USER_SEARCH_FAILED} = 1000;</code>
+ * <li> <code>{@link GlobalErrIds#USER_READ_FAILED} = 1001;</code>
+ * <li> <code>{@link GlobalErrIds#USER_ADD_FAILED} = 1002;</code>
+ * <li> <code>{@link GlobalErrIds#USER_UPDATE_FAILED} = 1003;</code>
+ * <li> <code>{@link GlobalErrIds#USER_DELETE_FAILED} = 1004;</code>
+ * <li> <code>{@link GlobalErrIds#USER_NOT_FOUND} = 1005;</code>
+ * <li> <code>{@link GlobalErrIds#USER_ID_NULL} = 1006;</code>
+ * <li> <code>{@link GlobalErrIds#USER_ID_DUPLICATE} = 1007;</code>
+ * <li> <code>{@link GlobalErrIds#USER_NULL} = 1008;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_NULL} = 1009;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_INVLD_LEN} = 1010;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PLCY_VIOLATION} = 1011;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_PLCY_DEL_FAILED} = 1012;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_INVLD} = 1013;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_CHK_FAILED} = 1014;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_RESET} = 1015;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_LOCKED} = 1016;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_EXPIRED} = 1017;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_MOD_NOT_ALLOWED} = 1018;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_MUST_SUPPLY_OLD} = 1019;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_NSF_QUALITY} = 1020;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_TOO_SHORT} = 1021;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_TOO_YOUNG} = 1022;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_IN_HISTORY} = 1023;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_UNLOCK_FAILED} = 1024;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_LOCK_FAILED} = 1025;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_CHANGE_FAILED} = 1026;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_RESET_FAILED} = 1027;</code>
+ * <li> <code>{@link GlobalErrIds#USER_LOCKED_BY_CONST} = 1028;</code>
+ * <li> <code>{@link GlobalErrIds#USER_SESS_CREATE_FAILED} = 1029;</code>
+ * <li> <code>{@link GlobalErrIds#USER_SESS_NULL} = 1030;</code>
+ * <li> <code>{@link GlobalErrIds#USER_ADMIN_NOT_AUTHORIZED} = 1031;</code>
+ * <li> <code>{@link GlobalErrIds#USER_CN_NULL} = 1032;</code>
+ * <li> <code>{@link GlobalErrIds#USER_SN_NULL} = 1033;</code>
+ * <li> <code>{@link GlobalErrIds#USER_PW_PLCY_INVALID} = 1034;</code>
+ * <li> <code>{@link GlobalErrIds#USER_OU_INVALID} = 1035;</code>
+ * <li> <code>{@link GlobalErrIds#SESS_CTXT_NULL} = 1036;</code>
+ * <li> <code>{@link GlobalErrIds#USER_BIND_FAILED} = 1037;</code>
+ *
+ *
+ * </ul>
+ * <h3>
+ * <p/>2000's User-Role assignments
+ * </h3>
+ * <h4>
+ * <p/> User-Role Rule and LDAP errors
+ * </h4>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#URLE_NULL} = 2003;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_ASSIGN_FAILED} = 2004;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_DEASSIGN_FAILED} = 2005;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_ACTIVATE_FAILED} = 2006;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_DEACTIVE_FAILED} = 2007;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_ASSIGN_EXIST} = 2008;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_ASSIGN_NOT_EXIST} = 2009;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_SEARCH_FAILED} = 2010;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_ALREADY_ACTIVE} = 2011;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_NOT_ACTIVE} = 2022;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_ADMIN_CANNOT_ASSIGN} = 2023;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_ADMIN_CANNOT_DEASSIGN} = 2024;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_ADMIN_CANNOT_GRANT} = 2025;</code>
+ * <li> <code>{@link GlobalErrIds#URLE_ADMIN_CANNOT_REVOKE} = 2026;</code>
+ * </ul>
+ * <h4>
+ * <p/> Temporal Constraint Activation Violations
+ * </h4>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#ACTV_FAILED_DAY} = 2050;</code>
+ * <li> <code>{@link GlobalErrIds#ACTV_FAILED_DATE} = 2051;</code>
+ * <li> <code>{@link GlobalErrIds#ACTV_FAILED_TIME} = 2052;</code>
+ * <li> <code>{@link GlobalErrIds#ACTV_FAILED_TIMEOUT} = 2053;</code>
+ * <li> <code>{@link GlobalErrIds#ACTV_FAILED_LOCK} = 2054;</code>
+ * <li> <code>{@link GlobalErrIds#ACTV_FAILED_DSD} = 2055;</code>
+ * </ul>
+ * <h3>
+ * <p/>3000's - Permission Entity
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#PERM_SEARCH_FAILED} = 3000;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_READ_OP_FAILED} = 3001;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_READ_OBJ_FAILED} = 3002;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_ADD_FAILED} = 3003;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_UPDATE_FAILED} = 3004;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_DELETE_FAILED} = 3005;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_OP_NOT_FOUND} = 3006;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_OBJ_NOT_FOUND} = 3007;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_NULL} = 3008;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_OPERATION_NULL} = 3009;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_OBJECT_NULL} = 3010;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_DUPLICATE} = 3011;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_GRANT_FAILED} = 3012;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_GRANT_USER_FAILED} = 3013;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_REVOKE_FAILED} = 3024;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_ROLE_EXIST} = 3015;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_ROLE_NOT_EXIST} = 3016;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_USER_EXIST} = 3017;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_USER_NOT_EXIST} = 3018;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_ROLE_SEARCH_FAILED} = 3019;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_USER_SEARCH_FAILED} = 3020;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_SESS_SEARCH_FAILED} = 3021;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_BULK_USER_REVOKE_FAILED} = 3022;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_BULK_ROLE_REVOKE_FAILED} = 3023;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_BULK_ADMINROLE_REVOKE_FAILED} = 3024;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_OU_INVALID} = 3025;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_OPERATION_NM_NULL} = 3026;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_OBJECT_NM_NULL} = 3027;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_COMPARE_OP_FAILED} = 3028;</code>
+ * <li> <code>{@link GlobalErrIds#PERM_NOT_EXIST} = 3029;</code>
+ * </ul>
+ * <h3>
+ * <p/>4000's - Password Policy Entity
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#PSWD_READ_FAILED} = 4000;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_CREATE_FAILED} = 4001;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_UPDATE_FAILED} = 4002;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_DELETE_FAILED} = 4003;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_SEARCH_FAILED} = 4004;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_NOT_FOUND} = 4005;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_NAME_INVLD_LEN} = 4006;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_QLTY_INVLD_LEN} = 4007;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_QLTY_INVLD} = 4008;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_MAXAGE_INVLD} = 4009;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_MINAGE_INVLD} = 4010;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_MINLEN_INVLD} = 4011;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_INTERVAL_INVLD} = 4012;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_MAXFAIL_INVLD} = 4013;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_MUSTCHG_INVLD} = 4014;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_SAFECHG_INVLD} = 4015;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_ALLOWCHG_INVLD} = 4016;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_HISTORY_INVLD} = 4017;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_GRACE_INVLD} = 4018;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_LOCKOUTDUR_INVLD} = 4019;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_EXPWARN_INVLD} = 4020;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_LOCKOUT_INVLD} = 4021;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_NAME_NULL} = 4022;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_PLCY_NULL} = 4023;</code>
+ * <li> <code>{@link GlobalErrIds#PSWD_CONST_VIOLATION} = 4024;</code>
+ * </ul>
+ * <h3>
+ * <p/>5000's - RBAC
+ * </h3>
+ * <h4>
+ * <p/> Role Rule and System errors
+ * </h4>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#ROLE_SEARCH_FAILED} = 5000;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_READ_FAILED} = 5001;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_ADD_FAILED} = 5002;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_UPDATE_FAILED} = 5003;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_DELETE_FAILED} = 5004;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_NM_NULL} = 5005;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_NOT_FOUND} = 5006;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_NULL} = 5007;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_USER_ASSIGN_FAILED} = 5008;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_USER_DEASSIGN_FAILED} = 5009;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_LST_NULL} = 5010;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_OCCUPANT_SEARCH_FAILED} = 5011;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_REMOVE_OCCUPANT_FAILED} = 5012;</code>
+ * <li> <code>{@link GlobalErrIds#PARENT_ROLE_NULL} = 5013;</code>
+ * <li> <code>{@link GlobalErrIds#CHILD_ROLE_NULL} = 5014;</code>
+ * <li> <code>{@link GlobalErrIds#ROLE_REMOVE_PARENT_FAILED} = 5015;</code>
+ * </ul>
+ * <h4>
+ * <p/> Hierarchical Constraints
+ * </h4>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#HIER_READ_FAILED} = 5051;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_ADD_FAILED} = 5052;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_UPDATE_FAILED} = 5053;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_DELETE_FAILED} = 5054;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_NOT_FOUND} = 5056;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_REL_INVLD} = 5057;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_DEL_FAILED_HAS_CHILD} = 5058;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_REL_EXIST} = 5059;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_REL_NOT_EXIST} = 5060;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_NULL} = 0561;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_TYPE_NULL} = 5062;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_CANNOT_PERFORM} = 5063;</code>
+ * <li> <code>{@link GlobalErrIds#HIER_REL_CYCLIC} = 5064;</code>
+ *
+ * </ul>
+ * <h4>
+ * <p/> Separation of Duty Relations
+ * </h4>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#SSD_SEARCH_FAILED} = 5080;</code>
+ * <li> <code>{@link GlobalErrIds#SSD_READ_FAILED} = 5081;</code>
+ * <li> <code>{@link GlobalErrIds#SSD_ADD_FAILED} = 5082;</code>
+ * <li> <code>{@link GlobalErrIds#SSD_UPDATE_FAILED} = 5083;</code>
+ * <li> <code>{@link GlobalErrIds#SSD_DELETE_FAILED} = 0584;</code>
+ * <li> <code>{@link GlobalErrIds#SSD_NM_NULL} = 5085;</code>
+ * <li> <code>{@link GlobalErrIds#SSD_NOT_FOUND} = 5086;</code>
+ * <li> <code>{@link GlobalErrIds#SSD_NULL} = 5087;</code>
+ * <li> <code>{@link GlobalErrIds#SSD_VALIDATION_FAILED} = 5088;</code>
+ * <li> <code>{@link GlobalErrIds#DSD_SEARCH_FAILED} = 5089;</code>
+ * <li> <code>{@link GlobalErrIds#DSD_READ_FAILED} = 5090;</code>
+ * <li> <code>{@link GlobalErrIds#DSD_ADD_FAILED} = 5091;</code>
+ * <li> <code>{@link GlobalErrIds#DSD_UPDATE_FAILED} = 5092;</code>
+ * <li> <code>{@link GlobalErrIds#DSD_DELETE_FAILED} = 5093;</code>
+ * <li> <code>{@link GlobalErrIds#DSD_NM_NULL} = 5094;</code>
+ * <li> <code>{@link GlobalErrIds#DSD_NOT_FOUND} = 5095;</code>
+ * <li> <code>{@link GlobalErrIds#DSD_NULL} = 5096;</code>
+ * <li> <code>{@link GlobalErrIds#DSD_VALIDATION_FAILED} = 5097;</code>
+ * </ul>
+ * <h3>
+ * <p/>6000's - LDAP Suffix and Container Entities
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#CNTR_CREATE_FAILED} = 6001;</code>
+ * <li> <code>{@link GlobalErrIds#CNTR_DELETE_FAILED} = 6002;</code>
+ * <li> <code>{@link GlobalErrIds#CNTR_NAME_NULL} = 6003;</code>
+ * <li> <code>{@link GlobalErrIds#CNTR_NAME_INVLD} = 6004;</code>
+ * <li> <code>{@link GlobalErrIds#CNTR_PARENT_NULL} = 6005;</code>
+ * <li> <code>{@link GlobalErrIds#CNTR_PARENT_INVLD} = 6006;</code>
+ * <li> <code>{@link GlobalErrIds#SUFX_CREATE_FAILED} = 6010;</code>
+ * <li> <code>{@link GlobalErrIds#SUFX_DELETE_FAILED} = 6011;</code>
+ * <li> <code>{@link GlobalErrIds#SUFX_NAME_NULL} = 6012;</code>
+ * <li> <code>{@link GlobalErrIds#SUFX_NAME_INVLD} = 6013;</code>
+ * <li> <code>{@link GlobalErrIds#SUFX_DCTOP_NULL} = 6014;</code>
+ * <li> <code>{@link GlobalErrIds#SUFX_DCTOP_INVLD} = 6015;</code>
+ * </ul>
+ * <h3>
+ * <p/>7000's - Audit Activities
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#AUDT_BIND_SEARCH_FAILED} = 7000;</code>
+ * <li> <code>{@link GlobalErrIds#AUDT_INPUT_NULL} = 7001;</code>
+ * <li> <code>{@link GlobalErrIds#AUDT_AUTHZ_SEARCH_FAILED} = 7002;</code>
+ * <li> <code>{@link GlobalErrIds#AUDT_MOD_SEARCH_FAILED} = 7003;</code>
+ * <li> <code>{@link GlobalErrIds#AUDT_MOD_ADMIN_SEARCH_FAILED} = 7004;</code>
+ * <li> <code>{@link GlobalErrIds#AUDT_AUTHN_INVALID_FAILED} = 7005;</code>
+ * </ul>
+ * <h3>
+ * <p/>8000's Organizational Unit Rule and System errors
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#ORG_NULL} = 8001;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_TYPE_NULL} = 8002;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_READ_FAILED_USER} = 8011;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_ADD_FAILED_USER} = 8012;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_UPDATE_FAILED_USER} = 8013;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_DELETE_FAILED_USER} = 8014;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_SEARCH_FAILED_USER} = 8015;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_GET_FAILED_USER} = 0816;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_NOT_FOUND_USER} = 8017;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_NULL_USER} = 0818;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_TYPE_NULL_USER} = 8019;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_DEL_FAILED_USER} = 8020;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_REMOVE_PARENT_FAILED_USER} = 8021;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_READ_FAILED_PERM} = 8061;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_ADD_FAILED_PERM} = 8062;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_UPDATE_FAILED_PERM} = 8063;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_DELETE_FAILED_PERM} = 8064;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_SEARCH_FAILED_PERM} = 8065;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_GET_FAILED_PERM} = 8066;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_NOT_FOUND_PERM} = 8067;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_NULL_PERM} = 8068;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_TYPE_NULL_PERM} = 8069;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_DEL_FAILED_PERM} = 8070;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_LEN_INVLD} = 8071;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_PARENT_NULL} = 8072;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_CHILD_NULL} = 8073;</code>
+ * <li> <code>{@link GlobalErrIds#ORG_REMOVE_PARENT_FAILED_PERM} = 8074;</code>
+ * </ul>
+ * <h3>
+ * <p/>9000's Administrative RBAC
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#ARLE_SEARCH_FAILED} = 9000;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_READ_FAILED} = 9001;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_ADD_FAILED} = 9002;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_UPDATE_FAILED} = 9003;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_DELETE_FAILED} = 9004;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_NM_NULL} = 9005;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_NOT_FOUND} = 9006;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_NULL} = 9007;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_USER_ASSIGN_FAILED} = 9008;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_USER_DEASSIGN_FAILED} = 9009;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_LST_NULL} = 9010;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_BEGIN_RANGE_NULL} = 9011;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_END_RANGE_NULL} = 0911;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_INVLD_RANGE} = 9012;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_INVLD_RANGE_INCLUSIVE} = 9013;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_ACTIVATE_FAILED} = 9014;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_DEACTIVE_FAILED} = 9015;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_ALREADY_ACTIVE} = 9016;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_NOT_ACTIVE} = 9017;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_USER_SEARCH_FAILED} = 9018;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_PARENT_NULL} = 9019;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_CHILD_NULL} = 9020;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_ASSIGN_EXIST} = 9021;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_ASSIGN_NOT_EXIST} = 9022;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_DEASSIGN_NOT_EXIST} = 9023;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_ASSIGN_FAILED} = 9024;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_DEASSIGN_FAILED} = 9025;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_OCCUPANT_SEARCH_FAILED} = 9026;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_REMOVE_OCCUPANT_FAILED} = 9027;</code>
+ * <li> <code>{@link GlobalErrIds#ARLE_REMOVE_PARENT_FAILED} = 9028;</code>
+ * </ul>
+ *
+ * <h3>
+ * <p/>10000's - Temporal Constraint Validation Error Ids
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#CONST_INVLD_TEXT} = 10001;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_INVLD_FIELD_LEN} = 10002;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_TIMEOUT_INVLD} = 10003;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_BEGINTIME_INVLD} = 10004;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_BEGINTIME_LEN_ERR} = 10005;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_ENDTIME_INVLD} = 10006;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_ENDTIME_LEN_ERR} = 10007;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_BEGINDATE_INVLD} = 10008;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_BEGINDATE_NULL} = 10009;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_ENDDATE_INVLD} = 10010;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_ENDDATE_NULL} = 10011;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_DAYMASK_INVLD} = 10012;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_DAYMASK_NULL} = 10013;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_DESC_LEN_INVLD} = 10014;</code>
+ * <li> <code>{@link GlobalErrIds#CONST_NULL_TEXT} = 10015;</code>
+ * </ul>
+ * <h3>
+ * <p/>10100's - REST calls through remote En Masse Interface Error Ids
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#REST_WEB_ERR} = 10101;</code>
+ * <li> <code>{@link GlobalErrIds#REST_IO_ERR} = 10102;</code>
+ * <li> <code>{@link GlobalErrIds#REST_MARSHALL_ERR} = 10103;</code>
+ * <li> <code>{@link GlobalErrIds#REST_UNMARSHALL_ERR} = 10104;</code>
+ * <li> <code>{@link GlobalErrIds#REST_GET_FAILED} = 10105;</code>
+ * <li> <code>{@link GlobalErrIds#REST_NOT_FOUND_ERR} = 10106;</code>
+ * <li> <code>{@link GlobalErrIds#REST_UNKNOWN_ERR} = 10107;</code>
+ * <li> <code>{@link GlobalErrIds#REST_FORBIDDEN_ERR} = 10108;</code>
+ * <li> <code>{@link GlobalErrIds#REST_UNAUTHORIZED_ERR} = 10109;</code>
+ * </ul>
+ * <h3>
+ * <p/>10200's - RBAC Accelerator extended LDAP operation Error Ids
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#ACEL_CREATE_SESSION_ERR} = 10201;</code>
+ * <li> <code>{@link GlobalErrIds#ACEL_DELETE_SESSION_ERR} = 10202;</code>
+ * <li> <code>{@link GlobalErrIds#ACEL_CHECK_ACCESS_ERR} = 10203;</code>
+ * <li> <code>{@link GlobalErrIds#ACEL_ADD_ROLE_ERR} = 10204;</code>
+ * <li> <code>{@link GlobalErrIds#ACEL_DROP_ROLE_ERR} = 10205;</code>
+ * </ul>
+ * <h3>
+ * <p/>10300's - LDAP Group operation Error Ids
+ * </h3>
+ * <ul>
+ * <li> <code>{@link GlobalErrIds#GROUP_SEARCH_FAILED} = 10300;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_READ_FAILED} = 10301;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_ADD_FAILED} = 10302;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_UPDATE_FAILED} = 10303;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_DELETE_FAILED} = 10304;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_ADD_PROPERTY_FAILED} = 10305;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_DELETE_PROPERTY_FAILED} = 10306;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_NOT_FOUND} = 10307;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_NULL} = 10308;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_USER_ASSIGN_FAILED} = 10309;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_USER_DEASSIGN_FAILED} = 10310;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_NAME_NULL} = 10311;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_NAME_INVLD} = 10312;</code>
+ * <li> <code>{@link GlobalErrIds#GROUP_PROTOCOL_INVLD} = 10313;</code>
+ * </ul>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class SecurityException extends BaseException
+{
+    /**
+     * Create exception with error id and message.
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     */
+    public SecurityException(int errorId, String msg)
+    {
+        super(errorId, msg);
+    }
+
+
+    /**
+     * Create exception with error id, message and related exception.
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     * @param previousException contains reference to related exception which usually is system related, i.e. ldap.
+     */
+    public SecurityException(int errorId, String msg, Exception previousException)
+    {
+        super(errorId, msg, previousException);
+    }
+}
\ 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/StandardException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/StandardException.java b/src/main/java/org/apache/directory/fortress/core/StandardException.java
new file mode 100755
index 0000000..97d5b3c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/StandardException.java
@@ -0,0 +1,37 @@
+/*
+ *   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;
+
+/**
+ *  Interface that is implemented by exception base class {@link StandardException} used to associate a Fortress error code to the exception instance.
+ * See the {@link GlobalErrIds} javadoc for list of error ids used by Fortress.
+ *
+ * @author Shawn McKinney
+ */
+public interface StandardException
+{
+    /**
+     * Return the Fortress error code that is optional to exceptions thrown within this security system.  See {@link GlobalErrIds} for list of all error codes.
+     *
+     * @return integer containing the source error code.  Valid values for Fortress error codes fall between 0 and 100_000.
+     */
+	public int getErrorId();
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/UpdateException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/UpdateException.java b/src/main/java/org/apache/directory/fortress/core/UpdateException.java
new file mode 100755
index 0000000..ffdfbb5
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/UpdateException.java
@@ -0,0 +1,54 @@
+/*
+ *   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;
+
+import java.lang.*;
+
+/**
+ * This exception extends {@link SecurityException} and is thrown when DAO cannot update entity.
+ * See the {@link GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+public class UpdateException extends SecurityException
+{
+    /**
+     * Create an exception with an error code that maps to {@link GlobalErrIds} and message text.
+     *
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     */
+    public UpdateException(int errorId, String msg)
+    {
+        super(errorId, msg);
+    }
+
+    /**
+     * Create exception with error id, message and related exception.
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     * @param previousException contains reference to related exception which usually is system related, i.e. ldap.
+     */
+    public UpdateException(int errorId, String msg, Exception previousException)
+    {
+        super(errorId, msg, previousException);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ValidationException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ValidationException.java b/src/main/java/org/apache/directory/fortress/core/ValidationException.java
new file mode 100755
index 0000000..6028ff6
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ValidationException.java
@@ -0,0 +1,44 @@
+/*
+ *   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;
+
+
+import java.lang.*;
+
+/**
+ * This exception extends {@link SecurityException} and is thrown when Fortress cannot validate entity.
+ * See the {@link GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+public class ValidationException extends SecurityException
+{
+    /**
+     * Create an exception with an error code that maps to {@link GlobalErrIds} and message text.
+     *
+     * @param  errorId see {@link GlobalErrIds} for list of valid error codes that can be set.  Valid values between 0 & 100_000.
+     * @param msg contains textual information including method of origin and description of the root cause.
+     */
+    public ValidationException(int errorId, String msg)
+    {
+        super(errorId, msg);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addadminrole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addadminrole.java b/src/main/java/org/apache/directory/fortress/core/ant/Addadminrole.java
new file mode 100755
index 0000000..88582cc
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addadminrole.java
@@ -0,0 +1,88 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link org.apache.directory.fortress.core.rbac.AdminRole}s used to drive {@link org.apache.directory.fortress.core.DelAdminMgr#addRole(org.apache.directory.fortress.core.rbac.AdminRole)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addadminrole', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addadminrole>
+ *           ...
+ *         </addadminrole>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addadminrole
+{
+    final private List<AdminRoleAnt> roles = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addadminrole()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addRole', is used for derived xml tag 'role' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addadminrole>
+     *      <role name="DemoAdminUsers"
+     *          description="Test Admin Role for Demo"
+     *          osps="demoapps1,demoapps2"
+     *          osus="demousrs1,demousrs2"
+     *          beginrange="role1"
+     *          endrange="role1"
+     *          begininclusive="true"
+     *          endinclusive="true"/>
+     * </addadminrole>
+     * }
+     * </pre>
+     *
+     * @param role contains extension of {@link org.apache.directory.fortress.core.rbac.AdminRole}.
+     */
+    public void addRole(AdminRoleAnt role)
+    {
+        this.roles.add(role);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addAdminRoles()} to retrieve list of AdminRoles as defined in input xml file.
+     *
+     * @return collection containing {@link AdminRoleAnt}s targeted for insertion.
+     */
+    public List<AdminRoleAnt> getRoles()
+    {
+        return this.roles;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addadminroleinheritance.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addadminroleinheritance.java b/src/main/java/org/apache/directory/fortress/core/ant/Addadminroleinheritance.java
new file mode 100755
index 0000000..01a6405
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addadminroleinheritance.java
@@ -0,0 +1,85 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.Relationship;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link Relationship}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#addInheritance(org.apache.directory.fortress.core.rbac.Role, org.apache.directory.fortress.core.rbac.Role)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addadminroleinheritance', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addadminroleinheritance>
+ *           ...
+ *         </addadminroleinheritance>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addadminroleinheritance
+{
+    final private List<Relationship> relationships = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addadminroleinheritance()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addRelationship', is used for derived xml tag 'relationship' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addadminroleinheritance>
+     *     <relationship child="ar2" parent="ar1"/>
+     *     <relationship child="ar3" parent="ar1"/>
+     *     <relationship child="ar4" parent="ar1"/>
+     * </addadminroleinheritance>
+     * }
+     * </pre>
+     *
+     * @param relationship contains reference to data element targeted for insertion..
+     */
+    public void addRelationship(Relationship relationship)
+    {
+        this.relationships.add(relationship);
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#addAddadminrole(org.apache.directory.fortress.core.ant.Addadminrole)} to retrieve list of Roles as defined in input xml file.
+     *
+     * @return collection containing {@link Relationship}s targeted for insertion.
+     */
+    public List<Relationship> getRelationships()
+    {
+        return this.relationships;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addconfig.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addconfig.java b/src/main/java/org/apache/directory/fortress/core/ant/Addconfig.java
new file mode 100755
index 0000000..45950a5
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addconfig.java
@@ -0,0 +1,96 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link ConfigAnt}s used to drive {@link org.apache.directory.fortress.core.cfg.ConfigMgr#add(String, java.util.Properties)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addconfig', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addconfig>
+ *           ...
+ *         </addconfig>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addconfig
+{
+    final private List<ConfigAnt> config = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addconfig()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addConfig', is used for derived xml tag 'config' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addconfig>
+     *     <config props="config.realm:DEFAULT"/>
+     *     <config props="enable.audit:true"/>
+     *     <config props="authn.type:default"/>
+     *     <config props="password.policy:openldap"/>
+     *     <config props="clientside.sorting:true"/>
+     *     <config props="suffix:dc=jts\,dc=com"/>
+     *     <config props="user.root:ou=People\,dc=jts\,dc=com"/>
+     *     <config props="pwpolicy.root:ou=Policies\,dc=jts\,dc=com"/>
+     *     <config props="role.root:ou=Roles\,ou=RBAC\,dc=jts\,dc=com"/>
+     *     <config props="perm.root:ou=Permissions\,ou=RBAC\,dc=jts\,dc=com"/>
+     *     <config props="sdconstraint.root:ou=Constraints\,ou=RBAC\,dc=jts\,dc=com"/>
+     *     <config props="userou.root:ou=OS-U\,ou=ARBAC\,dc=jts\,dc=com"/>
+     *     <config props="permou.root:ou=OS-P\,ou=ARBAC\,dc=jts\,dc=com"/>
+     *     <config props="adminrole.root:ou=AdminRoles\,ou=ARBAC\,dc=jts\,dc=com"/>
+     *     <config props="adminperm.root:ou=AdminPerms\,ou=ARBAC\,dc=jts\,dc=com"/>
+     *     ...
+     * </addconfig>
+     * }
+     * </pre>
+     *
+     * @param config contains reference to data element targeted for insertion..
+     */
+    public void addConfig(ConfigAnt config)
+    {
+        this.config.add(config);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addConfig()} to retrieve list of properties as defined in input xml file.
+     *
+     * @return collection containing {@link ConfigAnt}s targeted for insertion.
+     */
+    public List<ConfigAnt> getConfig()
+    {
+        return this.config;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addcontainer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addcontainer.java b/src/main/java/org/apache/directory/fortress/core/ant/Addcontainer.java
new file mode 100755
index 0000000..814526f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addcontainer.java
@@ -0,0 +1,94 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.ldap.container.OrganizationalUnit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to create new {@link org.apache.directory.fortress.core.ldap.container.OrganizationalUnit}s used to drive {@link org.apache.directory.fortress.core.ldap.container.OrganizationalUnitP#add(org.apache.directory.fortress.core.ldap.container.OrganizationalUnit)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addcontainer', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addcontainer>
+ *           ...
+ *         </addcontainer>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addcontainer
+
+{
+    final private List<OrganizationalUnit> containers = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addcontainer()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addContainer', is used for derived xml tag 'container' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addcontainer>
+     *     <container name="Config" description="Fortress Configuration Realms"/>
+     *     <container name="People" description="Fortress People"/>
+     *     <container name="Policies" description="Fortress Policies"/>
+     *     <container name="RBAC" description="Fortress RBAC Policies"/>
+     *     <container name="Roles" parent="RBAC" description="Fortress Roles"/>
+     *     <container name="Permissions" parent="RBAC" description="Fortress Permissions"/>
+     *     <container name="Constraints" parent="RBAC" description="Fortress Separation of Duty Constraints"/>
+     *     <container name="ARBAC" description="Fortress Administrative RBAC Policies"/>
+     *     <container name="OS-U" parent="ARBAC" description="Fortress User Organizational Units"/>
+     *     <container name="OS-P" parent="ARBAC" description="Fortress Perm Organizational Units"/>
+     *     <container name="AdminRoles" parent="ARBAC" description="Fortress AdminRoles"/>
+     *     <container name="AdminPerms" parent="ARBAC" description="Fortress Admin Permissions"/>
+     * </addcontainer>
+     * }
+     * </pre>
+     *
+     * @param ou contains reference to data element targeted for insertion..
+     */
+    public void addContainer( OrganizationalUnit ou)
+    {
+        this.containers.add(ou);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addContainers()} to retrieve list of OrganizationalUnits as defined in input xml file.
+     * @return collection containing {@link org.apache.directory.fortress.core.ldap.container.OrganizationalUnit}s targeted for insertion.
+     */
+    public List<OrganizationalUnit> getContainers()
+    {
+        return this.containers;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addcontext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addcontext.java b/src/main/java/org/apache/directory/fortress/core/ant/Addcontext.java
new file mode 100755
index 0000000..086f0b9
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addcontext.java
@@ -0,0 +1,85 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.Context;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to create new {@link Context} used to define multi-tenant property.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addcontext', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addcontext>
+ *           ...
+ *         </addcontext>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addcontext
+
+{
+    final private List<Context> contexts = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addcontext()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addContext', is used for derived xml tag 'context' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addcontext>
+     *     <context name="123"/>
+     * </addsuffix>
+     * }
+     * </pre>
+     *
+     * @param context contains reference to data element targeted for insertion..
+     */
+    public void addContext(Context context)
+    {
+        this.contexts.add(context);
+    }
+
+    /**
+     * Used by {@link Context} to retrieve list of contexts as defined in input xml file.
+     *
+     * @return List of context names.
+     */
+    public List<Context> getContexts()
+    {
+        return this.contexts;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addgroup.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addgroup.java b/src/main/java/org/apache/directory/fortress/core/ant/Addgroup.java
new file mode 100755
index 0000000..62f248e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addgroup.java
@@ -0,0 +1,84 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.ldap.group.Group;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link Group}s used to drive {@link org.apache.directory.fortress
+ * .ldap.group.GroupMgr#add(org.apache.directory.fortress.ldap.group.Group)} .
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the
+ * xml tag used by load utility.
+ * <p>This class name, 'Addgroup', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addgroup>
+ *           ...
+ *         </addgroup>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addgroup
+{
+    final private List<Group> groups = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addgroup()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addGroup', is used for derived xml tag 'user' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addgroup>
+     *      <group name="test001" protocol="test" description="Test Group 001" members="guser1,guser2,guser3" properties="key1=value1, key2=val 2, key3='VAL 3'" />
+     * </addgroup>
+     * }
+     * </pre>
+     *
+     * @param group contains reference to data element targeted for insertion..
+     */
+    public void addGroup( Group group )
+    {
+        this.groups.add( group );
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addGroups()} to retrieve list of Groups as defined in input xml file.
+     *
+     * @return collection containing {@link Group}s targeted for insertion.
+     */
+    public List<Group> getGroups()
+    {
+        return this.groups;
+    }
+}
\ 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/ant/Addgroupmember.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addgroupmember.java b/src/main/java/org/apache/directory/fortress/core/ant/Addgroupmember.java
new file mode 100755
index 0000000..77eb248
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addgroupmember.java
@@ -0,0 +1,85 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.ldap.group.Group;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link Group}s used to drive {@link org.apache.directory.fortress
+ * .ldap.group.GroupMgr#add(org.apache.directory.fortress.ldap.group.Group)} .
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the
+ * xml tag used by load utility.
+ * <p>This class name, 'Addgroup', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addgroupmember>
+ *           ...
+ *         </addgroupmember>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addgroupmember
+{
+    final private List<Group> groups = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addgroupmember()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addGroup', is used for derived xml tag 'user' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addgroupmember>
+     *      <group name="test001" members="guser1,guser2,guser3" />
+     * </addgroupmember>
+     * }
+     * </pre>
+     *
+     * @param group contains reference to data element targeted for insertion..
+     */
+    public void addGroup( Group group )
+    {
+        this.groups.add( group );
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addGroupMembers()} to retrieve list of Groups as defined in input xml file.
+     *
+     * @return collection containing {@link Group}s targeted for insertion.
+     */
+    public List<Group> getGroups()
+    {
+        return this.groups;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addgroupproperty.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addgroupproperty.java b/src/main/java/org/apache/directory/fortress/core/ant/Addgroupproperty.java
new file mode 100755
index 0000000..712791c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addgroupproperty.java
@@ -0,0 +1,85 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.ldap.group.Group;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link Group}s used to drive {@link org.apache.directory.fortress
+ * .ldap.group.GroupMgr#add(org.apache.directory.fortress.ldap.group.Group)} .
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the
+ * xml tag used by load utility.
+ * <p>This class name, 'Addgroup', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addgroupproperty>
+ *           ...
+ *         </addgroupproperty>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addgroupproperty
+{
+    final private List<Group> groups = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addgroupproperty()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addGroup', is used for derived xml tag 'user' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addgroupproperty>
+     *      <group name="test001" properties="key1=value1, key2=val 2, key3='VAL 3'" />
+     * </addgroupproperty>
+     * }
+     * </pre>
+     *
+     * @param group contains reference to data element targeted for insertion..
+     */
+    public void addGroup( Group group )
+    {
+        this.groups.add( group );
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#addGroupProperties()} to retrieve list of Groups as defined in input xml file.
+     *
+     * @return collection containing {@link Group}s targeted for insertion.
+     */
+    public List<Group> getGroups()
+    {
+        return this.groups;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addorgunit.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addorgunit.java b/src/main/java/org/apache/directory/fortress/core/ant/Addorgunit.java
new file mode 100755
index 0000000..59f33ce
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addorgunit.java
@@ -0,0 +1,89 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.OrgUnitAnt;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to create new {@link org.apache.directory.fortress.core.rbac.OrgUnit}s used to drive {@link org.apache.directory.fortress.core.DelAdminMgr#add(org.apache.directory.fortress.core.rbac.OrgUnit)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addorgunit', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addorgunit>
+ *           ...
+ *         </addorgunit>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addorgunit
+{
+    final private List<OrgUnitAnt> ous = new ArrayList<>();
+
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addorgunit()
+    {
+    }
+
+
+    /**
+     * <p>This method name, 'addOrgUnit', is used for derived xml tag 'orgunit' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addorgunit>
+     *     <orgunit name="demousrs1" typeName="USER" description="Test User Org 1 for User on Tomcat Calendar App"/>
+     *     <orgunit name="demousrs2" typename="USER" description="Test User Org 2 for User on Tomcat  Calendar App"/>
+     *     <orgunit name="demoapps1" typeName="PERM" description="Test Perm Org 1 for Permission on Tomcat Calendar App"/>
+     *     <orgunit name="demoapps2" typename="PERM" description="Test Perm Org 2 for Permission on Tomcat Calendar App"/>
+     * </addorgunit>
+     * }
+     * </pre>
+     *
+     * @param ou contains reference to data element targeted for insertion..
+     */
+    public void addOrgUnit(OrgUnitAnt ou)
+    {
+        this.ous.add(ou);
+    }
+
+
+    /**
+     * Used by {@link FortressAntTask#addOrgunits()} to retrieve list of OrgUnits as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.OrgUnit}s targeted for insertion.
+     */
+    public List<OrgUnitAnt> getOrgUnits()
+    {
+        return this.ous;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/AddpermGrant.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/AddpermGrant.java b/src/main/java/org/apache/directory/fortress/core/ant/AddpermGrant.java
new file mode 100755
index 0000000..0ce7a1b
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/AddpermGrant.java
@@ -0,0 +1,90 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.PermGrant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to create new {@link PermGrant}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#grantPermission(org.apache.directory.fortress.core.rbac.Permission, org.apache.directory.fortress.core.rbac.Role)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'AddpermGrant', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addpermgrant>
+ *           ...
+ *         </addpermgrant>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class AddpermGrant
+{
+    private final List<PermGrant> permGrants = new ArrayList<>();
+
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public AddpermGrant()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addPermGrant', is used for derived xml tag 'permgrant' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addpermgrant>
+     *     <permgrant objName="/jsp/cal/cal1.jsp" opName="main" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="8am" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="10am" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="12pm" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="2pm" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="4pm" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="6pm" roleNm="role1"/>
+     * </addpermgrant>
+     * }
+     * </pre>
+     *
+     * @param permGrant contains reference to data element targeted for insertion..
+     */
+    public void addPermGrant(PermGrant permGrant)
+    {
+        this.permGrants.add(permGrant);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addPermGrants()} to retrieve list of PermGrant as defined in input xml file.
+     *
+     * @return collection containing {@link PermGrant}s targeted for insertion.
+     */
+    public List<PermGrant> getPermGrants()
+    {
+        return this.permGrants;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/AddpermObj.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/AddpermObj.java b/src/main/java/org/apache/directory/fortress/core/ant/AddpermObj.java
new file mode 100755
index 0000000..12be63d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/AddpermObj.java
@@ -0,0 +1,88 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.fortress.core.rbac.PermObj;
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link PermObj}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#addPermObj(org.apache.directory.fortress.core.rbac.PermObj)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'AddpermObj', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addpermobj>
+ *           ...
+ *         </addpermobj>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class AddpermObj
+{
+
+    final private List<PermObj> permObjs = new ArrayList<>();
+
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public AddpermObj()
+    {
+    }
+
+
+    /**
+     * <p>This method name, 'addPermObj', is used for derived xml tag 'permobj' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addpermobj>
+     *     <permobj objName="/jsp/cal/cal1.jsp" description="Fortress Web Demo App Object 1" ou="demoapps1" type="Ant"/>
+     *     <permobj objName="/jsp/cal/cal2.jsp" description="Fortress Web Demo App Object 2" ou="demoapps1" type="Ant"/>
+     * </addpermobj>
+     * }
+     * </pre>
+     *
+     * @param permObj contains reference to data element targeted for insertion..
+     */
+    public void addPermObj(PermObj permObj)
+    {
+        this.permObjs.add(permObj);
+    }
+
+
+    /**
+     * Used by {@link FortressAntTask#addPermObjs()} to retrieve list of PermObjs as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.PermObj}s targeted for insertion.
+     */
+    public List<PermObj> getPermObjs()
+    {
+        return this.permObjs;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/AddpermOp.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/AddpermOp.java b/src/main/java/org/apache/directory/fortress/core/ant/AddpermOp.java
new file mode 100755
index 0000000..fb9df6e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/AddpermOp.java
@@ -0,0 +1,92 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link org.apache.directory.fortress.core.ant.PermAnt}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#addPermission(org.apache.directory.fortress.core.rbac.Permission)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'AddpermOp', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addpermop>
+ *           ...
+ *         </addpermop>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class AddpermOp
+{
+    final private List<PermAnt> permissions = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public AddpermOp()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addPermOp', is used for derived xml tag 'permop' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addpermop>
+     *     <permop opName="main" objName="/jsp/cal/cal1.jsp" type="Ant"/>
+     *     <permop opName="8am" objName="/jsp/cal/cal2.jsp" type="Ant"/>
+     *     <permop opName="9am" objName="/jsp/cal/cal2.jsp" type="Ant"/>
+     *     <permop opName="10am" objName="/jsp/cal/cal2.jsp" type="Ant"/>
+     *     <permop opName="11am" objName="/jsp/cal/cal2.jsp" type="Ant"/>
+     *     <permop opName="12pm" objName="/jsp/cal/cal2.jsp" type="Ant"/>
+     *     <permop opName="1pm" objName="/jsp/cal/cal2.jsp" type="Ant"/>
+     *     <permop opName="2pm" objName="/jsp/cal/cal2.jsp" type="Ant"/>
+     *     <permop opName="3pm" objName="/jsp/cal/cal2.jsp" type="Ant"/>
+     *     <permop opName="4pm" objName="/jsp/cal/cal2.jsp" type="Ant"/>
+     *     <permop opName="5pm" objName="/jsp/cal/cal2.jsp" type="Ant"/>
+     *     <permop opName="6pm" objName="/jsp/cal/cal2.jsp" type="Ant"/>
+     * </addpermop>
+     * }
+     * </pre>
+     *
+     * @param permission contains reference to data element targeted for insertion..
+     */
+    public void addPermOp(PermAnt permission)
+    {
+        this.permissions.add(permission);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addPermOps()} to retrieve list of Permissions as defined in input xml file.
+     *
+     * @return collection containing {@link PermAnt}s targeted for insertion.
+     */
+    public List<PermAnt> getPermOps()
+    {
+        return this.permissions;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addpermorgunitinheritance.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addpermorgunitinheritance.java b/src/main/java/org/apache/directory/fortress/core/ant/Addpermorgunitinheritance.java
new file mode 100755
index 0000000..c6ca211
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addpermorgunitinheritance.java
@@ -0,0 +1,85 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.Relationship;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link Relationship}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#addInheritance(org.apache.directory.fortress.core.rbac.Role, org.apache.directory.fortress.core.rbac.Role)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addpermorgunitinheritance', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addpermorgunitinheritance>
+ *           ...
+ *         </addpermorgunitinheritance>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addpermorgunitinheritance
+{
+    final private List<Relationship> relationships = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addpermorgunitinheritance()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addRelationship', is used for derived xml tag 'relationship' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addpermorgunitinheritance>
+     *     <relationship child="ou2" parent="ou1"/>
+     *     <relationship child="ou3" parent="ou1"/>
+     *     <relationship child="ou4" parent="ou1"/>
+     * </addpermorgunitinheritance>
+     * }
+     * </pre>
+     *
+     * @param relationship contains reference to data element targeted for insertion..
+     */
+    public void addRelationship(Relationship relationship)
+    {
+        this.relationships.add(relationship);
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#addAdminRoles()} to retrieve list of Roles as defined in input xml file.
+     *
+     * @return collection containing {@link Relationship}s targeted for insertion.
+     */
+    public List<Relationship> getRelationships()
+    {
+        return this.relationships;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addpwpolicy.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addpwpolicy.java b/src/main/java/org/apache/directory/fortress/core/ant/Addpwpolicy.java
new file mode 100755
index 0000000..3922bc4
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addpwpolicy.java
@@ -0,0 +1,97 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.PwPolicy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link org.apache.directory.fortress.core.rbac.PwPolicy}s used to drive {@link org.apache.directory.fortress.core.PwPolicyMgr#add(org.apache.directory.fortress.core.rbac.PwPolicy)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addpwpolicy', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addpwpolicy>
+ *           ...
+ *         </addpwpolicy>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addpwpolicy
+{
+    final private List<PwPolicy> policies = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addpwpolicy()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addPolicy', is used for derived xml tag 'policy' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addpwpolicy>
+     *     <policy name="Test1"
+     *         minAge="0"
+     *         maxAge="2000000"
+     *         inHistory="5"
+     *         checkQuality="2"
+     *         minLength="4"
+     *         expireWarning="1000000"
+     *         graceLoginLimit="3"
+     *         lockout="true"
+     *         lockoutDuration="0"
+     *         maxFailure="3"
+     *         failureCountInterval="0"
+     *         mustChange="true"
+     *         allowUserChange="true"
+     *         safeModify="false" />
+     * </addpwpolicy>
+     * }
+     * </pre>
+     *
+     * @param policy contains reference to data element targeted for insertion..
+     */
+    public void addPolicy(PwPolicy policy)
+    {
+        this.policies.add(policy);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addPolicies()} to retrieve list of PwPolicy as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.PwPolicy}s targeted for insertion.
+     */
+    public List<PwPolicy> getPolicies()
+    {
+        return this.policies;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addrole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addrole.java b/src/main/java/org/apache/directory/fortress/core/ant/Addrole.java
new file mode 100755
index 0000000..6dd8692
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addrole.java
@@ -0,0 +1,84 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.Role;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link org.apache.directory.fortress.core.rbac.Role}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#addRole(org.apache.directory.fortress.core.rbac.Role)}}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addrole', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addrole>
+ *           ...
+ *         </addrole>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addrole
+{
+    final private List<Role> roles = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addrole()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addRole', is used for derived xml tag 'role' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addrole>
+     *     <role name="role1" description="Tomcat Role for Calendar App" beginTime="0800" endTime="1700" beginDate="20110101" endDate="20111231" beginLockDate="20110601" endLockDate="20110615" dayMask="23456" timeout="60"/>
+     *     <role name="role2" description="Tomcat Role 2 for Calendar App"/>
+     * </addrole>
+     * }
+     * </pre>
+     *
+     * @param role contains reference to data element targeted for insertion..
+     */
+    public void addRole(Role role)
+    {
+        this.roles.add(role);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addRoles()} to retrieve list of Roles as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.Role}s targeted for insertion.
+     */
+    public List<Role> getRoles()
+    {
+        return this.roles;
+    }
+}
+


[02/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/time/Constraint.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/time/Constraint.java b/src/main/java/org/apache/directory/fortress/core/util/time/Constraint.java
new file mode 100755
index 0000000..936b650
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/time/Constraint.java
@@ -0,0 +1,223 @@
+/*
+ *   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.util.time;
+
+
+/**
+ * The Fortress Constraint interface prescribes attributes that are used to store, process and retrieve temporal validation attributes on
+ * {@link org.apache.directory.fortress.core.rbac.User}, {@link org.apache.directory.fortress.core.rbac.UserRole}, {@link org.apache.directory.fortress.core.rbac.Role},
+ * {@link org.apache.directory.fortress.core.rbac.AdminRole}, {@link org.apache.directory.fortress.core.rbac.UserAdminRole} entities.
+ * <p/>
+ * <img src="../../doc-files/TemporalRbac.png">
+ * <p/>
+ * <h3>Temporal Constraints on User and Role Assignments</h3>
+ * In addition to the standard RBAC support, Fortress provides coverage for temporal constraints on role and user activation into session.
+ * Temporal constraints affect when Users may activate Roles within runtime system at a particular point in time.  For example a nurse may be assigned to the "ChargeNurse" role but be limited as to when she is permitted to perform those duties, i.e. weekend graveyard shift.  Another example is a bank teller who is assigned to a "Teller" role but may only act within role between the hours of 9:00 to 5:00 on Monday thru Friday during normal business hours.
+ * Additionally Fortress temporal constraints are checked during user authentication to control when a user is actually permitted to sign-on to a system.  The constraints may also be applied to enforce temporary blackout periods to cover vacations, leave of absences, sabbaticals, etc.
+ * <p/>
+ * <h4>Constraint Schema</h4>
+ * The entity maps to Fortress LDAP Schema object classes:
+ * <p/>
+ * 1. ftRls Structural objectclass is used to store the Role information like name and temporal constraint attributes.
+ * <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>
+ * <p/>
+ * 2. ftUserAttrs is used to store user RBAC and Admin role assignment and other security attributes on User entity.
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.1</code>
+ * <li> <code>NAME 'ftUserAttrs'</code>
+ * <li> <code>DESC 'Fortress User Attribute AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MUST ( ftId )</code>
+ * <li> <code>MAY ( ftRC $ ftRA $ ftARC $ ftARA $ ftCstr</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public interface Constraint
+{
+    /**
+     * temporal boolean flag is used by internal Fortress components.
+     *
+     * @return boolean indicating if temporal constraints are placed on user.
+     */
+    public boolean isTemporalSet();
+
+    /**
+     * 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public void setTimeout(Integer 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public void setBeginTime(String 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public void setEndTime(String 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public void setBeginDate(String 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public void setEndDate(String 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public void setDayMask(String 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public void setBeginLockDate(String 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public void setEndLockDate(String endLockDate);
+
+    /**
+     * This is used internally by Fortress for Constraint operations.  Values set here by external caller will be ignored.
+     *
+     * @param name contains attribute used internally for constraint checking.
+     */
+    public void setName(String name);
+
+    /**
+     * Required on DAO classes convert from raw data to object format.  Not intended for external use.
+     *
+     * @return String that maps to {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public String getRawData();
+
+    /**
+     * 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public Integer getTimeout();
+
+    /**
+     * 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 'ftCstr', 'ftRC', 'ftARC' attributes in 'ftUserAttrs' object class and 'ftCstr' attribute in 'ftRls' object class.
+     */
+    public String getBeginTime();
+
+    /**
+     * 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public String getEndTime();
+
+    /**
+     * 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public String getBeginDate();
+
+    /**
+     * 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public String getEndDate();
+
+    /**
+     * 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public String getBeginLockDate();
+
+    /**
+     * 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public String getEndLockDate();
+
+    /**
+     * 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 {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public String getDayMask();
+
+    /**
+     * This is used internally by Fortress for Constraint operations.
+     *
+     * @return String that maps to {@code ftCstr}, {@code ftRC}, {@code ftARC} attributes in {@code ftUserAttrs} object class and {@code ftCstr} attribute in {@code ftRls} object class.
+     */
+    public String getName();
+}
\ 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/util/time/Date.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/time/Date.java b/src/main/java/org/apache/directory/fortress/core/util/time/Date.java
new file mode 100755
index 0000000..f19bdfb
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/time/Date.java
@@ -0,0 +1,101 @@
+/*
+ *   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.util.time;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.rbac.Session;
+
+/**
+ * This class performs date validation for {@link Constraint}.  This validator will ensure the current date falls between {@link Constraint#getBeginDate()} and {@link Constraint#getEndDate()}
+ * The format requires YYYYMMDD, i.e. 20110101 for January 1, 2011.  The constant {@link org.apache.directory.fortress.core.GlobalIds#NONE} may be used to disable checks for a particular entity.
+ * <h4> Constraint Targets include</h4>
+ * <ol>
+ * <li>{@link org.apache.directory.fortress.core.rbac.User} maps to 'ftCstr' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserRole} maps to 'ftRC' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.Role}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole}  maps to 'ftARC' attribute on 'ftRls' object class</li>
+ * </ol>
+ * </p>
+ *
+ * @author Shawn McKinney
+ */
+public class Date
+    implements Validator
+{
+    /**
+     * This method is called during entity activation, {@link CUtil#validateConstraints} and ensures the current date is
+     * between {@link Constraint#getBeginDate()} and {@link Constraint#getEndDate()}.
+     *
+     * This validation routine allows for either beginDate or endDate to be null or set to "none" which will disable the corresponding check.
+     * For example if beginDate is null or equal to 'none', the validator will not skip the date eval for begin date.
+     * If either begin or end dates are set the validator will compare to the current date to ensure within range.
+     * If set, the expected date format is YYYYMMDD.  For example, '20110101' equals Jan 1, 2011.
+     *
+     * @param session    required for {@link Validator} interface but not used here.
+     * @param constraint contains the begin and end dates.  Maps listed above.
+     * @param time       contains the current time stamp.
+     * @return '0' if validation succeeds else {@link GlobalErrIds#ACTV_FAILED_DATE} if failed.
+     */
+    @Override
+    public int validate(Session session, Constraint constraint, Time time)
+    {
+        int rc = GlobalErrIds.ACTV_FAILED_DATE;
+        boolean noBegin = false;
+        boolean noEnd = false;
+        if (constraint.getBeginDate() == null || constraint.getBeginDate().compareToIgnoreCase(GlobalIds.NONE) == 0)
+        {
+            noBegin = true;
+        }
+        if (constraint.getEndDate() == null || constraint.getEndDate().compareToIgnoreCase(GlobalIds.NONE) == 0)
+        {
+            noEnd = true;
+        }
+        if(noBegin && noEnd)
+        {
+            rc = 0;
+        }
+        else if(noBegin)
+        {
+            if (constraint.getEndDate().compareTo(time.date) >= 0)
+            {
+                rc = 0;
+            }
+        }
+        else if(noEnd)
+        {
+            if (constraint.getBeginDate().compareTo(time.date) <= 0)
+            {
+                rc = 0;
+            }
+        }
+        else if(!noEnd)
+        {
+            if (constraint.getBeginDate().compareTo(time.date) <= 0
+                && constraint.getEndDate().compareTo(time.date) >= 0)
+            {
+                rc = 0;
+            }
+        }
+        return rc;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/time/Day.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/time/Day.java b/src/main/java/org/apache/directory/fortress/core/util/time/Day.java
new file mode 100755
index 0000000..21b9a04
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/time/Day.java
@@ -0,0 +1,71 @@
+/*
+ *   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.util.time;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.rbac.Session;
+
+/**
+ * This class performs lock day of week validation for {@link Constraint}.  This validator will ensure the current day is allowed for {@link Constraint#getDayMask()}.
+ * The data format requires 1234567 for Sun, Mon, Tue, Wed, Thur, Fri, Sat, Sun respectively.  i.e. 23456 will allow entity to activated Monday - Friday.  The constant {@link org.apache.directory.fortress.core.GlobalIds#ALL} may be used to disable checks for a particular entity.
+ * <h4> Constraint Targets include</h4>
+ * <ol>
+ * <li>{@link org.apache.directory.fortress.core.rbac.User} maps to 'ftCstr' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserRole} maps to 'ftRC' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.Role}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole}  maps to 'ftARC' attribute on 'ftRls' object class</li>
+ * </ol>
+ * </p>
+ *
+ * @author Shawn McKinney
+ */
+public class Day
+    implements Validator
+{
+    /**
+     * This method is called during entity activation, {@link CUtil#validateConstraints} and ensures the current day falls
+     * within {@link Constraint#getDayMask()} range.
+     *
+     * @param session    required for {@link Validator} interface but not used here.
+     * @param constraint contains the days of week entity may be activated.  Data mappings listed above.
+     * @param time       contains the current time stamp.
+     * @return '0' if validation succeeds else {@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_DAY} if failed.
+     */
+    @Override
+    public int validate(Session session, Constraint constraint, Time time)
+    {
+        int rc = GlobalErrIds.ACTV_FAILED_DAY;
+        if (constraint.getDayMask() == null || constraint.getDayMask().compareToIgnoreCase(GlobalIds.ALL) == 0)
+        {
+            rc = 0;
+        }
+        else
+        {
+            if (constraint.getDayMask().contains(time.day))
+            {
+                rc = 0;
+            }
+        }
+        return rc;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/time/LockDate.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/time/LockDate.java b/src/main/java/org/apache/directory/fortress/core/util/time/LockDate.java
new file mode 100755
index 0000000..399cb74
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/time/LockDate.java
@@ -0,0 +1,88 @@
+/*
+ *   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.util.time;
+
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.rbac.Session;
+
+/**
+ * This class performs lock date validation for {@link Constraint}.  This validator will ensure the current date falls outside {@link Constraint#getBeginLockDate()} and {@link Constraint#getEndLockDate()} range.
+ * The idea is an entity can be barred from activation for a particular blackout period, i.e. vacation, leave of absence, etc.
+ * The data format requires YYYYMMDD, i.e. 20110101 for January 1, 2011.  The constant {@link org.apache.directory.fortress.core.GlobalIds#NONE} may be used to disable checks for a particular entity.
+ * <h4> Constraint Targets include</h4>
+ * <ol>
+ * <li>{@link org.apache.directory.fortress.core.rbac.User} maps to 'ftCstr' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserRole} maps to 'ftRC' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.Role}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole}  maps to 'ftARC' attribute on 'ftRls' object class</li>
+ * </ol>
+ * </p>
+ *
+ * @author Shawn McKinney
+ */
+public class LockDate
+    implements Validator
+{
+    /**
+     * This method is called during entity activation, {@link CUtil#validateConstraints} and ensures the current date falls
+     * outside the {@link Constraint#getBeginLockDate()} and {@link Constraint#getEndLockDate()} range.
+     *
+     * This validation routine will automatically pass if either beginLockDate or endLockDate equals null or "none".
+     * If both beginLockDate and endLockDate are set the validator will ensure current date does not fall between the date range.
+     * The format expected if date is set is YYYYMMDD.  For example, '20110101' equals Jan 1, 2011.
+     *
+     * @param session    required for {@link Validator} interface but not used here.
+     * @param constraint contains the begin and end lock dates.  Maps listed above.
+     * @param time       contains the current time stamp.
+     * @return '0' if validation succeeds else {@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_LOCK} if failed.
+     */
+    @Override
+    public int validate(Session session, Constraint constraint, Time time)
+    {
+        int rc = GlobalErrIds.ACTV_FAILED_LOCK;
+
+        // if either beginLockDate or endLockDate equal to null or 'none', validation will automatically pass.
+        if ( constraint.getBeginLockDate() == null || constraint.getBeginLockDate().compareToIgnoreCase(GlobalIds.NONE) == 0
+          || constraint.getEndLockDate() == null || constraint.getEndLockDate().compareToIgnoreCase(GlobalIds.NONE) == 0)
+        {
+            rc = 0;
+        }
+        else
+        {
+            if (!(constraint.getBeginLockDate().compareTo(time.date) <= 0
+                && constraint.getEndLockDate().compareTo(time.date) >= 0))
+
+                //if (!(constraint.getBeginLockDate().compareTo(time.date) <= 0
+                //    && constraint.getEndLockDate().compareTo(time.date) >= 0))
+                //{
+                //    rc = 0;
+                //}
+
+            {
+                rc = 0;
+            }
+        }
+        return rc;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/time/TUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/time/TUtil.java b/src/main/java/org/apache/directory/fortress/core/util/time/TUtil.java
new file mode 100755
index 0000000..70ded67
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/time/TUtil.java
@@ -0,0 +1,74 @@
+/*
+ *   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.util.time;
+
+import java.util.GregorianCalendar;
+
+/**
+ * Utility class to convert current time/date into internal format, {@link Time}, used for {@link Constraint} checks {@link CUtil#validateConstraints(org.apache.directory.fortress.core.rbac.Session, CUtil.ConstraintType, boolean)}.
+ * This utility processes custom date formats and should not be used by external programs.
+ *
+ * @author Shawn McKinney
+ */
+public class TUtil
+{
+
+    /**
+     * Get the curent timestamp from Java and convert to {@link Time} format.
+     *
+     * @return Time
+     */
+    public static Time getCurrentTime()
+    {
+        Time time = new Time();
+        GregorianCalendar gc = new GregorianCalendar();
+        String szMinute = "" + gc.get(GregorianCalendar.MINUTE);
+        String szHour = "" + gc.get(GregorianCalendar.HOUR_OF_DAY);
+
+        time.day = "" + gc.get(GregorianCalendar.DAY_OF_WEEK);
+        String szDay = "" + gc.get(GregorianCalendar.DAY_OF_MONTH);
+        int month = gc.get(GregorianCalendar.MONTH);
+        String szMonth = "" + (month + 1);
+        String szYear = "" + gc.get(GregorianCalendar.YEAR);
+
+        if (szMinute.length() == 1)
+        {
+            szMinute = "0" + szMinute;
+        }
+        if (szHour.length() == 1)
+        {
+            szHour = "0" + szHour;
+        }
+        if (szDay.length() == 1)
+        {
+            szDay = "0" + szDay;
+        }
+        if (szMonth.length() == 1)
+        {
+            szMonth = "0" + szMonth;
+        }
+        String szCurrentTime = szHour + szMinute;
+
+        time.currentTime = new Integer(szCurrentTime);
+        time.date = szYear + szMonth + szDay;
+        return time;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/time/Time.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/time/Time.java b/src/main/java/org/apache/directory/fortress/core/util/time/Time.java
new file mode 100755
index 0000000..38685dc
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/time/Time.java
@@ -0,0 +1,44 @@
+/*
+ *   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.util.time;
+
+/**
+ * Class contains a custom timestamp that is processed by {@link Validator} to check {@link Constraint}.
+ *
+ * @author Shawn McKinney
+ */
+public class Time
+{
+    /**
+     * Stored as {@code System.out.getCurrentMillis()} format.
+     */
+    public Integer currentTime;
+
+    /**
+     * Stored in '1234567' format for Sun, Mon, Tue, Wed, Thur, Fri, Sat respectively.  i.e. '23456' is Mon-Friday.
+     */
+    public String day;
+
+    /**
+     * Stored in 'YYYYMMDD' format.  i.e. '20110101' is January 1, 2011.
+     */
+    public String date;
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/time/Timeout.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/time/Timeout.java b/src/main/java/org/apache/directory/fortress/core/util/time/Timeout.java
new file mode 100755
index 0000000..7d22e30
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/time/Timeout.java
@@ -0,0 +1,73 @@
+/*
+ *   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.util.time;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.rbac.Session;
+
+/**
+ * This class performs timeout validation for {@link Constraint}.  This validator will ensure the elapsed time an entity is active is less than {@link Constraint#getTimeout()} and {@link Constraint#getEndTime()}
+ * The timeout is in minutes and is stored as integer value.  i.e. 30 for 30 minutes.  A value of '0' specifies no timeout for a particular entity.
+ * <h4> Constraint Targets include</h4>
+ * <ol>
+ * <li>{@link org.apache.directory.fortress.core.rbac.User} maps to 'ftCstr' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserRole} maps to 'ftRC' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.Role}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole}  maps to 'ftARC' attribute on 'ftRls' object class</li>
+ * </ol>
+ * </p>
+ *
+ * @author Shawn McKinney
+ */
+public class Timeout
+    implements Validator
+{
+    /**
+     * This method is called during entity activation, {@link CUtil#validateConstraints} and ensures the elapsed time a particular entity has been activated does not exceed specified.
+     * value {@link Constraint#getTimeout()}.
+     *
+     * @param session    required for {@link Validator} interface but not used here.
+     * @param constraint contains the elapsed time entity may remain inactive in minutes.  Maps listed above.
+     * @param time       contains the current timestamp.
+     * @return '0' if validation succeeds else {@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_TIMEOUT} if failed.
+     */
+    public int validate(Session session, Constraint constraint, Time time)
+    {
+        int rc = GlobalErrIds.ACTV_FAILED_TIMEOUT;
+        long timeLimit;
+        long lastTime = session.getLastAccess();
+        if (lastTime == 0)
+        {
+            rc = 0;
+        }
+        else
+        {
+            long elapsedTime = System.currentTimeMillis() - lastTime;
+            timeLimit = constraint.getTimeout() * 60000;
+            if (elapsedTime < timeLimit || constraint.getTimeout() == 0)
+            {
+                rc = 0;
+            }
+        }
+        return rc;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/time/Validator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/time/Validator.java b/src/main/java/org/apache/directory/fortress/core/util/time/Validator.java
new file mode 100755
index 0000000..5adb79f
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/time/Validator.java
@@ -0,0 +1,81 @@
+/*
+ *   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.util.time;
+
+import org.apache.directory.fortress.core.rbac.Session;
+
+/**
+ * Interface used by Fortress to provide pluggable validation routines for constraints.
+ *
+ * <h4> Constraint Targets</h4>
+ * <ol>
+ * <li>{@link org.apache.directory.fortress.core.rbac.User}</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserRole}</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.Role}</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole}</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole}</li>
+ * </ol>
+ * </p>
+ * <h4> Constraint Processors </h4>
+ * <ol>
+ * <li>Time of day:  {@link ClockTime}</li>
+ * <li>Date:         {@link Date}</li>
+ * <li>Days of week: {@link Day}</li>
+ * <li>Timeout:      {@link Timeout}</li>
+ * <li>Lock dates:   {@link LockDate}</li>
+ * <li>DSDs:         {@link org.apache.directory.fortress.core.rbac.DSDChecker}</li>
+ * </ol>
+ * </p>
+ * <h4> Constraint Error Codes </h4>
+ * <ol>
+ * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_DAY}</li>
+ * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_DATE}</li>
+ * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_TIME}</li>
+ * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_TIMEOUT}</li>
+ * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_LOCK}</li>
+ * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_DSD}</li>
+ * </ol>
+ *
+ * @author Shawn McKinney
+ */
+public interface Validator
+{
+    /**
+     * This method is called during activation of {@link org.apache.directory.fortress.core.rbac.UserRole} and {@link org.apache.directory.fortress.core.rbac.UserAdminRole}
+     * </p>
+     * The following error codes can be returned for validations:
+     * <ol>
+     * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_DAY}</li>
+     * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_DATE}</li>
+     * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_TIME}</li>
+     * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_TIMEOUT}</li>
+     * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_LOCK}</li>
+     * <li>{@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_DSD}</li>
+     * </ol>
+     *
+     * @param session contains the reference to Fortress entities that are targets for constraints.
+     * @param constraint contains the temporal attributes.
+     * @param time current time of day.
+     * @return activation failure code.
+     * @throws org.apache.directory.fortress.core.SecurityException in the event of validation fails or system exception.
+     */
+    public int validate(Session session, Constraint constraint, Time time) throws org.apache.directory.fortress.core.SecurityException;
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/time/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/time/package.html b/src/main/java/org/apache/directory/fortress/core/util/time/package.html
new file mode 100755
index 0000000..320be82
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/time/package.html
@@ -0,0 +1,34 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.util.time</title>
+   </head>
+   <body>
+      <p>
+         This package contains utilities used to process fortress temporal constraint checks on entities being activated within the runtime system.
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress.util.time</b> package contains utilities to process temporal constraint checks on fortress runtime data entities.  The
+          temporal constraint checks may be activated and deactivated via switches in the configuration system.  The apis contained within this package are for fortress use only.
+          See the corresponding javadoc contained with this package for more info.
+      </p>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/openldap/fortress/AccelMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/AccelMgr.java b/src/main/java/org/openldap/fortress/AccelMgr.java
deleted file mode 100644
index 6c339de..0000000
--- a/src/main/java/org/openldap/fortress/AccelMgr.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- *   Licensed to the Apache Software Foundation (ASF) under one
- *   or more contributor license agreements.  See the NOTICE file
- *   distributed with this work for additional information
- *   regarding copyright ownership.  The ASF licenses this file
- *   to you under the Apache License, Version 2.0 (the
- *   "License"); you may not use this file except in compliance
- *   with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing,
- *   software distributed under the License is distributed on an
- *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *   KIND, either express or implied.  See the License for the
- *   specific language governing permissions and limitations
- *   under the License.
- *
- */
-package org.openldap.fortress;
-
-import java.util.List;
-
-import org.openldap.fortress.rbac.Permission;
-import org.openldap.fortress.rbac.User;
-import org.openldap.fortress.rbac.Session;
-import org.openldap.fortress.rbac.UserRole;
-
-/**
- * This object performs runtime access control operations on objects that are provisioned RBAC entities
- * that reside in LDAP directory.  These APIs map directly to similar named APIs specified by ANSI and NIST
- * RBAC system functions.
- * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
- * The RBAC Functional specification describes administrative operations for the creation
- * and maintenance of RBAC element sets and relations; administrative review functions for
- * performing administrative queries; and system functions for creating and managing
- * RBAC attributes on user sessions and making access control decisions.
- * <p/>
- * <hr>
- * <h4>RBAC0 - Core</h4>
- * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
- * <p/>
- * <img src="./doc-files/RbacCore.png">
- * <hr>
- * <h4>RBAC1 - General Hierarchical Roles</h4>
- * Simplifies role engineering tasks using inheritance of one or more parent roles.
- * <p/>
- * <img src="./doc-files/RbacHier.png">
- * <hr>
- * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
- * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
- * <p/>
- * <img src="./doc-files/RbacSSD.png">
- * <hr>
- * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
- * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
- * <p/>
- * <img src="./doc-files/RbacDSD.png">
- * <hr>
- * <p/>
- * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.openldap.fortress.rbac.Session)}) are set.
- * @author Shawn McKinney
- */
-public interface AccelMgr extends Manageable
-{
-
-    /**
-     * Perform user authentication {@link User#password} and role activations.<br />
-     * This method must be called once per user prior to calling other methods within this class.
-     * The successful result is {@link org.openldap.fortress.rbac.Session} that contains target user's RBAC {@link User#roles} and Admin role {@link User#adminRoles}.<br />
-     * In addition to checking user password validity it will apply configured password policy checks {@link org.openldap.fortress.rbac.User#pwPolicy}..<br />
-     * Method may also store parms passed in for audit trail {@link org.openldap.fortress.rbac.FortEntity}.
-     * <h4> This API will...</h4>
-     * <ul>
-     * <li> authenticate user password if trusted == false.
-     * <li> perform <a href="http://www.openldap.org/">OpenLDAP</a> <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10">password policy evaluation</a>, see {@link org.openldap.fortress.ldap.openldap.OLPWControlImpl}.
-     * <li> fail for any user who is locked by OpenLDAP's policies {@link org.openldap.fortress.rbac.User#isLocked()}, regardless of trusted flag being set as parm on API.
-     * <li> evaluate temporal {@link org.openldap.fortress.util.time.Constraint}(s) on {@link User}, {@link UserRole} and {@link org.openldap.fortress.rbac.UserAdminRole} entities.
-     * <li> process selective role activations into User RBAC Session {@link User#roles}.
-     * <li> check Dynamic Separation of Duties {@link org.openldap.fortress.rbac.DSDChecker#validate(org.openldap.fortress.rbac.Session, org.openldap.fortress.util.time.Constraint, org.openldap.fortress.util.time.Time)} on {@link org.openldap.fortress.rbac.User#roles}.
-     * <li> process selective administrative role activations {@link User#adminRoles}.
-     * <li> return a {@link org.openldap.fortress.rbac.Session} containing {@link org.openldap.fortress.rbac.Session#getUser()}, {@link org.openldap.fortress.rbac.Session#getRoles()} and (if admin user) {@link org.openldap.fortress.rbac.Session#getAdminRoles()} if everything checks out good.
-     * <li> throw a checked exception that will be {@link org.openldap.fortress.SecurityException} or its derivation.
-     * <li> throw a {@link SecurityException} for system failures.
-     * <li> throw a {@link PasswordException} for authentication and password policy violations.
-     * <li> throw a {@link ValidationException} for data validation errors.
-     * <li> throw a {@link FinderException} if User id not found.
-     * </ul>
-     * <h4>
-     * The function is valid if and only if:
-     * </h4>
-     * <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>
-     * <h4>
-     * The following attributes may be set when calling this method
-     * </h4>
-     * <ul>
-     * <li> {@link User#userId} - required
-     * <li> {@link org.openldap.fortress.rbac.User#password}
-     * <li> {@link org.openldap.fortress.rbac.User#roles} contains a list of RBAC role names authorized for user and targeted for activation within this session.  Default is all authorized RBAC roles will be activated into this Session.
-     * <li> {@link org.openldap.fortress.rbac.User#adminRoles} contains a list of Admin role names authorized for user and targeted for activation.  Default is all authorized ARBAC roles will be activated into this Session.
-     * <li> {@link User#props} collection of name value pairs collected on behalf of User during signon.  For example hostname:myservername or ip:192.168.1.99
-     * </ul>
-     * <h4>
-     * Notes:
-     * </h4>
-     * <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, see {@link User#setRole(String)}.
-     * </ul>
-     * </p>
-     *
-     * @param user      Contains {@link User#userId}, {@link org.openldap.fortress.rbac.User#password} (optional if {@code isTrusted} is 'true'), optional {@link User#roles}, optional {@link org.openldap.fortress.rbac.User#adminRoles}
-     * @param isTrusted if true password is not required.
-     * @return Session object will contain authentication result code {@link org.openldap.fortress.rbac.Session#errorId}, RBAC role activations {@link org.openldap.fortress.rbac.Session#getRoles()}, Admin Role activations {@link org.openldap.fortress.rbac.Session#getAdminRoles()},OpenLDAP pw policy codes {@link org.openldap.fortress.rbac.Session#warningId}, {@link org.openldap.fortress.rbac.Session#expirationSeconds}, {@link org.openldap.fortress.rbac.Session#graceLogins} and more.
-     * @throws org.openldap.fortress.SecurityException
-     *          in the event of data validation failure, security policy violation or DAO error.
-     */
-    public Session createSession(User user, boolean isTrusted)
-        throws SecurityException;
-
-
-    /**
-     * This function deletes a fortress session from the RBAC Policy Decision Point inside OpenLDAP RBAC Accelerator.  The function is valid if
-     * and only if the session is a valid Fortress session.
-     *
-     * @param session object contains the user's returned RBAC session from the createSession method.
-     * @throws SecurityException is thrown if session invalid or system. error.
-     */
-    public void deleteSession(Session session)
-        throws SecurityException;
-
-    /**
-     * This function returns the active roles associated with a session. The function is valid if
-     * and only if the session is a valid Fortress session.
-     *
-     * @param session object contains the user's returned RBAC session from the createSession method.
-     * @return List<UserRole> containing all roles active in user's session.  This will NOT contain inherited roles.
-     * @throws SecurityException is thrown if session invalid or system. error.
-     */
-    public List<UserRole> sessionRoles(Session session)
-        throws SecurityException;
-
-
-    /**
-     * Perform user RBAC authorization.  This function returns a Boolean value meaning whether the subject of a given session is
-     * allowed or not to perform a given operation on a given object. The function is valid if and
-     * only if the session is a valid Fortress session, the object is a member of the OBJS data set,
-     * and the operation is a member of the OPS data set. The session's subject has the permission
-     * to perform the operation on that object if and only if that permission is assigned to (at least)
-     * one of the session's active roles. This implementation will verify the roles or userId correspond
-     * to the subject's active roles are registered in the object's access control list.
-     *
-     * @param perm    must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, of permission User is trying to access.
-     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
-     * @return True if user has access, false otherwise.
-     * @throws org.openldap.fortress.SecurityException
-     *          in the event of data validation failure, security policy violation or DAO error.
-     */
-    public boolean checkAccess(Session session, Permission perm)
-        throws SecurityException;
-
-
-    /**
-     * This function returns the permissions of the session, i.e., the permissions assigned
-     * to its authorized roles. The function is valid if and only if the session is a valid Fortress session.
-     *
-     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
-     * @return List<Permission> containing permissions (op, obj) active for user's session.
-     * @throws SecurityException is thrown if runtime error occurs with system.
-     */
-    public List<Permission> sessionPermissions(Session session)
-        throws SecurityException;
-
-
-    /**
-     * This function adds a role as an active role of a session whose owner is a given user.
-     * <p>
-     * The function is valid if and only if:
-     * <ul>
-     * <li> the user is a member of the USERS data set
-     * <li> the role is a member of the ROLES data set
-     * <li> the role inclusion does not violate Dynamic Separation of Duty Relationships
-     * <li> the session is a valid Fortress session
-     * <li> the user is authorized to that role
-     * <li> the session is owned by that user.
-     * </ul>
-     * </p>
-     *
-     * @param session object contains the user's returned RBAC session from the createSession method.
-     * @param role    object contains the role name, {@link UserRole#name}, to be activated into session.
-     * @throws SecurityException is thrown if user is not allowed to activate or runtime error occurs with system.
-     */
-    public void addActiveRole(Session session, UserRole role)
-        throws SecurityException;
-
-
-    /**
-     * This function deletes a role from the active role set of a session owned by a given user.
-     * The function is valid if and only if the user is a member of the USERS data set, the
-     * session object contains a valid Fortress session, the session is owned by the user,
-     * and the role is an active role of that session.
-     *
-     * @param session object contains the user's returned RBAC session from the createSession method.
-     * @param role    object contains the role name, {@link org.openldap.fortress.rbac.UserRole#name}, to be deactivated.
-     * @throws SecurityException is thrown if user is not allowed to deactivate or runtime error occurs with system.
-     */
-    public void dropActiveRole(Session session, UserRole role)
-        throws SecurityException;
-}
-

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/openldap/fortress/AccelMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/AccelMgrFactory.java b/src/main/java/org/openldap/fortress/AccelMgrFactory.java
deleted file mode 100644
index 5b6f08c..0000000
--- a/src/main/java/org/openldap/fortress/AccelMgrFactory.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *   Licensed to the Apache Software Foundation (ASF) under one
- *   or more contributor license agreements.  See the NOTICE file
- *   distributed with this work for additional information
- *   regarding copyright ownership.  The ASF licenses this file
- *   to you under the Apache License, Version 2.0 (the
- *   "License"); you may not use this file except in compliance
- *   with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing,
- *   software distributed under the License is distributed on an
- *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *   KIND, either express or implied.  See the License for the
- *   specific language governing permissions and limitations
- *   under the License.
- *
- */
-package org.openldap.fortress;
-
-import org.openldap.fortress.cfg.Config;
-import org.openldap.fortress.rbac.AccelMgrImpl;
-import org.openldap.fortress.rbac.ClassUtil;
-import org.openldap.fortress.util.attr.VUtil;
-
-/**
- * Creates an instance of the AccelMgr object.
- * <p/>
- * The default implementation class is specified as {@link AccelMgrImpl} but can be overridden by
- * adding the {@link GlobalIds#ACCEL_IMPLEMENTATION} config property.
- * <p/>
-
- *
- * @author Shawn McKinney
- */
-public class AccelMgrFactory
-{
-    private static String accelClassName = Config.getProperty(GlobalIds.ACCEL_IMPLEMENTATION);
-    private static final String CLS_NM = AccelMgrFactory.class.getName();
-
-    /**
-     * Create and return a reference to {@link org.openldap.fortress.AccelMgr} object using HOME context.
-     *
-     * @return instance of {@link org.openldap.fortress.AccelMgr}.
-     * @throws org.openldap.fortress.SecurityException in the event of failure during instantiation.
-     */
-    public static AccelMgr createInstance()
-        throws SecurityException
-    {
-        return createInstance( GlobalIds.HOME );
-    }
-
-    /**
-     * Create and return a reference to {@link org.openldap.fortress.AccelMgr} object.
-     *
-     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
-     * @return instance of {@link org.openldap.fortress.AccelMgr}.
-     * @throws org.openldap.fortress.SecurityException in the event of failure during instantiation.
-     */
-    public static AccelMgr createInstance(String contextId)
-        throws SecurityException
-    {
-        VUtil.assertNotNull(contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance");
-        if (!VUtil.isNotNullOrEmpty(accelClassName))
-        {
-                accelClassName = AccelMgrImpl.class.getName();
-        }
-
-        AccelMgr accelMgr = (AccelMgr) ClassUtil.createInstance(accelClassName);
-        accelMgr.setContextId(contextId);
-        return accelMgr;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/openldap/fortress/AccessMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/AccessMgr.java b/src/main/java/org/openldap/fortress/AccessMgr.java
deleted file mode 100755
index 75c79d1..0000000
--- a/src/main/java/org/openldap/fortress/AccessMgr.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- *   Licensed to the Apache Software Foundation (ASF) under one
- *   or more contributor license agreements.  See the NOTICE file
- *   distributed with this work for additional information
- *   regarding copyright ownership.  The ASF licenses this file
- *   to you under the Apache License, Version 2.0 (the
- *   "License"); you may not use this file except in compliance
- *   with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing,
- *   software distributed under the License is distributed on an
- *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *   KIND, either express or implied.  See the License for the
- *   specific language governing permissions and limitations
- *   under the License.
- *
- */
-package org.openldap.fortress;
-
-import java.util.List;
-import java.util.Set;
-
-import org.openldap.fortress.rbac.Permission;
-import org.openldap.fortress.rbac.User;
-import org.openldap.fortress.rbac.Session;
-import org.openldap.fortress.rbac.UserRole;
-
-/**
- * This object performs runtime access control operations on objects that are provisioned RBAC entities
- * that reside in LDAP directory.  These APIs map directly to similar named APIs specified by ANSI and NIST
- * RBAC system functions.
- * Many of the java doc function descriptions found below were taken directly from ANSI INCITS 359-2004.
- * The RBAC Functional specification describes administrative operations for the creation
- * and maintenance of RBAC element sets and relations; administrative review functions for
- * performing administrative queries; and system functions for creating and managing
- * RBAC attributes on user sessions and making access control decisions.
- * <p/>
- * <hr>
- * <h4>RBAC0 - Core</h4>
- * Many-to-many relationship between Users, Roles and Permissions. Selective role activation into sessions.  API to add, update, delete identity data and perform identity and access control decisions during runtime operations.
- * <p/>
- * <img src="./doc-files/RbacCore.png">
- * <hr>
- * <h4>RBAC1 - General Hierarchical Roles</h4>
- * Simplifies role engineering tasks using inheritance of one or more parent roles.
- * <p/>
- * <img src="./doc-files/RbacHier.png">
- * <hr>
- * <h4>RBAC2 - Static Separation of Duty (SSD) Relations</h4>
- * Enforce mutual membership exclusions across role assignments.  Facilitate dual control policies by restricting which roles may be assigned to users in combination.  SSD provide added granularity for authorization limits which help enterprises meet strict compliance regulations.
- * <p/>
- * <img src="./doc-files/RbacSSD.png">
- * <hr>
- * <h4>RBAC3 - Dynamic Separation of Duty (DSD) Relations</h4>
- * Control allowed role combinations to be activated within an RBAC session.  DSD policies fine tune role policies that facilitate authorization dual control and two man policy restrictions during runtime security checks.
- * <p/>
- * <img src="./doc-files/RbacDSD.png">
- * <hr>
- * <p/>
- * This interface's implementer will NOT be thread safe if parent instance variables ({@link Manageable#setContextId(String)} or {@link Manageable#setAdmin(org.openldap.fortress.rbac.Session)}) are set.
- * @author Shawn McKinney
- */
-public interface AccessMgr extends Manageable
-{
-
-    /**
-     * Perform user authentication only.  It does not activate RBAC roles in session but will evaluate
-     * password policies.
-     *
-     * @param userId   Contains the userid of the user signing on.
-     * @param password Contains the user's password.
-     * @return Session object will be returned if authentication successful.  This will not contain user's roles.
-     * @throws org.openldap.fortress.SecurityException
-     *          in the event of data validation failure, security policy violation or DAO error.
-     */
-    public Session authenticate(String userId, char[] password)
-        throws org.openldap.fortress.SecurityException;
-
-
-    /**
-     * Perform user authentication {@link User#password} and role activations.<br />
-     * This method must be called once per user prior to calling other methods within this class.
-     * The successful result is {@link org.openldap.fortress.rbac.Session} that contains target user's RBAC {@link User#roles} and Admin role {@link User#adminRoles}.<br />
-     * In addition to checking user password validity it will apply configured password policy checks {@link org.openldap.fortress.rbac.User#pwPolicy}..<br />
-     * Method may also store parms passed in for audit trail {@link org.openldap.fortress.rbac.FortEntity}.
-     * <h4> This API will...</h4>
-     * <ul>
-     * <li> authenticate user password if trusted == false.
-     * <li> perform <a href="http://www.openldap.org/">OpenLDAP</a> <a href="http://tools.ietf.org/html/draft-behera-ldap-password-policy-10">password policy evaluation</a>, see {@link org.openldap.fortress.ldap.openldap.OLPWControlImpl}.
-     * <li> fail for any user who is locked by OpenLDAP's policies {@link org.openldap.fortress.rbac.User#isLocked()}, regardless of trusted flag being set as parm on API.
-     * <li> evaluate temporal {@link org.openldap.fortress.util.time.Constraint}(s) on {@link User}, {@link UserRole} and {@link org.openldap.fortress.rbac.UserAdminRole} entities.
-     * <li> process selective role activations into User RBAC Session {@link User#roles}.
-     * <li> check Dynamic Separation of Duties {@link org.openldap.fortress.rbac.DSDChecker#validate(org.openldap.fortress.rbac.Session, org.openldap.fortress.util.time.Constraint, org.openldap.fortress.util.time.Time)} on {@link org.openldap.fortress.rbac.User#roles}.
-     * <li> process selective administrative role activations {@link User#adminRoles}.
-     * <li> return a {@link org.openldap.fortress.rbac.Session} containing {@link org.openldap.fortress.rbac.Session#getUser()}, {@link org.openldap.fortress.rbac.Session#getRoles()} and (if admin user) {@link org.openldap.fortress.rbac.Session#getAdminRoles()} if everything checks out good.
-     * <li> throw a checked exception that will be {@link org.openldap.fortress.SecurityException} or its derivation.
-     * <li> throw a {@link SecurityException} for system failures.
-     * <li> throw a {@link PasswordException} for authentication and password policy violations.
-     * <li> throw a {@link ValidationException} for data validation errors.
-     * <li> throw a {@link FinderException} if User id not found.
-     * </ul>
-     * <h4>
-     * The function is valid if and only if:
-     * </h4>
-     * <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>
-     * <h4>
-     * The following attributes may be set when calling this method
-     * </h4>
-     * <ul>
-     * <li> {@link User#userId} - required
-     * <li> {@link org.openldap.fortress.rbac.User#password}
-     * <li> {@link org.openldap.fortress.rbac.User#roles} contains a list of RBAC role names authorized for user and targeted for activation within this session.  Default is all authorized RBAC roles will be activated into this Session.
-     * <li> {@link org.openldap.fortress.rbac.User#adminRoles} contains a list of Admin role names authorized for user and targeted for activation.  Default is all authorized ARBAC roles will be activated into this Session.
-     * <li> {@link User#props} collection of name value pairs collected on behalf of User during signon.  For example hostname:myservername or ip:192.168.1.99
-     * </ul>
-     * <h4>
-     * Notes:
-     * </h4>
-     * <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, see {@link User#setRole(String)}.
-     * </ul>
-     * </p>
-     *
-     * @param user      Contains {@link User#userId}, {@link org.openldap.fortress.rbac.User#password} (optional if {@code isTrusted} is 'true'), optional {@link User#roles}, optional {@link org.openldap.fortress.rbac.User#adminRoles}
-     * @param isTrusted if true password is not required.
-     * @return Session object will contain authentication result code {@link org.openldap.fortress.rbac.Session#errorId}, RBAC role activations {@link org.openldap.fortress.rbac.Session#getRoles()}, Admin Role activations {@link org.openldap.fortress.rbac.Session#getAdminRoles()},OpenLDAP pw policy codes {@link org.openldap.fortress.rbac.Session#warningId}, {@link org.openldap.fortress.rbac.Session#expirationSeconds}, {@link org.openldap.fortress.rbac.Session#graceLogins} and more.
-     * @throws org.openldap.fortress.SecurityException
-     *          in the event of data validation failure, security policy violation or DAO error.
-     */
-    public Session createSession(User user, boolean isTrusted)
-        throws SecurityException;
-
-
-    /**
-     * Perform user RBAC authorization.  This function returns a Boolean value meaning whether the subject of a given session is
-     * allowed or not to perform a given operation on a given object. The function is valid if and
-     * only if the session is a valid Fortress session, the object is a member of the OBJS data set,
-     * and the operation is a member of the OPS data set. The session's subject has the permission
-     * to perform the operation on that object if and only if that permission is assigned to (at least)
-     * one of the session's active roles. This implementation will verify the roles or userId correspond
-     * to the subject's active roles are registered in the object's access control list.
-     *
-     * @param perm    must contain the object, {@link Permission#objName}, and operation, {@link Permission#opName}, of permission User is trying to access.
-     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
-     * @return True if user has access, false otherwise.
-     * @throws org.openldap.fortress.SecurityException
-     *          in the event of data validation failure, security policy violation or DAO error.
-     */
-    public boolean checkAccess(Session session, Permission perm)
-        throws SecurityException;
-
-
-    /**
-     * This function returns the permissions of the session, i.e., the permissions assigned
-     * to its authorized roles. The function is valid if and only if the session is a valid Fortress session.
-     *
-     * @param session This object must be instantiated by calling {@link AccessMgr#createSession} method before passing into the method.  No variables need to be set by client after returned from createSession.
-     * @return List<Permission> containing permissions (op, obj) active for user's session.
-     * @throws SecurityException is thrown if runtime error occurs with system.
-     */
-    public List<Permission> sessionPermissions(Session session)
-        throws SecurityException;
-
-
-    /**
-     * This function returns the active roles associated with a session. The function is valid if
-     * and only if the session is a valid Fortress session.
-     *
-     * @param session object contains the user's returned RBAC session from the createSession method.
-     * @return List<UserRole> containing all roles active in user's session.  This will NOT contain inherited roles.
-     * @throws SecurityException is thrown if session invalid or system. error.
-     */
-    public List<UserRole> sessionRoles(Session session)
-        throws SecurityException;
-
-
-    /**
-     * This function returns the authorized roles associated with a session based on hierarchical relationships. The function is valid if
-     * and only if the session is a valid Fortress session.
-     *
-     * @param session object contains the user's returned RBAC session from the createSession method.
-     * @return Set<String> containing all roles active in user's session.  This will contain inherited roles.
-     * @throws SecurityException is thrown if session invalid or system. error.
-     */
-    public Set<String> authorizedRoles(Session session)
-        throws SecurityException;
-
-
-    /**
-     * This function adds a role as an active role of a session whose owner is a given user.
-     * <p>
-     * The function is valid if and only if:
-     * <ul>
-     * <li> the user is a member of the USERS data set
-     * <li> the role is a member of the ROLES data set
-     * <li> the role inclusion does not violate Dynamic Separation of Duty Relationships
-     * <li> the session is a valid Fortress session
-     * <li> the user is authorized to that role
-     * <li> the session is owned by that user.
-     * </ul>
-     * </p>
-     *
-     * @param session object contains the user's returned RBAC session from the createSession method.
-     * @param role    object contains the role name, {@link UserRole#name}, to be activated into session.
-     * @throws SecurityException is thrown if user is not allowed to activate or runtime error occurs with system.
-     */
-    public void addActiveRole(Session session, UserRole role)
-        throws SecurityException;
-
-
-    /**
-     * This function deletes a role from the active role set of a session owned by a given user.
-     * The function is valid if and only if the user is a member of the USERS data set, the
-     * session object contains a valid Fortress session, the session is owned by the user,
-     * and the role is an active role of that session.
-     *
-     * @param session object contains the user's returned RBAC session from the createSession method.
-     * @param role    object contains the role name, {@link org.openldap.fortress.rbac.UserRole#name}, to be deactivated.
-     * @throws SecurityException is thrown if user is not allowed to deactivate or runtime error occurs with system.
-     */
-    public void dropActiveRole(Session session, UserRole role)
-        throws SecurityException;
-
-
-    /**
-     * This function returns the userId value that is contained within the session object.
-     * The function is valid if and only if the session object contains a valid Fortress session.
-     *
-     * @param session object contains the user's returned RBAC session from the createSession method.
-     * @return The userId value
-     * @throws SecurityException is thrown if user session not active or runtime error occurs with system.
-     */
-    public String getUserId(Session session)
-        throws SecurityException;
-
-    /**
-     * This function returns the user object that is contained within the session object.
-     * The function is valid if and only if the session object contains a valid Fortress session.
-     *
-     * @param session object contains the user's returned RBAC session from the createSession method.
-     * @return The user value
-     *         Sample User data contained in Session object:
-     *         <ul> <code>Session</code>
-     *         <li> <code>session.getUserId() => demoUser4</code>
-     *         <li> <code>session.getInternalUserId() => be2dd2e:12a82ba707e:-7fee</code>
-     *         <li> <code>session.getMessage() => Fortress checkPwPolicies userId <demouser4> VALIDATION GOOD</code>
-     *         <li> <code>session.getErrorId() => 0</code>
-     *         <li> <code>session.getWarningId() => 11</code>
-     *         <li> <code>session.getExpirationSeconds() => 469831</code>
-     *         <li> <code>session.getGraceLogins() => 0</code>
-     *         <li> <code>session.getIsAuthenticated() => true</code>
-     *         <li> <code>session.getLastAccess() => 1283623680440</code>
-     *         <li> <code>session.getSessionId() => -7410986f:12addeea576:-7fff</code>
-     *         <li>  ------------------------------------------
-     *         <li> <code>User user = session.getUser();</code>
-     *         <ul> <li> <code>user.getUserId() => demoUser4</code>
-     *         <li> <code>user.getInternalId() => be2dd2e:12a82ba707e:-7fee</code>
-     *         <li> <code>user.getCn() => JoeUser4</code>
-     *         <li> <code>user.getDescription() => Demo Test User 4</code>
-     *         <li> <code>user.getOu() => test</code>
-     *         <li> <code>user.getSn() => User4</code>
-     *         <li> <code>user.getBeginDate() => 20090101</code>
-     *         <li> <code>user.getEndDate() => none</code>
-     *         <li> <code>user.getBeginLockDate() => none</code>
-     *         <li> <code>user.getEndLockDate() => none</code>
-     *         <li> <code>user.getDayMask() => 1234567</code>
-     *         <li> <code>user.getTimeout() => 60</code>
-     *         <li> <code>List<UserRole> roles = session.getRoles();</code>
-     *         <ul> <li><code>UserRole userRole = roles.get(i);</code>
-     *         <li> <code>userRole.getName() => role1</code>
-     *         <li> <code>userRole.getBeginTime() => 0000</code>
-     *         <li> <code>userRole.getEndTime() => 0000</code>
-     *         <li> <code>userRole.getBeginDate() => none</code>
-     *         <li> <code>userRole.getEndDate() => none</code>
-     *         <li> <code>userRole.getBeginLockDate() => null</code>
-     *         <li> <code>userRole.getEndLockDate() => null</code>
-     *         <li> <code>userRole.getDayMask() => null</code>
-     *         <li> <code>userRole.getTimeout() => 0</code>
-     *         </ul>
-     *         </ul>
-     *         </ul>
-     * @throws SecurityException is thrown if user session not active or runtime error occurs with system.
-     */
-    public User getUser(Session session)
-        throws SecurityException;
-}
-

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/openldap/fortress/AccessMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/openldap/fortress/AccessMgrFactory.java b/src/main/java/org/openldap/fortress/AccessMgrFactory.java
deleted file mode 100755
index 97f84bd..0000000
--- a/src/main/java/org/openldap/fortress/AccessMgrFactory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *   Licensed to the Apache Software Foundation (ASF) under one
- *   or more contributor license agreements.  See the NOTICE file
- *   distributed with this work for additional information
- *   regarding copyright ownership.  The ASF licenses this file
- *   to you under the Apache License, Version 2.0 (the
- *   "License"); you may not use this file except in compliance
- *   with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing,
- *   software distributed under the License is distributed on an
- *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *   KIND, either express or implied.  See the License for the
- *   specific language governing permissions and limitations
- *   under the License.
- *
- */
-package org.openldap.fortress;
-
-import org.openldap.fortress.cfg.Config;
-import org.openldap.fortress.rbac.AccessMgrImpl;
-import org.openldap.fortress.rbac.ClassUtil;
-import org.openldap.fortress.rest.AccessMgrRestImpl;
-import org.openldap.fortress.util.attr.VUtil;
-
-/**
- * Creates an instance of the AccessMgr object.
- * <p/>
- * The default implementation class is specified as {@link AccessMgrImpl} but can be overridden by
- * adding the {@link GlobalIds#ACCESS_IMPLEMENTATION} config property.
- * <p/>
-
- *
- * @author Shawn McKinney
- */
-public class AccessMgrFactory
-{
-    private static String accessClassName = Config.getProperty(GlobalIds.ACCESS_IMPLEMENTATION);
-    private static final String CLS_NM = AccessMgrFactory.class.getName();
-
-    /**
-     * Create and return a reference to {@link org.openldap.fortress.AccessMgr} object using HOME context.
-     *
-     * @return instance of {@link org.openldap.fortress.AccessMgr}.
-     * @throws org.openldap.fortress.SecurityException in the event of failure during instantiation.
-     */
-    public static AccessMgr createInstance()
-        throws SecurityException
-    {
-        return createInstance( GlobalIds.HOME );
-    }
-
-    /**
-     * Create and return a reference to {@link org.openldap.fortress.AccessMgr} object.
-     *
-     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
-     * @return instance of {@link org.openldap.fortress.AccessMgr}.
-     * @throws org.openldap.fortress.SecurityException in the event of failure during instantiation.
-     */
-    public static AccessMgr createInstance(String contextId)
-        throws SecurityException
-    {
-        VUtil.assertNotNull(contextId, GlobalErrIds.CONTEXT_NULL, CLS_NM + ".createInstance");
-        if (!VUtil.isNotNullOrEmpty(accessClassName))
-        {
-            if(GlobalIds.IS_REST)
-            {
-                accessClassName = AccessMgrRestImpl.class.getName();
-            }
-            else
-            {
-                accessClassName = AccessMgrImpl.class.getName();
-            }
-        }
-
-        AccessMgr accessMgr = (AccessMgr) ClassUtil.createInstance(accessClassName);
-        accessMgr.setContextId(contextId);
-        return accessMgr;
-    }
-}
\ No newline at end of file


[43/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addroleinheritance.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addroleinheritance.java b/src/main/java/org/apache/directory/fortress/core/ant/Addroleinheritance.java
new file mode 100755
index 0000000..f1e2f4d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addroleinheritance.java
@@ -0,0 +1,85 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.Relationship;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link Relationship}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#addInheritance(org.apache.directory.fortress.core.rbac.Role, org.apache.directory.fortress.core.rbac.Role)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addroleinheritance', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addroleinheritance>
+ *           ...
+ *         </addroleinheritance>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addroleinheritance
+{
+    final private List<Relationship> relationships = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addroleinheritance()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addRelationship', is used for derived xml tag 'relationship' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addroleinheritance>
+     *     <relationship child="r2" parent="r1"/>
+     *     <relationship child="r3" parent="r1"/>
+     *     <relationship child="r4" parent="r1"/>
+     * </addroleinheritance>
+     * }
+     * </pre>
+     *
+     * @param relationship contains reference to data element targeted for insertion..
+     */
+    public void addRelationship(Relationship relationship)
+    {
+        this.relationships.add(relationship);
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#addRoleInheritances()} to retrieve list of Role relationships as defined in input xml file.
+     *
+     * @return collection containing {@link Relationship}s targeted for insertion.
+     */
+    public List<Relationship> getRelationships()
+    {
+        return this.relationships;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addsdset.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addsdset.java b/src/main/java/org/apache/directory/fortress/core/ant/Addsdset.java
new file mode 100755
index 0000000..06d88a3
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addsdset.java
@@ -0,0 +1,91 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to create new {@link SDSetAnt}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#createSsdSet(org.apache.directory.fortress.core.rbac.SDSet)} or {@link org.apache.directory.fortress.core.AdminMgr#createDsdSet(org.apache.directory.fortress.core.rbac.SDSet)}.
+ *
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addsdset', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addsdset>
+ *           ...
+ *         </addsdset>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addsdset
+{
+    final private List<SDSetAnt> sds = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addsdset()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addSdset', is used for derived xml tag 'sdset' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addsdset>
+     *     <sdset name="DemoSSD1"
+     *         description="Demo static separation of duties"
+     *         cardinality="2"
+     *         settype="STATIC"
+     *         setmembers="role1,role2"/>
+     *     <sdset name="DemoDSD1"
+     *         description="Demo dynamic separation of duties"
+     *         cardinality="2"
+     *         settype="DYNAMIC"
+     *         setmembers="role1,role3"/>
+     * </addsdset>
+     * }
+     * </pre>
+     *
+     * @param sd contains reference to data element targeted for insertion..
+     */
+    public void addSdset(SDSetAnt sd)
+    {
+        this.sds.add(sd);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addSdsets()} to retrieve list of SDSetAnt as defined in input xml file.
+     *
+     * @return collection containing {@link SDSetAnt}s targeted for insertion.
+     */
+    public List<SDSetAnt> getSdset()
+    {
+        return this.sds;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Addsuffix.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Addsuffix.java b/src/main/java/org/apache/directory/fortress/core/ant/Addsuffix.java
new file mode 100755
index 0000000..cfeb710
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Addsuffix.java
@@ -0,0 +1,84 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.fortress.core.ldap.suffix.Suffix;
+
+/**
+ * The class is used by {@link FortressAntTask} to create new {@link org.apache.directory.fortress.core.ldap.suffix.Suffix} used to drive {@link org.apache.directory.fortress.core.ldap.suffix.SuffixP#add(org.apache.directory.fortress.core.ldap.suffix.Suffix)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Addsuffix', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <addsuffix>
+ *           ...
+ *         </addsuffix>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Addsuffix
+
+{
+    final private List<Suffix> suffixes = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Addsuffix()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addSuffix', is used for derived xml tag 'suffix' in the load script.</p>
+     * <pre>
+     * {@code
+     * <addsuffix>
+     *     <suffix name="jts" dc="com" description="Joshua Tree Software"/>
+     * </addsuffix>
+     * }
+     * </pre>
+     *
+     * @param suffix contains reference to data element targeted for insertion..
+     */
+    public void addSuffix(Suffix suffix)
+    {
+        this.suffixes.add(suffix);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addSuffixes()} to retrieve list of Suffixes as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.ldap.suffix.Suffix}s targeted for insertion.
+     */
+    public List<Suffix> getSuffixes()
+    {
+        return this.suffixes;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Adduser.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Adduser.java b/src/main/java/org/apache/directory/fortress/core/ant/Adduser.java
new file mode 100755
index 0000000..c9ddcf5
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Adduser.java
@@ -0,0 +1,92 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link UserAnt}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#addUser(org.apache.directory.fortress.core.rbac.User)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Adduser', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <adduser>
+ *           ...
+ *         </adduser>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Adduser
+{
+    final private List<UserAnt> users = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Adduser()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addUser', is used for derived xml tag 'user' in the load script.</p>
+     * <pre>
+     * {@code
+     * <adduser>
+     *     <!-- Bad User end time -->
+     *     <user userId="demoUser1" password="password" description="Demo Test User 1" ou="demousrs1" cn="JoeUser1" sn="User1" pwPolicy="Test1" beginTime="0000" endTime="0800" beginDate="20090101" endDate="20990101" beginLockDate="none" endLockDate="none" dayMask="1234567" timeout="60"/>
+     *     <!-- Bad User day mask -->
+     *     <user userId="demoUser3" password="password" description="Demo Test User 3" ou="demousrs1" cn="JoeUser3" sn="User3"  pwPolicy="Test1" beginTime="0000" endTime="0000" beginDate="20090101" endDate="20990101" beginLockDate="none" endLockDate="none" dayMask="17" timeout="60"/>
+     *     <!-- This one is good -->
+     *     <user userId="demoUser4" password="password" description="Demo Test User 4" ou="demousrs1" cn="JoeUser4" sn="User4"  pwPolicy="Test1" beginTime="0000" endTime="0000" beginDate="20090101" endDate="20990101" beginLockDate="none" endLockDate="none" dayMask="1234567" timeout="60"/>
+     *     <!-- Bad User end time -->
+     *     <user userId="demoUser5" password="password" description="Demo Test User 5" ou="demousrs1" cn="JoeUser5" sn="User5"  pwPolicy="Test1" beginTime="0000" endTime="0000" beginDate="20090101" endDate="20990101" beginLockDate="none" endLockDate="none" dayMask="1234567" timeout="60"/>
+     *     <!-- Bad User begin date -->
+     *     <user userId="demoUser7" password="password" description="Demo Test User 7" ou="demousrs1" cn="JoeUser7" sn="User7"  pwPolicy="Test1" beginTime="0000" endTime="0000" beginDate="20090101" endDate="20990101" beginLockDate="none" endLockDate="none" dayMask="1234567" timeout="60"/>
+     *     <!-- Bad User end date -->
+     *     <user userId="demoUser9" password="password" description="Demo Test User 9" ou="demousrs1" cn="JoeUser9" sn="User9"  pwPolicy="Test1" beginTime="0000" endTime="0000" beginDate="20090101" endDate="20990101" beginLockDate="none" endLockDate="none" dayMask="1234567" timeout="60"/>
+     * </adduser>
+     * }
+     * </pre>
+     *
+     * @param user contains reference to data element targeted for insertion..
+     */
+    public void addUser(UserAnt user)
+    {
+        this.users.add(user);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addUsers()} to retrieve list of Users as defined in input xml file.
+     *
+     * @return collection containing {@link UserAnt}s targeted for insertion.
+     */
+    public List<UserAnt> getUsers()
+    {
+        return this.users;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Adduseradminrole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Adduseradminrole.java b/src/main/java/org/apache/directory/fortress/core/ant/Adduseradminrole.java
new file mode 100755
index 0000000..7f8ce8c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Adduseradminrole.java
@@ -0,0 +1,92 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link org.apache.directory.fortress.core.rbac.UserAdminRole}s used to drive {@link org.apache.directory.fortress.core.DelAdminMgr#assignUser(org.apache.directory.fortress.core.rbac.UserAdminRole)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Adduseradminrole', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <adduseradminrole>
+ *           ...
+ *         </adduseradminrole>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Adduseradminrole
+{
+    final private List<UserAdminRole> userroles = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Adduseradminrole()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addUserRole', is used for derived xml tag 'userrole' in the load script.</p>
+     * <pre>
+     * {@code
+     * <adduseradminrole>
+     *     <userrole userId="demouser4"
+     *         name="DemoAdminUsers"
+     *         beginTime="0800"
+     *         endTime="1700"
+     *         beginDate="20110101"
+     *         endDate="none"
+     *         beginLockDate="none"
+     *         endLockDate="none"
+     *         dayMask="23456"
+     *         timeout="15"/>
+     * </adduseradminrole>
+     * }
+     * </pre>
+     *
+     * @param userRole contains reference to data element targeted for insertion..
+     */
+    public void addUserRole(UserAdminRole userRole)
+    {
+        this.userroles.add(userRole);
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#addUserAdminRoles()} to retrieve list of UserAdminRoles as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.UserAdminRole}s targeted for insertion.
+     */
+    public List<UserAdminRole> getUserRoles()
+    {
+        return this.userroles;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Adduserorgunitinheritance.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Adduserorgunitinheritance.java b/src/main/java/org/apache/directory/fortress/core/ant/Adduserorgunitinheritance.java
new file mode 100755
index 0000000..924ebb8
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Adduserorgunitinheritance.java
@@ -0,0 +1,85 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.Relationship;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link Relationship}s used to drive {@link org.apache.directory.fortress.core.DelAdminMgr#addAscendant(org.apache.directory.fortress.core.rbac.OrgUnit, org.apache.directory.fortress.core.rbac.OrgUnit)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Adduserorgunitinheritance', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <adduserorgunitinheritance>
+ *           ...
+ *         </adduserorgunitinheritance>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Adduserorgunitinheritance
+{
+    final private List<Relationship> relationships = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Adduserorgunitinheritance()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addRelationship', is used for derived xml tag 'relationship' in the load script.</p>
+     * <pre>
+     * {@code
+     * <adduserorgunitinheritance>
+     *     <relationship child="ou2" parent="ou1"/>
+     *     <relationship child="ou3" parent="ou1"/>
+     *     <relationship child="ou4" parent="ou1"/>
+     * </adduserorgunitinheritance>
+     * }
+     * </pre>
+     *
+     * @param relationship contains reference to data element targeted for insertion..
+     */
+    public void addRelationship(Relationship relationship)
+    {
+        this.relationships.add(relationship);
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#addAdduserorgunitinheritance(Adduserorgunitinheritance)} to retrieve list of User Org Unit relationships as defined in input xml file.
+     *
+     * @return collection containing {@link Relationship}s targeted for insertion.
+     */
+    public List<Relationship> getRelationships()
+    {
+        return this.relationships;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Adduserrole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Adduserrole.java b/src/main/java/org/apache/directory/fortress/core/ant/Adduserrole.java
new file mode 100755
index 0000000..c93e077
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Adduserrole.java
@@ -0,0 +1,89 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.UserRole;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link org.apache.directory.fortress.core.rbac.UserRole}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#assignUser(org.apache.directory.fortress.core.rbac.UserRole)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Adduserrole', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <adduserrole>
+ *           ...
+ *         </adduserrole>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Adduserrole
+{
+    final private List<UserRole> userroles = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Adduserrole()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addUserRole', is used for derived xml tag 'userrole' in the load script.</p>
+     * <pre>
+     * {@code
+     * <adduserrole>
+     *     <userrole userId="demoUser1" name="role1" beginTime="0800" endTime="0700" beginDate="20110101" endDate="none" beginLockDate="none" endLockDate="none" dayMask="23456" timeout="30"/>
+     *     <!-- Bad - role end time -->
+     *     <userrole userId="demoUser5" name="role1"  beginTime="0700" endTime="0800" beginDate="20100101" endDate="21000101" beginLockDate="none" endLockDate="none" dayMask="all" timeout="0"/>
+     *     <!-- Bad - role  begin date -->
+     *     <userrole userId="demoUser7" name="role1"  beginTime="0000" endTime="0000" beginDate="20110110" endDate="21000101" beginLockDate="none" endLockDate="none" dayMask="all" timeout="0"/>
+     *     <!-- Bad - role  end date -->
+     *     <userrole userId="demoUser9" name="role1"  beginTime="0000" endTime="0000" beginDate="20100101" endDate="20100608" beginLockDate="none" endLockDate="none" dayMask="all" timeout="0"/>
+     * </adduserrole>
+     * }
+     * </pre>
+     *
+     * @param userRole contains reference to data element targeted for insertion..
+     */
+    public void addUserRole(UserRole userRole)
+    {
+        this.userroles.add(userRole);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addUserRoles()} to retrieve list of UserRoles as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.UserRole}s targeted for insertion.
+     */
+    public List<UserRole> getUserRoles()
+    {
+        return this.userroles;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/AdminRoleAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/AdminRoleAnt.java b/src/main/java/org/apache/directory/fortress/core/ant/AdminRoleAnt.java
new file mode 100755
index 0000000..ac2438d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/AdminRoleAnt.java
@@ -0,0 +1,110 @@
+/*
+ *   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.ant;
+
+
+import org.apache.directory.fortress.core.rbac.AdminRole;
+
+import java.util.StringTokenizer;
+
+/**
+ * Entity is used by custom Apache Ant task for special handling of collections.  This is necessary because the
+ * Ant parser cannot deal with complex data attribute types.
+ *
+ * @author Shawn McKinney
+ */
+public class AdminRoleAnt extends AdminRole
+{
+    private String osPs;
+    private String osUs;
+
+    /**
+     * Default constructor required for all Ant entities.
+     *
+     * @return String containing OSPs.
+     */
+    public String getOSPs()
+    {
+        return osPs;
+    }
+
+    /**
+     * Set the list of Perm OUs as a comma delimited string.  This method will convert from that format to
+     * the AdminRole native format which is collection of Strings.
+     *
+     * @param osPs
+     */
+    public void setOSPs(String osPs)
+    {
+        this.osPs = osPs;
+        if (osPs != null)
+        {
+            // allow the setter to process comma delimited strings:
+            StringTokenizer tkn = new StringTokenizer(osPs, ",");
+            if (tkn.countTokens() > 0)
+            {
+                while (tkn.hasMoreTokens())
+                {
+                    String osP = tkn.nextToken();
+                    setOsP(osP);                                                            /**
+                 * Set the list of Perm OUs as a comma delimited string.  This method will convert from that format to
+                 * the AdminRole native format which is collection of Strings.
+                 * @param osPs
+                 */
+
+                }
+            }
+        }
+    }
+
+    /**
+     * Return the comma delimited OU string.
+     *
+     * @return String containing OSUs.
+     */
+    public String getOSUs()
+    {
+        return osUs;
+    }
+
+    /**
+     * Load an OU into the collection of OUs stored by collection.
+     *
+     * @param osUs contains OU name.
+     */
+    public void setOSUs(String osUs)
+    {
+        this.osUs = osUs;
+        if (osUs != null)
+        {
+            // allow the setter to process comma delimited strings:
+            StringTokenizer tkn = new StringTokenizer(osUs, ",");
+            if (tkn.countTokens() > 0)
+            {
+                while (tkn.hasMoreTokens())
+                {
+                    String osU = tkn.nextToken();
+                    setOsU(osU);
+                }
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/ConfigAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/ConfigAnt.java b/src/main/java/org/apache/directory/fortress/core/ant/ConfigAnt.java
new file mode 100755
index 0000000..f143875
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/ConfigAnt.java
@@ -0,0 +1,61 @@
+/*
+ *   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.ant;
+
+
+/**
+ * This entity contains the list of name/value pairs targeted for updating on server.
+ *
+ * @author Shawn McKinney
+ */
+public class ConfigAnt
+{
+    private String props;
+
+    /**
+     * Default constructor required for all Ant entities.
+     *
+     */
+    public ConfigAnt()
+    {
+    }
+
+
+    /**
+     * Get the properties as a String.
+     *
+     * @return String containing property name/values.
+     */
+    public String getProps()
+    {
+        return props;
+    }
+
+    /**
+     * Set the properties as a String.
+     *
+     * @param szProps
+     */
+    public void setProps(String szProps)
+    {
+        this.props = szProps;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Deladminrole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Deladminrole.java b/src/main/java/org/apache/directory/fortress/core/ant/Deladminrole.java
new file mode 100755
index 0000000..b6c6bd7
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Deladminrole.java
@@ -0,0 +1,80 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * This class is used by {@link FortressAntTask} to load {@link org.apache.directory.fortress.core.rbac.AdminRole}s used to drive {@link org.apache.directory.fortress.core.DelAdminMgr#deleteRole(org.apache.directory.fortress.core.rbac.AdminRole)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>The class name, 'Deladminrole', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <deladminrole>
+ *           ...
+ *         </deladminrole>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Deladminrole
+{
+	final private List<AdminRoleAnt> roles = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+	public Deladminrole() { }
+
+
+    /**
+     * <p>This method name, 'addRole', is used for the derived xml tag 'role' in the load script.</p>
+     * <pre>
+     * {@code
+     * <deladminrole>
+     *      <role name="DemoAdminUsers"
+     * </deladminrole>
+     * }
+     * </pre>
+     *
+     * @param role contains extension of {@link org.apache.directory.fortress.core.rbac.AdminRole}.
+     */
+	public void addRole(AdminRoleAnt role)
+	{
+		this.roles.add(role);
+	}
+
+    /**
+     * Used by {@link FortressAntTask#deleteAdminRoles()} to retrieve list of AdminRoles as defined in input xml file.
+     * @return collection containing {@link AdminRoleAnt}s targeted for removal.
+     */
+	public List<AdminRoleAnt> getRoles()
+	{
+		return this.roles;
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Deladminroleinheritance.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Deladminroleinheritance.java b/src/main/java/org/apache/directory/fortress/core/ant/Deladminroleinheritance.java
new file mode 100755
index 0000000..e0affb7
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Deladminroleinheritance.java
@@ -0,0 +1,86 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.Relationship;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link Relationship}s used to drive {@link org.apache.directory.fortress.core.DelAdminMgr#deleteInheritance(org.apache.directory.fortress.core.rbac.AdminRole, org.apache.directory.fortress.core.rbac.AdminRole)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Deladminroleinheritance', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <deladminroleinheritance>
+ *           ...
+ *         </deladminroleinheritance>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ *
+ * @author Shawn McKinney
+ */
+public class Deladminroleinheritance
+{
+    final private List<Relationship> relationships = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Deladminroleinheritance()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addRelationship', is used for derived xml tag 'relationship' in the load script.</p>
+     * <pre>
+     * {@code
+     * <deladminroleinheritance>
+     *     <relationship child="ar2" parent="ar1"/>
+     *     <relationship child="ar3" parent="ar1"/>
+     * </deladminroleinheritance>
+     * }
+     * </pre>
+     *
+     * @param relationship contains reference to data element targeted for removal.
+     */
+    public void addRelationship(Relationship relationship)
+    {
+        this.relationships.add(relationship);
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#deleteAdminRoles()} to retrieve list of Relationships as defined in input xml file.
+     *
+     * @return collection containing {@link Relationship}s targeted for removal.
+     */
+    public List<Relationship> getRelationships()
+    {
+        return this.relationships;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Delconfig.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delconfig.java b/src/main/java/org/apache/directory/fortress/core/ant/Delconfig.java
new file mode 100755
index 0000000..9f65199
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delconfig.java
@@ -0,0 +1,97 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link org.apache.directory.fortress.core.ant.ConfigAnt}s used to drive {@link org.apache.directory.fortress.core.cfg.ConfigMgr#delete(String, java.util.Properties)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delconfig', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delconfig>
+ *           ...
+ *         </delconfig>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Delconfig
+{
+    final private List<ConfigAnt> config = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delconfig()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addConfig', is used for derived xml tag 'config' in the load script.</p>
+     * <pre>
+     * {@code
+     * <delconfig>
+     *     <config props="config.realm:DEFAULT"/>
+     *     <config props="enable.audit:true"/>
+     *     <config props="authn.type:default"/>
+     *     <config props="password.policy:openldap"/>
+     *     <config props="clientside.sorting:true"/>
+     *     <config props="suffix:dc=jts\,dc=com"/>
+     *     <config props="user.root:ou=People\,dc=jts\,dc=com"/>
+     *     <config props="pwpolicy.root:ou=Policies\,dc=jts\,dc=com"/>
+     *     <config props="role.root:ou=Roles\,ou=RBAC\,dc=jts\,dc=com"/>
+     *     <config props="perm.root:ou=Permissions\,ou=RBAC\,dc=jts\,dc=com"/>
+     *     <config props="sdconstraint.root:ou=Constraints\,ou=RBAC\,dc=jts\,dc=com"/>
+     *     <config props="userou.root:ou=OS-U\,ou=ARBAC\,dc=jts\,dc=com"/>
+     *     <config props="permou.root:ou=OS-P\,ou=ARBAC\,dc=jts\,dc=com"/>
+     *     <config props="adminrole.root:ou=AdminRoles\,ou=ARBAC\,dc=jts\,dc=com"/>
+     *     <config props="adminperm.root:ou=AdminPerms\,ou=ARBAC\,dc=jts\,dc=com"/>
+     *     ...
+     * </delconfig>
+     * }
+     * </pre>
+     *
+     * @param config contains reference to data element targeted for removal..
+     */
+    public void addConfig(ConfigAnt config)
+    {
+        this.config.add(config);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#deleteConfig()} to retrieve list of properties as defined in input xml file.
+     *
+     * @return collection containing {@link ConfigAnt}s targeted for removal.
+     */
+    public List<ConfigAnt> getConfig()
+    {
+        return this.config;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Delcontainer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delcontainer.java b/src/main/java/org/apache/directory/fortress/core/ant/Delcontainer.java
new file mode 100755
index 0000000..52176a0
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delcontainer.java
@@ -0,0 +1,105 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.ldap.container.OrganizationalUnit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to remove {@link org.apache.directory.fortress.core.ldap.container.OrganizationalUnit}s  used to drive {@link org.apache.directory.fortress.core.ldap.container.OrganizationalUnitP#delete(org.apache.directory.fortress.core.ldap.container.OrganizationalUnit)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delcontainer', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delcontainer>
+ *           ...
+ *         </delcontainer>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ * <p/>
+ * <font size="4" color="red">
+ * This class is destructive as it will remove all nodes below the container using recursive delete function.<BR>
+ * Extreme care should be taken during execution to ensure target dn is correct and permanent removal of data is intended.  There is no
+ * 'undo' for this operation.
+ * </font>
+ * <p/>
+ *
+ * @author Shawn McKinney
+ */
+public class Delcontainer
+{
+    final private List<OrganizationalUnit> containers = new ArrayList<>();
+
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delcontainer()
+    {
+    }
+
+
+    /**
+     * <p>This method name, 'addContainer', is used for derived xml tag 'container' in the load script.</p>
+     * <pre>
+     * {@code
+     * <delcontainer>
+     *     <container name="Config"/>
+     *     <container name="People"/>
+     *     <container name="Policies"/>
+     *     <container name="RBAC"/>
+     *     <container name="Roles" parent="RBAC"/>
+     *     <container name="Permissions" parent="RBAC"/>
+     *     <container name="Constraints" parent="RBAC"/>
+     *     <container name="ARBAC"/>
+     *     <container name="OS-U" parent="ARBAC"/>
+     *     <container name="OS-P" parent="ARBAC"/>
+     *     <container name="AdminRoles" parent="ARBAC"/>
+     *     <container name="AdminPerms" parent="ARBAC"/>
+     * </delcontainer>
+     * }
+     * </pre>
+     *
+     * @param ou contains reference to data element targeted for deletion.
+     */
+    public void addContainer( OrganizationalUnit ou)
+    {
+        this.containers.add(ou);
+    }
+
+
+    /**
+     * Used by {@link FortressAntTask#deleteContainers()} to retrieve list of OrganizationalUnits as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.ldap.container.OrganizationalUnit}s targeted for removal.
+     */
+    public List<OrganizationalUnit> getContainers()
+    {
+        return this.containers;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Delgroup.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delgroup.java b/src/main/java/org/apache/directory/fortress/core/ant/Delgroup.java
new file mode 100755
index 0000000..ddcf8fe
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delgroup.java
@@ -0,0 +1,83 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.ldap.group.Group;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link GroupAnt}s used to drive {@link org.apache.directory.fortress.core.ldap.group.GroupMgr#add(org.apache.directory.fortress.core.ldap.group.Group)} .
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delgroup', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delgroup>
+ *           ...
+ *         </delgroup>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Delgroup
+{
+    final private List<Group> groups = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delgroup()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addGroup', is used for derived xml tag 'group' in the load script.</p>
+     * <pre>
+     * {@code
+     *  <delgroup>
+     *      <group name="test001"/>
+     *  </delgroup>
+     * }
+     * </pre>
+     *
+     * @param group contains reference to data element targeted for removal.
+     */
+    public void addGroup(Group group)
+    {
+        this.groups.add(group);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#deleteGroups()} to retrieve list of Groups as defined in input xml file.
+     *
+     * @return collection containing {@link GroupAnt}s targeted for removal.
+     */
+    public List<Group> getGroups()
+    {
+        return this.groups;
+    }
+}
\ 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/ant/Delgroupmember.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delgroupmember.java b/src/main/java/org/apache/directory/fortress/core/ant/Delgroupmember.java
new file mode 100755
index 0000000..3b7f9f7
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delgroupmember.java
@@ -0,0 +1,83 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.ldap.group.Group;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link Group}s.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delgroup', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delgroupmember>
+ *           ...
+ *         </delgroupmember>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Delgroupmember
+{
+    final private List<Group> groups = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delgroupmember()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addGroup', is used for derived xml tag 'group' in the load script.</p>
+     * <pre>
+     * {@code
+     *  <delgroupmember>
+     *      <group name="test001" members="guser1,guser2,guser3" />
+     *  </delgroupmember>
+     * }
+     * </pre>
+     *
+     * @param group contains reference to data element targeted for removal.
+     */
+    public void addGroup(Group group)
+    {
+        this.groups.add(group);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addGroupMembers()} to retrieve list of Groups as defined in input xml file.
+     *
+     * @return collection containing {@link Group}s targeted for removal.
+     */
+    public List<Group> getGroups()
+    {
+        return this.groups;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Delgroupproperty.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delgroupproperty.java b/src/main/java/org/apache/directory/fortress/core/ant/Delgroupproperty.java
new file mode 100755
index 0000000..2647724
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delgroupproperty.java
@@ -0,0 +1,83 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.ldap.group.Group;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link Group}s.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delgroup', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delgroupmember>
+ *           ...
+ *         </delgroupmember>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Delgroupproperty
+{
+    final private List<Group> groups = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delgroupproperty()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addGroup', is used for derived xml tag 'group' in the load script.</p>
+     * <pre>
+     * {@code
+     *  <delgroupmember>
+     *      <group name="test001"/>
+     *  </delgroupmember>
+     * }
+     * </pre>
+     *
+     * @param group contains reference to data element targeted for removal.
+     */
+    public void addGroup(Group group)
+    {
+        this.groups.add(group);
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#deleteGroups()} to retrieve list of Groups as defined in input xml file.
+     *
+     * @return collection containing {@link Group}s targeted for removal.
+     */
+    public List<Group> getGroups()
+    {
+        return this.groups;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Delorgunit.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delorgunit.java b/src/main/java/org/apache/directory/fortress/core/ant/Delorgunit.java
new file mode 100755
index 0000000..7af0216
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delorgunit.java
@@ -0,0 +1,89 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.fortress.core.rbac.OrgUnitAnt;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to delete {@link org.apache.directory.fortress.core.rbac.OrgUnit}s used to drive {@link org.apache.directory.fortress.core.DelAdminMgr#delete(org.apache.directory.fortress.core.rbac.OrgUnit)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delorgunit', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delorgunit>
+ *           ...
+ *         </delorgunit>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Delorgunit
+{
+    final private List<OrgUnitAnt> ous = new ArrayList<>();
+
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delorgunit()
+    {
+    }
+
+
+    /**
+     * <p>This method name, 'addOrgUnit', is used for derived xml tag 'orgunit' in the load script.</p>
+     * <pre>
+     * {@code
+     * <delorgunit>
+     *     <orgunit name="demousrs1" typeName="USER"/>
+     *     <orgunit name="demousrs2" typename="USER"/>
+     *     <orgunit name="demoapps1" typeName="PERM"/>
+     *     <orgunit name="demoapps2" typename="PERM"/>
+     * </delorgunit>
+     * }
+     * </pre>
+     *
+     * @param ou contains reference to data element targeted for deletion..
+     */
+    public void addOrgUnit(OrgUnitAnt ou)
+    {
+        this.ous.add(ou);
+    }
+
+
+    /**
+     * Used by {@link FortressAntTask#addOrgunits()} to retrieve list of OrgUnits as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.OrgUnit}s targeted for removal.
+     */
+    public List<OrgUnitAnt> getOrgUnits()
+    {
+        return this.ous;
+    }
+}
\ 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/ant/DelpermGrant.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/DelpermGrant.java b/src/main/java/org/apache/directory/fortress/core/ant/DelpermGrant.java
new file mode 100755
index 0000000..a68cd7d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/DelpermGrant.java
@@ -0,0 +1,92 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.PermGrant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is used by {@link FortressAntTask} to revoke {@link PermGrant}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#revokePermission(org.apache.directory.fortress.core.rbac.Permission, org.apache.directory.fortress.core.rbac.Role)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'DelpermGrant', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delpermgrant>
+ *           ...
+ *         </delpermgrant>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class DelpermGrant
+{
+    private List<PermGrant> permGrants = new ArrayList<>();
+
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public DelpermGrant()
+    {
+    }
+
+
+    /**
+     * <p>This method name, 'addPermGrant', is used for derived xml tag 'permgrant' in the load script.</p>
+     * <pre>
+     * {@code
+     * <delpermgrant>
+     *     <permgrant objName="/jsp/cal/cal1.jsp" opName="main" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="8am" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="10am" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="12pm" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="2pm" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="4pm" roleNm="role1"/>
+     *     <permgrant objName="/jsp/cal/cal2.jsp" opName="6pm" roleNm="role1"/>
+     * </delpermgrant>
+     * }
+     * </pre>
+     *
+     * @param permGrant contains reference to data element targeted for revocation.
+     */
+    public void addPermGrant(PermGrant permGrant)
+    {
+        this.permGrants.add(permGrant);
+    }
+
+
+    /**
+     * Used by {@link FortressAntTask#addPermGrants()} to retrieve list of PermGrant as defined in input xml file.
+     *
+     * @return collection containing {@link PermGrant}s targeted for revocation.
+     */
+    public List<PermGrant> getPermGrants()
+    {
+        return this.permGrants;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/DelpermObj.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/DelpermObj.java b/src/main/java/org/apache/directory/fortress/core/ant/DelpermObj.java
new file mode 100755
index 0000000..851ecc4
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/DelpermObj.java
@@ -0,0 +1,85 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.fortress.core.rbac.PermObj;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link PermObj}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#deletePermObj(org.apache.directory.fortress.core.rbac.PermObj)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'DelpermObj', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delpermobj>
+ *           ...
+ *         </delpermobj>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class DelpermObj
+{
+    final private List<PermObj> permObjs = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public DelpermObj()
+    {
+    }
+
+    /**
+     * <p>This method name, 'delPermObj', is used for derived xml tag 'permobj' in the load script.</p>
+     * <pre>
+     * {@code
+     * <delpermobj>
+     *     <permobj objName="/jsp/cal/cal1.jsp"/>
+     *     <permobj objName="/jsp/cal/cal2.jsp"/>
+     * </delpermobj>
+     * }
+     * </pre>
+     *
+     * @param permObj contains reference to data element targeted for insertion..
+     */
+    public void addPermObj(PermObj permObj)
+    {
+        this.permObjs.add(permObj);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#addPermObjs()} to retrieve list of PermObjs as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.PermObj}s targeted for deletion.
+     */
+    public List<PermObj> getObjs()
+    {
+        return this.permObjs;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/DelpermOp.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/DelpermOp.java b/src/main/java/org/apache/directory/fortress/core/ant/DelpermOp.java
new file mode 100755
index 0000000..119bc2e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/DelpermOp.java
@@ -0,0 +1,96 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link org.apache.directory.fortress.core.ant.PermAnt}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#deletePermission(org.apache.directory.fortress.core.rbac.Permission)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'DelpermOp', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delpermop>
+ *           ...
+ *         </delpermop>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class DelpermOp
+{
+    final private List<PermAnt> permissions = new ArrayList<>();
+
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public DelpermOp()
+    {
+    }
+
+
+    /**
+     * <p>This method name, 'addPermOp', is used for derived xml tag 'permop' in the load script.</p>
+     * <pre>
+     * {@code
+     * <delpermop>
+     *     <permop opName="main" objName="/jsp/cal/cal1.jsp"/>
+     *     <permop opName="8am" objName="/jsp/cal/cal2.jsp"/>
+     *     <permop opName="9am" objName="/jsp/cal/cal2.jsp"/>
+     *     <permop opName="10am" objName="/jsp/cal/cal2.jsp"/>
+     *     <permop opName="11am" objName="/jsp/cal/cal2.jsp"/>
+     *     <permop opName="12pm" objName="/jsp/cal/cal2.jsp"/>
+     *     <permop opName="1pm" objName="/jsp/cal/cal2.jsp"/>
+     *     <permop opName="2pm" objName="/jsp/cal/cal2.jsp"/>
+     *     <permop opName="3pm" objName="/jsp/cal/cal2.jsp"/>
+     *     <permop opName="4pm" objName="/jsp/cal/cal2.jsp"/>
+     *     <permop opName="5pm" objName="/jsp/cal/cal2.jsp"/>
+     *     <permop opName="6pm" objName="/jsp/cal/cal2.jsp"/>
+     * </delpermop>
+     * }
+     * </pre>
+     *
+     * @param permission contains reference to data element targeted for removal..
+     */
+    public void addPermOp(PermAnt permission)
+    {
+        this.permissions.add(permission);
+    }
+
+
+    /**
+     * Used by {@link FortressAntTask#addPermOps()} to retrieve list of Permissions as defined in input xml file.
+     *
+     * @return collection containing {@link PermAnt}s targeted for removal.
+     */
+    public List<PermAnt> getPermOps()
+    {
+        return this.permissions;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Delpermorgunitinheritance.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delpermorgunitinheritance.java b/src/main/java/org/apache/directory/fortress/core/ant/Delpermorgunitinheritance.java
new file mode 100755
index 0000000..51ffc85
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delpermorgunitinheritance.java
@@ -0,0 +1,87 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.Relationship;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link Relationship}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#deleteInheritance(org.apache.directory.fortress.core.rbac.Role, org.apache.directory.fortress.core.rbac.Role)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delpermorgunitinheritance', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delpermorgunitinheritance>
+ *           ...
+ *         </delpermorgunitinheritance>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ *
+ * @author Shawn McKinney
+ */
+public class Delpermorgunitinheritance
+{
+    final private List<Relationship> relationships = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delpermorgunitinheritance()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addRelationship', is used for derived xml tag 'relationship' in the load script.</p>
+     * <pre>
+     * {@code
+     * <delpermorgunitinheritance>
+     *     <relationship child="ou2" parent="ou1"/>
+     *     <relationship child="ou3" parent="ou1"/>
+     *     <relationship child="ou4" parent="ou1"/>
+     * </delpermorgunitinheritance>
+     * }
+     * </pre>
+     *
+     * @param relationship contains reference to data element targeted for removal.
+     */
+    public void addRelationship(Relationship relationship)
+    {
+        this.relationships.add(relationship);
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#deleteRoles()} to retrieve list of Relationships as defined in input xml file.
+     *
+     * @return collection containing {@link Relationship}s targeted for removal.
+     */
+    public List<Relationship> getRelationships()
+    {
+        return this.relationships;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Delpwpolicy.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delpwpolicy.java b/src/main/java/org/apache/directory/fortress/core/ant/Delpwpolicy.java
new file mode 100755
index 0000000..ebc8dd7
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delpwpolicy.java
@@ -0,0 +1,84 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.PwPolicy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link org.apache.directory.fortress.core.rbac.PwPolicy}s used to drive {@link org.apache.directory.fortress.core.PwPolicyMgr#delete(org.apache.directory.fortress.core.rbac.PwPolicy)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delpwpolicy', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delpwpolicy>
+ *           ...
+ *         </delpwpolicy>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Delpwpolicy
+{
+    final private List<PwPolicy> policies = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delpwpolicy()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addPolicy', is used for derived xml tag 'policy' in the load script.</p>
+     * <pre>
+     * {@code
+     * <delpwpolicy>
+     *     <policy name="Test1"/>
+     * </delpwpolicy>
+     * }
+     * </pre>
+     *
+     * @param policy contains reference to data element targeted for removal.
+     */
+    public void addPolicy(PwPolicy policy)
+    {
+        this.policies.add(policy);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#deletePolicies()} to retrieve list of PwPolicy as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.PwPolicy}s targeted for removal.
+     */
+    public List<PwPolicy> getPolicies()
+    {
+        return this.policies;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Delrole.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delrole.java b/src/main/java/org/apache/directory/fortress/core/ant/Delrole.java
new file mode 100755
index 0000000..c2721b7
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delrole.java
@@ -0,0 +1,85 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.Role;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to load {@link org.apache.directory.fortress.core.rbac.Role}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#deleteRole(org.apache.directory.fortress.core.rbac.Role)}}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delrole', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delrole>
+ *           ...
+ *         </delrole>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Delrole
+{
+    final private List<Role> roles = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delrole()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addRole', is used for derived xml tag 'role' in the load script.</p>
+     * <pre>
+     * {@code
+     * <delrole>
+     *     <role name="role1"/>
+     *     <role name="role2"/>
+     * </delrole>
+     * }
+     * </pre>
+     *
+     * @param role contains reference to data element targeted for removal.
+     */
+    public void addRole(Role role)
+    {
+        this.roles.add(role);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#deleteRoles()} to retrieve list of Roles as defined in input xml file.
+     *
+     * @return collection containing {@link org.apache.directory.fortress.core.rbac.Role}s targeted for removal.
+     */
+    public List<Role> getRoles()
+    {
+        return this.roles;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Delroleinheritance.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delroleinheritance.java b/src/main/java/org/apache/directory/fortress/core/ant/Delroleinheritance.java
new file mode 100755
index 0000000..39582ed
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delroleinheritance.java
@@ -0,0 +1,86 @@
+/*
+ *   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.ant;
+
+import org.apache.directory.fortress.core.rbac.Relationship;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link org.apache.directory.fortress.core.ant.FortressAntTask} to load {@link Relationship}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#deleteInheritance(org.apache.directory.fortress.core.rbac.Role, org.apache.directory.fortress.core.rbac.Role)}.
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delroleinheritance', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delroleinheritance>
+ *           ...
+ *         </delroleinheritance>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ *
+ * @author Shawn McKinney
+ */
+public class Delroleinheritance
+{
+    final private List<Relationship> relationships = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delroleinheritance()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addRelationship', is used for derived xml tag 'relationship' in the load script.</p>
+     * <pre>
+     * {@code
+     * <delroleinheritance>
+     *     <relationship child="r2" parent="r1"/>
+     *     <relationship child="r3" parent="r1"/>
+     * </delroleinheritance>
+     * }
+     * </pre>
+     *
+     * @param relationship contains reference to data element targeted for removal.
+     */
+    public void addRelationship(Relationship relationship)
+    {
+        this.relationships.add(relationship);
+    }
+
+    /**
+     * Used by {@link org.apache.directory.fortress.core.ant.FortressAntTask#deleteRoleInheritances()} to retrieve list of Role relationships as defined in input xml file.
+     *
+     * @return collection containing {@link Relationship}s targeted for removal.
+     */
+    public List<Relationship> getRelationships()
+    {
+        return this.relationships;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/Delsdset.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/Delsdset.java b/src/main/java/org/apache/directory/fortress/core/ant/Delsdset.java
new file mode 100755
index 0000000..75f3610
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/Delsdset.java
@@ -0,0 +1,84 @@
+/*
+ *   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.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The class is used by {@link FortressAntTask} to create new {@link SDSetAnt}s used to drive {@link org.apache.directory.fortress.core.AdminMgr#deleteSsdSet(org.apache.directory.fortress.core.rbac.SDSet)} or {@link org.apache.directory.fortress.core.AdminMgr#deleteDsdSet(org.apache.directory.fortress.core.rbac.SDSet)}.
+ *
+ * It is not intended to be callable by programs outside of the Ant load utility.  The class name itself maps to the xml tag used by load utility.
+ * <p>This class name, 'Delsdset', is used for the xml tag in the load script.</p>
+ * <pre>
+ * {@code
+ * <target name="all">
+ *     <FortressAdmin>
+ *         <delsdset>
+ *           ...
+ *         </delsdset>
+ *     </FortressAdmin>
+ * </target>
+ * }
+ * </pre>
+ *
+ * @author Shawn McKinney
+ */
+public class Delsdset
+{
+    final private List<SDSetAnt> sds = new ArrayList<>();
+
+    /**
+     * All Ant data entities must have a default constructor.
+     */
+    public Delsdset()
+    {
+    }
+
+    /**
+     * <p>This method name, 'addSdset', is used for derived xml tag 'sdset' in the load script.</p>
+     * <pre>
+     * {@code
+     * <delsdset>
+     *     <sdset name="DemoSSD1" settype="STATIC" />
+     *     <sdset name="DemoDSD1" settype="DYNAMIC" />
+     * </delsdset>
+     * }
+     * </pre>
+     *
+     * @param sd contains reference to data element targeted for removal.
+     */
+    public void addSdset(SDSetAnt sd)
+    {
+        this.sds.add(sd);
+    }
+
+    /**
+     * Used by {@link FortressAntTask#deleteSdsets()} to retrieve list of SDSetAnt as defined in input xml file.
+     *
+     * @return collection containing {@link SDSetAnt}s targeted for removal.
+     */
+    public List<SDSetAnt> getSdset()
+    {
+        return this.sds;
+    }
+}
+


[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.

Posted by sm...@apache.org.
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;
+}


[10/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/UserDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/UserDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/UserDAO.java
new file mode 100755
index 0000000..2c953e1
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/unboundid/UserDAO.java
@@ -0,0 +1,2365 @@
+/*
+ *   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.unboundid;
+
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.PasswordException;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.ldap.UnboundIdDataProvider;
+import org.apache.directory.fortress.core.ldap.openldap.OLPWControlImpl;
+import org.apache.directory.fortress.core.rbac.Address;
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.GlobalPwMsgIds;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.PwMessage;
+import org.apache.directory.fortress.core.rbac.PwPolicyControl;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.RoleUtil;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+import org.apache.directory.fortress.core.rbac.UserRole;
+import org.apache.directory.fortress.core.rbac.Warning;
+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;
+
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttribute;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttributeSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPEntry;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModification;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPModificationSet;
+import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPSearchResults;
+
+
+/**
+ * Data access class for LDAP User entity.
+ * <p/>
+ * <p/>
+ * The Fortress User LDAP schema follows:
+ * <p/>
+ * <h4>1. InetOrgPerson Structural Object Class </h4>
+ * <code># The inetOrgPerson represents people who are associated with an</code><br />
+ * <code># organization in some way.  It is a structural class and is derived</code><br />
+ * <code># from the organizationalPerson which is defined in X.521 [X521].</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 2.16.840.1.113730.3.2.2</code>
+ * <li> <code>NAME 'inetOrgPerson'</code>
+ * <li> <code>DESC 'RFC2798: Internet Organizational Person'</code>
+ * <li> <code>SUP organizationalPerson</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MAY ( audio $ businessCategory $ carLicense $ departmentNumber $</code>
+ * <li> <code>displayName $ employeeNumber $ employeeType $ givenName $</code>
+ * <li> <code>homePhone $ homePostalAddress $ initials $ jpegPhoto $</code>
+ * <li> <code>labeledURI $ mail $ manager $ mobile $ o $ pager $ photo $</code>
+ * <li> <code>roomNumber $ secretary $ uid $ userCertificate $</code>
+ * <li> <code>x500uniqueIdentifier $ preferredLanguage $</code>
+ * <li> <code>userSMIMECertificate $ userPKCS12 ) )</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>
+ * <p/>
+ * <h4>3. ftUserAttrs is used to store user RBAC and Admin role assignment and other security attributes on User entity</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.1</code>
+ * <li> <code>NAME 'ftUserAttrs'</code>
+ * <li> <code>DESC 'Fortress User Attribute AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MUST ( ftId )</code>
+ * <li> <code>MAY ( ftRC $ ftRA $ ftARC $ ftARA $ ftCstr</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
+ * @created August 30, 2009
+ */
+public final class UserDAO extends UnboundIdDataProvider implements org.apache.directory.fortress.core.rbac.dao.UserDAO
+{
+    private static final String CLS_NM = UserDAO.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static PwPolicyControl pwControl;
+
+    /**
+     * Initialize the OpenLDAP Pw Policy validator.
+     */
+    static
+    {
+        if ( GlobalIds.IS_OPENLDAP )
+        {
+            pwControl = new OLPWControlImpl();
+        }
+    }
+
+    /*
+      *  *************************************************************************
+      *  **  OpenAccessMgr USERS STATICS
+      *  ************************************************************************
+      */
+    private static final String USERS_AUX_OBJECT_CLASS_NAME = "ftUserAttrs";
+    private static final String ORGANIZATIONAL_PERSON_OBJECT_CLASS_NAME = "organizationalPerson";
+    private static final String USER_OBJECT_CLASS = "user.objectclass";
+    private static final String USERS_EXTENSIBLE_OBJECT = "extensibleObject";
+
+    // The Fortress User entity attributes are stored within standard LDAP object classes along with custom auxiliary object classes:
+    private static final String USER_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP,
+            Config.getProperty( USER_OBJECT_CLASS ),
+            USERS_AUX_OBJECT_CLASS_NAME,
+            GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME,
+            GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME,
+            USERS_EXTENSIBLE_OBJECT
+    };
+
+    private static final String objectClassImpl = Config.getProperty( USER_OBJECT_CLASS );
+    private static final String SN = "sn";
+    private static final String PW = "userpassword";
+    private static final String SYSTEM_USER = "ftSystem";
+
+    /**
+     * Constant contains the locale attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String L = "l";
+
+    /**
+     * Constant contains the postal address attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String POSTAL_ADDRESS = "postalAddress";
+
+    /**
+     * Constant contains the state attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String STATE = "st";
+
+    /**
+     * Constant contains the postal code attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String POSTAL_CODE = "postalCode";
+
+    /**
+     * Constant contains the post office box attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String POST_OFFICE_BOX = "postOfficeBox";
+
+    /**
+     * Constant contains the country attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String COUNTRY = "c";
+
+    /**
+     * Constant contains the  attribute name used within inetorgperson ldap object classes.
+     */
+    private static final String PHYSICAL_DELIVERY_OFFICE_NAME = "physicalDeliveryOfficeName";
+
+    /**
+     * Constant contains the  attribute name used within inetorgperson ldap object classes.
+     */
+    private static final String DEPARTMENT_NUMBER = "departmentNumber";
+
+    /**
+     * Constant contains the  attribute name used within inetorgperson ldap object classes.
+     */
+    private static final String ROOM_NUMBER = "roomNumber";
+
+    /**
+     * Constant contains the mobile attribute values used within iNetOrgPerson ldap object classes.
+     */
+    private static final String MOBILE = "mobile";
+
+    /**
+     * Constant contains the telephone attribute values used within organizationalPerson ldap object classes.
+     */
+    private static final String TELEPHONE_NUMBER = "telephoneNumber";
+
+    /**
+     * Constant contains the  attribute name for jpeg images to be stored within inetorgperson ldap object classes.
+     */
+    private static final String JPEGPHOTO = "jpegPhoto";
+
+    /**
+     * Constant contains the email attribute values used within iNetOrgPerson ldap object classes.
+     */
+    private static final String MAIL = "mail";
+    private static final String DISPLAY_NAME = "displayName";
+    private static final String TITLE = "title";
+    private static final String EMPLOYEE_TYPE = "employeeType";
+
+    private static final String OPENLDAP_POLICY_SUBENTRY = "pwdPolicySubentry";
+    private static final String OPENLDAP_PW_RESET = "pwdReset";
+    private static final String OPENLDAP_PW_LOCKED_TIME = "pwdAccountLockedTime";
+    private static final String OPENLDAP_ACCOUNT_LOCKED_TIME = "pwdAccountLockedTime";
+    private static final String LOCK_VALUE = "000001010000Z";
+    private static final String[] USERID =
+        { GlobalIds.UID };
+    private static final String[] ROLES =
+        { GlobalIds.USER_ROLE_ASSIGN };
+
+    private static final String[] USERID_ATRS =
+        {
+            GlobalIds.UID
+    };
+
+    // This smaller result set of attributes are needed for user validation and authentication operations.
+    private static final String[] AUTHN_ATRS =
+        {
+            GlobalIds.FT_IID,
+            GlobalIds.UID, PW,
+            GlobalIds.DESC,
+            GlobalIds.OU, GlobalIds.CN,
+            SN,
+            GlobalIds.CONSTRAINT,
+            GlobalIds.IS_OPENLDAP ? OPENLDAP_PW_RESET : null,
+            GlobalIds.IS_OPENLDAP ? OPENLDAP_PW_LOCKED_TIME : null,
+            GlobalIds.PROPS
+    };
+
+    // This default set of attributes contains all and is used for search operations.
+    private static final String[] DEFAULT_ATRS =
+        {
+            GlobalIds.FT_IID,
+            GlobalIds.UID, PW,
+            GlobalIds.DESC,
+            GlobalIds.OU,
+            GlobalIds.CN,
+            SN,
+            GlobalIds.USER_ROLE_DATA,
+            GlobalIds.CONSTRAINT,
+            GlobalIds.USER_ROLE_ASSIGN,
+            GlobalIds.IS_OPENLDAP ? OPENLDAP_PW_RESET : null,
+            GlobalIds.IS_OPENLDAP ? OPENLDAP_PW_LOCKED_TIME : null,
+            GlobalIds.IS_OPENLDAP ? OPENLDAP_POLICY_SUBENTRY : null,
+            GlobalIds.PROPS,
+            GlobalIds.USER_ADMINROLE_ASSIGN,
+            GlobalIds.USER_ADMINROLE_DATA,
+            POSTAL_ADDRESS,
+            L,
+            POSTAL_CODE,
+            POST_OFFICE_BOX,
+            STATE,
+            PHYSICAL_DELIVERY_OFFICE_NAME,
+            DEPARTMENT_NUMBER,
+            ROOM_NUMBER,
+            TELEPHONE_NUMBER,
+            MOBILE,
+            MAIL,
+            EMPLOYEE_TYPE,
+            TITLE,
+            SYSTEM_USER,
+            DISPLAY_NAME,
+            JPEGPHOTO
+    };
+
+    private static final String[] ROLE_ATR =
+        {
+            GlobalIds.USER_ROLE_DATA
+    };
+
+    private static final String[] AROLE_ATR =
+        {
+            GlobalIds.USER_ADMINROLE_DATA
+    };
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws CreateException
+     *
+     */
+    public final User create( User entity )
+        throws CreateException
+    {
+        LDAPConnection ld = null;
+
+        try
+        {
+            LDAPAttributeSet attrs = new LDAPAttributeSet();
+            attrs.add( createAttributes( GlobalIds.OBJECT_CLASS, USER_OBJ_CLASS ) );
+
+            entity.setInternalId();
+            attrs.add( createAttribute( GlobalIds.FT_IID, entity.getInternalId() ) );
+            attrs.add( createAttribute( GlobalIds.UID, entity.getUserId() ) );
+
+            // CN is required on inetOrgPerson object class, if caller did not set, use the userId:
+            if ( !VUtil.isNotNullOrEmpty( entity.getCn() ) )
+            {
+                entity.setCn( entity.getUserId() );
+            }
+
+            attrs.add( createAttribute( GlobalIds.CN, entity.getCn() ) );
+
+            // SN is required on inetOrgPerson object class, if caller did not set, use the userId:
+            if ( !VUtil.isNotNullOrEmpty( entity.getSn() ) )
+            {
+                entity.setSn( entity.getUserId() );
+            }
+
+            attrs.add( createAttribute( SN, entity.getSn() ) );
+
+            // guard against npe
+            attrs.add( createAttribute( PW,
+                VUtil.isNotNullOrEmpty( entity.getPassword() ) ? new String( entity.getPassword() ) : new String(
+                    new char[]
+                        {} ) ) );
+
+            if ( VUtil.isNotNullOrEmpty( entity.getDisplayName() ) )
+            {
+                attrs.add( createAttribute( DISPLAY_NAME, entity.getDisplayName() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getTitle() ) )
+            {
+                attrs.add( createAttribute( TITLE, entity.getTitle() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getEmployeeType() ) )
+            {
+                attrs.add( createAttribute( EMPLOYEE_TYPE, entity.getEmployeeType() ) );
+            }
+
+            // These are multi-valued attributes, use the util function to load:
+            // These items are optional.  The utility function will return quietly if no items are loaded into collection:
+            loadAttrs( entity.getPhones(), attrs, TELEPHONE_NUMBER );
+            loadAttrs( entity.getMobiles(), attrs, MOBILE );
+            loadAttrs( entity.getEmails(), attrs, MAIL );
+
+            // The following attributes are optional:
+            if ( VUtil.isNotNullOrEmpty( entity.isSystem() ) )
+            {
+                attrs.add( createAttribute( SYSTEM_USER, entity.isSystem().toString().toUpperCase() ) );
+            }
+            if ( GlobalIds.IS_OPENLDAP && VUtil.isNotNullOrEmpty( entity.getPwPolicy() ) )
+            {
+                String dn = GlobalIds.POLICY_NODE_TYPE + "=" + entity.getPwPolicy() + ","
+                    + getRootDn( entity.getContextId(), GlobalIds.PPOLICY_ROOT );
+                attrs.add( createAttribute( OPENLDAP_POLICY_SUBENTRY, dn ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getOu() ) )
+            {
+                attrs.add( createAttribute( GlobalIds.OU, entity.getOu() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                attrs.add( createAttribute( GlobalIds.DESC, entity.getDescription() ) );
+            }
+
+            // props are optional as well:
+            // Add "initial" property here.
+            entity.addProperty( "init", "" );
+            loadProperties( entity.getProperties(), attrs, GlobalIds.PROPS );
+            // map the userid to the name field in constraint:
+            entity.setName( entity.getUserId() );
+            attrs.add( createAttribute( GlobalIds.CONSTRAINT, CUtil.setConstraint( entity ) ) );
+            loadAddress( entity.getAddress(), attrs );
+            if ( VUtil.isNotNullOrEmpty( entity.getJpegPhoto() ) )
+            {
+                attrs.add( new LDAPAttribute( JPEGPHOTO, entity.getJpegPhoto() ) );
+            }
+
+            String dn = getDn( entity.getUserId(), entity.getContextId() );
+
+            LDAPEntry myEntry = new LDAPEntry( dn, attrs );
+            ld = getAdminConnection();
+            add( ld, myEntry, entity );
+            entity.setDn( dn );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "create userId [" + entity.getUserId() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new CreateException( GlobalErrIds.USER_ADD_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws UpdateException
+     */
+    public final User update( User entity )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String userDn = getDn( entity.getUserId(), entity.getContextId() );
+
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+
+            if ( VUtil.isNotNullOrEmpty( entity.getCn() ) )
+            {
+                LDAPAttribute cn = new LDAPAttribute( GlobalIds.CN, entity.getCn() );
+                mods.add( LDAPModification.REPLACE, cn );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getSn() ) )
+            {
+                LDAPAttribute sn = new LDAPAttribute( SN, entity.getSn() );
+                mods.add( LDAPModification.REPLACE, sn );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getOu() ) )
+            {
+                LDAPAttribute ou = new LDAPAttribute( GlobalIds.OU, entity.getOu() );
+                mods.add( LDAPModification.REPLACE, ou );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getPassword() ) )
+            {
+                LDAPAttribute pw = new LDAPAttribute( PW, new String( entity.getPassword() ) );
+                mods.add( LDAPModification.REPLACE, pw );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                LDAPAttribute desc = new LDAPAttribute( GlobalIds.DESC,
+                    entity.getDescription() );
+                mods.add( LDAPModification.REPLACE, desc );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getEmployeeType() ) )
+            {
+                LDAPAttribute employeeType = new LDAPAttribute( EMPLOYEE_TYPE, entity.getEmployeeType() );
+                mods.add( LDAPModification.REPLACE, employeeType );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getTitle() ) )
+            {
+                LDAPAttribute title = new LDAPAttribute( TITLE, entity.getTitle() );
+                mods.add( LDAPModification.REPLACE, title );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getDisplayName() ) )
+            {
+                LDAPAttribute name = new LDAPAttribute( DISPLAY_NAME, entity.getDisplayName() );
+                mods.add( LDAPModification.REPLACE, name );
+            }
+
+            if ( GlobalIds.IS_OPENLDAP && VUtil.isNotNullOrEmpty( entity.getPwPolicy() ) )
+            {
+                String szDn = GlobalIds.POLICY_NODE_TYPE + "=" + entity.getPwPolicy() + ","
+                    + getRootDn( entity.getContextId(), GlobalIds.PPOLICY_ROOT );
+                LDAPAttribute dn = new LDAPAttribute( OPENLDAP_POLICY_SUBENTRY, szDn );
+                mods.add( LDAPModification.REPLACE, dn );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.isSystem() ) )
+            {
+                LDAPAttribute system = new LDAPAttribute( SYSTEM_USER, entity.isSystem().toString().toUpperCase() );
+                mods.add( LDAPModification.REPLACE, system );
+            }
+
+            if ( entity.isTemporalSet() )
+            {
+                // map the userid to the name field in constraint:
+                entity.setName( entity.getUserId() );
+                String szRawData = CUtil.setConstraint( entity );
+
+                if ( VUtil.isNotNullOrEmpty( szRawData ) )
+                {
+                    LDAPAttribute constraint = new LDAPAttribute( GlobalIds.CONSTRAINT, szRawData );
+                    mods.add( LDAPModification.REPLACE, constraint );
+                }
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getProperties() ) )
+            {
+                loadProperties( entity.getProperties(), mods, GlobalIds.PROPS, true );
+            }
+
+            loadAddress( entity.getAddress(), mods );
+            // These are multi-valued attributes, use the util function to load:
+            loadAttrs( entity.getPhones(), mods, TELEPHONE_NUMBER );
+            loadAttrs( entity.getMobiles(), mods, MOBILE );
+            loadAttrs( entity.getEmails(), mods, MAIL );
+            if ( VUtil.isNotNullOrEmpty( entity.getJpegPhoto() ) )
+            {
+                mods.add( LDAPModification.REPLACE, new LDAPAttribute( JPEGPHOTO, entity.getJpegPhoto() ) );
+            }
+
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, userDn, mods, entity );
+                entity.setDn( userDn );
+            }
+
+            entity.setDn( userDn );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "update userId [" + entity.getUserId() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @param replace
+     * @return
+     * @throws UpdateException
+     */
+    public final User updateProps( User entity, boolean replace )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String userDn = getDn( entity.getUserId(), entity.getContextId() );
+
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+
+            if ( VUtil.isNotNullOrEmpty( entity.getProperties() ) )
+            {
+                loadProperties( entity.getProperties(), mods, GlobalIds.PROPS, replace );
+            }
+
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, userDn, mods, entity );
+                entity.setDn( userDn );
+            }
+
+            entity.setDn( userDn );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "updateProps userId [" + entity.getUserId() + "] isReplace [" + replace
+                + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param user
+     * @throws RemoveException
+     */
+    public final String remove( User user )
+        throws RemoveException
+    {
+        LDAPConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, userDn, user );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "remove userId [" + user.getUserId() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new RemoveException( GlobalErrIds.USER_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param user
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    public final void lock( User user )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute pwdAccoutLock = new LDAPAttribute( OPENLDAP_PW_LOCKED_TIME, LOCK_VALUE );
+            mods.add( LDAPModification.REPLACE, pwdAccoutLock );
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, user );
+        }
+        catch ( LDAPException e )
+        {
+            String error = "lock user [" + user.getUserId() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_PW_LOCK_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param user
+     * @throws UpdateException
+     *
+     */
+    public final void unlock( User user )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            //ld = getAdminConnection();
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute pwdlockedTime = new LDAPAttribute( OPENLDAP_PW_LOCKED_TIME );
+            mods.add( LDAPModification.DELETE, pwdlockedTime );
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, user );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_ATTRIBUTE )
+            {
+                LOG.info( "unlock user [" + user.getUserId() + "] no such attribute:"
+                    + OPENLDAP_ACCOUNT_LOCKED_TIME );
+            }
+            else
+            {
+                String error = "unlock user [" + user.getUserId() + "] caught LDAPException= "
+                    + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                throw new UpdateException( GlobalErrIds.USER_PW_UNLOCK_FAILED, error, e );
+            }
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final User getUser( User user, boolean isRoles )
+        throws FinderException
+    {
+        User entity = null;
+        LDAPConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        String[] uATTRS;
+        // Retrieve role attributes?
+
+        if ( isRoles )
+        {
+            // Retrieve the User's assigned RBAC and Admin Role attributes from directory.
+            uATTRS = DEFAULT_ATRS;
+
+        }
+        else
+        {
+            // Do not retrieve the User's assigned RBAC and Admin Role attributes from directory.
+            uATTRS = AUTHN_ATRS;
+        }
+
+        LDAPEntry findEntry = null;
+
+        try
+        {
+            ld = getAdminConnection();
+            findEntry = read( ld, userDn, uATTRS );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "getUser COULD NOT FIND ENTRY for user [" + user.getUserId() + "]";
+                throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+            }
+
+            String error = "getUser [" + userDn + "]= caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        entity = unloadLdapEntry( findEntry, 0, user.getContextId() );
+
+        if ( entity == null )
+        {
+            String warning = "getUser userId [" + user.getUserId() + "] not found, Fortress rc="
+                + GlobalErrIds.USER_NOT_FOUND;
+            throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     */
+    public final List<UserAdminRole> getUserAdminRoles( User user )
+        throws FinderException
+    {
+        List<UserAdminRole> roles = null;
+        LDAPConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            LDAPEntry findEntry = read( ld, userDn, AROLE_ATR );
+            roles = unloadUserAdminRoles( findEntry, user.getUserId(), user.getContextId() );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "getUserAdminRoles COULD NOT FIND ENTRY for user [" + user.getUserId() + "]";
+                throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+            }
+
+            String error = "getUserAdminRoles [" + userDn + "]= caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return roles;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<String> getRoles( User user )
+        throws FinderException
+    {
+        List<String> roles = null;
+        LDAPConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            LDAPEntry findEntry = read( ld, userDn, ROLES );
+
+            if ( findEntry == null )
+            {
+                String warning = "getRoles userId [" + user.getUserId() + "] not found, Fortress rc="
+                    + GlobalErrIds.USER_NOT_FOUND;
+                throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+            }
+
+            roles = getAttributes( findEntry, GlobalIds.USER_ROLE_ASSIGN );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "getRoles COULD NOT FIND ENTRY for user [" + user.getUserId() + "]";
+                throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+            }
+
+            String error = "getRoles [" + userDn + "]= caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return roles;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     * @throws org.apache.directory.fortress.core.SecurityException
+     */
+    public final Session checkPassword( User user ) throws FinderException
+    {
+        Session session = null;
+        LDAPConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            session = new ObjectFactory().createSession();
+            session.setUserId( user.getUserId() );
+            ld = getUserConnection();
+            boolean result = bind( ld, userDn, user.getPassword() );
+
+            if ( result )
+            {
+                // check openldap password policies here
+                checkPwPolicies( ld, session );
+
+                if ( session.getErrorId() == 0 )
+                {
+                    session.setAuthenticated( true );
+                }
+            }
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.INVALID_CREDENTIALS )
+            {
+                // Check controls to see if password is locked, expired or out of grace:
+                checkPwPolicies( ld, session );
+                // if check pw control did not find problem the user entered invalid pw:
+                if ( session.getErrorId() == 0 )
+                {
+                    String info = "checkPassword INVALID PASSWORD for userId [" + user.getUserId() + "]";
+                    session.setMsg( info );
+                    session.setErrorId( GlobalErrIds.USER_PW_INVLD );
+                    session.setAuthenticated( false );
+                }
+            }
+            else
+            {
+                String error = "checkPassword userId [" + user.getUserId() + "] caught LDAPException="
+                    + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                throw new FinderException( GlobalErrIds.USER_BIND_FAILED, error, e );
+            }
+        }
+        finally
+        {
+            closeUserConnection( ld );
+        }
+
+        return session;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws FinderException
+     */
+    public final List<User> findUsers( User user ) throws FinderException
+    {
+        List<User> userList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String userRoot = getRootDn( user.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String filter;
+
+            if ( VUtil.isNotNullOrEmpty( user.getUserId() ) )
+            {
+                // place a wild card after the input userId:
+                String searchVal = encodeSafeText( user.getUserId(), GlobalIds.USERID_LEN );
+                filter = GlobalIds.FILTER_PREFIX + objectClassImpl + ")("
+                    + GlobalIds.UID + "=" + searchVal + "*))";
+            }
+            else if ( VUtil.isNotNullOrEmpty( user.getInternalId() ) )
+            {
+                // internalUserId search
+                String searchVal = encodeSafeText( user.getInternalId(), GlobalIds.USERID_LEN );
+                // this is not a wildcard search. Must be exact match.
+                filter = GlobalIds.FILTER_PREFIX + objectClassImpl + ")("
+                    + GlobalIds.FT_IID + "=" + searchVal + "))";
+            }
+            else
+            {
+                // Beware - returns ALL users!!:"
+                filter = "(objectclass=" + objectClassImpl + ")";
+            }
+
+            ld = getAdminConnection();
+            searchResults = search( ld, userRoot,
+                LDAPConnection.SCOPE_ONE, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.hasMoreElements() )
+            {
+                userList.add( unloadLdapEntry( searchResults.next(), sequence++, user.getContextId() ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "findUsers userRoot [" + userRoot + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param user
+     * @param limit
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final List<String> findUsers( User user, int limit ) throws FinderException
+    {
+        List<String> userList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String userRoot = getRootDn( user.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String searchVal = encodeSafeText( user.getUserId(), GlobalIds.USERID_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + objectClassImpl + ")("
+                + GlobalIds.UID + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            searchResults = search( ld, userRoot,
+                LDAPConnection.SCOPE_ONE, filter, USERID, false, GlobalIds.BATCH_SIZE, limit );
+
+            while ( searchResults.hasMoreElements() )
+            {
+                LDAPEntry entry = searchResults.next();
+                userList.add( getAttribute( entry, GlobalIds.UID ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "findUsers caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final List<User> getAuthorizedUsers( Role role )
+        throws FinderException
+    {
+        List<User> userList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String userRoot = getRootDn( role.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String roleVal = encodeSafeText( role.getName(), GlobalIds.USERID_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + USERS_AUX_OBJECT_CLASS_NAME + ")(";
+            Set<String> roles = RoleUtil.getDescendants( role.getName(), role.getContextId() );
+
+            if ( VUtil.isNotNullOrEmpty( roles ) )
+            {
+                filter += "|(" + GlobalIds.USER_ROLE_ASSIGN + "=" + roleVal + ")";
+
+                for ( String uRole : roles )
+                {
+                    filter += "(" + GlobalIds.USER_ROLE_ASSIGN + "=" + uRole + ")";
+                }
+
+                filter += ")";
+            }
+            else
+            {
+                filter += GlobalIds.USER_ROLE_ASSIGN + "=" + roleVal + ")";
+            }
+
+            filter += ")";
+            ld = getAdminConnection();
+            searchResults = search( ld, userRoot,
+                LDAPConnection.SCOPE_ONE, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.hasMoreElements() )
+            {
+                userList.add( unloadLdapEntry( searchResults.next(), sequence++, role.getContextId() ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "getAuthorizedUsers role name [" + role.getName() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws FinderException
+     */
+    public final List<User> getAssignedUsers( Role role )
+        throws FinderException
+    {
+        List<User> userList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String userRoot = getRootDn( role.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String roleVal = encodeSafeText( role.getName(), GlobalIds.USERID_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + USERS_AUX_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.USER_ROLE_ASSIGN + "=" + roleVal + "))";
+            ld = getAdminConnection();
+            searchResults = search( ld, userRoot,
+                LDAPConnection.SCOPE_ONE, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.hasMoreElements() )
+            {
+                userList.add( unloadLdapEntry( searchResults.next(), sequence++, role.getContextId() ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "getAssignedUsers role name [" + role.getName() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     *
+     * @param roles
+     * @return
+     * @throws FinderException
+     */
+    public final Set<String> getAssignedUsers( Set<String> roles, String contextId )
+        throws FinderException
+    {
+        Set<String> userSet = new HashSet<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String userRoot = getRootDn( contextId, GlobalIds.USER_ROOT );
+
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + USERS_AUX_OBJECT_CLASS_NAME + ")(|";
+            if ( VUtil.isNotNullOrEmpty( roles ) )
+            {
+                for ( String roleVal : roles )
+                {
+                    String filteredVal = encodeSafeText( roleVal, GlobalIds.USERID_LEN );
+                    filter += "(" + GlobalIds.USER_ROLE_ASSIGN + "=" + filteredVal + ")";
+                }
+            }
+            else
+            {
+                return null;
+            }
+
+            filter += "))";
+            ld = getAdminConnection();
+            searchResults = search( ld, userRoot,
+                LDAPConnection.SCOPE_ONE, filter, USERID_ATRS, false, GlobalIds.BATCH_SIZE );
+
+            while ( searchResults.hasMoreElements() )
+            {
+                userSet.add( getAttribute( searchResults.next(), GlobalIds.UID ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "getAssignedUsers caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userSet;
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws FinderException
+     */
+    public final List<User> getAssignedUsers( AdminRole role )
+        throws FinderException
+    {
+        List<User> userList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String userRoot = getRootDn( role.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String roleVal = encodeSafeText( role.getName(), GlobalIds.USERID_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + USERS_AUX_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.USER_ADMINROLE_ASSIGN + "=" + roleVal + "))";
+            ld = getAdminConnection();
+            searchResults = search( ld, userRoot,
+                LDAPConnection.SCOPE_ONE, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.hasMoreElements() )
+            {
+                userList.add( unloadLdapEntry( searchResults.next(), sequence++, role.getContextId() ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "getAssignedUsers admin role name [" + role.getName()
+                + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_USER_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param role
+     * @param limit
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final List<String> getAuthorizedUsers( Role role, int limit )
+        throws FinderException
+    {
+        List<String> userList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String userRoot = getRootDn( role.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String roleVal = encodeSafeText( role.getName(), GlobalIds.USERID_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + USERS_AUX_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.USER_ROLE_ASSIGN + "=" + roleVal + "))";
+            ld = getAdminConnection();
+            searchResults = search( ld, userRoot,
+                LDAPConnection.SCOPE_ONE, filter, USERID, false, GlobalIds.BATCH_SIZE, limit );
+
+            while ( searchResults.hasMoreElements() )
+            {
+                LDAPEntry entry = searchResults.next();
+                userList.add( getAttribute( entry, GlobalIds.UID ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "getAuthorizedUsers role name [" + role.getName() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param searchVal
+     * @return
+     * @throws FinderException
+     */
+    public final List<String> findUsersList( String searchVal, String contextId )
+        throws FinderException
+    {
+        List<String> userList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String userRoot = getRootDn( contextId, GlobalIds.USER_ROOT );
+
+        try
+        {
+            searchVal = encodeSafeText( searchVal, GlobalIds.USERID_LEN );
+            //ld = getAdminConnection();
+            String filter = GlobalIds.FILTER_PREFIX + objectClassImpl + ")("
+                + GlobalIds.UID + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            searchResults = search( ld, userRoot,
+                LDAPConnection.SCOPE_ONE, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.hasMoreElements() )
+            {
+                userList.add( ( unloadLdapEntry( searchResults.next(), sequence++, contextId ) ).getUserId() );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "findUsersList caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param ou
+     * @return
+     * @throws FinderException
+     */
+    public final List<User> findUsers( OrgUnit ou, boolean limitSize ) throws FinderException
+    {
+        List<User> userList = new ArrayList<>();
+        LDAPConnection ld = null;
+        LDAPSearchResults searchResults;
+        String userRoot = getRootDn( ou.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String szOu = encodeSafeText( ou.getName(), GlobalIds.OU_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + objectClassImpl + ")("
+                + GlobalIds.OU + "=" + szOu + "))";
+            int maxLimit;
+
+            if ( limitSize )
+            {
+                maxLimit = 10;
+            }
+            else
+            {
+                maxLimit = 0;
+            }
+
+            ld = getAdminConnection();
+            searchResults = search( ld, userRoot,
+                LDAPConnection.SCOPE_ONE, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE, maxLimit );
+            long sequence = 0;
+
+            while ( searchResults.hasMoreElements() )
+            {
+                userList.add( unloadLdapEntry( searchResults.next(), sequence++, ou.getContextId() ) );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "findUsers caught LDAPException=" + e.getLDAPResultCode() + " msg="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param entity
+     * @param newPassword
+     * @return
+     * @throws UpdateException
+     *
+     * @throws SecurityException
+     */
+    public final boolean changePassword( User entity, char[] newPassword )
+        throws SecurityException
+    {
+        boolean rc = true;
+        LDAPConnection ld = null;
+        LDAPModificationSet mods;
+        String userDn = getDn( entity.getUserId(), entity.getContextId() );
+
+        try
+        {
+            ld = getUserConnection();
+            bind( ld, userDn, entity.getPassword() );
+            mods = new LDAPModificationSet();
+            LDAPAttribute pw = new LDAPAttribute( PW, new String( newPassword ) );
+            mods.add( LDAPModification.REPLACE, pw );
+            modify( ld, userDn, mods );
+
+            // The 2nd modify is to update audit attributes on the User entry:
+            if ( GlobalIds.IS_AUDIT && entity.getAdminSession() != null )
+            {
+                // Because the user modified their own password, set their userId here:
+                //(entity.getAdminSession()).setInternalUserId(entity.getUserId());
+                mods = new LDAPModificationSet();
+                modify( ld, userDn, mods, entity );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = User.class.getName() + ".changePassword user [" + entity.getUserId() + "] ";
+
+            if ( e.getLDAPResultCode() == LDAPException.CONSTRAINT_VIOLATION )
+            {
+                warning += " constraint violation, ldap rc=" + e.getLDAPResultCode() + " ldap msg=" + e.getMessage()
+                    + " Fortress rc=" + GlobalErrIds.PSWD_CONST_VIOLATION;
+                throw new PasswordException( GlobalErrIds.PSWD_CONST_VIOLATION, warning );
+            }
+            else if ( e.getLDAPResultCode() == LDAPException.INSUFFICIENT_ACCESS_RIGHTS )
+            {
+                warning += " user not authorized to change password, ldap rc=" + e.getLDAPResultCode() + " ldap msg="
+                    + e.getMessage() + " Fortress rc=" + GlobalErrIds.USER_PW_MOD_NOT_ALLOWED;
+                throw new UpdateException( GlobalErrIds.USER_PW_MOD_NOT_ALLOWED, warning );
+            }
+
+            warning += " caught LDAPException rc=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_PW_CHANGE_FAILED, warning, e );
+        }
+        finally
+        {
+            closeUserConnection( ld );
+        }
+
+        return rc;
+    }
+
+
+    /**
+     * @param user
+     * @throws UpdateException
+     *
+     */
+    public final void resetUserPassword( User user )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute pw = new LDAPAttribute( PW, new String( user.getPassword() ) );
+            mods.add( LDAPModification.REPLACE, pw );
+            LDAPAttribute pwdReset = new LDAPAttribute( OPENLDAP_PW_RESET, "TRUE" );
+            mods.add( LDAPModification.REPLACE, pwdReset );
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, user );
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "resetUserPassword userId [" + user.getUserId() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_PW_RESET_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param uRole
+     * @return
+     * @throws UpdateException
+     *
+     * @throws FinderException
+     *
+     */
+    public final String assign( UserRole uRole )
+        throws UpdateException, FinderException
+    {
+        LDAPConnection ld = null;
+        String userDn = getDn( uRole.getUserId(), uRole.getContextId() );
+
+        try
+        {
+            //ld = getAdminConnection();
+            LDAPModificationSet mods = new LDAPModificationSet();
+            String szUserRole = uRole.getRawData();
+            LDAPAttribute attr = new LDAPAttribute( GlobalIds.USER_ROLE_DATA, szUserRole );
+            mods.add( LDAPModification.ADD, attr );
+            attr = new LDAPAttribute( GlobalIds.USER_ROLE_ASSIGN, uRole.getName() );
+            mods.add( LDAPModification.ADD, attr );
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, uRole );
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "assign userId [" + uRole.getUserId() + "] name [" + uRole.getName() + "] ";
+
+            if ( e.getLDAPResultCode() == LDAPException.ATTRIBUTE_OR_VALUE_EXISTS )
+            {
+                warning += "assignment already exists.";
+                throw new FinderException( GlobalErrIds.URLE_ASSIGN_EXIST, warning );
+            }
+            else
+            {
+                warning += "caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                throw new UpdateException( GlobalErrIds.URLE_ASSIGN_FAILED, warning, e );
+            }
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param uRole
+     * @return
+     * @throws UpdateException
+     *
+     * @throws FinderException
+     *
+     */
+    public final String deassign( UserRole uRole )
+        throws UpdateException, FinderException
+    {
+        LDAPConnection ld = null;
+        String userDn = getDn( uRole.getUserId(), uRole.getContextId() );
+
+        try
+        {
+            // read the user's RBAC role assignments to locate target record.  Need the raw data before attempting removal:
+            List<UserRole> roles = getUserRoles( uRole.getUserId(), uRole.getContextId() );
+            int indx = -1;
+
+            // Does the user have any roles assigned?
+            if ( roles != null )
+            {
+                // function call will set indx to -1 if name not found:
+                indx = roles.indexOf( uRole );
+
+                // Is the targeted name assigned to user?
+                if ( indx > -1 )
+                {
+                    // Retrieve the targeted name:
+                    UserRole fRole = roles.get( indx );
+                    // delete the name assignment attribute using the raw name data:
+                    LDAPModificationSet mods = new LDAPModificationSet();
+                    LDAPAttribute rAttr = new LDAPAttribute( GlobalIds.USER_ROLE_DATA, fRole.getRawData() );
+                    mods.add( LDAPModification.DELETE, rAttr );
+                    rAttr = new LDAPAttribute( GlobalIds.USER_ROLE_ASSIGN, fRole.getName() );
+                    mods.add( LDAPModification.DELETE, rAttr );
+                    ld = getAdminConnection();
+                    modify( ld, userDn, mods, uRole );
+                }
+            }
+            // target name not found:
+            if ( indx == -1 )
+            {
+                // The user does not have the target name assigned,
+                String warning = "deassign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                    + "] assignment does not exist.";
+                throw new FinderException( GlobalErrIds.URLE_ASSIGN_NOT_EXIST, warning );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "deassign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.URLE_DEASSIGN_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param uRole
+     * @return
+     * @throws UpdateException
+     *
+     * @throws FinderException
+     *
+     */
+    public final String assign( UserAdminRole uRole )
+        throws UpdateException, FinderException
+    {
+        LDAPConnection ld = null;
+        String userDn = getDn( uRole.getUserId(), uRole.getContextId() );
+
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            String szUserRole = uRole.getRawData();
+            LDAPAttribute attr = new LDAPAttribute( GlobalIds.USER_ADMINROLE_DATA, szUserRole );
+            mods.add( LDAPModification.ADD, attr );
+            attr = new LDAPAttribute( GlobalIds.USER_ADMINROLE_ASSIGN, uRole.getName() );
+            mods.add( LDAPModification.ADD, attr );
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, uRole );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.ATTRIBUTE_OR_VALUE_EXISTS )
+            {
+                String warning = "assign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                    + "] assignment already exists.";
+                throw new FinderException( GlobalErrIds.ARLE_ASSIGN_EXIST, warning );
+            }
+            else
+            {
+                String warning = "assign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                    + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+                throw new UpdateException( GlobalErrIds.ARLE_ASSIGN_FAILED, warning, e );
+            }
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param uRole
+     * @return
+     * @throws UpdateException
+     *
+     * @throws FinderException
+     *
+     */
+    public final String deassign( UserAdminRole uRole )
+        throws UpdateException, FinderException
+    {
+        LDAPConnection ld = null;
+        String userDn = getDn( uRole.getUserId(), uRole.getContextId() );
+
+        try
+        {
+            // read the user's ARBAC roles to locate record.  Need the raw data before attempting removal:
+            User user = new User( uRole.getUserId() );
+            user.setContextId( uRole.getContextId() );
+            List<UserAdminRole> roles = getUserAdminRoles( user );
+            //User user = getUser(uRole.getUserId(), true);
+            //List<UserAdminRole> roles = user.getAdminRoles();
+            int indx = -1;
+
+            // Does the user have any roles assigned?
+            if ( roles != null )
+            {
+                // function call will set indx to -1 if name not found:
+                indx = roles.indexOf( uRole );
+
+                // Is the targeted name assigned to user?
+                if ( indx > -1 )
+                {
+                    // Retrieve the targeted name:
+                    UserRole fRole = roles.get( indx );
+                    // delete the name assignment attribute using the raw name data:
+                    LDAPModificationSet mods = new LDAPModificationSet();
+                    LDAPAttribute rAttr = new LDAPAttribute( GlobalIds.USER_ADMINROLE_DATA, fRole.getRawData() );
+                    mods.add( LDAPModification.DELETE, rAttr );
+                    rAttr = new LDAPAttribute( GlobalIds.USER_ADMINROLE_ASSIGN, fRole.getName() );
+                    mods.add( LDAPModification.DELETE, rAttr );
+                    ld = getAdminConnection();
+                    modify( ld, userDn, mods, uRole );
+                }
+            }
+
+            // target name not found:
+            if ( indx == -1 )
+            {
+                // The user does not have the target name assigned,
+                String warning = "deassign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                    + "] assignment does not exist.";
+                throw new FinderException( GlobalErrIds.ARLE_DEASSIGN_NOT_EXIST, warning );
+            }
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "deassign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                + "] caught LDAPException=" + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ARLE_DEASSIGN_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws UpdateException
+     *
+     */
+    public final String deletePwPolicy( User user )
+        throws UpdateException
+    {
+        LDAPConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            LDAPModificationSet mods = new LDAPModificationSet();
+            LDAPAttribute policy = new LDAPAttribute( OPENLDAP_POLICY_SUBENTRY );
+            mods.add( LDAPModification.DELETE, policy );
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, user );
+        }
+        catch ( LDAPException e )
+        {
+            String warning = "deletePwPolicy userId [" + user.getUserId() + "] caught LDAPException="
+                + e.getLDAPResultCode() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_PW_PLCY_DEL_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param le
+     * @return
+     * @throws LDAPException
+     */
+    private User unloadLdapEntry( LDAPEntry le, long sequence, String contextId )
+    {
+        User entity = new ObjectFactory().createUser();
+        entity.setSequenceId( sequence );
+        entity.setInternalId( getAttribute( le, GlobalIds.FT_IID ) );
+        entity.setDescription( getAttribute( le, GlobalIds.DESC ) );
+        entity.setUserId( getAttribute( le, GlobalIds.UID ) );
+        entity.setCn( getAttribute( le, GlobalIds.CN ) );
+        entity.setDisplayName( getAttribute( le, DISPLAY_NAME ) );
+        entity.setSn( getAttribute( le, SN ) );
+        entity.setOu( getAttribute( le, GlobalIds.OU ) );
+        entity.setDn( le.getDN() );
+        entity.setTitle( getAttribute( le, TITLE ) );
+        entity.setEmployeeType( getAttribute( le, EMPLOYEE_TYPE ) );
+        unloadTemporal( le, entity );
+        entity.setRoles( unloadUserRoles( le, entity.getUserId(), contextId ) );
+        entity.setAdminRoles( unloadUserAdminRoles( le, entity.getUserId(), contextId ) );
+        entity.setAddress( unloadAddress( le ) );
+        entity.setPhones( getAttributes( le, TELEPHONE_NUMBER ) );
+        entity.setMobiles( getAttributes( le, MOBILE ) );
+        entity.setEmails( getAttributes( le, MAIL ) );
+        String szBoolean = getAttribute( le, SYSTEM_USER );
+        if ( szBoolean != null )
+        {
+            entity.setSystem( Boolean.valueOf( szBoolean ) );
+        }
+
+        entity.addProperties( AttrHelper.getProperties( getAttributes( le, GlobalIds.PROPS ) ) );
+
+        if ( GlobalIds.IS_OPENLDAP )
+        {
+            szBoolean = getAttribute( le, OPENLDAP_PW_RESET );
+            if ( szBoolean != null && szBoolean.equalsIgnoreCase( "true" ) )
+            {
+                entity.setReset( true );
+            }
+            String szPolicy = getAttribute( le, OPENLDAP_POLICY_SUBENTRY );
+            if ( VUtil.isNotNullOrEmpty( szPolicy ) )
+            {
+                entity.setPwPolicy( getRdn( szPolicy ) );
+            }
+            szBoolean = getAttribute( le, OPENLDAP_PW_LOCKED_TIME );
+            if ( szBoolean != null && szBoolean.equals( LOCK_VALUE ) )
+            {
+                entity.setLocked( true );
+            }
+        }
+        entity.setJpegPhoto( getPhoto( le, JPEGPHOTO ) );
+        return entity;
+    }
+
+
+    /**
+     * @param userId
+     * @return
+     * @throws FinderException
+     */
+    private List<UserRole> getUserRoles( String userId, String contextId )
+        throws FinderException
+    {
+        List<UserRole> roles = null;
+        LDAPConnection ld = null;
+        String userDn = getDn( userId, contextId );
+        try
+        {
+            ld = getAdminConnection();
+            LDAPEntry findEntry = read( ld, userDn, ROLE_ATR );
+            roles = unloadUserRoles( findEntry, userId, contextId );
+        }
+        catch ( LDAPException e )
+        {
+            if ( e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT )
+            {
+                String warning = "getUserRoles COULD NOT FIND ENTRY for user [" + userId + "]";
+                throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+            }
+
+            String error = "getUserRoles [" + userDn + "]= caught LDAPException=" + e.getLDAPResultCode()
+                + " msg=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+        return roles;
+    }
+
+
+    /**
+     * @param ld
+     * @param pwMsg
+     */
+    private void checkPwPolicies( LDAPConnection ld, PwMessage pwMsg )
+    {
+        int rc = 0;
+        boolean success = false;
+        String msgHdr = "checkPwPolicies for userId [" + pwMsg.getUserId() + "] ";
+
+        if ( ld != null )
+        {
+            if ( !GlobalIds.IS_OPENLDAP )
+            {
+                //pwMsg.setWarningId( GlobalPwMsgIds.NOT_OLPW_POLICY_ENABLED );
+                String msg = msgHdr + "OPENLDAP PW POLICY NOT ENABLED";
+                pwMsg.setWarning( new ObjectFactory().createWarning( GlobalPwMsgIds.NOT_OLPW_POLICY_ENABLED, msg, Warning.Type.PASSWORD ) );
+                pwMsg.setErrorId( GlobalPwMsgIds.GOOD );
+                //String msg = msgHdr + "OPENLDAP PW POLICY NOT ENABLED";
+                //pwMsg.setMsg( msg );
+                LOG.debug( msg );
+                return;
+            }
+            else if ( pwControl != null )
+            {
+                pwControl.checkPasswordPolicy( ld.getResponseControls(), success, pwMsg );
+            }
+
+            // OpenLDAP has notified of password policy violation:
+            if ( pwMsg.getErrorId() > 0 )
+            {
+                String errMsg;
+
+                switch ( pwMsg.getErrorId() )
+                {
+                    case GlobalPwMsgIds.CHANGE_AFTER_RESET:
+                        // Don't throw exception if authenticating in J2EE Realm - The Web application must give user a chance to modify their password.
+                        if ( !GlobalIds.IS_REALM )
+                        {
+                            errMsg = msgHdr + "PASSWORD HAS BEEN RESET BY LDAP_ADMIN_POOL_UID";
+                            rc = GlobalErrIds.USER_PW_RESET;
+                        }
+                        else
+                        {
+                            errMsg = msgHdr
+                                + "PASSWORD HAS BEEN RESET BY LDAP_ADMIN_POOL_UID BUT ALLOWING TO CONTINUE DUE TO REALM";
+                            success = true;
+                            pwMsg.setWarning( new ObjectFactory().createWarning( GlobalErrIds.USER_PW_RESET, errMsg, Warning.Type.PASSWORD ) );
+                        }
+
+                        break;
+
+                    case GlobalPwMsgIds.ACCOUNT_LOCKED:
+                        errMsg = msgHdr + "ACCOUNT HAS BEEN LOCKED";
+                        rc = GlobalErrIds.USER_PW_LOCKED;
+                        break;
+
+                    case GlobalPwMsgIds.PASSWORD_HAS_EXPIRED:
+                        errMsg = msgHdr + "PASSWORD HAS EXPIRED";
+                        rc = GlobalErrIds.USER_PW_EXPIRED;
+                        break;
+
+                    case GlobalPwMsgIds.NO_MODIFICATIONS:
+                        errMsg = msgHdr + "PASSWORD MOD NOT ALLOWED";
+                        rc = GlobalErrIds.USER_PW_MOD_NOT_ALLOWED;
+                        break;
+
+                    case GlobalPwMsgIds.MUST_SUPPLY_OLD:
+                        errMsg = msgHdr + "MUST SUPPLY OLD PASSWORD";
+                        rc = GlobalErrIds.USER_PW_MUST_SUPPLY_OLD;
+                        break;
+
+                    case GlobalPwMsgIds.INSUFFICIENT_QUALITY:
+                        errMsg = msgHdr + "PASSWORD QUALITY VIOLATION";
+                        rc = GlobalErrIds.USER_PW_NSF_QUALITY;
+                        break;
+
+                    case GlobalPwMsgIds.PASSWORD_TOO_SHORT:
+                        errMsg = msgHdr + "PASSWORD TOO SHORT";
+                        rc = GlobalErrIds.USER_PW_TOO_SHORT;
+                        break;
+
+                    case GlobalPwMsgIds.PASSWORD_TOO_YOUNG:
+                        errMsg = msgHdr + "PASSWORD TOO YOUNG";
+                        rc = GlobalErrIds.USER_PW_TOO_YOUNG;
+                        break;
+
+                    case GlobalPwMsgIds.HISTORY_VIOLATION:
+                        errMsg = msgHdr + "PASSWORD IN HISTORY VIOLATION";
+                        rc = GlobalErrIds.USER_PW_IN_HISTORY;
+                        break;
+
+                    default:
+                        errMsg = msgHdr + "PASSWORD CHECK FAILED";
+                        rc = GlobalErrIds.USER_PW_CHK_FAILED;
+                        break;
+                }
+
+                pwMsg.setMsg( errMsg );
+                pwMsg.setErrorId( rc );
+                pwMsg.setAuthenticated( success );
+                LOG.debug( errMsg );
+            }
+            else
+            {
+                // Checked out good:
+                String msg = msgHdr + "PASSWORD CHECK SUCCESS";
+                pwMsg.setMsg( msg );
+                pwMsg.setErrorId( 0 );
+                pwMsg.setAuthenticated( true );
+                LOG.debug( msg );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of ARBAC roles, {@link UserAdminRole}, convert to raw data format and load into ldap attribute set in preparation for ldap add.
+     *
+     * @param list  contains List of type {@link UserAdminRole} targeted for adding to ldap.
+     * @param attrs collection of ldap attributes containing ARBAC role assignments in raw ldap format.
+     */
+    private void loadUserAdminRoles( List<UserAdminRole> list, LDAPAttributeSet attrs )
+    {
+        if ( list != null )
+        {
+            LDAPAttribute attr = null;
+            LDAPAttribute attrNm = null;
+
+            for ( UserAdminRole userRole : list )
+            {
+                String szUserRole = userRole.getRawData();
+
+                if ( attr == null )
+                {
+                    attr = new LDAPAttribute( GlobalIds.USER_ADMINROLE_DATA, szUserRole );
+                    attrNm = new LDAPAttribute( GlobalIds.USER_ADMINROLE_ASSIGN, userRole.getName() );
+                }
+                else
+                {
+                    attr.addValue( szUserRole );
+                    attrNm.addValue( userRole.getName() );
+                }
+            }
+
+            if ( attr != null )
+            {
+                attrs.add( attr );
+                attrs.add( attrNm );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of RBAC roles, {@link UserRole}, convert to raw data format and load into ldap modification set in preparation for ldap modify.
+     *
+     * @param list contains List of type {@link UserRole} targeted for updating into ldap.
+     * @param mods contains ldap modification set containing RBAC role assignments in raw ldap format to be updated.
+     */
+    private void loadUserRoles( List<UserRole> list, LDAPModificationSet mods )
+    {
+        LDAPAttribute attr = null;
+        LDAPAttribute attrNm = null;
+
+        if ( list != null )
+        {
+            for ( UserRole userRole : list )
+            {
+                String szUserRole = userRole.getRawData();
+
+                if ( attr == null )
+                {
+                    attr = new LDAPAttribute( GlobalIds.USER_ROLE_DATA, szUserRole );
+                    attrNm = new LDAPAttribute( GlobalIds.USER_ROLE_ASSIGN, userRole.getName() );
+                }
+                else
+                {
+                    attr.addValue( szUserRole );
+                    attrNm.addValue( userRole.getName() );
+                }
+            }
+
+            if ( attr != null )
+            {
+                mods.add( LDAPModification.REPLACE, attr );
+                mods.add( LDAPModification.REPLACE, attrNm );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of ARBAC roles, {@link UserAdminRole}, convert to raw data format and load into ldap modification set in preparation for ldap modify.
+     *
+     * @param list contains List of type {@link UserAdminRole} targeted for updating to ldap.
+     * @param mods contains ldap modification set containing ARBAC role assignments in raw ldap format to be updated.
+     */
+    private void loadUserAdminRoles( List<UserAdminRole> list, LDAPModificationSet mods )
+    {
+        LDAPAttribute attr = null;
+        LDAPAttribute attrNm = null;
+
+        if ( list != null )
+        {
+            for ( UserAdminRole userRole : list )
+            {
+                String szUserRole = userRole.getRawData();
+
+                if ( attr == null )
+                {
+                    attr = new LDAPAttribute( GlobalIds.USER_ADMINROLE_DATA, szUserRole );
+                    attrNm = new LDAPAttribute( GlobalIds.USER_ADMINROLE_ASSIGN, userRole.getName() );
+                }
+                else
+                {
+                    attr.addValue( szUserRole );
+                    attrNm.addValue( userRole.getName() );
+                }
+            }
+
+            if ( attr != null )
+            {
+                mods.add( LDAPModification.REPLACE, attr );
+                mods.add( LDAPModification.REPLACE, attrNm );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of RBAC roles, {@link UserRole}, convert to raw data format and load into ldap attribute set in preparation for ldap add.
+     *
+     * @param list  contains List of type {@link UserRole} targeted for adding to ldap.
+     * @param attrs collection of ldap attributes containing RBAC role assignments in raw ldap format.
+     */
+    private void loadUserRoles( List<UserRole> list, LDAPAttributeSet attrs )
+    {
+        if ( list != null )
+        {
+            LDAPAttribute attr = null;
+            LDAPAttribute attrNm = null;
+
+            for ( UserRole userRole : list )
+            {
+                String szUserRole = userRole.getRawData();
+
+                if ( attr == null )
+                {
+                    attr = new LDAPAttribute( GlobalIds.USER_ROLE_DATA, szUserRole );
+                    attrNm = new LDAPAttribute( GlobalIds.USER_ROLE_ASSIGN, userRole.getName() );
+                }
+                else
+                {
+                    attr.addValue( szUserRole );
+                    attrNm.addValue( userRole.getName() );
+                }
+            }
+
+            if ( attr != null )
+            {
+                attrs.add( attr );
+                attrs.add( attrNm );
+            }
+        }
+    }
+
+
+    /**
+     * Given a User address, {@link Address}, load into ldap attribute set in preparation for ldap add.
+     *
+     * @param address  contains User address {@link Address} targeted for adding to ldap.
+     * @param attrs collection of ldap attributes containing RBAC role assignments in raw ldap format.
+     */
+    private void loadAddress( Address address, LDAPAttributeSet attrs )
+    {
+        if ( address != null )
+        {
+            LDAPAttribute attr;
+
+            if ( VUtil.isNotNullOrEmpty( address.getAddresses() ) )
+            {
+                for ( String val : address.getAddresses() )
+                {
+                    attr = new LDAPAttribute( POSTAL_ADDRESS, val );
+                    attrs.add( attr );
+                }
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getCity() ) )
+            {
+                attr = new LDAPAttribute( L, address.getCity() );
+                attrs.add( attr );
+            }
+
+            //if(VUtil.isNotNullOrEmpty(address.getCountry()))
+            //{
+            //    attr = new LDAPAttribute(GlobalIds.COUNTRY, address.getAddress1());
+            //    attrs.add(attr);
+            //}
+            if ( VUtil.isNotNullOrEmpty( address.getPostalCode() ) )
+            {
+                attr = new LDAPAttribute( POSTAL_CODE, address.getPostalCode() );
+                attrs.add( attr );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getPostOfficeBox() ) )
+            {
+                attr = new LDAPAttribute( POST_OFFICE_BOX, address.getPostOfficeBox() );
+                attrs.add( attr );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getState() ) )
+            {
+                attr = new LDAPAttribute( STATE, address.getState() );
+                attrs.add( attr );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getBuilding() ) )
+            {
+                attr = new LDAPAttribute( PHYSICAL_DELIVERY_OFFICE_NAME, address.getBuilding() );
+                attrs.add( attr );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getDepartmentNumber() ) )
+            {
+                attr = new LDAPAttribute( DEPARTMENT_NUMBER, address.getDepartmentNumber() );
+                attrs.add( attr );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getRoomNumber() ) )
+            {
+                attr = new LDAPAttribute( ROOM_NUMBER, address.getRoomNumber() );
+                attrs.add( attr );
+            }
+        }
+    }
+
+
+    /**
+     * Given an address, {@link Address}, load into ldap modification set in preparation for ldap modify.
+     *
+     * @param address contains entity of type {@link Address} targeted for updating into ldap.
+     * @param mods contains ldap modification set contains attributes to be updated in ldap.
+     */
+    private void loadAddress( Address address, LDAPModificationSet mods )
+    {
+        LDAPAttribute attr;
+
+        if ( address != null )
+        {
+            if ( VUtil.isNotNullOrEmpty( address.getAddresses() ) )
+            {
+                attr = new LDAPAttribute( POSTAL_ADDRESS );
+                mods.add( LDAPModification.REPLACE, attr );
+
+                for ( String val : address.getAddresses() )
+                {
+                    attr = new LDAPAttribute( POSTAL_ADDRESS, val );
+                    mods.add( LDAPModification.ADD, attr );
+                }
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getCity() ) )
+            {
+                attr = new LDAPAttribute( L, address.getCity() );
+                mods.add( LDAPModification.REPLACE, attr );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getPostalCode() ) )
+            {
+                attr = new LDAPAttribute( POSTAL_CODE, address.getPostalCode() );
+                mods.add( LDAPModification.REPLACE, attr );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getPostOfficeBox() ) )
+            {
+                attr = new LDAPAttribute( POST_OFFICE_BOX, address.getPostOfficeBox() );
+                mods.add( LDAPModification.REPLACE, attr );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getState() ) )
+            {
+                attr = new LDAPAttribute( STATE, address.getState() );
+                mods.add( LDAPModification.REPLACE, attr );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getBuilding() ) )
+            {
+                attr = new LDAPAttribute( PHYSICAL_DELIVERY_OFFICE_NAME, address.getBuilding() );
+                mods.add( LDAPModification.REPLACE, attr );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getDepartmentNumber() ) )
+            {
+                attr = new LDAPAttribute( DEPARTMENT_NUMBER, address.getDepartmentNumber() );
+                mods.add( LDAPModification.REPLACE, attr );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getRoomNumber() ) )
+            {
+                attr = new LDAPAttribute( ROOM_NUMBER, address.getRoomNumber() );
+                mods.add( LDAPModification.REPLACE, attr );
+            }
+        }
+    }
+
+
+    /**
+     * Given an ldap entry containing organzationalPerson address information, convert to {@link Address}
+     *
+     * @param le     contains ldap entry to retrieve admin roles from.
+     * @return entity of type {@link Address}.
+     * @throws com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException in the event of ldap client error.
+     */
+    private Address unloadAddress( LDAPEntry le )
+    {
+        Address addr = new ObjectFactory().createAddress();
+        List<String> pAddrs = getAttributes( le, POSTAL_ADDRESS );
+        if ( pAddrs != null )
+        {
+            for ( String pAddr : pAddrs )
+            {
+                addr.setAddress( pAddr );
+            }
+        }
+        addr.setCity( getAttribute( le, L ) );
+        addr.setState( getAttribute( le, STATE ) );
+        addr.setPostalCode( getAttribute( le, POSTAL_CODE ) );
+        addr.setPostOfficeBox( getAttribute( le, POST_OFFICE_BOX ) );
+        addr.setBuilding( getAttribute( le, PHYSICAL_DELIVERY_OFFICE_NAME ) );
+        addr.setDepartmentNumber( getAttribute( le, DEPARTMENT_NUMBER ) );
+        addr.setRoomNumber( getAttribute( le, ROOM_NUMBER ) );
+        // todo: add support for country attribute
+        //addr.setCountry(getAttribute(le, GlobalIds.COUNTRY));
+
+        return addr;
+    }
+
+
+    /**
+     * Given an ldap entry containing ARBAC roles assigned to user, retrieve the raw data and convert to a collection of {@link UserAdminRole}
+     * including {@link org.apache.directory.fortress.core.util.time.Constraint}.
+     *
+     * @param le     contains ldap entry to retrieve admin roles from.
+     * @param userId attribute maps to {@link UserAdminRole#userId}.
+     * @param contextId
+     * @return List of type {@link UserAdminRole} containing admin roles assigned to a particular user.
+     * @throws com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException in the event of ldap client error.
+     */
+    private List<UserAdminRole> unloadUserAdminRoles( LDAPEntry le, String userId, String contextId )
+    {
+        List<UserAdminRole> uRoles = null;
+        List<String> roles = getAttributes( le, GlobalIds.USER_ADMINROLE_DATA );
+
+        if ( roles != null )
+        {
+            long sequence = 0;
+            uRoles = new ArrayList<>();
+
+            for ( String raw : roles )
+            {
+                UserAdminRole ure = new ObjectFactory().createUserAdminRole();
+                ure.load( raw, contextId );
+                ure.setSequenceId( sequence++ );
+                ure.setUserId( userId );
+                uRoles.add( ure );
+            }
+        }
+
+        return uRoles;
+    }
+
+
+    /**
+     *
+     * @param userId
+     * @param contextId
+     * @return
+     */
+    private String getDn( String userId, String contextId )
+    {
+        return GlobalIds.UID + "=" + userId + "," + getRootDn( contextId, GlobalIds.USER_ROOT );
+    }
+
+
+    /**
+    * Given an ldap entry containing RBAC roles assigned to user, retrieve the raw data and convert to a collection of {@link UserRole}
+    * including {@link org.apache.directory.fortress.core.util.time.Constraint}.
+    *
+    * @param le     contains ldap entry to retrieve roles from.
+    * @param userId attribute maps to {@link UserRole#userId}.
+    * @param contextId
+    * @return List of type {@link UserRole} containing RBAC roles assigned to a particular user.
+    * @throws com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException in the event of ldap client error.
+    */
+    private List<UserRole> unloadUserRoles( LDAPEntry le, String userId, String contextId )
+    {
+        List<UserRole> uRoles = null;
+        List<String> roles = getAttributes( le, GlobalIds.USER_ROLE_DATA );
+
+        if ( roles != null )
+        {
+            long sequence = 0;
+            uRoles = new ArrayList<>();
+
+            for ( String raw : roles )
+            {
+                UserRole ure = new ObjectFactory().createUserRole();
+                ure.load( raw, contextId );
+                ure.setUserId( userId );
+                ure.setSequenceId( sequence++ );
+                uRoles.add( ure );
+            }
+        }
+
+        return uRoles;
+    }
+}
\ No newline at end of file


[14/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/UserDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/UserDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/UserDAO.java
new file mode 100755
index 0000000..8f4d973
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/dao/apache/UserDAO.java
@@ -0,0 +1,2383 @@
+/*
+ *   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.apache;
+
+
+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.Attribute;
+import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
+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.LdapAttributeInUseException;
+import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
+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.LdapNoPermissionException;
+import org.apache.directory.api.ldap.model.exception.LdapNoSuchAttributeException;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.PasswordException;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.apache.directory.fortress.core.ldap.openldap.OLPWControlImpl;
+import org.apache.directory.fortress.core.rbac.Address;
+import org.apache.directory.fortress.core.rbac.AdminRole;
+import org.apache.directory.fortress.core.rbac.GlobalPwMsgIds;
+import org.apache.directory.fortress.core.rbac.OrgUnit;
+import org.apache.directory.fortress.core.rbac.PwMessage;
+import org.apache.directory.fortress.core.rbac.PwPolicyControl;
+import org.apache.directory.fortress.core.rbac.Role;
+import org.apache.directory.fortress.core.rbac.RoleUtil;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.rbac.UserAdminRole;
+import org.apache.directory.fortress.core.rbac.UserRole;
+import org.apache.directory.fortress.core.rbac.Warning;
+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;
+
+
+/**
+ * Data access class for LDAP User entity.
+ * <p/>
+ * <p/>
+ * The Fortress User LDAP schema follows:
+ * <p/>
+ * <h4>1. InetOrgPerson Structural Object Class </h4>
+ * <code># The inetOrgPerson represents people who are associated with an</code><br />
+ * <code># organization in some way.  It is a structural class and is derived</code><br />
+ * <code># from the organizationalPerson which is defined in X.521 [X521].</code><br />
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 2.16.840.1.113730.3.2.2</code>
+ * <li> <code>NAME 'inetOrgPerson'</code>
+ * <li> <code>DESC 'RFC2798: Internet Organizational Person'</code>
+ * <li> <code>SUP organizationalPerson</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MAY ( audio $ businessCategory $ carLicense $ departmentNumber $</code>
+ * <li> <code>displayName $ employeeNumber $ employeeType $ givenName $</code>
+ * <li> <code>homePhone $ homePostalAddress $ initials $ jpegPhoto $</code>
+ * <li> <code>labeledURI $ mail $ manager $ mobile $ o $ pager $ photo $</code>
+ * <li> <code>roomNumber $ secretary $ uid $ userCertificate $</code>
+ * <li> <code>x500uniqueIdentifier $ preferredLanguage $</code>
+ * <li> <code>userSMIMECertificate $ userPKCS12 ) )</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>
+ * <p/>
+ * <h4>3. ftUserAttrs is used to store user RBAC and Admin role assignment and other security attributes on User entity</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.1</code>
+ * <li> <code>NAME 'ftUserAttrs'</code>
+ * <li> <code>DESC 'Fortress User Attribute AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MUST ( ftId )</code>
+ * <li> <code>MAY ( ftRC $ ftRA $ ftARC $ ftARA $ ftCstr</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
+ * @created August 30, 2009
+ */
+public final class UserDAO extends ApacheDsDataProvider implements org.apache.directory.fortress.core.rbac.dao.UserDAO
+{
+    private static final String CLS_NM = UserDAO.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static PwPolicyControl pwControl;
+
+    /**
+     * Initialize the OpenLDAP Pw Policy validator.
+     */
+    static
+    {
+        if ( GlobalIds.IS_OPENLDAP )
+        {
+            pwControl = new OLPWControlImpl();
+        }
+    }
+
+    /*
+      *  *************************************************************************
+      *  **  OpenAccessMgr USERS STATICS
+      *  ************************************************************************
+      */
+    private static final String USERS_AUX_OBJECT_CLASS_NAME = "ftUserAttrs";
+    private static final String ORGANIZATIONAL_PERSON_OBJECT_CLASS_NAME = "organizationalPerson";
+    private static final String USER_OBJECT_CLASS = "user.objectclass";
+    private static final String USERS_EXTENSIBLE_OBJECT = "extensibleObject";
+
+    // The Fortress User entity attributes are stored within standard LDAP object classes along with custom auxiliary object classes:
+    private static final String USER_OBJ_CLASS[] =
+        {
+            GlobalIds.TOP,
+            Config.getProperty( USER_OBJECT_CLASS ),
+            USERS_AUX_OBJECT_CLASS_NAME,
+            GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME,
+            GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME,
+            USERS_EXTENSIBLE_OBJECT
+    };
+
+    private static final String objectClassImpl = Config.getProperty( USER_OBJECT_CLASS );
+    private static final String SN = "sn";
+    private static final String PW = "userpassword";
+    private static final String SYSTEM_USER = "ftSystem";
+
+    /**
+     * Constant contains the locale attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String L = "l";
+
+    /**
+     * Constant contains the postal address attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String POSTAL_ADDRESS = "postalAddress";
+
+    /**
+     * Constant contains the state attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String STATE = "st";
+
+    /**
+     * Constant contains the postal code attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String POSTAL_CODE = "postalCode";
+
+    /**
+     * Constant contains the post office box attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String POST_OFFICE_BOX = "postOfficeBox";
+
+    /**
+     * Constant contains the country attribute name used within organizationalPerson ldap object classes.
+     */
+    private static final String COUNTRY = "c";
+
+    /**
+     * Constant contains the  attribute name used within inetorgperson ldap object classes.
+     */
+    private static final String PHYSICAL_DELIVERY_OFFICE_NAME = "physicalDeliveryOfficeName";
+
+    /**
+     * Constant contains the  attribute name used within inetorgperson ldap object classes.
+     */
+    private static final String DEPARTMENT_NUMBER = "departmentNumber";
+
+    /**
+     * Constant contains the  attribute name used within inetorgperson ldap object classes.
+     */
+    private static final String ROOM_NUMBER = "roomNumber";
+
+    /**
+     * Constant contains the mobile attribute values used within iNetOrgPerson ldap object classes.
+     */
+    private static final String MOBILE = "mobile";
+
+    /**
+     * Constant contains the telephone attribute values used within organizationalPerson ldap object classes.
+     */
+    private static final String TELEPHONE_NUMBER = "telephoneNumber";
+
+    /**
+     * Constant contains the  attribute name for jpeg images to be stored within inetorgperson ldap object classes.
+     */
+    private static final String JPEGPHOTO = "jpegPhoto";
+
+    /**
+     * Constant contains the email attribute values used within iNetOrgPerson ldap object classes.
+     */
+    private static final String MAIL = "mail";
+    private static final String DISPLAY_NAME = "displayName";
+    private static final String TITLE = "title";
+    private static final String EMPLOYEE_TYPE = "employeeType";
+
+    private static final String OPENLDAP_POLICY_SUBENTRY = "pwdPolicySubentry";
+    private static final String OPENLDAP_PW_RESET = "pwdReset";
+    private static final String OPENLDAP_PW_LOCKED_TIME = "pwdAccountLockedTime";
+    private static final String OPENLDAP_ACCOUNT_LOCKED_TIME = "pwdAccountLockedTime";
+    private static final String LOCK_VALUE = "000001010000Z";
+    private static final String[] USERID =
+        { GlobalIds.UID };
+    private static final String[] ROLES =
+        { GlobalIds.USER_ROLE_ASSIGN };
+
+    private static final String[] USERID_ATRS =
+        {
+            GlobalIds.UID
+    };
+
+    // This smaller result set of attributes are needed for user validation and authentication operations.
+    private static final String[] AUTHN_ATRS =
+        {
+            GlobalIds.FT_IID,
+            GlobalIds.UID, PW,
+            GlobalIds.DESC,
+            GlobalIds.OU, GlobalIds.CN,
+            SN,
+            GlobalIds.CONSTRAINT,
+            GlobalIds.IS_OPENLDAP ? OPENLDAP_PW_RESET : null,
+            GlobalIds.IS_OPENLDAP ? OPENLDAP_PW_LOCKED_TIME : null,
+            GlobalIds.PROPS
+    };
+
+    // This default set of attributes contains all and is used for search operations.
+    private static final String[] DEFAULT_ATRS =
+        {
+            GlobalIds.FT_IID,
+            GlobalIds.UID, PW,
+            GlobalIds.DESC,
+            GlobalIds.OU,
+            GlobalIds.CN,
+            SN,
+            GlobalIds.USER_ROLE_DATA,
+            GlobalIds.CONSTRAINT,
+            GlobalIds.USER_ROLE_ASSIGN,
+            GlobalIds.IS_OPENLDAP ? OPENLDAP_PW_RESET : null,
+            GlobalIds.IS_OPENLDAP ? OPENLDAP_PW_LOCKED_TIME : null,
+            GlobalIds.IS_OPENLDAP ? OPENLDAP_POLICY_SUBENTRY : null,
+            GlobalIds.PROPS,
+            GlobalIds.USER_ADMINROLE_ASSIGN,
+            GlobalIds.USER_ADMINROLE_DATA,
+            POSTAL_ADDRESS,
+            L,
+            POSTAL_CODE,
+            POST_OFFICE_BOX,
+            STATE,
+            PHYSICAL_DELIVERY_OFFICE_NAME,
+            DEPARTMENT_NUMBER,
+            ROOM_NUMBER,
+            TELEPHONE_NUMBER,
+            MOBILE,
+            MAIL,
+            EMPLOYEE_TYPE,
+            TITLE,
+            SYSTEM_USER,
+            JPEGPHOTO
+    };
+
+    private static final String[] ROLE_ATR =
+        {
+            GlobalIds.USER_ROLE_DATA
+    };
+
+    private static final String[] AROLE_ATR =
+        {
+            GlobalIds.USER_ADMINROLE_DATA
+    };
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws CreateException
+     *
+     */
+    public final User create( User entity ) throws CreateException
+    {
+        LdapConnection ld = null;
+
+        try
+        {
+            entity.setInternalId();
+
+            String dn = getDn( entity.getUserId(), entity.getContextId() );
+
+            Entry myEntry = new DefaultEntry( dn );
+
+            myEntry.add( GlobalIds.OBJECT_CLASS, USER_OBJ_CLASS );
+            myEntry.add( GlobalIds.FT_IID, entity.getInternalId() );
+            myEntry.add( GlobalIds.UID, entity.getUserId() );
+
+            // CN is required on inetOrgPerson object class, if caller did not set, use the userId:
+            if ( !VUtil.isNotNullOrEmpty( entity.getCn() ) )
+            {
+                entity.setCn( entity.getUserId() );
+            }
+
+            myEntry.add( GlobalIds.CN, entity.getCn() );
+
+            // SN is required on inetOrgPerson object class, if caller did not set, use the userId:
+            if ( !VUtil.isNotNullOrEmpty( entity.getSn() ) )
+            {
+                entity.setSn( entity.getUserId() );
+            }
+
+            myEntry.add( SN, entity.getSn() );
+
+            // guard against npe
+            myEntry.add( PW,
+                VUtil.isNotNullOrEmpty( entity.getPassword() ) ? new String( entity.getPassword() ) : new String(
+                    new char[]
+                        {} ) );
+            myEntry.add( DISPLAY_NAME, entity.getCn() );
+
+            if ( VUtil.isNotNullOrEmpty( entity.getTitle() ) )
+            {
+                myEntry.add( TITLE, entity.getTitle() );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getEmployeeType() ) )
+            {
+                myEntry.add( EMPLOYEE_TYPE, entity.getEmployeeType() );
+            }
+
+            // These are multi-valued attributes, use the util function to load.
+            // These items are optional.  The utility function will return quietly if item list is empty:
+            loadAttrs( entity.getPhones(), myEntry, TELEPHONE_NUMBER );
+            loadAttrs( entity.getMobiles(), myEntry, MOBILE );
+            loadAttrs( entity.getEmails(), myEntry, MAIL );
+
+            // The following attributes are optional:
+            if ( VUtil.isNotNullOrEmpty( entity.isSystem() ) )
+            {
+                myEntry.add( SYSTEM_USER, entity.isSystem().toString().toUpperCase() );
+            }
+
+            if ( GlobalIds.IS_OPENLDAP && VUtil.isNotNullOrEmpty( entity.getPwPolicy() ) )
+            {
+                String pwdPolicyDn = GlobalIds.POLICY_NODE_TYPE + "=" + entity.getPwPolicy() + ","
+                    + getRootDn( entity.getContextId(), GlobalIds.PPOLICY_ROOT );
+                myEntry.add( OPENLDAP_POLICY_SUBENTRY, pwdPolicyDn );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getOu() ) )
+            {
+                myEntry.add( GlobalIds.OU, entity.getOu() );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                myEntry.add( GlobalIds.DESC, entity.getDescription() );
+            }
+
+            // props are optional as well:
+            // Add "initial" property here.
+            entity.addProperty( "init", "" );
+            loadProperties( entity.getProperties(), myEntry, GlobalIds.PROPS );
+            // map the userid to the name field in constraint:
+            entity.setName( entity.getUserId() );
+            myEntry.add( GlobalIds.CONSTRAINT, CUtil.setConstraint( entity ) );
+            loadAddress( entity.getAddress(), myEntry );
+
+            if ( VUtil.isNotNullOrEmpty( entity.getJpegPhoto() ) )
+            {
+                myEntry.add( JPEGPHOTO, entity.getJpegPhoto() );
+            }
+
+            ld = getAdminConnection();
+            add( ld, myEntry, entity );
+            entity.setDn( dn );
+        }
+        catch ( LdapException e )
+        {
+            String error = "create userId [" + entity.getUserId() + "] caught LDAPException="
+                + e.getMessage();
+            throw new CreateException( GlobalErrIds.USER_ADD_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws UpdateException
+     */
+    public final User update( User entity )
+        throws UpdateException
+    {
+        LdapConnection ld = null;
+        String userDn = getDn( entity.getUserId(), entity.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            if ( VUtil.isNotNullOrEmpty( entity.getCn() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.CN, entity.getCn() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getSn() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, SN, entity.getSn() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getOu() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.OU, entity.getOu() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getPassword() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, PW, new String( entity.getPassword() ) ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getDescription() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.DESC, entity.getDescription() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getEmployeeType() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, EMPLOYEE_TYPE, entity.getEmployeeType() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getTitle() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, TITLE, entity.getTitle() ) );
+            }
+
+            if ( GlobalIds.IS_OPENLDAP && VUtil.isNotNullOrEmpty( entity.getPwPolicy() ) )
+            {
+                String szDn = GlobalIds.POLICY_NODE_TYPE + "=" + entity.getPwPolicy() + ","
+                    + getRootDn( entity.getContextId(), GlobalIds.PPOLICY_ROOT );
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, OPENLDAP_POLICY_SUBENTRY, szDn ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.isSystem() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, SYSTEM_USER, entity.isSystem().toString().toUpperCase() ) );
+            }
+
+            if ( entity.isTemporalSet() )
+            {
+                // map the userid to the name field in constraint:
+                entity.setName( entity.getUserId() );
+                String szRawData = CUtil.setConstraint( entity );
+
+                if ( VUtil.isNotNullOrEmpty( szRawData ) )
+                {
+                    mods.add( new DefaultModification(
+                        ModificationOperation.REPLACE_ATTRIBUTE, GlobalIds.CONSTRAINT, szRawData ) );
+                }
+            }
+
+            if ( VUtil.isNotNullOrEmpty( entity.getProperties() ) )
+            {
+                loadProperties( entity.getProperties(), mods, GlobalIds.PROPS, true );
+            }
+
+            loadAddress( entity.getAddress(), mods );
+
+            // These are multi-valued attributes, use the util function to load:
+            loadAttrs( entity.getPhones(), mods, TELEPHONE_NUMBER );
+            loadAttrs( entity.getMobiles(), mods, MOBILE );
+            loadAttrs( entity.getEmails(), mods, MAIL );
+
+            if ( VUtil.isNotNullOrEmpty( entity.getJpegPhoto() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, JPEGPHOTO, entity.getJpegPhoto() ) );
+            }
+
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, userDn, mods, entity );
+                entity.setDn( userDn );
+            }
+
+            entity.setDn( userDn );
+        }
+        catch ( LdapException e )
+        {
+            String error = "update userId [" + entity.getUserId() + "] caught LDAPException="
+                + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @param replace
+     * @return
+     * @throws UpdateException
+     */
+    public final User updateProps( User entity, boolean replace )
+        throws UpdateException
+    {
+        LdapConnection ld = null;
+        String userDn = getDn( entity.getUserId(), entity.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            if ( VUtil.isNotNullOrEmpty( entity.getProperties() ) )
+            {
+                loadProperties( entity.getProperties(), mods, GlobalIds.PROPS, replace );
+            }
+
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, userDn, mods, entity );
+                entity.setDn( userDn );
+            }
+
+            entity.setDn( userDn );
+        }
+        catch ( LdapException e )
+        {
+            String error = "updateProps userId [" + entity.getUserId() + "] isReplace [" + replace
+                + "] caught LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_UPDATE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param user
+     * @throws RemoveException
+     */
+    public final String remove( User user )
+        throws RemoveException
+    {
+        LdapConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, userDn, user );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove userId [" + user.getUserId() + "] caught LDAPException="
+                + e.getMessage();
+            throw new RemoveException( GlobalErrIds.USER_DELETE_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param user
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    public final void lock( User user ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, OPENLDAP_PW_LOCKED_TIME,
+                LOCK_VALUE ) );
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, user );
+        }
+        catch ( LdapException e )
+        {
+            String error = "lock user [" + user.getUserId() + "] caught LDAPException="
+                + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_PW_LOCK_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param user
+     * @throws UpdateException
+     *
+     */
+    public final void unlock( User user )
+        throws UpdateException
+    {
+        LdapConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            //ld = getAdminConnection();
+            List<Modification> mods = new ArrayList<Modification>();
+
+            mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, OPENLDAP_PW_LOCKED_TIME ) );
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, user );
+        }
+        catch ( LdapNoSuchAttributeException e )
+        {
+            LOG.info( "unlock user [" + user.getUserId() + "] no such attribute:"
+                + OPENLDAP_ACCOUNT_LOCKED_TIME );
+        }
+        catch ( LdapException e )
+        {
+            String error = "unlock user [" + user.getUserId() + "] caught LDAPException= "
+                + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_PW_UNLOCK_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final User getUser( User user, boolean isRoles )
+        throws FinderException
+    {
+        User entity = null;
+        LdapConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        String[] uATTRS;
+        // Retrieve role attributes?
+
+        if ( isRoles )
+        {
+            // Retrieve the User's assigned RBAC and Admin Role attributes from directory.
+            uATTRS = DEFAULT_ATRS;
+
+        }
+        else
+        {
+            // Do not retrieve the User's assigned RBAC and Admin Role attributes from directory.
+            uATTRS = AUTHN_ATRS;
+        }
+
+        Entry findEntry = null;
+
+        try
+        {
+            ld = getAdminConnection();
+            findEntry = read( ld, userDn, uATTRS );
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getUser COULD NOT FIND ENTRY for user [" + user.getUserId() + "]";
+            throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getUser [" + userDn + "]= caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        try
+        {
+            if(findEntry != null)
+            {
+                entity = unloadLdapEntry( findEntry, 0, user.getContextId() );
+            }
+        }
+        catch ( LdapInvalidAttributeValueException e )
+        {
+            entity = null;
+        }
+
+        if ( entity == null )
+        {
+            String warning = "getUser userId [" + user.getUserId() + "] not found, Fortress rc="
+                + GlobalErrIds.USER_NOT_FOUND;
+            throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     */
+    public final List<UserAdminRole> getUserAdminRoles( User user )
+        throws FinderException
+    {
+        List<UserAdminRole> roles = null;
+        LdapConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, userDn, AROLE_ATR );
+            roles = unloadUserAdminRoles( findEntry, user.getUserId(), user.getContextId() );
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getUserAdminRoles COULD NOT FIND ENTRY for user [" + user.getUserId() + "]";
+            throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getUserAdminRoles [" + userDn + "]= caught LDAPException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return roles;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    public final List<String> getRoles( User user )
+        throws FinderException
+    {
+        List<String> roles = null;
+        LdapConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, userDn, ROLES );
+
+            if ( findEntry == null )
+            {
+                String warning = "getRoles userId [" + user.getUserId() + "] not found, Fortress rc="
+                    + GlobalErrIds.USER_NOT_FOUND;
+                throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+            }
+
+            roles = getAttributes( findEntry, GlobalIds.USER_ROLE_ASSIGN );
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getRoles COULD NOT FIND ENTRY for user [" + user.getUserId() + "]";
+            throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getRoles [" + userDn + "]= caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return roles;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     * @throws org.apache.directory.fortress.core.SecurityException
+     */
+    public final Session checkPassword( User user ) throws FinderException
+    {
+        Session session = null;
+        LdapConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            session = new ObjectFactory().createSession();
+            session.setUserId( user.getUserId() );
+            ld = getUserConnection();
+            boolean result = bind( ld, userDn, user.getPassword() );
+
+            if ( result )
+            {
+                // check openldap password policies here
+                checkPwPolicies( ld, session );
+
+                if ( session.getErrorId() == 0 )
+                {
+                    session.setAuthenticated( true );
+                }
+            }
+        }
+        catch ( LdapAuthenticationException e )
+        {
+            // Check controls to see if password is locked, expired or out of grace:
+            checkPwPolicies( ld, session );
+            // if check pw control did not find problem the user entered invalid pw:
+            if ( session.getErrorId() == 0 )
+            {
+                String info = "checkPassword INVALID PASSWORD for userId [" + user.getUserId() + "]";
+                session.setMsg( info );
+                session.setErrorId( GlobalErrIds.USER_PW_INVLD );
+                session.setAuthenticated( false );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "checkPassword userId [" + user.getUserId() + "] caught LDAPException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeUserConnection( ld );
+        }
+
+        return session;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws FinderException
+     */
+    public final List<User> findUsers( User user ) throws FinderException
+    {
+        List<User> userList = new ArrayList<>();
+        LdapConnection ld = null;
+        String userRoot = getRootDn( user.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String filter;
+
+            if ( VUtil.isNotNullOrEmpty( user.getUserId() ) )
+            {
+                // place a wild card after the input userId:
+                String searchVal = encodeSafeText( user.getUserId(), GlobalIds.USERID_LEN );
+                filter = GlobalIds.FILTER_PREFIX + objectClassImpl + ")("
+                    + GlobalIds.UID + "=" + searchVal + "*))";
+            }
+            else if ( VUtil.isNotNullOrEmpty( user.getInternalId() ) )
+            {
+                // internalUserId search
+                String searchVal = encodeSafeText( user.getInternalId(), GlobalIds.USERID_LEN );
+                // this is not a wildcard search. Must be exact match.
+                filter = GlobalIds.FILTER_PREFIX + objectClassImpl + ")("
+                    + GlobalIds.FT_IID + "=" + searchVal + "))";
+            }
+            else
+            {
+                // Beware - returns ALL users!!:"
+                filter = "(objectclass=" + objectClassImpl + ")";
+            }
+
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, userRoot,
+                SearchScope.ONELEVEL, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                userList.add( unloadLdapEntry( searchResults.getEntry(), sequence++, user.getContextId() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String warning = "findUsers userRoot [" + userRoot + "] caught LDAPException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        catch ( CursorException e )
+        {
+            String warning = "findUsers userRoot [" + userRoot + "] caught LDAPException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param user
+     * @param limit
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final List<String> findUsers( User user, int limit ) throws FinderException
+    {
+        List<String> userList = new ArrayList<>();
+        LdapConnection ld = null;
+        String userRoot = getRootDn( user.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String searchVal = encodeSafeText( user.getUserId(), GlobalIds.USERID_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + objectClassImpl + ")("
+                + GlobalIds.UID + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, userRoot,
+                SearchScope.ONELEVEL, filter, USERID, false, GlobalIds.BATCH_SIZE, limit );
+
+            while ( searchResults.next() )
+            {
+                Entry entry = searchResults.getEntry();
+                userList.add( getAttribute( entry, GlobalIds.UID ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String warning = "findUsers caught LdapException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        catch ( CursorException e )
+        {
+            String warning = "findUsers caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final List<User> getAuthorizedUsers( Role role ) throws FinderException
+    {
+        List<User> userList = new ArrayList<>();
+        LdapConnection ld = null;
+        String userRoot = getRootDn( role.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String roleVal = encodeSafeText( role.getName(), GlobalIds.USERID_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + USERS_AUX_OBJECT_CLASS_NAME + ")(";
+            Set<String> roles = RoleUtil.getDescendants( role.getName(), role.getContextId() );
+
+            if ( VUtil.isNotNullOrEmpty( roles ) )
+            {
+                filter += "|(" + GlobalIds.USER_ROLE_ASSIGN + "=" + roleVal + ")";
+
+                for ( String uRole : roles )
+                {
+                    filter += "(" + GlobalIds.USER_ROLE_ASSIGN + "=" + uRole + ")";
+                }
+
+                filter += ")";
+            }
+            else
+            {
+                filter += GlobalIds.USER_ROLE_ASSIGN + "=" + roleVal + ")";
+            }
+
+            filter += ")";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, userRoot,
+                SearchScope.ONELEVEL, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                userList.add( unloadLdapEntry( searchResults.getEntry(), sequence++, role.getContextId() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String warning = "getAuthorizedUsers role name [" + role.getName() + "] caught LDAPException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        catch ( CursorException e )
+        {
+            String warning = "getAuthorizedUsers role name [" + role.getName() + "] caught LDAPException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws FinderException
+     */
+    public final List<User> getAssignedUsers( Role role )
+        throws FinderException
+    {
+        List<User> userList = new ArrayList<>();
+        LdapConnection ld = null;
+        String userRoot = getRootDn( role.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String roleVal = encodeSafeText( role.getName(), GlobalIds.USERID_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + USERS_AUX_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.USER_ROLE_ASSIGN + "=" + roleVal + "))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, userRoot,
+                SearchScope.ONELEVEL, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                userList.add( unloadLdapEntry( searchResults.getEntry(), sequence++, role.getContextId() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String warning = "getAssignedUsers role name [" + role.getName() + "] caught LDAPException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        catch ( CursorException e )
+        {
+            String warning = "getAssignedUsers role name [" + role.getName() + "] caught LDAPException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     *
+     * @param roles
+     * @return
+     * @throws FinderException
+     */
+    public final Set<String> getAssignedUsers( Set<String> roles, String contextId )
+        throws FinderException
+    {
+        Set<String> userSet = new HashSet<>();
+        LdapConnection ld = null;
+        String userRoot = getRootDn( contextId, GlobalIds.USER_ROOT );
+
+        try
+        {
+            String filter = GlobalIds.FILTER_PREFIX + USERS_AUX_OBJECT_CLASS_NAME + ")(|";
+
+            if ( VUtil.isNotNullOrEmpty( roles ) )
+            {
+                for ( String roleVal : roles )
+                {
+                    String filteredVal = encodeSafeText( roleVal, GlobalIds.USERID_LEN );
+                    filter += "(" + GlobalIds.USER_ROLE_ASSIGN + "=" + filteredVal + ")";
+                }
+            }
+            else
+            {
+                return null;
+            }
+
+            filter += "))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, userRoot,
+                SearchScope.ONELEVEL, filter, USERID_ATRS, false, GlobalIds.BATCH_SIZE );
+
+            while ( searchResults.next() )
+            {
+                userSet.add( getAttribute( searchResults.getEntry(), GlobalIds.UID ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String warning = "getAssignedUsers caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        catch ( CursorException e )
+        {
+            String warning = "getAssignedUsers caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userSet;
+    }
+
+
+    /**
+     * @param role
+     * @return
+     * @throws FinderException
+     */
+    public final List<User> getAssignedUsers( AdminRole role )
+        throws FinderException
+    {
+        List<User> userList = new ArrayList<>();
+        LdapConnection ld = null;
+        String userRoot = getRootDn( role.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String roleVal = encodeSafeText( role.getName(), GlobalIds.USERID_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + USERS_AUX_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.USER_ADMINROLE_ASSIGN + "=" + roleVal + "))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, userRoot,
+                SearchScope.ONELEVEL, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                userList.add( unloadLdapEntry( searchResults.getEntry(), sequence++, role.getContextId() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String warning = "getAssignedUsers admin role name [" + role.getName()
+                + "] caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_USER_SEARCH_FAILED, warning, e );
+        }
+        catch ( CursorException e )
+        {
+            String warning = "getAssignedUsers admin role name [" + role.getName()
+                + "] caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_USER_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param role
+     * @param limit
+     * @return
+     * @throws FinderException
+     *
+     */
+    public final List<String> getAuthorizedUsers( Role role, int limit )
+        throws FinderException
+    {
+        List<String> userList = new ArrayList<>();
+        LdapConnection ld = null;
+        String userRoot = getRootDn( role.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String roleVal = encodeSafeText( role.getName(), GlobalIds.USERID_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + USERS_AUX_OBJECT_CLASS_NAME + ")("
+                + GlobalIds.USER_ROLE_ASSIGN + "=" + roleVal + "))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, userRoot,
+                SearchScope.ONELEVEL, filter, USERID, false, GlobalIds.BATCH_SIZE, limit );
+
+            while ( searchResults.next() )
+            {
+                Entry entry = searchResults.getEntry();
+                userList.add( getAttribute( entry, GlobalIds.UID ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String warning = "getAuthorizedUsers role name [" + role.getName() + "] caught LDAPException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        catch ( CursorException e )
+        {
+            String warning = "getAuthorizedUsers role name [" + role.getName() + "] caught LDAPException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.URLE_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param searchVal
+     * @return
+     * @throws FinderException
+     */
+    public final List<String> findUsersList( String searchVal, String contextId )
+        throws FinderException
+    {
+        List<String> userList = new ArrayList<>();
+        LdapConnection ld = null;
+        String userRoot = getRootDn( contextId, GlobalIds.USER_ROOT );
+
+        try
+        {
+            searchVal = encodeSafeText( searchVal, GlobalIds.USERID_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + objectClassImpl + ")("
+                + GlobalIds.UID + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, userRoot,
+                SearchScope.ONELEVEL, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                userList.add( ( unloadLdapEntry( searchResults.getEntry(), sequence++, contextId ) ).getUserId() );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String warning = "findUsersList caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        catch ( CursorException e )
+        {
+            String warning = "findUsersList caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param ou
+     * @return
+     * @throws FinderException
+     */
+    public final List<User> findUsers( OrgUnit ou, boolean limitSize )
+        throws FinderException
+    {
+        List<User> userList = new ArrayList<>();
+        LdapConnection ld = null;
+        String userRoot = getRootDn( ou.getContextId(), GlobalIds.USER_ROOT );
+
+        try
+        {
+            String szOu = encodeSafeText( ou.getName(), GlobalIds.OU_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + objectClassImpl + ")("
+                + GlobalIds.OU + "=" + szOu + "))";
+            int maxLimit;
+
+            if ( limitSize )
+            {
+                maxLimit = 10;
+            }
+            else
+            {
+                maxLimit = 0;
+            }
+
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, userRoot,
+                SearchScope.ONELEVEL, filter, DEFAULT_ATRS, false, GlobalIds.BATCH_SIZE, maxLimit );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                userList.add( unloadLdapEntry( searchResults.getEntry(), sequence++, ou.getContextId() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String warning = "findUsers caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        catch ( CursorException e )
+        {
+            String warning = "findUsers caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_SEARCH_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userList;
+    }
+
+
+    /**
+     * @param entity
+     * @param newPassword
+     * @return
+     * @throws UpdateException
+     *
+     * @throws SecurityException
+     * @throws PasswordException 
+     */
+    public final boolean changePassword( User entity, char[] newPassword ) throws SecurityException
+    {
+        boolean rc = true;
+        LdapConnection ld = null;
+        List<Modification> mods;
+        String userDn = getDn( entity.getUserId(), entity.getContextId() );
+
+        try
+        {
+            ld = getUserConnection();
+            bind( ld, userDn, entity.getPassword() );
+            mods = new ArrayList<Modification>();
+
+            mods.add( new DefaultModification(
+                ModificationOperation.REPLACE_ATTRIBUTE, PW, new String( newPassword ) ) );
+
+            modify( ld, userDn, mods );
+
+            // The 2nd modify is to update audit attributes on the User entry:
+            if ( GlobalIds.IS_AUDIT && ( entity.getAdminSession() != null ) )
+            {
+                // Because the user modified their own password, set their userId here:
+                //(entity.getAdminSession()).setInternalUserId(entity.getUserId());
+                mods = new ArrayList<Modification>();
+                modify( ld, userDn, mods, entity );
+            }
+        }
+        catch ( LdapInvalidAttributeValueException e )
+        {
+            String warning = User.class.getName() + ".changePassword user [" + entity.getUserId() + "] ";
+
+            warning += " constraint violation, ldap rc=" + e.getMessage()
+                + " Fortress rc=" + GlobalErrIds.PSWD_CONST_VIOLATION;
+
+            throw new PasswordException( GlobalErrIds.PSWD_CONST_VIOLATION, warning );
+        }
+        catch ( LdapNoPermissionException e )
+        {
+            String warning = User.class.getName() + ".changePassword user [" + entity.getUserId() + "] ";
+            warning += " user not authorized to change password, ldap rc=" + e.getMessage() + " Fortress rc="
+                + GlobalErrIds.USER_PW_MOD_NOT_ALLOWED;
+            throw new UpdateException( GlobalErrIds.USER_PW_MOD_NOT_ALLOWED, warning );
+        }
+        catch ( LdapException e )
+        {
+            String warning = User.class.getName() + ".changePassword user [" + entity.getUserId() + "] ";
+            warning += " caught LDAPException rc=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_PW_CHANGE_FAILED, warning, e );
+        }
+        finally
+        {
+            closeUserConnection( ld );
+        }
+
+        return rc;
+    }
+
+
+    /**
+     * @param user
+     * @throws UpdateException
+     *
+     */
+    public final void resetUserPassword( User user ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            mods.add( new DefaultModification(
+                ModificationOperation.REPLACE_ATTRIBUTE, PW, new String( user.getPassword() ) ) );
+
+            mods.add( new DefaultModification(
+                ModificationOperation.REPLACE_ATTRIBUTE, OPENLDAP_PW_RESET, "TRUE" ) );
+
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, user );
+        }
+        catch ( LdapException e )
+        {
+            String warning = "resetUserPassword userId [" + user.getUserId() + "] caught LDAPException="
+                + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_PW_RESET_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param uRole
+     * @return
+     * @throws UpdateException
+     *
+     * @throws FinderException
+     *
+     */
+    public final String assign( UserRole uRole ) throws UpdateException, FinderException
+    {
+        LdapConnection ld = null;
+        String userDn = getDn( uRole.getUserId(), uRole.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            String szUserRole = uRole.getRawData();
+
+            mods.add( new DefaultModification(
+                ModificationOperation.ADD_ATTRIBUTE, GlobalIds.USER_ROLE_DATA, szUserRole ) );
+
+            mods.add( new DefaultModification(
+                ModificationOperation.ADD_ATTRIBUTE, GlobalIds.USER_ROLE_ASSIGN, uRole.getName() ) );
+
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, uRole );
+        }
+        catch ( LdapAttributeInUseException e )
+        {
+            String warning = "assign userId [" + uRole.getUserId() + "] name [" + uRole.getName() + "] ";
+
+            warning += "assignment already exists.";
+            throw new FinderException( GlobalErrIds.URLE_ASSIGN_EXIST, warning );
+        }
+        catch ( LdapException e )
+        {
+            String warning = "assign userId [" + uRole.getUserId() + "] name [" + uRole.getName() + "] ";
+
+            warning += "caught LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.URLE_ASSIGN_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param uRole
+     * @return
+     * @throws UpdateException
+     *
+     * @throws FinderException
+     *
+     */
+    public final String deassign( UserRole uRole )
+        throws UpdateException, FinderException
+    {
+        LdapConnection ld = null;
+        String userDn = getDn( uRole.getUserId(), uRole.getContextId() );
+
+        try
+        {
+            // read the user's RBAC role assignments to locate target record.  Need the raw data before attempting removal:
+            List<UserRole> roles = getUserRoles( uRole.getUserId(), uRole.getContextId() );
+            int indx = -1;
+
+            // Does the user have any roles assigned?
+            if ( roles != null )
+            {
+                // function call will set indx to -1 if name not found:
+                indx = roles.indexOf( uRole );
+
+                // Is the targeted name assigned to user?
+                if ( indx > -1 )
+                {
+                    // Retrieve the targeted name:
+                    UserRole fRole = roles.get( indx );
+                    // delete the name assignment attribute using the raw name data:
+                    List<Modification> mods = new ArrayList<Modification>();
+
+                    mods.add( new DefaultModification(
+                        ModificationOperation.REMOVE_ATTRIBUTE,
+                        GlobalIds.USER_ROLE_DATA, fRole.getRawData() ) );
+
+                    mods.add( new DefaultModification(
+                        ModificationOperation.REMOVE_ATTRIBUTE,
+                        GlobalIds.USER_ROLE_ASSIGN, fRole.getName() ) );
+                    ld = getAdminConnection();
+                    modify( ld, userDn, mods, uRole );
+                }
+            }
+            // target name not found:
+            if ( indx == -1 )
+            {
+                // The user does not have the target name assigned,
+                String warning = "deassign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                    + "] assignment does not exist.";
+                throw new FinderException( GlobalErrIds.URLE_ASSIGN_NOT_EXIST, warning );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String warning = "deassign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                + "] caught LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.URLE_DEASSIGN_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param uRole
+     * @return
+     * @throws UpdateException
+     *
+     * @throws FinderException
+     *
+     */
+    public final String assign( UserAdminRole uRole ) throws UpdateException, FinderException
+    {
+        LdapConnection ld = null;
+        String userDn = getDn( uRole.getUserId(), uRole.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            String szUserRole = uRole.getRawData();
+            mods.add( new DefaultModification(
+                ModificationOperation.ADD_ATTRIBUTE,
+                GlobalIds.USER_ADMINROLE_DATA, szUserRole ) );
+
+            mods.add( new DefaultModification(
+                ModificationOperation.ADD_ATTRIBUTE,
+                GlobalIds.USER_ADMINROLE_ASSIGN, uRole.getName() ) );
+
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, uRole );
+        }
+        catch ( LdapAttributeInUseException e )
+        {
+            String warning = "assign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                + "] assignment already exists.";
+            throw new FinderException( GlobalErrIds.ARLE_ASSIGN_EXIST, warning );
+        }
+        catch ( LdapException e )
+        {
+            String warning = "assign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                + "] caught LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ARLE_ASSIGN_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param uRole
+     * @return
+     * @throws UpdateException
+     *
+     * @throws FinderException
+     *
+     */
+    public final String deassign( UserAdminRole uRole )
+        throws UpdateException, FinderException
+    {
+        LdapConnection ld = null;
+        String userDn = getDn( uRole.getUserId(), uRole.getContextId() );
+
+        try
+        {
+            // read the user's ARBAC roles to locate record.  Need the raw data before attempting removal:
+            User user = new User( uRole.getUserId() );
+            user.setContextId( uRole.getContextId() );
+            List<UserAdminRole> roles = getUserAdminRoles( user );
+
+            int indx = -1;
+
+            // Does the user have any roles assigned?
+            if ( roles != null )
+            {
+                // function call will set index to -1 if name not found:
+                indx = roles.indexOf( uRole );
+
+                // Is the targeted name assigned to user?
+                if ( indx > -1 )
+                {
+                    // Retrieve the targeted name:
+                    UserRole fRole = roles.get( indx );
+                    // delete the name assignment attribute using the raw name data:
+                    List<Modification> mods = new ArrayList<Modification>();
+
+                    mods.add( new DefaultModification(
+                        ModificationOperation.REMOVE_ATTRIBUTE, GlobalIds.USER_ADMINROLE_DATA, fRole.getRawData() ) );
+
+                    mods.add( new DefaultModification(
+                        ModificationOperation.REMOVE_ATTRIBUTE, GlobalIds.USER_ADMINROLE_ASSIGN, fRole.getName() ) );
+
+                    ld = getAdminConnection();
+                    modify( ld, userDn, mods, uRole );
+                }
+            }
+
+            // target name not found:
+            if ( indx == -1 )
+            {
+                // The user does not have the target name assigned,
+                String warning = "deassign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                    + "] assignment does not exist.";
+                throw new FinderException( GlobalErrIds.ARLE_DEASSIGN_NOT_EXIST, warning );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String warning = "deassign userId [" + uRole.getUserId() + "] name [" + uRole.getName()
+                + "] caught LDAPException=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.ARLE_DEASSIGN_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param user
+     * @return
+     * @throws UpdateException 
+     * @throws Exception 
+     *
+     */
+    public final String deletePwPolicy( User user ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        String userDn = getDn( user.getUserId(), user.getContextId() );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, OPENLDAP_POLICY_SUBENTRY ) );
+            ld = getAdminConnection();
+            modify( ld, userDn, mods, user );
+        }
+        catch ( LdapException e )
+        {
+            String warning = "deletePwPolicy userId [" + user.getUserId() + "] caught LDAPException="
+                + e.getMessage() + " msg=" + e.getMessage();
+            throw new UpdateException( GlobalErrIds.USER_PW_PLCY_DEL_FAILED, warning, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return userDn;
+    }
+
+
+    /**
+     * @param entry
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     */
+    private User unloadLdapEntry( Entry entry, long sequence, String contextId )
+        throws LdapInvalidAttributeValueException
+    {
+        User entity = new ObjectFactory().createUser();
+        entity.setSequenceId( sequence );
+        entity.setInternalId( getAttribute( entry, GlobalIds.FT_IID ) );
+        entity.setDescription( getAttribute( entry, GlobalIds.DESC ) );
+        entity.setUserId( getAttribute( entry, GlobalIds.UID ) );
+        entity.setCn( getAttribute( entry, GlobalIds.CN ) );
+        entity.setName( entity.getCn() );
+        entity.setSn( getAttribute( entry, SN ) );
+        entity.setOu( getAttribute( entry, GlobalIds.OU ) );
+        entity.setDn( entry.getDn().getName() );
+        entity.setTitle( getAttribute( entry, TITLE ) );
+        entity.setEmployeeType( getAttribute( entry, EMPLOYEE_TYPE ) );
+        unloadTemporal( entry, entity );
+        entity.setRoles( unloadUserRoles( entry, entity.getUserId(), contextId ) );
+        entity.setAdminRoles( unloadUserAdminRoles( entry, entity.getUserId(), contextId ) );
+        entity.setAddress( unloadAddress( entry ) );
+        entity.setPhones( getAttributes( entry, TELEPHONE_NUMBER ) );
+        entity.setMobiles( getAttributes( entry, MOBILE ) );
+        entity.setEmails( getAttributes( entry, MAIL ) );
+        String szBoolean = getAttribute( entry, SYSTEM_USER );
+        if ( szBoolean != null )
+        {
+            entity.setSystem( Boolean.valueOf( szBoolean ) );
+        }
+
+        entity.addProperties( AttrHelper.getProperties( getAttributes( entry, GlobalIds.PROPS ) ) );
+
+        if ( GlobalIds.IS_OPENLDAP )
+        {
+            szBoolean = getAttribute( entry, OPENLDAP_PW_RESET );
+            if ( szBoolean != null && szBoolean.equalsIgnoreCase( "true" ) )
+            {
+                entity.setReset( true );
+            }
+            String szPolicy = getAttribute( entry, OPENLDAP_POLICY_SUBENTRY );
+            if ( VUtil.isNotNullOrEmpty( szPolicy ) )
+            {
+                entity.setPwPolicy( getRdn( szPolicy ) );
+            }
+
+            szBoolean = getAttribute( entry, OPENLDAP_PW_LOCKED_TIME );
+
+            if ( szBoolean != null && szBoolean.equals( LOCK_VALUE ) )
+            {
+                entity.setLocked( true );
+            }
+        }
+
+        entity.setJpegPhoto( getPhoto( entry, JPEGPHOTO ) );
+
+        return entity;
+    }
+
+
+    /**
+     * @param userId
+     * @return
+     * @throws FinderException
+     */
+    private List<UserRole> getUserRoles( String userId, String contextId )
+        throws FinderException
+    {
+        List<UserRole> roles = null;
+        LdapConnection ld = null;
+        String userDn = getDn( userId, contextId );
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, userDn, ROLE_ATR );
+            roles = unloadUserRoles( findEntry, userId, contextId );
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "getUserRoles COULD NOT FIND ENTRY for user [" + userId + "]";
+            throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "getUserRoles [" + userDn + "]= caught LDAPException=" + e.getMessage();
+            throw new FinderException( GlobalErrIds.USER_READ_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return roles;
+    }
+
+
+    /**
+     * @param ld
+     * @param pwMsg
+     */
+    private void checkPwPolicies( LdapConnection ld, PwMessage pwMsg )
+    {
+        int rc = 0;
+        boolean success = false;
+        String msgHdr = "checkPwPolicies for userId [" + pwMsg.getUserId() + "] ";
+
+        if ( ld != null )
+        {
+            if ( !GlobalIds.IS_OPENLDAP )
+            {
+                String msg = msgHdr + "OPENLDAP PW POLICY NOT ENABLED";
+                pwMsg.setWarning( new ObjectFactory().createWarning( GlobalPwMsgIds.NOT_OLPW_POLICY_ENABLED, msg, Warning.Type.PASSWORD ) );
+                pwMsg.setErrorId( GlobalPwMsgIds.GOOD );
+                LOG.debug( msg );
+                return;
+            }
+            else if ( pwControl != null )
+            {
+                // ------------> pwControl.checkPasswordPolicy( ld, success, pwMsg );
+            }
+
+            // OpenLDAP has notified of password violation:
+            if ( pwMsg.getErrorId() > 0 )
+            {
+                String errMsg;
+
+                switch ( pwMsg.getErrorId() )
+                {
+
+                    case GlobalPwMsgIds.CHANGE_AFTER_RESET:
+                        // Don't throw exception if authenticating in J2EE Realm - The Web application must give user a chance to modify their password.
+                        if ( !GlobalIds.IS_REALM )
+                        {
+                            errMsg = msgHdr + "PASSWORD HAS BEEN RESET BY LDAP_ADMIN_POOL_UID";
+                            rc = GlobalErrIds.USER_PW_RESET;
+                        }
+                        else
+                        {
+                            errMsg = msgHdr
+                                + "PASSWORD HAS BEEN RESET BY LDAP_ADMIN_POOL_UID BUT ALLOWING TO CONTINUE DUE TO REALM";
+                            success = true;
+                            pwMsg.setWarning( new ObjectFactory().createWarning( GlobalErrIds.USER_PW_RESET, errMsg, Warning.Type.PASSWORD ) );
+                        }
+
+                        break;
+
+                    case GlobalPwMsgIds.ACCOUNT_LOCKED:
+                        errMsg = msgHdr + "ACCOUNT HAS BEEN LOCKED";
+                        rc = GlobalErrIds.USER_PW_LOCKED;
+                        break;
+
+                    case GlobalPwMsgIds.PASSWORD_HAS_EXPIRED:
+                        errMsg = msgHdr + "PASSWORD HAS EXPIRED";
+                        rc = GlobalErrIds.USER_PW_EXPIRED;
+                        break;
+
+                    case GlobalPwMsgIds.NO_MODIFICATIONS:
+                        errMsg = msgHdr + "PASSWORD MOD NOT ALLOWED";
+                        rc = GlobalErrIds.USER_PW_MOD_NOT_ALLOWED;
+                        break;
+
+                    case GlobalPwMsgIds.MUST_SUPPLY_OLD:
+                        errMsg = msgHdr + "MUST SUPPLY OLD PASSWORD";
+                        rc = GlobalErrIds.USER_PW_MUST_SUPPLY_OLD;
+                        break;
+
+                    case GlobalPwMsgIds.INSUFFICIENT_QUALITY:
+                        errMsg = msgHdr + "PASSWORD QUALITY VIOLATION";
+                        rc = GlobalErrIds.USER_PW_NSF_QUALITY;
+                        break;
+
+                    case GlobalPwMsgIds.PASSWORD_TOO_SHORT:
+                        errMsg = msgHdr + "PASSWORD TOO SHORT";
+                        rc = GlobalErrIds.USER_PW_TOO_SHORT;
+                        break;
+
+                    case GlobalPwMsgIds.PASSWORD_TOO_YOUNG:
+                        errMsg = msgHdr + "PASSWORD TOO YOUNG";
+                        rc = GlobalErrIds.USER_PW_TOO_YOUNG;
+                        break;
+
+                    case GlobalPwMsgIds.HISTORY_VIOLATION:
+                        errMsg = msgHdr + "PASSWORD IN HISTORY VIOLATION";
+                        rc = GlobalErrIds.USER_PW_IN_HISTORY;
+                        break;
+
+                    default:
+                        errMsg = msgHdr + "PASSWORD CHECK FAILED";
+                        rc = GlobalErrIds.USER_PW_CHK_FAILED;
+                        break;
+                }
+
+                pwMsg.setMsg( errMsg );
+                pwMsg.setErrorId( rc );
+                pwMsg.setAuthenticated( success );
+                LOG.debug( errMsg );
+            }
+            else
+            {
+                // Checked out good:
+                String msg = msgHdr + "PASSWORD CHECK SUCCESS";
+                pwMsg.setMsg( msg );
+                pwMsg.setErrorId( 0 );
+                pwMsg.setAuthenticated( true );
+                LOG.debug( msg );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of ARBAC roles, {@link UserAdminRole}, convert to raw data format and load into ldap attribute set in preparation for ldap add.
+     *
+     * @param list  contains List of type {@link UserAdminRole} targeted for adding to ldap.
+     * @param entry collection of ldap attributes containing ARBAC role assignments in raw ldap format.
+     * @throws LdapException 
+     */
+    private void loadUserAdminRoles( List<UserAdminRole> list, Entry entry ) throws LdapException
+    {
+        if ( list != null )
+        {
+            Attribute userAdminRoleData = new DefaultAttribute( GlobalIds.USER_ADMINROLE_DATA );
+            Attribute userAdminRoleAssign = new DefaultAttribute( GlobalIds.USER_ADMINROLE_ASSIGN );
+
+            for ( UserAdminRole userRole : list )
+            {
+                userAdminRoleData.add( userRole.getRawData() );
+                userAdminRoleAssign.add( userRole.getName() );
+            }
+
+            if ( userAdminRoleData.size() != 0 )
+            {
+                entry.add( userAdminRoleData );
+                entry.add( userAdminRoleAssign );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of RBAC roles, {@link UserRole}, convert to raw data format and load into ldap modification set in preparation for ldap modify.
+     *
+     * @param list contains List of type {@link UserRole} targeted for updating into ldap.
+     * @param mods contains ldap modification set containing RBAC role assignments in raw ldap format to be updated.
+     * @throws LdapInvalidAttributeValueException 
+     */
+    private void loadUserRoles( List<UserRole> list, List<Modification> mods )
+        throws LdapInvalidAttributeValueException
+    {
+        Attribute userRoleData = new DefaultAttribute( GlobalIds.USER_ROLE_DATA );
+        Attribute userRoleAssign = new DefaultAttribute( GlobalIds.USER_ROLE_ASSIGN );
+
+        if ( list != null )
+        {
+            for ( UserRole userRole : list )
+            {
+                userRoleData.add( userRole.getRawData() );
+                userRoleAssign.add( userRole.getName() );
+            }
+
+            if ( userRoleData.size() != 0 )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, userRoleData ) );
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, userRoleAssign ) );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of ARBAC roles, {@link UserAdminRole}, convert to raw data format and load into ldap modification set in preparation for ldap modify.
+     *
+     * @param list contains List of type {@link UserAdminRole} targeted for updating to ldap.
+     * @param mods contains ldap modification set containing ARBAC role assignments in raw ldap format to be updated.
+     * @throws LdapInvalidAttributeValueException 
+     */
+    private void loadUserAdminRoles( List<UserAdminRole> list, List<Modification> mods )
+        throws LdapInvalidAttributeValueException
+    {
+        Attribute userAdminRoleData = new DefaultAttribute( GlobalIds.USER_ADMINROLE_DATA );
+        Attribute userAdminRoleAssign = new DefaultAttribute( GlobalIds.USER_ADMINROLE_ASSIGN );
+
+        if ( list != null )
+        {
+            boolean nameSeen = false;
+
+            for ( UserAdminRole userRole : list )
+            {
+                userAdminRoleData.add( userRole.getRawData() );
+
+                if ( !nameSeen )
+                {
+                    userAdminRoleAssign.add( userRole.getName() );
+                    nameSeen = true;
+                }
+            }
+
+            if ( userAdminRoleData.size() != 0 )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, userAdminRoleData ) );
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, userAdminRoleAssign ) );
+            }
+        }
+    }
+
+
+    /**
+     * Given a collection of RBAC roles, {@link UserRole}, convert to raw data format and load into ldap attribute set in preparation for ldap add.
+     *
+     * @param list  contains List of type {@link UserRole} targeted for adding to ldap.
+     * @param entry ldap entry containing attributes mapping to RBAC role assignments in raw ldap format.
+     * @throws LdapException 
+     */
+    private void loadUserRoles( List<UserRole> list, Entry entry ) throws LdapException
+    {
+        if ( list != null )
+        {
+            Attribute userRoleData = new DefaultAttribute( GlobalIds.USER_ROLE_DATA );
+            Attribute userRoleAssign = new DefaultAttribute( GlobalIds.USER_ROLE_ASSIGN );
+
+            for ( UserRole userRole : list )
+            {
+                userRoleData.add( userRole.getRawData() );
+                userRoleAssign.add( userRole.getName() );
+            }
+
+            if ( userRoleData.size() != 0 )
+            {
+                entry.add( userRoleData, userRoleAssign );
+            }
+        }
+    }
+
+
+    /**
+     * Given a User address, {@link Address}, load into ldap attribute set in preparation for ldap add.
+     *
+     * @param address  contains User address {@link Address} targeted for adding to ldap.
+     * @param entry collection of ldap attributes containing RBAC role assignments in raw ldap format.
+     */
+    private void loadAddress( Address address, Entry entry ) throws LdapException
+    {
+        if ( address != null )
+        {
+            if ( VUtil.isNotNullOrEmpty( address.getAddresses() ) )
+            {
+                for ( String val : address.getAddresses() )
+                {
+                    entry.add( POSTAL_ADDRESS, val );
+                }
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getCity() ) )
+            {
+                entry.add( L, address.getCity() );
+            }
+
+            //if(VUtil.isNotNullOrEmpty(address.getCountry()))
+            //{
+            //    attrs.add(GlobalIds.COUNTRY, address.getAddress1());
+            //}
+
+            if ( VUtil.isNotNullOrEmpty( address.getPostalCode() ) )
+            {
+                entry.add( POSTAL_CODE, address.getPostalCode() );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getPostOfficeBox() ) )
+            {
+                entry.add( POST_OFFICE_BOX, address.getPostOfficeBox() );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getState() ) )
+            {
+                entry.add( STATE, address.getState() );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getBuilding() ) )
+            {
+                entry.add( PHYSICAL_DELIVERY_OFFICE_NAME, address.getBuilding() );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getDepartmentNumber() ) )
+            {
+                entry.add( DEPARTMENT_NUMBER, address.getDepartmentNumber() );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getRoomNumber() ) )
+            {
+                entry.add( ROOM_NUMBER, address.getRoomNumber() );
+            }
+        }
+    }
+
+
+    /**
+     * Given an address, {@link Address}, load into ldap modification set in preparation for ldap modify.
+     *
+     * @param address contains entity of type {@link Address} targeted for updating into ldap.
+     * @param mods contains ldap modification set contains attributes to be updated in ldap.
+     */
+    private void loadAddress( Address address, List<Modification> mods )
+    {
+        if ( address != null )
+        {
+            if ( VUtil.isNotNullOrEmpty( address.getAddresses() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, POSTAL_ADDRESS ) );
+
+                for ( String val : address.getAddresses() )
+                {
+                    mods.add( new DefaultModification(
+                        ModificationOperation.ADD_ATTRIBUTE, POSTAL_ADDRESS, val ) );
+                }
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getCity() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, L, address.getCity() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getPostalCode() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, POSTAL_CODE, address.getPostalCode() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getPostOfficeBox() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, POST_OFFICE_BOX, address.getPostOfficeBox() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getState() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, STATE, address.getState() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getBuilding() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, PHYSICAL_DELIVERY_OFFICE_NAME, address.getBuilding() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getDepartmentNumber() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, DEPARTMENT_NUMBER, address.getDepartmentNumber() ) );
+            }
+
+            if ( VUtil.isNotNullOrEmpty( address.getRoomNumber() ) )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, ROOM_NUMBER, address.getRoomNumber() ) );
+            }
+        }
+    }
+
+
+    /**
+     * Given an ldap entry containing organzationalPerson address information, convert to {@link Address}
+     *
+     * @param entry     contains ldap entry to retrieve admin roles from.
+     * @return entity of type {@link Address}.
+     * @throws LdapInvalidAttributeValueException 
+     * @throws com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException in the event of ldap client error.
+     */
+    private Address unloadAddress( Entry entry ) throws LdapInvalidAttributeValueException
+    {
+        Address addr = new ObjectFactory().createAddress();
+        List<String> pAddrs = getAttributes( entry, POSTAL_ADDRESS );
+
+        if ( pAddrs != null )
+        {
+            for ( String pAddr : pAddrs )
+            {
+                addr.setAddress( pAddr );
+            }
+        }
+
+        addr.setCity( getAttribute( entry, L ) );
+        addr.setState( getAttribute( entry, STATE ) );
+        addr.setPostalCode( getAttribute( entry, POSTAL_CODE ) );
+        addr.setPostOfficeBox( getAttribute( entry, POST_OFFICE_BOX ) );
+        addr.setBuilding( getAttribute( entry, PHYSICAL_DELIVERY_OFFICE_NAME ) );
+        addr.setDepartmentNumber( getAttribute( entry, DEPARTMENT_NUMBER ) );
+        addr.setRoomNumber( getAttribute( entry, ROOM_NUMBER ) );
+        // todo: add support for country attribute
+        //addr.setCountry(getAttribute(le, GlobalIds.COUNTRY));
+
+        return addr;
+    }
+
+
+    /**
+     * Given an ldap entry containing ARBAC roles assigned to user, retrieve the raw data and convert to a collection of {@link UserAdminRole}
+     * including {@link org.apache.directory.fortress.core.util.time.Constraint}.
+     *
+     * @param entry     contains ldap entry to retrieve admin roles from.
+     * @param userId attribute maps to {@link UserAdminRole#userId}.
+     * @param contextId
+     * @return List of type {@link UserAdminRole} containing admin roles assigned to a particular user.
+     * @throws com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException in the event of ldap client error.
+     */
+    private List<UserAdminRole> unloadUserAdminRoles( Entry entry, String userId, String contextId )
+    {
+        List<UserAdminRole> uRoles = null;
+        List<String> roles = getAttributes( entry, GlobalIds.USER_ADMINROLE_DATA );
+
+        if ( roles != null )
+        {
+            long sequence = 0;
+            uRoles = new ArrayList<>();
+
+            for ( String raw : roles )
+            {
+                UserAdminRole ure = new ObjectFactory().createUserAdminRole();
+                ure.load( raw, contextId );
+                ure.setSequenceId( sequence++ );
+                ure.setUserId( userId );
+                uRoles.add( ure );
+            }
+        }
+
+        return uRoles;
+    }
+
+
+    /**
+     *
+     * @param userId
+     * @param contextId
+     * @return
+     */
+    private String getDn( String userId, String contextId )
+    {
+        return GlobalIds.UID + "=" + userId + "," + getRootDn( contextId, GlobalIds.USER_ROOT );
+    }
+
+
+    /**
+    * Given an ldap entry containing RBAC roles assigned to user, retrieve the raw data and convert to a collection of {@link UserRole}
+    * including {@link org.apache.directory.fortress.core.util.time.Constraint}.
+    *
+    * @param entry     contains ldap entry to retrieve roles from.
+    * @param userId attribute maps to {@link UserRole#userId}.
+    * @param contextId
+    * @return List of type {@link UserRole} containing RBAC roles assigned to a particular user.
+    * @throws com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException in the event of ldap client error.
+    */
+    private List<UserRole> unloadUserRoles( Entry entry, String userId, String contextId )
+    {
+        List<UserRole> uRoles = null;
+        List<String> roles = getAttributes( entry, GlobalIds.USER_ROLE_DATA );
+
+        if ( roles != null )
+        {
+            long sequence = 0;
+            uRoles = new ArrayList<>();
+
+            for ( String raw : roles )
+            {
+                UserRole ure = new ObjectFactory().createUserRole();
+                ure.load( raw, contextId );
+                ure.setUserId( userId );
+                ure.setSequenceId( sequence++ );
+                uRoles.add( ure );
+            }
+        }
+
+        return uRoles;
+    }
+}
\ No newline at end of file


[03/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.

Posted by sm...@apache.org.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/attr/VUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/attr/VUtil.java b/src/main/java/org/apache/directory/fortress/core/util/attr/VUtil.java
new file mode 100755
index 0000000..4df14e4
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/attr/VUtil.java
@@ -0,0 +1,706 @@
+/*
+ *   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.util.attr;
+
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.slf4j.LoggerFactory;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.ValidationException;
+import org.apache.directory.fortress.core.cfg.Config;
+
+
+/**
+ * This class contains simple data validation utilities.  The data validations include null, length
+ * and simple reasonability checking.  All utilities will throw {@link ValidationException} for failures.
+ */
+public class VUtil
+{
+    private static final String CLS_NM = VUtil.class.getName();
+    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static int maximumFieldLen = 130;
+    private final static String VALIDATE_LENGTH = "field.length";
+
+    static
+    {
+        String lengthProp = Config.getProperty( VALIDATE_LENGTH );
+        try
+        {
+            if ( lengthProp != null )
+            {
+                Integer len = new Integer( lengthProp );
+                maximumFieldLen = len;
+            }
+        }
+        catch ( java.lang.NumberFormatException nfe )
+        {
+            //ignore
+        }
+    }
+
+    private final static int MAXIMUM_FIELD_LEN = maximumFieldLen;
+    private final static int maxFieldLength = MAXIMUM_FIELD_LEN;
+    private final static char[] LDAP_META_CHARS = loadLdapEscapeChars();
+    private final static String[] LDAP_REPL_VALS = loadValidLdapVals();
+    private static final int TIME_LEN = 4;
+    private static final int DATE_LEN = 8;
+    private static final int DAYMASK_LEN = 7;
+    private static final String TIME_FORMAT = "HHmm";
+    private static final String DATE_FORMAT = "yyyyMMdd";
+    private static final char SUNDAY = '1';
+    private static final char SATURDAY = '7';
+    private static final SimpleDateFormat TIME_FORMATER = new SimpleDateFormat( TIME_FORMAT );
+    private static final SimpleDateFormat DATE_FORMATER = new SimpleDateFormat( DATE_FORMAT );
+
+    static
+    {
+        String lengthProp = Config.getProperty( VALIDATE_LENGTH );
+
+        if ( lengthProp != null )
+        {
+            maximumFieldLen = Integer.parseInt( lengthProp );
+        }
+
+        TIME_FORMATER.setLenient( false );
+        DATE_FORMATER.setLenient( false );
+    }
+
+
+    /**
+     * Simple length check on orgunit that uses {@link org.apache.directory.fortress.core.GlobalIds#OU_LEN}.
+     *
+     * @param orgUnitId contains the ou name.
+     * @throws ValidationException in the event of failure, {@link org.apache.directory.fortress.core.GlobalErrIds#ORG_LEN_INVLD}.
+     */
+    public static void orgUnit( String orgUnitId ) throws ValidationException
+    {
+        int length = orgUnitId.length();
+
+        if ( length > maxFieldLength )
+        {
+            String error = "orgUnit value [" + orgUnitId + "] invalid length [" + length + "]";
+            throw new ValidationException( GlobalErrIds.ORG_LEN_INVLD, error );
+        }
+    }
+
+
+    /**
+     * Simple length check on User password that uses {@link org.apache.directory.fortress.core.GlobalIds#PASSWORD_LEN}.
+     * @param password contains the User's password.
+     * @throws ValidationException in the event of failure, {@link org.apache.directory.fortress.core.GlobalErrIds#USER_PW_INVLD_LEN}.
+     */
+    public static void password( char[] password ) throws ValidationException
+    {
+        int length = password.length;
+
+        if ( length > GlobalIds.PASSWORD_LEN )
+        {
+            String error = "password invalid length [" + length + "]";
+            throw new ValidationException( GlobalErrIds.USER_PW_INVLD_LEN, error );
+        }
+    }
+
+
+    /**
+     * Simple length check and safe text validation on description field that uses {@link org.apache.directory.fortress.core.GlobalIds#DESC_LEN}.
+     * @param description contains the User's password.
+     * @throws ValidationException in the event of failure, {@link org.apache.directory.fortress.core.GlobalErrIds#CONST_DESC_LEN_INVLD}.
+     *
+     * @param description contains the User's password.
+     * @throws org.apache.directory.fortress.core.ValidationException
+     *          in the event of failure, {@link org.apache.directory.fortress.core.GlobalErrIds#CONST_DESC_LEN_INVLD}.
+     */
+    public static void description( String description ) throws ValidationException
+    {
+        int length = description.length();
+
+        if ( length > GlobalIds.DESC_LEN )
+        {
+            String error = "description value [" + description + "] invalid length [" + length + "]";
+            throw new ValidationException( GlobalErrIds.CONST_DESC_LEN_INVLD, error );
+        }
+
+        RegExUtil.safeText( description );
+    }
+
+
+    /**
+     * Perform a simple length and safe text validation.
+     * @param value contains the attribute to check.
+     * @param validLen contains the length to use.
+     * @throws ValidationException in the event of length {@link org.apache.directory.fortress.core.GlobalErrIds#CONST_INVLD_FIELD_LEN} or regex failure.
+     *
+     * @param value    contains the attribute to check.
+     * @param validLen contains the length to use.
+     * @throws org.apache.directory.fortress.core.ValidationException
+     *          in the event of length {@link org.apache.directory.fortress.core.GlobalErrIds#CONST_INVLD_FIELD_LEN} or regex failure.
+     */
+    public static void safeText( String value, int validLen ) throws ValidationException
+    {
+        if ( !isNotNullOrEmpty( value ) )
+        {
+            String error = "safeText null value";
+            throw new ValidationException( GlobalErrIds.CONST_NULL_TEXT, error );
+        }
+
+        int length = value.length();
+
+        if ( length > validLen )
+        {
+            String error = "safeText value [" + value + "] invalid length [" + length + "]";
+            throw new ValidationException( GlobalErrIds.CONST_INVLD_FIELD_LEN, error );
+        }
+
+        RegExUtil.safeText( value );
+    }
+
+
+    /**
+     * Simple null, {@link org.apache.directory.fortress.core.GlobalErrIds#USER_ID_NULL}, and length checks, {@link org.apache.directory.fortress.core.GlobalErrIds#CONST_INVLD_FIELD_LEN}, on userId.
+     * @param userId contains the userId, maps to {@link org.apache.directory.fortress.core.rbac.User#userId}.
+     * @throws ValidationException in the event of failure, {@link GlobalErrIds#CONST_INVLD_FIELD_LEN}.
+     *
+     * @param userId contains the userId, maps to {@link org.apache.directory.fortress.core.rbac.User#userId}.
+     * @throws org.apache.directory.fortress.core.ValidationException
+     *          in the event of failure, {@link GlobalErrIds#CONST_INVLD_FIELD_LEN}.
+     */
+    public static void userId( String userId ) throws ValidationException
+    {
+        if ( !isNotNullOrEmpty( userId ) )
+        {
+            String error = "userId validation failed, null or empty value";
+            throw new ValidationException( GlobalErrIds.USER_ID_NULL, error );
+        }
+
+        int length = userId.length();
+
+        if ( length > GlobalIds.USERID_LEN )
+        {
+            String error = "safeText value [" + userId + "] invalid length [" + length + "]";
+            throw new ValidationException( GlobalErrIds.CONST_INVLD_FIELD_LEN, error );
+        }
+    }
+
+
+    /**
+     * Perform simple length and safe text validations on collection of name-value pairs.
+     *
+     * @param props contains name-value pairs in {@code name:value} format.
+     * @throws ValidationException in the event of failure.
+     */
+    public static void properties( Properties props ) throws ValidationException
+    {
+        if ( isNotNullOrEmpty( props ) )
+        {
+            for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+            {
+                String key = ( String ) e.nextElement();
+                String val = props.getProperty( key );
+                safeText( key, GlobalIds.PROP_LEN );
+                safeText( val, GlobalIds.PROP_LEN );
+            }
+        }
+    }
+
+
+    /**
+     * Perform simple reasonability check on contraint timeout value.
+     * @param timeout must be greater than 0 and less than max value for {@link Integer#MAX_VALUE}
+     * @throws ValidationException in the event value falls out of range.
+     *
+     * @param timeout must be greater than 0 and less than max value for {@link Integer#MAX_VALUE}
+     * @throws org.apache.directory.fortress.core.ValidationException
+     *          in the event value falls out of range.
+     */
+    public static void timeout( Integer timeout ) throws ValidationException
+    {
+        if ( ( timeout < 0 ) || ( timeout >= Integer.MAX_VALUE ) )
+        {
+            String error = "timeout - invalid timeout value [" + timeout + "]";
+            throw new ValidationException( GlobalErrIds.CONST_TIMEOUT_INVLD, error );
+        }
+    }
+
+
+    /**
+     * Perform simple reasonability check on contraint beginTime value.
+     * @param beginTime if set, must be equal to {@link #TIME_LEN}.
+     * @throws ValidationException in the event value falls out of range.
+     *
+     * @param beginTime if set, must be equal to {@link #TIME_LEN}.
+     * @throws org.apache.directory.fortress.core.ValidationException
+     *          in the event value falls out of range.
+     */
+    public static void beginTime( String beginTime ) throws ValidationException
+    {
+        if ( ( beginTime != null ) && ( beginTime.length() == TIME_LEN ) )
+        {
+            if ( checkTime( beginTime ) )
+            {
+                String error = "beginTime - invalid beginTime value [" + beginTime + "]";
+                throw new ValidationException( GlobalErrIds.CONST_BEGINTIME_INVLD, error );
+            }
+        }
+        else
+        {
+            String error = "beginTime - null or invalid length (must be 4) for beginTime value";
+            throw new ValidationException( GlobalErrIds.CONST_BEGINTIME_LEN_ERR, error );
+        }
+    }
+
+
+    /**
+     * Perform simple reasonability check on contraint endTime value.
+     * @param endTime if set, must be equal to {@link #TIME_LEN}.
+     * @throws ValidationException in the event value falls out of range.
+     */
+    public static void endTime( String endTime ) throws ValidationException
+    {
+        if ( ( endTime != null ) && ( endTime.length() == TIME_LEN ) )
+        {
+            if ( checkTime( endTime ) )
+            {
+                String error = "endTime - invalid endTime value [" + endTime + "]";
+                throw new ValidationException( GlobalErrIds.CONST_ENDTIME_INVLD, error );
+            }
+        }
+        else
+        {
+            String error = "endTime - null or invalid length (must be 4) for endTime value";
+            throw new ValidationException( GlobalErrIds.CONST_ENDTIME_LEN_ERR, error );
+        }
+    }
+
+
+    /**
+     * Perform simple reasonability check on contraint beginDate value.
+     * @param beginDate if set, must be equal to {@link #DATE_LEN}.
+     * @throws ValidationException in the event value falls out of range.
+     */
+    public static void beginDate( String beginDate )
+        throws ValidationException
+    {
+        if ( isNotNullOrEmpty( beginDate ) )
+        {
+            if ( ( beginDate.compareToIgnoreCase( GlobalIds.NONE ) != 0 ) &&
+                ( ( beginDate.length() != DATE_LEN ) || checkDate( beginDate ) ) )
+            {
+                String error = "beginDate - invalid beginDate value [" + beginDate + "]";
+                throw new ValidationException( GlobalErrIds.CONST_BEGINDATE_INVLD, error );
+            }
+        }
+        else
+        {
+            String error = "beginDate - null or empty beginDate value";
+            throw new ValidationException( GlobalErrIds.CONST_BEGINDATE_NULL, error );
+        }
+    }
+
+
+    /**
+     * Perform simple reasonability check on contraint endDate value.
+     * @param endDate if set, must be equal to {@link #DATE_LEN}.
+     * @throws ValidationException in the event value falls out of range.
+     */
+    public static void endDate( String endDate ) throws ValidationException
+    {
+        if ( isNotNullOrEmpty( endDate ) )
+        {
+            if ( endDate.compareToIgnoreCase( GlobalIds.NONE ) != 0 )
+            {
+                if ( endDate.length() != DATE_LEN || checkDate( endDate ) )
+                {
+                    String error = "endDate - invalid endDate value [" + endDate + "]";
+                    throw new ValidationException( GlobalErrIds.CONST_ENDDATE_INVLD, error );
+                }
+            }
+        }
+        else
+        {
+            String error = "endDate - null or empty endDate value";
+            throw new ValidationException( GlobalErrIds.CONST_ENDDATE_NULL, error );
+        }
+    }
+
+
+    /**
+     * Perform simple reasonability check on contraint dayMask value.
+     * @param dayMask if set, will be validated.
+     * @throws ValidationException in the event value falls out of range.
+     */
+    public static void dayMask( String dayMask ) throws ValidationException
+    {
+        if ( isNotNullOrEmpty( dayMask ) )
+        {
+            if ( dayMask.compareToIgnoreCase( GlobalIds.ALL ) != 0 )
+            {
+                if ( dayMask.length() > DAYMASK_LEN || checkMask( dayMask ) )
+                {
+                    String error = "dayMask - invalid dayMask value [" + dayMask + "]";
+                    throw new ValidationException( GlobalErrIds.CONST_DAYMASK_INVLD, error );
+                }
+            }
+        }
+        else
+        {
+            String error = "dayMask - null or empty dayMask value";
+            throw new ValidationException( GlobalErrIds.CONST_DAYMASK_NULL, error );
+        }
+    }
+
+
+    /**
+     * @param time
+     * @return boolean
+     */
+    private static boolean checkTime( String time )
+    {
+        try
+        {
+            synchronized ( TIME_FORMATER )
+            {
+                TIME_FORMATER.parse( time );
+                return false;
+            }
+        }
+        catch ( ParseException pe )
+        {
+            String error = "checkTime - time [" + time + "] failed validation with ParseException=" + pe;
+            LOG.warn( error );
+            return true;
+        }
+    }
+
+
+    /**
+     * @param date
+     * @return boolean
+     */
+    private static boolean checkDate( String date )
+    {
+        try
+        {
+            synchronized ( DATE_FORMATER )
+            {
+                DATE_FORMATER.parse( date );
+                return false;
+            }
+        }
+        catch ( ParseException pe )
+        {
+            String error = "checkDate - date [" + date + "] failed validation with ParseException=" + pe;
+            LOG.warn( error );
+
+            return true;
+        }
+    }
+
+
+    /**
+     * @param mask
+     * @return boolean
+     */
+    private static boolean checkMask( String mask )
+    {
+        for ( char c : mask.toCharArray() )
+        {
+            if ( ( c < SUNDAY ) || ( c > SATURDAY ) )
+            {
+                String error = "checkMask - mask [" + mask + "] failed validation";
+                LOG.warn( error );
+
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+
+    /**
+     * Method will throw exception with supplied error id and object.method name if object reference is null.
+     *
+     * @param obj       contains the reference to check.
+     * @param errorCode contains the error id to use if null.
+     * @param method contains the method name of caller.
+     * @throws ValidationException in the event object is null.
+     */
+    public static void assertNotNull( Object obj, int errorCode, String method )
+        throws ValidationException
+    {
+        if ( obj == null )
+        {
+            String error = "assertContext detected null entity for method [" + method + "], error code ["
+                + errorCode + "]";
+            throw new ValidationException( errorCode, error );
+        }
+    }
+
+
+    /**
+     * Method will throw exception with supplied error id and object.method name if string reference is null or empty.
+     *
+     * @param value     contains the reference to check.
+     * @param errorCode contains the error id to use if null.
+     * @param method contains the method name of caller.
+     * @throws ValidationException in the event supplied string is null or empty.
+     */
+    public static void assertNotNullOrEmpty( String value, int errorCode, String method )
+        throws ValidationException
+    {
+        if ( !isNotNullOrEmpty( value ) )
+        {
+            String error = "assertContext detected null entity for method [" + method + "], error code ["
+                + errorCode + "]";
+            throw new ValidationException( errorCode, error );
+        }
+    }
+
+
+    /**
+     * Method will throw exception with supplied error id and object.method name if string reference is null or empty.
+     *
+     * @param value     contains the reference to check.
+     * @param errorCode contains the error id to use if null.
+     * @param method contains the method name of caller.
+     * @throws ValidationException in the event supplied string is null or empty.
+     */
+    public static void assertNotNullOrEmpty( char[] value, int errorCode, String method )
+        throws ValidationException
+    {
+        if ( !isNotNullOrEmpty( value ) )
+        {
+            String error = "assertContext detected null entity for method [" + method + "], error code ["
+                + errorCode + "]";
+            throw new ValidationException( errorCode, error );
+        }
+    }
+
+
+    /**
+     * Method will return true if string array reference is not null or empty.
+     *
+     * @param value contains the reference to string array.
+     * @return boolean if validation succeeds.
+     */
+    public static boolean isNotNullOrEmpty( String[] value )
+    {
+        return ( value != null ) && ( value.length > 0 );
+    }
+
+
+    /**
+     * Method will return true if string reference is not null or empty.
+     *
+     * @param value contains the reference to string.
+     * @return boolean if validation succeeds.
+     */
+    public static boolean isNotNullOrEmpty( String value )
+    {
+        return ( value != null ) && ( value.length() > 0 );
+    }
+
+
+    /**
+     * Method will return true if string reference is not null or empty.
+     *
+     * @param value contains the reference to string.
+     * @return boolean if validation succeeds.
+     */
+    public static boolean isNotNullOrEmpty( char[] value )
+    {
+        return ( value != null ) && ( value.length > 0 );
+    }
+
+
+    /**
+     * Method will return true if list is not null or empty.
+     *
+     * @param list contains the reference to list.
+     * @return boolean if validation succeeds.
+     */
+    public static boolean isNotNullOrEmpty( Collection list )
+    {
+        return ( list != null ) && ( list.size() > 0 );
+    }
+
+
+    /**
+     * Method will return true if props is not null or empty.
+     *
+     * @param props contains the reference to props.
+     * @return boolean if validation succeeds.
+     */
+    public static boolean isNotNullOrEmpty( Properties props )
+    {
+        return ( props != null ) && ( props.size() > 0 );
+    }
+
+
+    /**
+     * Method will return true if input is not null or empty.
+     *
+     * @param iVal contains the reference to Integer variable.
+     * @return boolean if validation succeeds.
+     */
+    public static boolean isNotNullOrEmpty( Integer iVal )
+    {
+        return ( iVal != null );
+    }
+
+
+    /**
+     * Method will return true if input is not null or empty.
+     *
+     * @param bVal contains the reference to Boolean variable.
+     * @return boolean if validation succeeds.
+     */
+    public static boolean isNotNullOrEmpty( Boolean bVal )
+    {
+        return ( bVal != null );
+    }
+
+
+    /**
+     * Method will return true if byte array reference is not null or empty.
+     *
+     * @param value contains the reference to byte array.
+     * @return boolean if validation succeeds.
+     */
+    public static boolean isNotNullOrEmpty( byte[] value )
+    {
+        boolean result = false;
+        if ( value != null && value.length > 0 )
+        {
+            result = true;
+        }
+        return result;
+    }
+
+
+    /**
+     *
+     */
+    private static char[] loadLdapEscapeChars()
+    {
+        if ( !GlobalIds.LDAP_FILTER_SIZE_FOUND )
+        {
+            return null;
+        }
+
+        char[] ldapMetaChars = new char[GlobalIds.LDAP_FILTER_SIZE];
+
+        for ( int i = 1;; i++ )
+        {
+            String prop = GlobalIds.LDAP_FILTER + i;
+            String value = Config.getProperty( prop );
+
+            if ( value == null )
+            {
+                break;
+            }
+
+            ldapMetaChars[i - 1] = value.charAt( 0 );
+        }
+
+        return ldapMetaChars;
+    }
+
+
+    /**
+     *
+     */
+    private static String[] loadValidLdapVals()
+    {
+        if ( !GlobalIds.LDAP_FILTER_SIZE_FOUND )
+        {
+            return null;
+        }
+
+        String[] ldapReplacements = new String[GlobalIds.LDAP_FILTER_SIZE];
+
+        for ( int i = 1;; i++ )
+        {
+            String prop = GlobalIds.LDAP_SUB + i;
+            String value = Config.getProperty( prop );
+
+            if ( value == null )
+            {
+                break;
+            }
+
+            ldapReplacements[i - 1] = value;
+        }
+
+        return ldapReplacements;
+    }
+
+
+    /**
+     * Perform encoding on supplied input string for certain unsafe ascii characters.  These chars may be unsafe
+     * because ldap reserves some
+     * characters as operands.  Safe encoding safeguards from malicious scripting input errors that are possible iff
+     * data filtering
+     * did not get performed before being passed into dao layer.
+     *
+     * @param filter contains the data to filter.
+     * @return possibly modified input string for matched characters.
+     */
+    public static String escapeLDAPSearchFilter( String filter )
+    {
+        StringBuilder sb = new StringBuilder();
+        int filterLen = filter.length();
+
+        for ( int i = 0; i < filterLen; i++ )
+        {
+            boolean found = false;
+            char curChar = filter.charAt( i );
+            int j = 0;
+
+            for ( ; j < GlobalIds.LDAP_FILTER_SIZE; j++ )
+            {
+                if ( LDAP_META_CHARS[j] > curChar )
+                {
+                    break;
+                }
+                else if ( curChar == LDAP_META_CHARS[j] )
+                {
+                    sb.append( "\\" );
+                    sb.append( LDAP_REPL_VALS[j] );
+                    found = true;
+                    break;
+                }
+            }
+
+            if ( !found )
+            {
+                sb.append( curChar );
+            }
+        }
+
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/attr/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/attr/package.html b/src/main/java/org/apache/directory/fortress/core/util/attr/package.html
new file mode 100755
index 0000000..60257ac
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/attr/package.html
@@ -0,0 +1,33 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.util.attr</title>
+   </head>
+   <body>
+      <p>
+         This package contains utilities used for data validation and formatting by fortress process modules.
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress.util.attr</b> package contains utilities to format and validate low level attributes both inbound and outbound to ldap server.  The apis contained within this package are used by fortress process modules and are not intended for external use.
+          See the corresponding javadoc contained with this package for more info.
+      </p>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/cache/Cache.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/cache/Cache.java b/src/main/java/org/apache/directory/fortress/core/util/cache/Cache.java
new file mode 100644
index 0000000..711153e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/cache/Cache.java
@@ -0,0 +1,82 @@
+/*
+ *   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.util.cache;
+
+import net.sf.ehcache.search.Attribute;
+import net.sf.ehcache.search.Query;
+
+/**
+ * This Interface is implemented by cacheable Fortress objects and is used to wrap the caching implementation to provide isolation.
+ *
+ * @author Shawn McKinney
+ */
+public interface Cache
+{
+    /**
+     * Given a key name, return the corresponding value.
+     *
+     * @param key is the name used to store the entry.
+     * @return entry stored in the cache.
+     * @throws CacheException will wraps the implementation's exception.
+     */
+    public Object get(Object key) throws CacheException;
+
+    /**
+     * Add a new entry to the cache.
+     *
+     * @param key name to be used for the entry.
+     * @param value object that is stored.
+     * @throws CacheException will wraps the implementation's exception.
+     */
+    public void put(Object key, Object value) throws CacheException;
+
+    /**
+     * Clear a cache entry for a given name.
+     *
+     * @param key name that entry is stored as.
+     * @return boolean value will be false if entry not found and true if entry was found and removed.
+     * @throws CacheException will wraps the implementation's exception.
+     */
+    public boolean clear(Object key) throws CacheException;
+
+    /**
+     * Remove all entries from the cache.
+     *
+     * @throws CacheException will wraps the implementation's exception.
+     */
+    public void flush() throws CacheException;
+
+    /**
+     * Retrieve the Cache attribute
+     *
+     * @param attributeName the name of search attribute
+     * @param <T> the type of search attribute
+     * @return the search attribute
+     * @throws CacheException will wraps the implementation's exception.
+     */
+    public <T> Attribute<T> getSearchAttribute(String attributeName) throws CacheException;
+
+    /**
+     * Create a search query for the cache.
+     *
+     * @return a new Query builder
+     */
+    public Query createQuery();
+}
\ 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/util/cache/CacheException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/cache/CacheException.java b/src/main/java/org/apache/directory/fortress/core/util/cache/CacheException.java
new file mode 100644
index 0000000..3e09e32
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/cache/CacheException.java
@@ -0,0 +1,70 @@
+/*
+ *   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.util.cache;
+
+import org.apache.directory.fortress.core.BaseRuntimeException;
+
+
+/**
+ * This exception extends {@code BaseRuntimeException} and is thrown when Fortress caching operation failed.
+ * This is critical runtime exception and means system is inoperable due to a caching error.
+ * See the {@link org.apache.directory.fortress.core.GlobalErrIds} javadoc for list of error ids.
+ *
+ * @author Shawn McKinney
+ */
+class CacheException extends BaseRuntimeException
+{
+    private int subsystem;
+    private Exception exception;
+    private Object moreInfo;
+
+    /**
+     * Create exception with error id, message and related exception.
+     * @param errorId contains error code that is contained within {@link org.apache.directory.fortress.core.GlobalErrIds}
+     * @param newMsgText contains text related to the exception.
+     * @param newException contains related exception.
+     */
+    public CacheException(int errorId, String newMsgText, Exception newException)
+    {
+        super(errorId, newMsgText, newException);
+        this.exception = newException;
+    }
+
+    /**
+     * Create exception with error id and message.
+     * @param errorId contains error code that is contained within {@link org.apache.directory.fortress.core.GlobalErrIds}
+     * @param newMsgText contains text related to the exception.
+     */
+    public CacheException(int errorId, String newMsgText)
+    {
+        super(errorId, newMsgText);
+    }
+
+    /**
+     * Get the exception object.
+     *
+     * @return reference to Exception.
+     */
+    public Exception getException()
+    {
+        return exception;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/cache/CacheFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/cache/CacheFactory.java b/src/main/java/org/apache/directory/fortress/core/util/cache/CacheFactory.java
new file mode 100644
index 0000000..7ecbcc4
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/cache/CacheFactory.java
@@ -0,0 +1,52 @@
+/*
+ *   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.util.cache;
+
+import org.apache.directory.fortress.core.CfgRuntimeException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import net.sf.ehcache.constructs.blocking.BlockingCache;
+
+/**
+ * Creates an instance of the {@link EhCacheImpl} object with a {@link Cache} facade.
+ *
+ * @author Shawn McKinney
+ */
+class CacheFactory
+{
+    private static final String CLS_NM = CacheFactory.class.getName();
+
+    /**
+     * Create and return a reference to {@link Cache} object.
+     *
+     * @return instance of {@link Cache}.
+     */
+    public static Cache createInstance(String name, net.sf.ehcache.CacheManager cacheManager)
+    {
+        net.sf.ehcache.Ehcache cache = cacheManager.getEhcache(name);
+        if(cache == null)
+        {
+            String error = "createInstance cache: " + name + " is null";
+            throw new CfgRuntimeException(GlobalErrIds.FT_CACHE_NOT_CONFIGURED, error);
+        }
+        BlockingCache blockingCache = new BlockingCache(cache);
+        cacheManager.replaceCacheWithDecoratedCache(cache, blockingCache);
+        return new EhCacheImpl(name, blockingCache);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/cache/CacheMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/cache/CacheMgr.java b/src/main/java/org/apache/directory/fortress/core/util/cache/CacheMgr.java
new file mode 100644
index 0000000..8ac9420
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/cache/CacheMgr.java
@@ -0,0 +1,110 @@
+/*
+ *   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.util.cache;
+
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import net.sf.ehcache.CacheManager;
+import org.apache.directory.fortress.core.CfgException;
+import org.apache.directory.fortress.core.CfgRuntimeException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+
+
+/**
+ * This class is a facade and shields internal Fortress objects from specifics of the actual
+ * cache implementation that is in use.
+ *
+ * @author Shawn McKinney
+ */
+public class CacheMgr
+{
+    private static final String EHCACHE_CONFIG_FILE = "ehcache.config.file";
+    private final CacheManager m_ehCacheImpl;
+    private static CacheMgr m_ftCacheImpl;
+    private static final AtomicBoolean isCacheInitialized = new AtomicBoolean( false );
+    private static final Object m_lock = new Object();
+
+
+    /**
+     * Private constructor.
+     *
+     * @param cacheMangerImpl contains a reference to cache implementation manager.
+     */
+    private CacheMgr( CacheManager cacheMangerImpl )
+    {
+        m_ehCacheImpl = cacheMangerImpl;
+        this.m_ftCacheImpl = this;
+    }
+
+
+    /**
+     * Create or return the fortress cache manager reference.
+     * @return handle to the cache manager in effect for process.
+     */
+    public static CacheMgr getInstance()
+    {
+        // only drop into this block of the cache object hasn't previously been set on this classloader:
+        if ( !isCacheInitialized.get() )
+        {
+            // ensure only one thread can enter this block
+            synchronized ( m_lock )
+            {
+                String cacheConfig = null;
+                try
+                {
+                    // this property contains the cache file name.
+                    cacheConfig = Config.getProperty( EHCACHE_CONFIG_FILE );
+                    // This call will create a new CacheManager, or throw exception if the it already exists, or if the configuration file is not found on classloader.
+                    m_ftCacheImpl = new CacheMgr( new CacheManager( ClassUtil.resourceAsStream( cacheConfig ) ) );
+                    isCacheInitialized.set( true );
+                }
+                catch ( CfgException ce )
+                {
+                    throw new CfgRuntimeException( GlobalErrIds.FT_CACHE_NOT_CONFIGURED, cacheConfig );
+                }
+            }
+        }
+        return m_ftCacheImpl;
+    }
+
+
+    /**
+     * Create a new reference to the ehcache cache implementation.
+     *
+     * @param cacheName contains the name of the cache to retrieve
+     * @return reference to cache for specified object.
+     */
+    public Cache getCache( String cacheName )
+    {
+        return CacheFactory.createInstance( cacheName, m_ehCacheImpl );
+    }
+
+    /**
+     * Used to clear all elements from all cache objects.
+     *
+     */
+    public void clearAll()
+    {
+        m_ehCacheImpl.clearAll();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/cache/DsdCacheEntry.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/cache/DsdCacheEntry.java b/src/main/java/org/apache/directory/fortress/core/util/cache/DsdCacheEntry.java
new file mode 100644
index 0000000..d7db689
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/cache/DsdCacheEntry.java
@@ -0,0 +1,153 @@
+/*
+ *   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.util.cache;
+
+import org.apache.directory.fortress.core.rbac.SDSet;
+
+/**
+ * Value object wraps {@link SDSet} for caching purposes.  This class also provides attributes that are used for
+ * searching the DSD cache.
+ *
+ * @author Shawn McKinney
+ */
+public class DsdCacheEntry
+{
+    private String name;
+    private String member;
+    private SDSet sdSet;
+    private boolean empty;
+    private String contextId;
+
+    /**
+     * Non-default contructor takes a {@link DsdCacheEntry#member} that maps to  {@link org.apache.directory.fortress.core.rbac.Role#name}, along
+     * with a reference to {@link org.apache.directory.fortress.core.rbac.SDSet} and a boolean value to indicate if DSD not found for member, which indicates empty.
+     *
+     * @param member maps to {@link org.apache.directory.fortress.core.rbac.Role#name}
+     * @param sdSet contains DSD entry.
+     * @param empty if true, the DSD entry was not found for a corresponding Role.
+     */
+    public DsdCacheEntry(String member, SDSet sdSet, boolean empty)
+    {
+        this.sdSet = sdSet;
+        this.member = member;
+        this.empty = empty;
+        this.contextId = sdSet.getContextId();
+    }
+
+    /**
+     * To prevent repeated reads of the DSD's in the directory, Entries are added to the cache and marked empty.
+     *
+     * @return boolean if cache entry is 'empty'.
+     */
+    public boolean isEmpty()
+    {
+        return empty;
+    }
+
+    /**
+     * To prevent repeated reads of the DSD's in the directory, Entries are added to the cache and marked empty.
+     *
+     * @param empty if the cache entry is 'empty'.
+     */
+    public void setEmpty(boolean empty)
+    {
+        this.empty = empty;
+    }
+
+    /**
+     * Return the Role name this cache entry corresponds with.
+     *
+     * @return Role name.
+     */
+    public String getMember()
+    {
+        return member;
+    }
+
+    /**
+     * Set the Role name this cache entry corresponds with.
+     *
+     * @param member Role name
+     */
+    public void setMember(String member)
+    {
+        this.member = member;
+    }
+
+    /**
+     * Get the DSD for this cache entry.
+     *
+     * @return SDSet of type {@link org.apache.directory.fortress.core.rbac.SDSet.SDType#DYNAMIC}.
+     */
+    public SDSet getSdSet()
+    {
+        return sdSet;
+    }
+
+    /**
+     * Set the DSD for this cache entry.
+     *
+     * @param sdSet reference to non-null {@link SDSet} of type {@link org.apache.directory.fortress.core.rbac.SDSet.SDType#DYNAMIC}.
+     */
+    public void setSdSet(SDSet sdSet)
+    {
+        this.sdSet = sdSet;
+    }
+
+    /**
+     * Return the name that is used as the cache name for this entry.
+     *
+     * @return name for the Cache entry.
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * Set the name to be used for this cache entry.
+     *
+     * @param name of the cache entry.
+     */
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    /**
+     * Set the contextId for this record.  The contextId is used for multi-tenancy to isolate data sets within a particular sub-tree within DIT
+     *
+     * @return value maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     */
+    public String getContextId()
+    {
+        return contextId;
+    }
+
+    /**
+     * Return the contextId associated with this record.  The contextId is used for multi-tenancy to isolate data sets within a particular sub-tree within DIT
+     *
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     */
+    void setContextId(String contextId)
+    {
+        this.contextId = contextId;
+    }
+}
\ 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/util/cache/EhCacheImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/cache/EhCacheImpl.java b/src/main/java/org/apache/directory/fortress/core/util/cache/EhCacheImpl.java
new file mode 100644
index 0000000..1941bf1
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/cache/EhCacheImpl.java
@@ -0,0 +1,221 @@
+/*
+ *   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.util.cache;
+
+
+import net.sf.ehcache.Element;
+import net.sf.ehcache.constructs.blocking.BlockingCache;
+import net.sf.ehcache.search.Attribute;
+import net.sf.ehcache.search.Query;
+import org.apache.directory.fortress.core.CfgRuntimeException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+
+
+/**
+ * This class provides cache functionality from <a href="http://ehcache.org//">Ehcache</a> provider.
+ *
+ * @author Shawn McKinney
+ */
+public class EhCacheImpl implements Cache
+{
+    private BlockingCache cache;
+    private final String name;
+
+
+    /**
+     * Create an instance of a wrapped, singleton cache instance using Ehcache.
+     *
+     * @param name name for the cache instance.
+     * @param blockingCache that is being wrapped.
+     */
+    EhCacheImpl( String name, BlockingCache blockingCache )
+    {
+        this.name = name;
+        if ( blockingCache == null )
+        {
+            String error = " constructor cache: " + name + " is null";
+            throw new CfgRuntimeException( GlobalErrIds.FT_CACHE_NOT_CONFIGURED, error );
+        }
+        this.cache = blockingCache;
+    }
+
+
+    /**
+     * Given a key name, return the corresponding value.
+     *
+     * @param key is the name used to store the entry.
+     * @return entry stored in the cache.
+     * @throws CacheException in the event ehcache throws an exception it will be wrapped.
+     */
+    @Override
+    public Object get( Object key ) throws CacheException
+    {
+        if ( cache == null )
+        {
+            String error = "get detected null cache name [" + name + "]";
+            throw new CacheException( GlobalErrIds.FT_NULL_CACHE, error );
+        }
+        try
+        {
+            Element element = cache.get( key );
+            if ( element != null )
+            {
+                return element.getObjectValue();
+            }
+            else
+            {
+                return null;
+            }
+        }
+        catch ( net.sf.ehcache.CacheException ce )
+        {
+            String error = "get cache name [" + name + "] key [" + key + "] caught CacheException="
+                + ce.getMessage();
+            throw new CacheException( GlobalErrIds.FT_CACHE_GET_ERR, error, ce );
+        }
+    }
+
+
+    /**
+     * Add a new entry to the cache.
+     *
+     * @param key name to be used for the entry.
+     * @param value object that is stored.
+     * @throws CacheException in the event ehcache throws an exception it will be wrapped.
+     */
+    @Override
+    public void put( Object key, Object value ) throws CacheException
+    {
+        if ( cache == null )
+        {
+            String error = "put detected null cache name [" + name + "]";
+            throw new CacheException( GlobalErrIds.FT_NULL_CACHE, error );
+        }
+        try
+        {
+            cache.put( new Element( key, value ) );
+        }
+        catch ( net.sf.ehcache.CacheException ce )
+        {
+            String error = "put cache name [" + name + "] key [" + key + "] caught CacheException="
+                + ce.getMessage();
+            throw new CacheException( GlobalErrIds.FT_CACHE_PUT_ERR, error, ce );
+        }
+    }
+
+
+    /**
+     * Clear a cache entry for a given name.
+     *
+     * @param key name that entry is stored as.
+     * @return boolean value will be false if entry not found and true if entry was found and removed.
+     * @throws CacheException in the event ehcache throws an exception it will be wrapped.
+     */
+    @Override
+    public boolean clear( Object key ) throws CacheException
+    {
+        boolean result;
+        if ( cache == null )
+        {
+            String error = "clear detected null cache name [" + name + "]";
+            throw new CacheException( GlobalErrIds.FT_NULL_CACHE, error );
+        }
+        try
+        {
+            result = cache.remove( key );
+        }
+        catch ( net.sf.ehcache.CacheException ce )
+        {
+            String error = "clear cache name [" + name + "] key [" + key + "] caught CacheException="
+                + ce.getMessage();
+            throw new CacheException( GlobalErrIds.FT_CACHE_CLEAR_ERR, error, ce );
+        }
+        return result;
+    }
+
+
+    /**
+     * Remove all entries from this cache.
+     *
+     * @throws CacheException in the event ehcache throws an exception it will be wrapped.
+     */
+    @Override
+    public void flush() throws CacheException
+    {
+        if ( cache == null )
+        {
+            String error = "flush detected null cache name [" + name + "]";
+            throw new CacheException( GlobalErrIds.FT_NULL_CACHE, error );
+        }
+        try
+        {
+            cache.removeAll();
+        }
+        catch ( net.sf.ehcache.CacheException ce )
+        {
+            String error = "flush cache name [" + name + "] caught CacheException=" + ce.getMessage();
+            throw new CacheException( GlobalErrIds.FT_CACHE_FLUSH_ERR, error, ce );
+
+        }
+    }
+
+
+    /**
+     * Retrieve the Cache attribute
+     *
+     * @param attributeName the name of search attribute
+     * @param <T> the type of search attribute
+     * @return the search attribute
+     * @throws CacheException in the event ehcache throws an exception it will be wrapped.
+     */
+    @Override
+    public <T> Attribute<T> getSearchAttribute( String attributeName ) throws CacheException
+    {
+        if ( cache == null )
+        {
+            String error = "getSearchAttribute detected null cache name [" + name + "]";
+            throw new CacheException( GlobalErrIds.FT_NULL_CACHE, error );
+        }
+        return this.cache.getSearchAttribute( attributeName );
+    }
+
+
+    /**
+     * Create a search query builder for the cache.
+     *
+     * @return a new Query builder
+     */
+    @Override
+    public Query createQuery()
+    {
+        if ( cache == null )
+        {
+            String error = "createQuery detected null cache name [" + name + "]";
+            throw new CacheException( GlobalErrIds.FT_NULL_CACHE, error );
+        }
+        return this.cache.createQuery();
+    }
+
+
+    public void clear()
+    {
+        cache.flush();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/cache/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/cache/package.html b/src/main/java/org/apache/directory/fortress/core/util/cache/package.html
new file mode 100755
index 0000000..69ba381
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/cache/package.html
@@ -0,0 +1,34 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.util.cache</title>
+   </head>
+   <body>
+      <p>
+          This package contains a caching facade used by internal Fortress functions.  Currently this package
+          uses <a href="http://ehcache.org//">Ehcache</a> implementation but this can be swapped out for another
+          mechanism as needed without disturbing the calling functions.
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress.util.cache</b> package contains utilities to perform caching functions.
+      </p>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/crypto/EncryptUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/crypto/EncryptUtil.java b/src/main/java/org/apache/directory/fortress/core/util/crypto/EncryptUtil.java
new file mode 100755
index 0000000..565fa57
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/crypto/EncryptUtil.java
@@ -0,0 +1,94 @@
+/*
+ *   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.util.crypto;
+
+import org.apache.directory.fortress.core.cfg.Config;
+import org.jasypt.util.text.BasicTextEncryptor;
+
+/**
+ * Contains a simple wrapper for Jasypt open source encryption APIs, see <a href="http://www.jasypt.org/">Jasypt</a>.
+ *
+ * @author Shawn McKinney
+ */
+public class EncryptUtil
+{
+    private static final BasicTextEncryptor textEncryptor;
+    private static String CRYPTO_PROP = "crypto.prop";
+    static
+    {
+        textEncryptor = new BasicTextEncryptor();
+        textEncryptor.setPassword(Config.getProperty(CRYPTO_PROP, "adlfarerovcja;39 d"));
+    }
+
+    /**
+     * This wraps {@link #encrypt(String)} method.  Will return an encrypted value to standard out using System.out.println().
+     * It can be used for ad-hoc encryption of vars {@code fortress.properties} bound.
+     * @param args contains a single String to {@link #encrypt(String)}.
+     */
+    public static void main(String[] args)
+    {
+        if(args[0] != null && args[0].length() > 0)
+        {
+            String encryptedValue = textEncryptor.encrypt(args[0]);
+            System.out.println("Encrypted value=" + encryptedValue);
+        }
+    }
+
+
+    /**
+     * Returns 'true' if the property {@code crypto.prop} has a value set in fortress cfg.  If this value
+     * is 'false', Fortress will assume LDAP password in cfg file are clear text.
+     *
+     * @return boolean
+     */
+    public static boolean isEnabled()
+    {
+        boolean result = false;
+        if(Config.getProperty(CRYPTO_PROP)!= null && !Config.getProperty(CRYPTO_PROP).equals("${crypto.prop}"))
+        {
+            result = true;
+        }
+        return result;
+    }
+
+
+    /**
+     * Encrypt a value using Jasypt utility.
+     *
+     * @param clearText contains the text to be encrypted.
+     * @return String containing encrypted text.
+     */
+    public static String encrypt(String clearText)
+    {
+        return textEncryptor.encrypt(clearText);
+    }
+
+    /**
+     * Decrypt a value using Jasypt utility.
+     *
+     * @param encryptedText contains the text to be decrypted.
+     * @return String containing decrypted text.
+     */
+    public static String decrypt(String encryptedText)
+    {
+        return textEncryptor.decrypt(encryptedText);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/crypto/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/crypto/package.html b/src/main/java/org/apache/directory/fortress/core/util/crypto/package.html
new file mode 100755
index 0000000..ddadd2c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/crypto/package.html
@@ -0,0 +1,33 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.util.crypto</title>
+   </head>
+   <body>
+      <p>
+          This package uses <a href="http://www.jasypt.org/">Jasypt</a> to provide basic encryption/decryption functionality of textual data.
+          The Main function on {@code EncryptUtil} class is called by the {@code encrypt} Ant target and can be used to encrypt ad-hoc data including ldap server configuration passwords bound for {@code fortress.properties} file.
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress.util.crypto</b> package contains utilities to perform basic crypto functions on text.
+      </p>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/package.html b/src/main/java/org/apache/directory/fortress/core/util/package.html
new file mode 100755
index 0000000..7c0b991
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/package.html
@@ -0,0 +1,33 @@
+<!--
+ *   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.
+ *
+-->
+<html>
+   <head>
+      <title>Package Documentation for org.apache.directory.fortress.util</title>
+   </head>
+   <body>
+      <p>
+         This package contains miscellaneous utilities used by internal fortress procedures.
+      </p>
+      <p>
+         The <b>org.apache.directory.fortress.util</b> package contains a class factory and other misc utils that is used by classes in this system.  The apis contained within this package are for fortress use only.
+          See the corresponding javadoc contained with this package for more info.
+      </p>
+   </body>
+</html>

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/util/time/CUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/time/CUtil.java b/src/main/java/org/apache/directory/fortress/core/util/time/CUtil.java
new file mode 100755
index 0000000..1c3c81d
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/time/CUtil.java
@@ -0,0 +1,494 @@
+/*
+ *   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.util.time;
+
+import org.apache.directory.fortress.core.CfgException;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.ObjectFactory;
+import org.apache.directory.fortress.core.cfg.Config;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.ValidationException;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.rbac.Session;
+import org.apache.directory.fortress.core.rbac.Warning;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.StringTokenizer;
+
+/**
+ * This class contains utilities for temporal constraint processing that are used by Fortress internal.  All of the methods are static and the class
+ * is thread safe.
+ * The Validators are configured via properties set in Fortress cfg:
+ * <p/>
+ * <h4> Validators supported include</h4>
+ * <ol>
+ * <li>{@link org.apache.directory.fortress.core.GlobalIds#VALIDATOR_PROPS}0={@link Date}</li>
+ * <li>{@link org.apache.directory.fortress.core.GlobalIds#VALIDATOR_PROPS}1={@link LockDate}</li>
+ * <li>{@link org.apache.directory.fortress.core.GlobalIds#VALIDATOR_PROPS}2={@link Timeout}</li>
+ * <li>{@link org.apache.directory.fortress.core.GlobalIds#VALIDATOR_PROPS}3={@link ClockTime}</li>
+ * <li>{@link org.apache.directory.fortress.core.GlobalIds#VALIDATOR_PROPS}4={@link Day}</li>
+ * <li>{@link org.apache.directory.fortress.core.GlobalIds#DSD_VALIDATOR_PROP}={@link org.apache.directory.fortress.core.rbac.DSDChecker}</li>
+ * </ol>
+ * </p>
+ *
+ * @author Shawn McKinney
+ */
+public class CUtil
+{
+    private static final String CLS_NM = CUtil.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static List<Validator> validators;
+    private static final String DSDVALIDATOR = Config.getProperty(GlobalIds.DSD_VALIDATOR_PROP);
+
+    /**
+     * Used by DAO utilities to convert from a string with comma delimited values to fortress internal format {@link Constraint}.
+     *
+     * @param inputString contains raw data format which is comma delimited containing temporal data.
+     * @param constraint  used by internal processing to perform validations.
+     */
+    public static void setConstraint(String inputString, Constraint constraint)
+    {
+        if(VUtil.isNotNullOrEmpty(inputString))
+        {
+            StringTokenizer tkn = new StringTokenizer(inputString, GlobalIds.DELIMITER, true);
+            if (tkn.countTokens() > 0)
+            {
+                int count = tkn.countTokens();
+                int index = 0;
+                boolean previousTokenWasDelimiter = false;
+                for (int i = 0; i < count; i++)
+                {
+                    String szValue = tkn.nextToken();
+                    if(szValue.equals(GlobalIds.DELIMITER) && !previousTokenWasDelimiter)
+                    {
+                        previousTokenWasDelimiter = true;
+                    }
+                    else if(szValue.equals(GlobalIds.DELIMITER))
+                    {
+                        previousTokenWasDelimiter = true;
+                        index++;
+                    }
+                    else
+                    {
+                        previousTokenWasDelimiter = false;
+                        switch (index++)
+                        {
+                            case 0:
+                                // only set the name attr if it isn't already set:
+                                if (constraint.getName() == null || constraint.getName().length() == 0)
+                                    constraint.setName(szValue);
+                                break;
+                            case 1:
+                                constraint.setTimeout(Integer.parseInt(szValue));
+                                break;
+                            case 2:
+                                constraint.setBeginTime(szValue);
+                                break;
+                            case 3:
+                                constraint.setEndTime(szValue);
+                                break;
+                            case 4:
+                                constraint.setBeginDate(szValue);
+                                break;
+                            case 5:
+                                constraint.setEndDate(szValue);
+                                break;
+                            case 6:
+                                constraint.setBeginLockDate(szValue);
+                                break;
+                            case 7:
+                                constraint.setEndLockDate(szValue);
+                                break;
+                            case 8:
+                                constraint.setDayMask(szValue);
+                                break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Convert from fortress {@link Constraint} to comma delimited ldap format.
+     *
+     * @param constraint contains the temporal data.
+     * @return string containing raw data bound for ldap.
+     */
+    public static String setConstraint(Constraint constraint)
+    {
+        String szConstraint = null;
+        if (constraint != null)
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.append(constraint.getName());
+            sb.append(GlobalIds.DELIMITER);
+            if(constraint.getTimeout() != null)
+                sb.append(constraint.getTimeout());
+            sb.append(GlobalIds.DELIMITER);
+            if (constraint.getBeginTime() != null)
+                sb.append(constraint.getBeginTime());
+            sb.append(GlobalIds.DELIMITER);
+            if (constraint.getEndTime() != null)
+                sb.append(constraint.getEndTime());
+            sb.append(GlobalIds.DELIMITER);
+            if (constraint.getBeginDate() != null)
+                sb.append(constraint.getBeginDate());
+            sb.append(GlobalIds.DELIMITER);
+            if (constraint.getEndDate() != null)
+                sb.append(constraint.getEndDate());
+            sb.append(GlobalIds.DELIMITER);
+            if (constraint.getBeginLockDate() != null)
+                sb.append(constraint.getBeginLockDate());
+            sb.append(GlobalIds.DELIMITER);
+            if (constraint.getEndLockDate() != null)
+                sb.append(constraint.getEndLockDate());
+            sb.append(GlobalIds.DELIMITER);
+            if (constraint.getDayMask() != null)
+                sb.append(constraint.getDayMask());
+            szConstraint = sb.toString();
+        }
+        return szConstraint;
+    }
+
+    /**
+     * Validate the non-null attributes on the constraint.
+     *
+     * @param c1 contains the temporal values associated with an entity.
+     * @throws org.apache.directory.fortress.core.ValidationException on first invalid attribute found.
+     */
+    public static void validate(Constraint c1)
+        throws ValidationException
+    {
+        if (VUtil.isNotNullOrEmpty(c1.getTimeout()))
+        {
+            VUtil.timeout(c1.getTimeout());
+        }
+        if (VUtil.isNotNullOrEmpty(c1.getBeginTime()))
+        {
+            VUtil.beginTime(c1.getBeginTime());
+        }
+        if (VUtil.isNotNullOrEmpty(c1.getEndTime()))
+        {
+            VUtil.endTime(c1.getEndTime());
+        }
+        if (VUtil.isNotNullOrEmpty(c1.getBeginDate()))
+        {
+            VUtil.beginDate(c1.getBeginDate());
+        }
+        if (VUtil.isNotNullOrEmpty(c1.getEndDate()))
+        {
+            VUtil.endDate(c1.getEndDate());
+        }
+        if (VUtil.isNotNullOrEmpty(c1.getDayMask()))
+        {
+            VUtil.dayMask(c1.getDayMask());
+        }
+        if (VUtil.isNotNullOrEmpty(c1.getBeginLockDate()))
+        {
+            VUtil.beginDate(c1.getBeginLockDate());
+        }
+        if (VUtil.isNotNullOrEmpty(c1.getEndLockDate()))
+        {
+            VUtil.endDate(c1.getEndLockDate());
+        }
+    }
+
+    /**
+     * Utility is used during processing of constraint values.  The rule used here is if the target constraint will
+     * accept the source constraint attribute only when not set initially.  If target constraint's attribute is set,
+     * validation on the constraint will be performed.
+     *
+     * @param srcC Contains instantiated constraint with one or more attributes to be copied.
+     * @param trgC instantiated object may contain zero or more attributes set.  Copy will not be performed on set attrs.
+     * @throws org.apache.directory.fortress.core.ValidationException on first invalid attribute found.
+     */
+    public static void validateOrCopy(Constraint srcC, Constraint trgC)
+        throws ValidationException
+    {
+        //VUtil.timeout(trgC.getTimeout());
+        if (VUtil.isNotNullOrEmpty(trgC.getTimeout()))
+        {
+            srcC.setTimeout(trgC.getTimeout());
+        }
+        else if (VUtil.isNotNullOrEmpty(srcC.getTimeout()))
+        {
+            trgC.setTimeout(srcC.getTimeout());
+        }
+        if (VUtil.isNotNullOrEmpty(trgC.getBeginTime()))
+        {
+            VUtil.beginTime(trgC.getBeginTime());
+        }
+        else if (VUtil.isNotNullOrEmpty(srcC.getBeginTime()))
+        {
+            trgC.setBeginTime(srcC.getBeginTime());
+        }
+        if (VUtil.isNotNullOrEmpty(trgC.getEndTime()))
+        {
+            VUtil.endTime(trgC.getEndTime());
+        }
+        else if (VUtil.isNotNullOrEmpty(srcC.getEndTime()))
+        {
+            trgC.setEndTime(srcC.getEndTime());
+        }
+        if (VUtil.isNotNullOrEmpty(trgC.getBeginDate()))
+        {
+            VUtil.beginDate(trgC.getBeginDate());
+        }
+        else if (VUtil.isNotNullOrEmpty(srcC.getBeginDate()))
+        {
+            trgC.setBeginDate(srcC.getBeginDate());
+        }
+        if (VUtil.isNotNullOrEmpty(trgC.getEndDate()))
+        {
+            VUtil.endDate(trgC.getEndDate());
+        }
+        else if (VUtil.isNotNullOrEmpty(srcC.getEndDate()))
+        {
+            trgC.setEndDate(srcC.getEndDate());
+        }
+        if (VUtil.isNotNullOrEmpty(trgC.getDayMask()))
+        {
+            VUtil.dayMask(trgC.getDayMask());
+        }
+        else if (VUtil.isNotNullOrEmpty(srcC.getDayMask()))
+        {
+            trgC.setDayMask(srcC.getDayMask());
+        }
+        if (VUtil.isNotNullOrEmpty(trgC.getBeginLockDate()))
+        {
+            VUtil.beginDate(trgC.getBeginLockDate());
+        }
+        else if (VUtil.isNotNullOrEmpty(srcC.getBeginLockDate()))
+        {
+            trgC.setBeginLockDate(srcC.getBeginLockDate());
+        }
+        if (VUtil.isNotNullOrEmpty(trgC.getEndLockDate()))
+        {
+            VUtil.endDate(trgC.getEndLockDate());
+        }
+        else if (VUtil.isNotNullOrEmpty(srcC.getEndLockDate()))
+        {
+            trgC.setEndLockDate(srcC.getEndLockDate());
+        }
+    }
+
+    /**
+     * enum specifies what type of constraint is being targeted - User or Rold.
+     */
+    public static enum ConstraintType
+    {
+        /**
+         * Specifies {@link org.apache.directory.fortress.core.rbac.User}
+         */
+        USER,
+        /**
+         * Specifies {@link org.apache.directory.fortress.core.rbac.Role}
+         */
+        ROLE
+    }
+
+    /**
+     * static initializer retrieves Validators names from config and constructs for later processing.
+     */
+    static
+    {
+        try
+        {
+            validators = getValidators();
+        }
+        catch ( SecurityException ex)
+        {
+            LOG.error("static initialzier caught SecurityException=" + ex.getMessage(), ex);
+        }
+    }
+
+    /**
+     * Copy source constraint to target. Both must be created before calling this utility.
+     *
+     * @param srcC contains constraint source.
+     * @param trgC contains target constraint.
+     */
+    public static void copy(Constraint srcC, Constraint trgC)
+    {
+        // Both variables must be instantiated before being passed in to this method.
+        trgC.setTimeout(srcC.getTimeout());
+
+        if (VUtil.isNotNullOrEmpty(srcC.getName()))
+        {
+            trgC.setName(srcC.getName());
+        }
+        if (VUtil.isNotNullOrEmpty(srcC.getBeginTime()))
+        {
+            trgC.setBeginTime(srcC.getBeginTime());
+        }
+        if (VUtil.isNotNullOrEmpty(srcC.getEndTime()))
+        {
+            trgC.setEndTime(srcC.getEndTime());
+        }
+        if (VUtil.isNotNullOrEmpty(srcC.getDayMask()))
+        {
+            trgC.setDayMask(srcC.getDayMask());
+        }
+        if (VUtil.isNotNullOrEmpty(srcC.getBeginDate()))
+        {
+            trgC.setBeginDate(srcC.getBeginDate());
+        }
+        if (VUtil.isNotNullOrEmpty(srcC.getEndDate()))
+        {
+            trgC.setEndDate(srcC.getEndDate());
+        }
+        if (VUtil.isNotNullOrEmpty(srcC.getBeginLockDate()))
+        {
+            trgC.setBeginLockDate(srcC.getBeginLockDate());
+        }
+        if (VUtil.isNotNullOrEmpty(srcC.getEndLockDate()))
+        {
+            trgC.setEndLockDate(srcC.getEndLockDate());
+        }
+    }
+
+
+    /**
+     * This utility iterates over all of the Validators initialized for runtime and calls them passing the {@link Constraint} contained within the
+     * targeted entity.  If a particular {@link org.apache.directory.fortress.core.rbac.UserRole} violates constraint it will not be activated.  If {@link org.apache.directory.fortress.core.rbac.User} validation fails a ValidationException will be thrown thus preventing User logon.
+     *
+     * @param session contains {@link org.apache.directory.fortress.core.rbac.User} and {@link org.apache.directory.fortress.core.rbac.UserRole} constraints {@link Constraint} to be checked.
+     * @param type    specifies User {@link ConstraintType#USER} or rOLE {@link ConstraintType#ROLE}.
+     * @param checkDsd will check DSD constraints if true
+     * @throws org.apache.directory.fortress.core.SecurityException in the event validation fails for User or system error occurs.
+     */
+    public static void validateConstraints(Session session, ConstraintType type, boolean checkDsd)
+        throws SecurityException
+    {
+        String location = "validateConstraints";
+        int rc;
+        if (validators == null)
+        {
+            if(LOG.isDebugEnabled())
+            {
+                LOG.debug(location + " userId [" + session.getUserId() + "]  no constraints enabled");
+            }
+            return;
+        }
+        // no need to continue if the role list is empty and we're trying to check role constraints:
+        else if (type == ConstraintType.ROLE && !VUtil.isNotNullOrEmpty(session.getRoles()) && !VUtil.isNotNullOrEmpty(session.getAdminRoles()))
+        {
+            if(LOG.isDebugEnabled())
+            {
+                LOG.debug(location + " userId [" + session.getUserId() + "] has no roles assigned");
+            }
+            return;
+        }
+        for (Validator val : validators)
+        {
+            Time currTime = TUtil.getCurrentTime();
+            // first check the constraint on the user:
+            if (type == ConstraintType.USER)
+            {
+                rc = val.validate(session, session.getUser(), currTime);
+                if (rc > 0)
+                {
+                    String info = location + " user [" + session.getUserId() + "] was deactivated reason code [" + rc + "]";
+                    throw new ValidationException(rc, info);
+                }
+            }
+            // Check the constraints for each role assignment:
+            else
+            {
+                if (VUtil.isNotNullOrEmpty(session.getRoles()))
+                {
+                    // now check the constraint on every rbac role activation candidate contained within session object:
+                    ListIterator roleItems = session.getRoles().listIterator();
+                    while (roleItems.hasNext())
+                    {
+                        Constraint constraint = (Constraint) roleItems.next();
+                        rc = val.validate(session, constraint, currTime);
+                        if (rc > 0)
+                        {
+                            String msg = location + " role [" + constraint.getName() + "] for user ["
+                                + session.getUserId() + "] was deactivated reason code [" + rc + "]";
+                            LOG.info(msg);
+                            roleItems.remove();
+                            session.setWarning( new ObjectFactory().createWarning( rc, msg, Warning.Type.ROLE, constraint.getName() ) );
+                        }
+                    }
+                }
+                if (VUtil.isNotNullOrEmpty(session.getAdminRoles()))
+                {
+                    // now check the constraint on every arbac role activation candidate contained within session object:
+                    ListIterator roleItems = session.getAdminRoles().listIterator();
+                    while (roleItems.hasNext())
+                    {
+                        Constraint constraint = (Constraint) roleItems.next();
+                        rc = val.validate(session, constraint, currTime);
+                        if (rc > 0)
+                        {
+                            String msg = location + " admin role [" + constraint.getName() + "] for user ["
+                                + session.getUserId() + "] was deactivated reason code [" + rc + "]";
+                            LOG.info(msg);
+                            roleItems.remove();
+                            session.setWarning( new ObjectFactory().createWarning( rc, msg, Warning.Type.ROLE, constraint.getName() ) );
+                        }
+                    }
+                }
+            }
+        }
+
+        // now perform DSD validation on session's rbac roles:
+        if (checkDsd && DSDVALIDATOR != null && DSDVALIDATOR.length() > 0 && type == ConstraintType.ROLE && VUtil.isNotNullOrEmpty( session.getRoles() ))
+        {
+            Validator dsdVal = (Validator) ClassUtil.createInstance(DSDVALIDATOR);
+            dsdVal.validate(session, session.getUser(), null);
+        }
+        // reset the user's last access timestamp:
+        session.setLastAccess();
+    }
+
+    /**
+     * Utility is used internally by this class to retrieve a list of all Validator class names, instantiate and return.
+     *
+     * @return list of type {@link Validator} containing all active validation routines for entity constraint processing.
+     * @throws org.apache.directory.fortress.core.CfgException in the event validator cannot be instantiated.
+     */
+    private static List<Validator> getValidators()
+        throws CfgException
+    {
+        List<Validator> validators = new ArrayList<>();
+        for (int i = 0; ; i++)
+        {
+            String prop = GlobalIds.VALIDATOR_PROPS + i;
+            String className = Config.getProperty(prop);
+            if (className == null)
+            {
+                break;
+            }
+
+            validators.add((Validator) ClassUtil.createInstance(className));
+        }
+        return validators;
+    }
+}
\ 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/util/time/ClockTime.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/util/time/ClockTime.java b/src/main/java/org/apache/directory/fortress/core/util/time/ClockTime.java
new file mode 100755
index 0000000..0fed241
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/util/time/ClockTime.java
@@ -0,0 +1,81 @@
+/*
+ *   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.util.time;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.rbac.Session;
+
+/**
+ * This class performs time validation for {@link Constraint}.  This validator will ensure the current time falls between {@link Constraint#getBeginTime()} and {@link Constraint#getEndTime()}
+ * The format requires military time, i.e. 0800 for 8:00 am, 1700 for 5:00 pm.  The constant {@link org.apache.directory.fortress.core.GlobalIds#NONE} may be used to disable checks for a particular entity.
+ * for {@link Constraint} validations that occur in
+ * <h4> Constraint Targets include</h4>
+ * <ol>
+ * <li>{@link org.apache.directory.fortress.core.rbac.User} maps to 'ftCstr' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserRole} maps to 'ftRC' attribute on 'ftUserAttrs' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.Role}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.AdminRole}  maps to 'ftCstr' attribute on 'ftRls' object class</li>
+ * <li>{@link org.apache.directory.fortress.core.rbac.UserAdminRole}  maps to 'ftARC' attribute on 'ftRls' object class</li>
+ * </ol>
+ * </p>
+ *
+ * @author Shawn McKinney
+ */
+public class ClockTime
+    implements Validator
+{
+    /**
+     * This method is called during entity activation, {@link CUtil#validateConstraints} and ensures the current time is
+     * between {@link Constraint#getBeginTime()} and {@link Constraint#getBeginTime()}.
+     *
+     * @param session    required for {@link Validator} interface but not used here.
+     * @param constraint contains the begin and end times.  Maps listed above.
+     * @param time       contains the current time.
+     * @return '0' if validation succeeds else {@link org.apache.directory.fortress.core.GlobalErrIds#ACTV_FAILED_TIME} if failed.
+     */
+    @Override
+    public int validate(Session session, Constraint constraint, Time time)
+    {
+        int rc = GlobalErrIds.ACTV_FAILED_TIME;
+        if (constraint.getBeginTime() == null || constraint.getBeginTime().compareToIgnoreCase(GlobalIds.NONE) == 0)
+        {
+            rc = 0;
+        }
+        else
+        {
+            Integer beginTime = new Integer(constraint.getBeginTime());
+            Integer endTime = new Integer(constraint.getEndTime());
+            if (beginTime == 0 && endTime == 0)
+            {
+                rc = 0;
+            }
+            else
+            {
+                if (beginTime.compareTo(time.currentTime) <= 0
+                    && endTime.compareTo(time.currentTime) >= 0)
+                {
+                    rc = 0;
+                }
+            }
+        }
+        return rc;
+    }
+}
\ No newline at end of file