You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by sm...@apache.org on 2014/10/22 19:48:29 UTC
[14/16] Remove the unboundid daos classes and lib,
move the apache dao's into rbac package and make its classes and
methods package private.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/AcceleratorDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AcceleratorDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/AcceleratorDAO.java
new file mode 100644
index 0000000..b01b5a3
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AcceleratorDAO.java
@@ -0,0 +1,373 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.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.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
+ */
+final class AcceleratorDAO extends ApacheDsDataProvider
+
+{
+ 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}.
+ *
+ */
+ 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}.
+ */
+ 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}.
+ */
+ 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}.
+ */
+ 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}.
+ */
+ 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}.
+ */
+ 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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/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
index 88bf87f..07a35ee 100755
--- a/src/main/java/org/apache/directory/fortress/core/rbac/AdminRole.java
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AdminRole.java
@@ -28,8 +28,6 @@ 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;
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleDAO.java
new file mode 100755
index 0000000..e0dfdaa
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/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;
+
+
+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
+ */
+final class AdminRoleDAO extends ApacheDsDataProvider
+{
+ 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.
+ */
+ 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.
+ */
+ 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
+ */
+ 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.
+ */
+ 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.
+ */
+ 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.
+ */
+ 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.
+ */
+ 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
+ *
+ */
+ 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
+ *
+ */
+ 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
+ */
+ 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
+ */
+ 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/49e82a58/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
index d589b3c..35aece2 100755
--- a/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleP.java
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AdminRoleP.java
@@ -30,8 +30,6 @@ 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;
@@ -57,7 +55,7 @@ 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 AdminRoleDAO rDao = new AdminRoleDAO();
private static final OrgUnitP op = new OrgUnitP();
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/src/main/java/org/apache/directory/fortress/core/rbac/AuditDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/rbac/AuditDAO.java b/src/main/java/org/apache/directory/fortress/core/rbac/AuditDAO.java
new file mode 100755
index 0000000..1f0858c
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AuditDAO.java
@@ -0,0 +1,780 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.fortress.core.rbac;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.api.ldap.model.cursor.CursorException;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.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.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
+ */
+final class AuditDAO extends ApacheDsDataProvider
+{
+ 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
+ *
+ */
+ 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
+ *
+ */
+ 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
+ *
+ */
+ 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
+ *
+ */
+ 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
+ *
+ */
+ 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
+ */
+ 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/49e82a58/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
index fd4a8ee..0fd7e17 100755
--- a/src/main/java/org/apache/directory/fortress/core/rbac/AuditP.java
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/AuditP.java
@@ -23,7 +23,6 @@ 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;
/**
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/49e82a58/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
index ddb20bd..a1db133 100755
--- a/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnit.java
+++ b/src/main/java/org/apache/directory/fortress/core/rbac/OrgUnit.java
@@ -31,10 +31,6 @@ 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