opends/resource/config/config.ldif
@@ -57,7 +57,7 @@ ds-cfg-global-aci: (target="ldap:///")(targetscope="base")(targetattr="namingContexts||supportedAuthPasswordSchemes||supportedControl||supportedExtension||supportedFeatures||supportedSASLMechanisms||vendorName||vendorVersion")(version 3.0; acl "User-Visible Root DSE Operational Attributes"; allow (read,search,compare) userdn="ldap:///anyone";) ds-cfg-global-aci: (targetattr="createTimestamp||creatorsName||modifiersName||modifyTimestamp||entryDN||entryUUID||subschemaSubentry")(version 3.0; acl "User-Visible Operational Attributes"; allow (read,search,compare) userdn="ldap:///anyone";) cn: Access Control Handler ds-cfg-acl-handler-class: org.opends.server.authorization.dseecompat.AciProvider ds-cfg-acl-handler-class: org.opends.server.authorization.dseecompat.AciHandler ds-cfg-acl-handler-enabled: true dn: cn=Account Status Notification Handlers,cn=config opends/src/admin/defn/org/opends/server/admin/std/AccessControlHandlerConfiguration.xml
@@ -68,7 +68,7 @@ <adm:syntax> <adm:java-class> <adm:instance-of> org.opends.server.api.AccessControlProvider org.opends.server.api.AccessControlHandler </adm:instance-of> </adm:java-class> </adm:syntax> opends/src/server/org/opends/server/api/AccessControlHandler.java
@@ -27,21 +27,61 @@ package org.opends.server.api; import org.opends.server.admin.std.server.AccessControlHandlerCfg; import org.opends.server.config.ConfigException; import org.opends.server.core.*; import org.opends.server.types.*; import org.opends.server.workflowelement.localbackend.*; /** * This class defines the set of methods and structures that must be * implemented by a Directory Server access control handler. All * methods in this class should take the entire request into account * when making the determination, including any request controls that * might have been provided. * * @param <T> The type of access control configuration handled by * this access control provider implementation. */ public abstract class AccessControlHandler <T extends AccessControlHandlerCfg> { /** * Initializes the access control handler implementation based on * the information in the provided configuration entry. * * @param configuration The configuration object that contains the * information to use to initialize this * access control handler. * * @throws ConfigException If an unrecoverable problem arises in * the process of performing the * initialization. * * @throws InitializationException If a problem occurs during * initialization that is not * related to the server * configuration. */ public abstract void initializeAccessControlHandler(T configuration) throws ConfigException, InitializationException; /** * Performs any necessary finalization for the access control * handler implementation. This will be called just after the * handler has been deregistered with the server but before it has * been unloaded. */ public abstract void finalizeAccessControlHandler(); /** * Indicates whether the provided add operation is allowed based on * the access control configuration. This method should not alter * the provided add operation in any way. @@ -49,12 +89,11 @@ * @param addOperation The operation for which to make the * determination. * * @return <CODE>true</CODE> if the operation should be allowed by * the access control configuration, or <CODE>false</CODE> * if not. * @return {@code true} if the operation should be allowed by the * access control configuration, or {@code false} if not. */ public abstract boolean isAllowed(LocalBackendAddOperation addOperation); addOperation); @@ -66,12 +105,11 @@ * @param bindOperation The operation for which to make the * determination. * * @return <CODE>true</CODE> if the operation should be allowed by * the access control configuration, or <CODE>false</CODE> * if not. * @return {@code true} if the operation should be allowed by the * access control configuration, or {@code false} if not. */ public abstract boolean isAllowed(LocalBackendBindOperation bindOperation); bindOperation); @@ -83,9 +121,8 @@ * @param compareOperation The operation for which to make the * determination. * * @return <CODE>true</CODE> if the operation should be allowed by * the access control configuration, or <CODE>false</CODE> * if not. * @return {@code true} if the operation should be allowed by the * access control configuration, or {@code false} if not. */ public abstract boolean isAllowed(CompareOperation compareOperation); @@ -100,12 +137,11 @@ * @param deleteOperation The operation for which to make the * determination. * * @return <CODE>true</CODE> if the operation should be allowed by * the access control configuration, or <CODE>false</CODE> * if not. * @return {@code true} if the operation should be allowed by the * access control configuration, or {@code false} if not. */ public abstract boolean isAllowed(LocalBackendDeleteOperation deleteOperation); deleteOperation); @@ -117,9 +153,8 @@ * @param extendedOperation The operation for which to make the * determination. * * @return <CODE>true</CODE> if the operation should be allowed by * the access control configuration, or <CODE>false</CODE> * if not. * @return {@code true} if the operation should be allowed by the * access control configuration, or {@code false} if not. */ public abstract boolean isAllowed(ExtendedOperation extendedOperation); @@ -134,12 +169,11 @@ * @param modifyOperation The operation for which to make the * determination. * * @return <CODE>true</CODE> if the operation should be allowed by * the access control configuration, or <CODE>false</CODE> * if not. * @return {@code true} if the operation should be allowed by the * access control configuration, or {@code false} if not. */ public abstract boolean isAllowed(LocalBackendModifyOperation modifyOperation); modifyOperation); @@ -151,9 +185,8 @@ * @param modifyDNOperation The operation for which to make the * determination. * * @return <CODE>true</CODE> if the operation should be allowed by * the access control configuration, or <CODE>false</CODE> * if not. * @return {@code true} if the operation should be allowed by the * access control configuration, or {@code false} if not. */ public abstract boolean isAllowed(ModifyDNOperation modifyDNOperation); @@ -171,12 +204,11 @@ * @param searchOperation The operation for which to make the * determination. * * @return <CODE>true</CODE> if the operation should be allowed by * the access control configuration, or <CODE>false</CODE> * if not. * @return {@code true} if the operation should be allowed by the * access control configuration, or {@code false} if not. */ public abstract boolean isAllowed(LocalBackendSearchOperation searchOperation); searchOperation); @@ -190,13 +222,12 @@ * @param searchEntry The search result entry for which to * make the determination. * * @return <CODE>true</CODE> if the operation should be allowed by * the access control configuration, or <CODE>false</CODE> * @return {@code true} if the access control configuration allows * the entry to be returned to the client, or {@code false} * if not. */ public abstract boolean maySend( SearchOperation searchOperation, SearchResultEntry searchEntry); public abstract boolean maySend(SearchOperation searchOperation, SearchResultEntry searchEntry); @@ -212,9 +243,9 @@ * @return Returns the entry with filtered attributes and values * removed. */ public abstract SearchResultEntry filterEntry( SearchOperation searchOperation, SearchResultEntry searchEntry); public abstract SearchResultEntry filterEntry(SearchOperation searchOperation, SearchResultEntry searchEntry); @@ -222,57 +253,56 @@ * Indicates whether the provided search result reference may be * sent to the client. * * @param searchOperation * The search operation with which the provided reference * is associated. * @param searchReference * The search result reference for which to make the * determination. * @return <CODE>true</CODE> if the operation should be allowed by * the access control configuration, or <CODE>false</CODE> * if not. * @param searchOperation The search operation with which the * provided reference is associated. * @param searchReference The search result reference for which to * make the determination. * * @return {@code true} if the access control configuration allows * the reference to be returned to the client, or * {@code false} if not. */ public abstract boolean maySend( SearchOperation searchOperation, SearchResultReference searchReference); public abstract boolean maySend(SearchOperation searchOperation, SearchResultReference searchReference); /** * Indicates whether a proxied authorization control is allowed * based on the current operation and the new authorization * entry. * based on the current operation and the new authorization entry. * * @param operation * The operation with which the proxied authorization * control is associated. * @param newAuthorizationEntry * The new authorization entry related to the * proxied authorization control authorization ID. * @return <CODE>true</CODE> if the operation should be allowed by * the access control configuration, or <CODE>false</CODE> * if not. * @param operation The operation with which the * proxied authorization control is * associated. * @param newAuthorizationEntry The new authorization entry * related to the proxied * authorization control * authorization ID. * * @return {@code true} if the operation should be allowed to use * the proxied authorization control, or {@code false} if * not. */ public abstract boolean isProxiedAuthAllowed(Operation operation, Entry newAuthorizationEntry); Entry newAuthorizationEntry); /** * Indicates whether a geteffectiverights control is allowed * Indicates whether a getEffectiveRights control is allowed * based on the current operation and the control contents. * * @param operation * The operation with which the geteffectiverights * control is associated. This is always a * SearchOperation. * @param control * The control class containing the decoded * geteffectiverights control contents. * @return <CODE>true</CODE> if the operation should be allowed * by the access control configuration, or * <CODE>false</CODE> if not. * @param operation The operation with which the * getEffectiveRights control is associated. * This is always a SearchOperation. * @param control The control class containing the decoded * getEffectiveRights control contents. * * @return {@code true} if the use of the getEffectiveRights * control should be allowed, or {@code false} if not. */ public abstract boolean isGetEffectiveRightsAllowed(Operation operation, Control control); public abstract boolean isGetEffectiveRightsAllowed( SearchOperation operation, Control control); } opends/src/server/org/opends/server/api/AccessControlProvider.java
File was deleted opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -28,23 +28,15 @@ package org.opends.server.authorization.dseecompat; import static org.opends.server.authorization.dseecompat.Aci.*; import org.opends.server.admin.std.server.DseeCompatAccessControlHandlerCfg; import org.opends.server.api.AccessControlHandler; import static org.opends.server.config.ConfigConstants.ATTR_AUTHZ_GLOBAL_ACI; import org.opends.server.core.*; import static org.opends.server.loggers.ErrorLogger.logError; import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; import static org.opends.server.loggers.debug.DebugLogger.getTracer; import org.opends.server.loggers.debug.DebugTracer; import static org.opends.server.messages.AciMessages.*; import static org.opends.server.messages.MessageHandler.getMessage; import org.opends.server.protocols.internal.InternalClientConnection; import org.opends.server.protocols.internal.InternalSearchOperation; import static org.opends.server.schema.SchemaConstants.SYNTAX_DN_OID; import org.opends.server.types.*; import static org.opends.server.util.ServerConstants.OID_GET_EFFECTIVE_RIGHTS; import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; import static org.opends.server.util.StaticUtils.toLowerCase; @@ -52,104 +44,132 @@ import java.util.*; import java.util.concurrent.locks.Lock; import org.opends.server.admin.std.server.DseeCompatAccessControlHandlerCfg; import org.opends.server.api.AccessControlHandler; import org.opends.server.config.ConfigException; import org.opends.server.core.*; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.protocols.internal.InternalClientConnection; import org.opends.server.protocols.internal.InternalSearchOperation; import org.opends.server.types.*; import org.opends.server.workflowelement.localbackend.*; /** * The AciHandler class performs the main processing for the * dseecompat package. * The AciHandler class performs the main processing for the dseecompat package. */ public class AciHandler extends AccessControlHandler { public class AciHandler extends AccessControlHandler<DseeCompatAccessControlHandlerCfg> { /** * The tracer object for the debug logger. */ private static final DebugTracer TRACER = getTracer(); /* * The list that holds that ACIs keyed by the DN of the entry * holding the ACI. */ private AciList aciList; /** * The list that holds that ACIs keyed by the DN of the entry * holding the ACI. */ private AciList aciList; /* * The listener that handles ACI changes caused by LDAP operations, ACI * decode failure alert logging and backend initialization ACI list * adjustment. */ private AciListenerManager aciListenerMgr; /** * The listener that handles ACI changes caused by LDAP operations, ACI * decode failure alert logging and backend initialization ACI list * adjustment. */ private AciListenerManager aciListenerMgr; /** * Attribute type corresponding to "aci" attribute. */ public static AttributeType aciType; /** * Attribute type corresponding to "aci" attribute. */ public static AttributeType aciType; /** * Attribute type corresponding to global "ds-cfg-global-aci" attribute. */ public static AttributeType globalAciType; /** * Attribute type corresponding to global "ds-cfg-global-aci" attribute. */ public static AttributeType globalAciType; /** * String used to save the original authorization entry in an operation * attachment if a proxied authorization control was seen. */ public static String ORIG_AUTH_ENTRY="origAuthorizationEntry"; /** * String used to save the original authorization entry in an operation * attachment if a proxied authorization control was seen. */ public static String ORIG_AUTH_ENTRY="origAuthorizationEntry"; /** * String used to save a resource entry containing all the attributes in * the SearchOperation attachment list. This is only used during * geteffectiverights read right processing when all of an entry'ss * attributes need to examined. */ public static String ALL_ATTRS_RESOURCE_ENTRY = "allAttrsResourceEntry"; /** * String used to save a resource entry containing all the attributes in * the SearchOperation attachment list. This is only used during * geteffectiverights read right processing when all of an entry'ss * attributes need to examined. */ public static String ALL_ATTRS_RESOURCE_ENTRY = "allAttrsResourceEntry"; /** * String used to indicate that the evaluating ACI had a all user attributes * targetattr match (targetattr="*"). */ public static String ALL_USER_ATTRS_MATCHED = "allUserAttrsMatched"; /** * String used to indicate that the evaluating ACI had a all user attributes * targetattr match (targetattr="*"). */ public static String ALL_USER_ATTRS_MATCHED = "allUserAttrsMatched"; /** * String used to indicate that the evaluating ACI had a all operational * attributes targetattr match (targetattr="+"). */ public static String ALL_OP_ATTRS_MATCHED = "allOpAttrsMatched"; /** * String used to indicate that the evaluating ACI had a all operational * attributes targetattr match (targetattr="+"). */ public static String ALL_OP_ATTRS_MATCHED = "allOpAttrsMatched"; /** * This constructor instantiates the ACI handler class that performs the * main processing for the dseecompat ACI package. It does the following * initializations: * * * - Instantiates the ACI list cache. * * - Instantiates thr AciListenerManager. * * - Processes all global attribute types found in the configuration entry * and adds them to the ACI list cache. * * - Processes all "aci" attributes found in the "cn=config" naming * context and adds them to the ACI list cache. * * @param configuration The config handler containing the ACI * configuration information. * @throws InitializationException if there is a problem processing the * config entry or config naming context. */ public AciHandler(DseeCompatAccessControlHandlerCfg configuration) throws InitializationException { DN configurationDN=configuration.dn(); aciList = new AciList(configurationDN); aciListenerMgr = new AciListenerManager(aciList, configurationDN); if((aciType = DirectoryServer.getAttributeType("aci")) == null) aciType = DirectoryServer.getDefaultAttributeType("aci"); if((globalAciType = DirectoryServer.getAttributeType(ATTR_AUTHZ_GLOBAL_ACI)) == null) globalAciType = DirectoryServer.getDefaultAttributeType(ATTR_AUTHZ_GLOBAL_ACI); processGlobalAcis(configuration); processConfigAcis(); /** * Creates a new DSEE-compatible access control handler. */ public AciHandler() { // No implementation required. All initialization should be done in the // intializeAccessControlHandler method. } /** * {@inheritDoc} */ @Override() public void initializeAccessControlHandler( DseeCompatAccessControlHandlerCfg configuration) throws ConfigException, InitializationException { DN configurationDN=configuration.dn(); aciList = new AciList(configurationDN); aciListenerMgr = new AciListenerManager(aciList, configurationDN); if((aciType = DirectoryServer.getAttributeType("aci")) == null) { aciType = DirectoryServer.getDefaultAttributeType("aci"); } if((globalAciType = DirectoryServer.getAttributeType(ATTR_AUTHZ_GLOBAL_ACI)) == null) { globalAciType = DirectoryServer.getDefaultAttributeType(ATTR_AUTHZ_GLOBAL_ACI); } processGlobalAcis(configuration); processConfigAcis(); } /** * {@inheritDoc} */ @Override() public void finalizeAccessControlHandler() { // No implementation required. } /** * Process all global ACI attribute types found in the configuration * entry and adds them to that ACI list cache. It also logs messages about @@ -1153,7 +1173,8 @@ * @param c The request control to save. * @return True if the control is allowed access. */ public boolean isGetEffectiveRightsAllowed(Operation operation, Control c) { public boolean isGetEffectiveRightsAllowed(SearchOperation operation, Control c) { operation.setAttachment(OID_GET_EFFECTIVE_RIGHTS, c); return true; } @@ -1197,3 +1218,4 @@ return true; } } opends/src/server/org/opends/server/authorization/dseecompat/AciProvider.java
File was deleted opends/src/server/org/opends/server/core/AccessControlConfigManager.java
@@ -26,10 +26,10 @@ */ package org.opends.server.core; import org.opends.server.types.DebugLogLevel; import static org.opends.server.loggers.ErrorLogger.*; import static org.opends.server.loggers.debug.DebugLogger.*; import org.opends.server.loggers.debug.DebugTracer; import static org.opends.server.messages.ConfigMessages.*; import static org.opends.server.messages.MessageHandler.*; import static org.opends.server.util.ServerConstants.*; @@ -48,25 +48,29 @@ import org.opends.server.admin.std.server.AccessControlHandlerCfg; import org.opends.server.admin.std.server.RootCfg; import org.opends.server.api.AccessControlHandler; import org.opends.server.api.AccessControlProvider; import org.opends.server.api.AlertGenerator; import org.opends.server.config.ConfigException; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.types.ConfigChangeResult; import org.opends.server.types.DebugLogLevel; import org.opends.server.types.DN; import org.opends.server.types.ErrorLogCategory; import org.opends.server.types.ErrorLogSeverity; import org.opends.server.types.InitializationException; import org.opends.server.types.ResultCode; /** * This class manages the application-wide access-control configuration. * <p> * When access control is disabled a default "permissive" access control * implementation is used, which permits all operations regardless of * the identity of the user. * implementation is used, which permits all operations regardless of the * identity of the user. */ public final class AccessControlConfigManager implements AlertGenerator implements AlertGenerator , ConfigurationChangeListener<AccessControlHandlerCfg> { /** * The tracer object for the debug logger. @@ -81,48 +85,72 @@ private static AccessControlConfigManager instance = null; // The active access control implementation. private AtomicReference<AccessControlProvider> accessControlProvider; private AtomicReference<AccessControlHandler> accessControlHandler; // The current configuration. private PrivateACLConfiguration currentConfiguration; private AccessControlHandlerCfg currentConfiguration; /** * Creates a new instance of this access control configuration * manager. */ private AccessControlConfigManager() { this.accessControlHandler = new AtomicReference<AccessControlHandler>( new DefaultAccessControlHandler()); this.currentConfiguration = null; } /** * Get the single application-wide access control manager instance. * * @return The access control manager. */ public static AccessControlConfigManager getInstance() { if (instance == null) { public static AccessControlConfigManager getInstance() { if (instance == null) { instance = new AccessControlConfigManager(); } return instance; } /** * Determine if access control is enabled according to the current * configuration. * * @return Returns <code>true</code> if access control is enabled, * <code>false</code> otherwise. * @return {@code true} if access control is enabled, {@code false} * otherwise. */ public boolean isAccessControlEnabled() { public boolean isAccessControlEnabled() { return currentConfiguration.isEnabled(); } /** * Get the active access control handler. * <p> * When access control is disabled, this method returns a default * access control implementation which permits all operations. * When access control is disabled, this method returns a default access * control implementation which permits all operations. * * @return Returns the active access control handler (never * <code>null</code>). * @return The active access control handler (never {@code null}). */ public AccessControlHandler getAccessControlHandler() { return accessControlProvider.get().getInstance(); public AccessControlHandler getAccessControlHandler() { return accessControlHandler.get(); } /** * Initializes the access control sub-system. This should only be * called at Directory Server startup. If an error occurs then an @@ -137,9 +165,9 @@ * handler that is not related to the Directory Server * configuration. */ void initializeAccessControl() throws ConfigException, InitializationException { public void initializeAccessControl() throws ConfigException, InitializationException { // Get the root configuration object. ServerManagementContext managementContext = ServerManagementContext.getInstance(); @@ -153,371 +181,212 @@ AccessControlHandlerCfg accessControlConfiguration = rootConfiguration.getAccessControlHandler(); // Parse the configuration entry. PrivateACLConfiguration configuration = PrivateACLConfiguration .readConfiguration(accessControlConfiguration); // We have a valid usable entry, so register a change listener in // order to handle configuration changes. accessControlConfiguration.addChangeListener(new ChangeListener()); accessControlConfiguration.addChangeListener(this); // The configuration looks valid, so install it. updateConfiguration(configuration); updateConfiguration(accessControlConfiguration); } /** * Creates a new instance of this access control configuration * manager. */ private AccessControlConfigManager() { this.accessControlProvider = new AtomicReference<AccessControlProvider>( new DefaultAccessControlProvider()); this.currentConfiguration = null; } /** * Updates the access control configuration based on the contents of a * valid configuration entry. * * @param newConfiguration * The new configuration object. * @throws ConfigException * If the access control configuration is invalid. * @throws InitializationException * If the access control handler provider could not be * instantiated. * @param newConfiguration The new configuration object. * * @throws ConfigException If the access control configuration is invalid. * * @throws InitializationException If the access control handler provider * could not be instantiated. */ private void updateConfiguration(PrivateACLConfiguration newConfiguration) throws ConfigException, InitializationException { private void updateConfiguration(AccessControlHandlerCfg newConfiguration) throws ConfigException, InitializationException { DN configEntryDN = newConfiguration.dn(); String newHandlerClass = null; DN configEntryDN = newConfiguration.getConfiguration().dn(); Class<? extends AccessControlProvider> newHandlerClass = null; if (currentConfiguration == null) { if (currentConfiguration == null) { // Initialization phase. if (newConfiguration.isEnabled()) { newHandlerClass = newConfiguration.getProviderClass(); } else { newHandlerClass = DefaultAccessControlProvider.class; if (newConfiguration.isEnabled()) { newHandlerClass = newConfiguration.getAclHandlerClass(); } } else { else { newHandlerClass = DefaultAccessControlHandler.class.getName(); } } else { boolean enabledOld = currentConfiguration.isEnabled(); boolean enabledNew = newConfiguration.isEnabled(); if (enabledOld == false && enabledNew == true) { // Access control has been enabled - load new class. newHandlerClass = newConfiguration.getProviderClass(); } else if (enabledOld == true && enabledNew == false) { // Access control has been disabled - load null handler. newHandlerClass = DefaultAccessControlProvider.class; } else if (enabledNew == true) { // Access control is enabled - load new class if it has changed. if (currentConfiguration.getProviderClass().equals( newConfiguration.getProviderClass()) == false) { newHandlerClass = newConfiguration.getProviderClass(); } if ((! enabledOld) && enabledNew) { // Access control has been enabled - get the new class name. newHandlerClass = newConfiguration.getAclHandlerClass(); } else if (enabledOld && (! enabledNew)) { // Access control has been disabled - get the default handler class // name. newHandlerClass = DefaultAccessControlHandler.class.getName(); } else if (enabledNew) { // Access control is already enabled, but still get the handler class // name to see if it has changed. newHandlerClass = newConfiguration.getAclHandlerClass(); } } // If the access control handler provider class has changed, // finalize the old // one and instantiate the new. if (newHandlerClass != null) { AccessControlProvider<? extends AccessControlHandlerCfg> newHandler ; try { // If the access control handler provider class has changed, finalize the // old one and instantiate the new one. if (newHandlerClass != null) { AccessControlHandler<? extends AccessControlHandlerCfg> newHandler; try { if (newConfiguration.isEnabled()) { newHandler = loadProvider(newHandlerClass.getName(), newConfiguration .getConfiguration()); newHandler = loadHandler(newHandlerClass, newConfiguration); } else { newHandler = new DefaultAccessControlProvider(); newHandler = new DefaultAccessControlHandler(); newHandler.initializeAccessControlHandler(null); } } catch (Exception e) { } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } int msgID = MSGID_CONFIG_AUTHZ_UNABLE_TO_INSTANTIATE_HANDLER; String message = getMessage(msgID, newHandlerClass.getName(), String.valueOf(configEntryDN.toString()), stackTraceToSingleLineString(e)); String message = getMessage(msgID, newHandlerClass, String.valueOf(configEntryDN.toString()), stackTraceToSingleLineString(e)); throw new InitializationException(msgID, message, e); } // Switch the handlers without interfering with other threads. AccessControlProvider oldHandler = accessControlProvider .getAndSet(newHandler); AccessControlHandler oldHandler = accessControlHandler.getAndSet(newHandler); if (oldHandler != null) { if (oldHandler != null) { oldHandler.finalizeAccessControlHandler(); } // If access control has been disabled put a warning in the log. if (newHandlerClass.equals(DefaultAccessControlProvider.class)) { if (newHandlerClass.equals(DefaultAccessControlHandler.class)) { int msgID = MSGID_CONFIG_AUTHZ_DISABLED; String message = getMessage(msgID); logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_WARNING, message, msgID); ErrorLogSeverity.SEVERE_WARNING, message, msgID); if (currentConfiguration != null) { DirectoryServer.sendAlertNotification(this, ALERT_TYPE_ACCESS_CONTROL_DISABLED, msgID, message); ALERT_TYPE_ACCESS_CONTROL_DISABLED, msgID, message); } } else { } else { int msgID = MSGID_CONFIG_AUTHZ_ENABLED; String message = getMessage(msgID, newHandlerClass.getName()); logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.NOTICE, message, msgID); String message = getMessage(msgID, newHandlerClass); logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.NOTICE, message, msgID); if (currentConfiguration != null) { DirectoryServer.sendAlertNotification(this, ALERT_TYPE_ACCESS_CONTROL_ENABLED, msgID, message); ALERT_TYPE_ACCESS_CONTROL_ENABLED, msgID, message); } } } // Switch in the local configuration. // // TODO: possible race condition here - should be an atomic // reference and sync'ed with the handler reference. We can assume // that config changes won't happen that much though. currentConfiguration = newConfiguration; } /** * Internal class implementing the change listener interface. * {@inheritDoc} */ private class ChangeListener implements ConfigurationChangeListener<AccessControlHandlerCfg> public boolean isConfigurationChangeAcceptable( AccessControlHandlerCfg configuration, List<String> unacceptableReasons) { /** * {@inheritDoc} */ public boolean isConfigurationChangeAcceptable( AccessControlHandlerCfg configuration, List<String> unacceptableReasons) try { try { // Parse the configuration entry. PrivateACLConfiguration.readConfiguration(configuration); } catch (ConfigException e) { unacceptableReasons.add(e.getMessage()); return false; // If the access control handler is disabled, we don't care about the // configuration. If it is enabled, then all we care about is whether we // can load the access control handler class. if (configuration.isEnabled()) { loadHandler(configuration.getAclHandlerClass(), null); } return true; } catch (InitializationException e) { unacceptableReasons.add(e.getMessage()); return false; } /** * {@inheritDoc} */ public ConfigChangeResult applyConfigurationChange( AccessControlHandlerCfg configuration) { ResultCode resultCode = ResultCode.SUCCESS; ArrayList<String> messages = new ArrayList<String>(); try { // Parse the configuration entry. PrivateACLConfiguration newConfiguration = PrivateACLConfiguration .readConfiguration(configuration); // The configuration looks valid, so install it. updateConfiguration(newConfiguration); } catch (ConfigException e) { messages.add(e.getMessage()); resultCode = ResultCode.CONSTRAINT_VIOLATION; } catch (InitializationException e) { messages.add(e.getMessage()); resultCode = DirectoryServer.getServerErrorResultCode(); } return new ConfigChangeResult(resultCode, false, messages); } return true; } /** * Internal class used to represent the parsed configuration entry. * {@inheritDoc} */ private static class PrivateACLConfiguration { public ConfigChangeResult applyConfigurationChange( AccessControlHandlerCfg configuration) { ResultCode resultCode = ResultCode.SUCCESS; ArrayList<String> messages = new ArrayList<String>(); // Flag indicating whether or not access control is enabled. private boolean enabled; // The current access control provider class specified in // the configuration. private Class<? extends AccessControlProvider> providerClass; // The entry that this object is mapped to. private AccessControlHandlerCfg configuration; /** * Parses a configuration entry and, if it is valid, returns an * object representation of it. * * @param configuration * The access control configuration entry. * @return An object representation of the parsed configuration. * @throws ConfigException * If a the access control configuration is invalid. */ public static PrivateACLConfiguration readConfiguration( AccessControlHandlerCfg configuration) throws ConfigException { // The access control configuration entry must have the correct // object class. if (configuration.getAclHandlerClass() == null) { int msgID = MSGID_CONFIG_AUTHZ_ENTRY_DOES_NOT_HAVE_OBJECT_CLASS; String message = getMessage(msgID, configuration.toString()); throw new ConfigException(msgID, message); } // Parse the attributes. boolean enabled = configuration.isEnabled() ; Class<? extends AccessControlProvider> providerClass = getClassAttribute(configuration); return new PrivateACLConfiguration(configuration, enabled, providerClass); try { // Attempt to install the new configuration. updateConfiguration(configuration); } catch (ConfigException e) { messages.add(e.getMessage()); resultCode = ResultCode.CONSTRAINT_VIOLATION; } catch (InitializationException e) { messages.add(e.getMessage()); resultCode = DirectoryServer.getServerErrorResultCode(); } /** * Determine if access control is enabled according to the * configuration. * * @return Returns <code>true</code> if access control is enabled, * <code>false</code> otherwise. */ public boolean isEnabled() { return enabled; } /** * Get the access control provider class specified in the * configuration. * * @return Returns the {@link AccessControlProvider} class. */ public Class<? extends AccessControlProvider> getProviderClass() { return providerClass; } /** * Get the configuration entry associated with this configuration * object. * * @return Returns the configuration entry. */ public AccessControlHandlerCfg getConfiguration() { return configuration; } /** * Construct a new configuration object with the specified parsed * attribute values. * * @param configuration * The associated access control configuration entry. * @param enabled * The value of the enabled attribute. * @param providerClass * The access control provider class. */ private PrivateACLConfiguration( AccessControlHandlerCfg configuration, boolean enabled, Class<? extends AccessControlProvider> providerClass) { this.configuration = configuration; this.enabled = enabled; this.providerClass = providerClass; } /** * Read the value of the attribute which indicates which access * control implementation class to use. This method checks the * validity of the class name. * * @param configuration * The access control configuration. * @return The access control provider class. * @throws ConfigException * If the class attribute could not be read or if it * contains an invalid class name. */ private static Class<? extends AccessControlProvider> getClassAttribute( AccessControlHandlerCfg configuration) throws ConfigException { // If access control is enabled then make sure that the class // attribute is present. try { // Load the access control implementation class. String className = configuration.getAclHandlerClass(); try { return DirectoryServer.loadClass(className).asSubclass( AccessControlProvider.class); } catch (ClassNotFoundException e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } int msgID = MSGID_CONFIG_AUTHZ_UNABLE_TO_LOAD_CLASS; String message = getMessage(msgID, className, String .valueOf(configuration.dn().toString()), getExceptionMessage(e)); throw new ConfigException(msgID, message, e); } catch (ClassCastException e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } int msgID = MSGID_CONFIG_AUTHZ_BAD_CLASS; String message = getMessage(msgID, className, String .valueOf(configuration.dn().toString()), AccessControlProvider.class.getName(), getExceptionMessage(e)); throw new ConfigException(msgID, message, e); } } catch (ConfigException e) { int msgID = MSGID_CONFIG_AUTHZ_UNABLE_TO_DETERMINE_CLASS; String message = getMessage(msgID, configuration.dn() .toString(), getExceptionMessage(e)); throw new ConfigException(msgID, message, e); } } return new ConfigChangeResult(resultCode, false, messages); } /** * Retrieves the DN of the configuration entry with which this alert * generator is associated. * * @return The DN of the configuration entry with which this alert * generator is associated. * {@inheritDoc} */ public DN getComponentEntryDN() { return currentConfiguration.getConfiguration().dn(); return currentConfiguration.dn(); } /** * Retrieves the fully-qualified name of the Java class for this * alert generator implementation. * * @return The fully-qualified name of the Java class for this * alert generator implementation. * {@inheritDoc} */ public String getClassName() { @@ -527,15 +396,7 @@ /** * Retrieves information about the set of alerts that this generator * may produce. The map returned should be between the notification * type for a particular notification and the human-readable * description for that notification. This alert generator must not * generate any alerts with types that are not contained in this * list. * * @return Information about the set of alerts that this generator * may produce. * {@inheritDoc} */ public LinkedHashMap<String,String> getAlerts() { @@ -549,6 +410,8 @@ return alerts; } /** * Loads the specified class, instantiates it as a AccessControlProvider, and * optionally initializes that instance. @@ -564,21 +427,21 @@ * @throws InitializationException If a problem occurred while attempting to * initialize the Access Control Provider. */ private AccessControlProvider<? extends AccessControlHandlerCfg> loadProvider(String className, AccessControlHandlerCfg configuration) private AccessControlHandler<? extends AccessControlHandlerCfg> loadHandler(String className, AccessControlHandlerCfg configuration) throws InitializationException { try { AccessControlHandlerCfgDefn definition = AccessControlHandlerCfgDefn.getInstance(); AccessControlHandlerCfgDefn.getInstance(); ClassPropertyDefinition propertyDefinition = definition.getAclHandlerClassPropertyDefinition(); Class<? extends AccessControlProvider> providerClass = propertyDefinition.loadClass(className, AccessControlProvider.class); AccessControlProvider<? extends AccessControlHandlerCfg> provider = (AccessControlProvider<? extends AccessControlHandlerCfg>) Class<? extends AccessControlHandler> providerClass = propertyDefinition.loadClass(className, AccessControlHandler.class); AccessControlHandler<? extends AccessControlHandlerCfg> provider = (AccessControlHandler<? extends AccessControlHandlerCfg>) providerClass.newInstance(); if (configuration != null) opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java
New file @@ -0,0 +1,239 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Portions Copyright 2006-2007 Sun Microsystems, Inc. */ package org.opends.server.core; import org.opends.server.admin.std.server.AccessControlHandlerCfg; import org.opends.server.api.AccessControlHandler; import org.opends.server.config.ConfigException; import org.opends.server.types.*; import org.opends.server.workflowelement.localbackend.*; /** * This class implements a default access control provider for the Directory * Server. * <p> * This class provides and access control handler which is used when access * control is disabled and implements a default access control decision function * which grants access to everything and anyone. */ class DefaultAccessControlHandler extends AccessControlHandler<AccessControlHandlerCfg> { /** * The single handler instance. */ private static DefaultAccessControlHandler instance = null; /** * Create a new default access control handler. */ public DefaultAccessControlHandler() { super(); // No implementation required. } /** * {@inheritDoc} */ @Override() public void initializeAccessControlHandler(AccessControlHandlerCfg configuration) throws ConfigException, InitializationException { // No implementation required. } /** * {@inheritDoc} */ @Override() public void finalizeAccessControlHandler() { // No implementation required. } /** * {@inheritDoc} */ @Override public boolean isAllowed(LocalBackendAddOperation addOperation) { return true; } /** * {@inheritDoc} */ @Override public boolean isAllowed(LocalBackendBindOperation bindOperation) { return true; } /** * {@inheritDoc} */ @Override public boolean isAllowed(CompareOperation compareOperation) { return true; } /** * {@inheritDoc} */ @Override public boolean isAllowed(LocalBackendDeleteOperation deleteOperation) { return true; } /** * {@inheritDoc} */ @Override public boolean isAllowed(ExtendedOperation extendedOperation) { return true; } /** * {@inheritDoc} */ @Override public boolean isAllowed(LocalBackendModifyOperation modifyOperation) { return true; } /** * {@inheritDoc} */ @Override public boolean isAllowed(ModifyDNOperation modifyDNOperation) { return true; } /** * {@inheritDoc} */ @Override public boolean isAllowed(LocalBackendSearchOperation searchOperation) { return true; } /** * {@inheritDoc} */ @Override public boolean maySend(SearchOperation searchOperation, SearchResultEntry searchEntry) { return true; } /** * {@inheritDoc} */ @Override public SearchResultEntry filterEntry(SearchOperation searchOperation, SearchResultEntry searchEntry) { // No implementation required. return searchEntry; } /** * {@inheritDoc} */ @Override public boolean maySend(SearchOperation searchOperation, SearchResultReference searchReference) { return true; } /** * {@inheritDoc} */ @Override public boolean isProxiedAuthAllowed(Operation operation, Entry entry) { return true; } /** * {@inheritDoc} */ @Override public boolean isGetEffectiveRightsAllowed(SearchOperation operation, Control c) { return true; } } opends/src/server/org/opends/server/core/DefaultAccessControlProvider.java
File was deleted