opendj-sdk/opends/resource/config/config.ldif
@@ -50,6 +50,7 @@ dn: cn=Access Control Handler,cn=config objectClass: top objectClass: ds-cfg-access-control-handler objectClass: ds-cfg-dseecompat-access-control-handler cn: Access Control Handler ds-cfg-acl-handler-class: org.opends.server.authorization.dseecompat.AciProvider ds-cfg-acl-handler-enabled: false opendj-sdk/opends/resource/schema/02-config.ldif
@@ -150,6 +150,8 @@ attributeTypes: ( 1.3.6.1.4.1.26027.1.1.39 NAME 'ds-cfg-fixed-time-limit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' ) attributeTypes: ( 1.3.6.1.4.1.26027.1.1.320 NAME 'ds-cfg-global-aci' SYNTAX 1.3.6.1.4.1.26027.1.3.4 X-ORIGIN 'OpenDS Directory Server' ) attributeTypes: ( 1.3.6.1.4.1.26027.1.1.40 NAME 'ds-cfg-index-attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' ) @@ -1084,11 +1086,16 @@ attributeTypes: ( 1.3.6.1.4.1.26027.1.1.319 NAME 'ds-cfg-changelog-purge-delay' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' ) X-ORIGIN 'OpenDS Directory Server' ) objectClasses: ( 1.3.6.1.4.1.26027.1.2.1 NAME 'ds-cfg-access-control-handler' SUP top STRUCTURAL MUST ( cn $ ds-cfg-acl-handler-class $ ds-cfg-acl-handler-enabled ) X-ORIGIN 'OpenDS Directory Server' ) objectClasses: ( 1.3.6.1.4.1.26027.1.2.87 NAME 'ds-cfg-dseecompat-access-control-handler' SUP ds-cfg-access-control-handler STRUCTURAL MAY ds-cfg-global-aci X-ORIGIN 'OpenDS Directory Server' ) objectClasses: ( 1.3.6.1.4.1.26027.1.2.2 NAME 'ds-cfg-alert-handler' SUP top STRUCTURAL MUST ( cn $ ds-cfg-alert-handler-class $ ds-cfg-alert-handler-enabled ) opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -35,9 +35,17 @@ import static org.opends.server.messages.MessageHandler.getMessage; import org.opends.server.types.*; import static org.opends.server.util.StaticUtils.toLowerCase; import java.util.LinkedList; import java.util.List; import java.util.Map; import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; import org.opends.server.config.StringConfigAttribute; import org.opends.server.config.ConfigEntry; import org.opends.server.config.ConfigException; import static org.opends.server.config.ConfigConstants.*; import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; import static org.opends.server.loggers.debug.DebugLogger.debugCaught; import org.opends.server.protocols.internal.InternalSearchOperation; import org.opends.server.protocols.internal.InternalClientConnection; import java.util.*; /** * The AciHandler class performs the main processing for the @@ -57,21 +65,138 @@ public static AttributeType aciType; /** * Constructor that creates the ACI list * class that manages the ACI list. Instantiates and registers the change * notification listener that is used to manage the ACI list on * modifications and the backend initialization listener that is used to * register/de-register aci attribute types in backends when backends * are initialized/finalized. * Attribute type corresponding to global "ds-cfg-global-aci" attribute. */ public static AttributeType globalAciType; /** * 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 and registers the change notification listener that is * used to manage the ACI list cache after ACI modifications have been * performed. * * - Instantiates and registers the backend initialization listener that is * used to manage the ACI list cache when backends are * initialized/finalized. * * - 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 configEntry The configuration entry passed in from the provider. * @throws InitializationException if there is a problem processing the * config entry or config naming context. */ public AciHandler() { aciList = new AciList(); public AciHandler(ConfigEntry configEntry) throws InitializationException { aciList = new AciList(configEntry.getDN()); AciListenerManager aciListenerMgr = new AciListenerManager(aciList); DirectoryServer.registerChangeNotificationListener(aciListenerMgr); DirectoryServer.registerBackendInitializationListener(aciListenerMgr); 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(configEntry); processConfigAcis(); } /** * Process all global ACI attribute types found in the configuration * entry and adds them to that ACI list cache. It also logs messages about * the number of ACI attribute types added to the cache. This method is * called once at startup. * @param configEntry The configuraion entry to search for global ACIs. * @throws InitializationException If there is an error reading * the global ACIs from the configuration entry. */ private void processGlobalAcis(ConfigEntry configEntry) throws InitializationException { int msgID = MSGID_ACI_DESCRIPTION_GLOBAL_ACI; StringConfigAttribute aciGlobalStub = new StringConfigAttribute(ATTR_AUTHZ_GLOBAL_ACI, getMessage(msgID), false, true, false); try { StringConfigAttribute aciGlobalAttr = (StringConfigAttribute) configEntry.getConfigAttribute(aciGlobalStub); if (aciGlobalAttr != null) { Attribute attr = new Attribute(globalAciType, globalAciType.toString(), aciGlobalAttr.getActiveValues()); Entry e = new Entry(configEntry.getDN(), null, null, null); e.addAttribute(attr, new ArrayList<AttributeValue>()); int aciCount = aciList.addAci(e, false, true); msgID = MSGID_ACI_ADD_LIST_GLOBAL_ACIS; String message = getMessage(msgID, Integer.toString(aciCount)); logError(ErrorLogCategory.ACCESS_CONTROL, ErrorLogSeverity.NOTICE, message, msgID); } else { msgID = MSGID_ACI_ADD_LIST_NO_GLOBAL_ACIS; String message = getMessage(msgID); logError(ErrorLogCategory.ACCESS_CONTROL, ErrorLogSeverity.NOTICE, message, msgID); } } catch (ConfigException e) { if (debugEnabled()) debugCaught(DebugLogLevel.ERROR, e); msgID = MSGID_ACI_HANDLER_FAIL_PROCESS_GLOBAL_ACI; String message = getMessage(msgID, String.valueOf(configEntry.getDN()), stackTraceToSingleLineString(e)); throw new InitializationException(msgID, message, e); } } /** * Process all ACIs under the "cn=config" naming context and adds them to * the ACI list cache. It also logs messages about the number of ACIs added * to the cache. This method is called once at startup. * @throws InitializationException If there is an error searching for * the ACIs in the naming context. */ private void processConfigAcis() throws InitializationException { try { DN configDN=DN.decode("cn=config"); LinkedHashSet<String> attrs = new LinkedHashSet<String>(1); attrs.add("aci"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation op = conn.processSearch(configDN, SearchScope.WHOLE_SUBTREE, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, SearchFilter.createFilterFromString("aci=*"), attrs); if(op.getSearchEntries().isEmpty()) { int msgID = MSGID_ACI_ADD_LIST_NO_ACIS; String message = getMessage(msgID, String.valueOf(configDN)); logError(ErrorLogCategory.ACCESS_CONTROL, ErrorLogSeverity.NOTICE, message, msgID); } else { int validAcis = aciList.addAci(op.getSearchEntries()); int msgID = MSGID_ACI_ADD_LIST_ACIS; String message = getMessage(msgID, Integer.toString(validAcis), String.valueOf(configDN)); logError(ErrorLogCategory.ACCESS_CONTROL, ErrorLogSeverity.NOTICE, message, msgID); } } catch (DirectoryException e) { int msgID = MSGID_ACI_HANDLER_FAIL_PROCESS_ACI; String message = getMessage(msgID, stackTraceToSingleLineString(e)); throw new InitializationException(msgID, message, e); } } /** @@ -180,20 +305,25 @@ If so, check the syntax of that attribute value. Fail the the operation if the syntax check fails. */ if(modType.equals(aciType)) { try { Aci.decode(v.getValue(),dn); } catch (AciException ex) { int msgID = MSGID_ACI_MODIFY_FAILED_DECODE; String message = getMessage(msgID, String.valueOf(dn), ex.getMessage()); logError(ErrorLogCategory.ACCESS_CONTROL, if(modType.equals(aciType) || modType.equals(globalAciType)) { try { //A global ACI needs a NULL DN, not the DN of the //modification. if(modType.equals(globalAciType)) dn=DN.nullDN(); Aci.decode(v.getValue(),dn); } catch (AciException ex) { int msgID = MSGID_ACI_MODIFY_FAILED_DECODE; String message = getMessage(msgID, String.valueOf(dn), ex.getMessage()); logError(ErrorLogCategory.ACCESS_CONTROL, ErrorLogSeverity.SEVERE_WARNING, message, msgID); return false; } } return false; } } } } } opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciList.java
@@ -30,19 +30,11 @@ import static org.opends.server.authorization.dseecompat.AciMessages.*; import static org.opends.server.loggers.Error.logError; import static org.opends.server.messages.MessageHandler.getMessage; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.ArrayList; import org.opends.server.types.Attribute; import org.opends.server.types.AttributeValue; import org.opends.server.types.DN; import org.opends.server.types.Entry; import org.opends.server.types.ErrorLogCategory; import org.opends.server.types.ErrorLogSeverity; import java.util.*; import static org.opends.server.authorization.dseecompat.AciHandler.*; import org.opends.server.types.*; import org.opends.server.api.Backend; /** @@ -58,9 +50,23 @@ private volatile LinkedHashMap<DN, List<Aci>> aciList = new LinkedHashMap<DN, List<Aci>>(); /* * The configuration DN used to compare against the global ACI entry DN. */ private DN configDN; /** * Constructor to create an ACI list to cache ACI attribute types. * @param configDN The configuration entry DN. */ public AciList(DN configDN) { this.configDN=configDN; } /** * Accessor to the ACI list intended to be called from within unsynchronized * read-only methods. * @return The current ACI list. */ private LinkedHashMap<DN, List<Aci>> getList() { return aciList; @@ -74,14 +80,13 @@ return new LinkedHashMap<DN, List<Aci>>(aciList); } /* * TODO Add support for global ACIs in config.ldif. * */ /** * Using the base DN, return a list of ACIs that are candidates for * evaluation by walking up from the base DN towards the root of the * DIT gathering ACIs on parents. * DIT gathering ACIs on parents. Global ACIs use the NULL DN as the key * and are included in the candidate set only if they have no * "target" keyword rules, or if the target keyword rule matches for * the specified base DN. * * @param baseDN The DN to check. * @return A list of candidate ACIs that might be applicable. @@ -93,12 +98,26 @@ // Save a reference to the current ACI list, in case it gets changed. LinkedHashMap<DN, List<Aci>> aciList = getList(); //Save the baseDN in case we need to evaluate a global ACI. DN entryDN=baseDN; while(baseDN != null) { List<Aci> acis = aciList.get(baseDN); if (acis != null) { candidates.addAll(acis); if (acis != null) { //Check if there are global ACIs. Global ACI has a NULL DN. if(baseDN.isNullDN()) { for(Aci aci : acis) { AciTargets targets=aci.getTargets(); //If there is a target, evaluate it to see if this ACI should //be included in the candidate set. if(targets != null) { boolean ret=AciTargets.isTargetApplicable(aci, targets, entryDN); if(ret) candidates.add(aci); //Add this ACI to the candidates. } } } else candidates.addAll(acis); } if(baseDN.isNullDN()) break; @@ -112,7 +131,9 @@ } /** * Add all the ACI from a set of entries to the ACI list. * Add all the ACI from a set of entries to the ACI list. There is no need * to check for global ACIs since they are processe by the AciHandler at * startup using the addACi single entry method. * @param entries The set of entries containing the "aci" attribute values. * @return The number of valid ACI attribute values added to the ACI list. */ @@ -135,39 +156,47 @@ } /** * Add all of an entry's ACI attribute values to the ACI list. * @param entry The entry containing the "aci" attribute values. * Add all of an entry's ACI (global or regular) attribute values to the * ACI list. * @param entry The entry containing the ACI attributes. * @param hasAci True if the "aci" attribute type was seen in the entry. * @param hasGlobalAci True if the "ds-cfg-global-aci" attribute type was * seen in the entry. * @return The number of valid ACI attribute values added to the ACI list. */ public synchronized int addAci(Entry entry) { int validAcis; DN dn=entry.getDN(); List<Attribute> attributeList = entry.getOperationalAttribute(AciHandler.aciType); if (attributeList == null) { return 0; } public synchronized int addAci(Entry entry, boolean hasAci, boolean hasGlobalAci) { int validAcis=0; // Copy the ACI list. LinkedHashMap<DN,List<Aci>> aciCopy = copyList(); //Process global "ds-cfg-global-aci" attribute type. The oldentry //DN is checked to verify it is equal to the config DN. If not those //attributes are skipped. if(hasGlobalAci && entry.getDN().equals(configDN)) { List<Attribute> attributeList = entry.getAttribute(globalAciType); validAcis = addAciAttributeList(aciCopy, DN.nullDN(), attributeList); } validAcis=addAciAttributeList(aciCopy, dn, attributeList); if(hasAci) { List<Attribute> attributeList = entry.getAttribute(aciType); validAcis += addAciAttributeList(aciCopy, entry.getDN(), attributeList); } // Replace the ACI list with the copy. aciList = aciCopy; return validAcis; } /** * Add "aci" attribute type values to the ACI list. There is a chance * that an ACI will throw an exception if it has an invalid syntax. * If that happens a message will be logged and the ACI skipped. * Add an ACI's attribute type values to the ACI list. There is a chance that * an ACI will throw an exception if it has an invalid syntax. If that * happens a message will be logged and the ACI skipped. A count is * returned of the number of valid ACIs added. * @param aciList The ACI list to which the ACI is to be added. * @param dn The DN to use as the key in the ACI list. * @param attributeList List of attributes containing the "aci" attribute * @param attributeList List of attributes containing the ACI attribute * values. * @return The number of valid "aci" attribute values added to the ACI list. * @return The number of valid attribute values added to the ACI list. */ private static int addAciAttributeList( LinkedHashMap<DN,List<Aci>> aciList, DN dn, @@ -209,26 +238,41 @@ /** * Remove all of the ACIs related to the old entry and then add all of the * ACIs related to the new entry. This method locks/unlocks the list. * @param oldEntry The old entry possibly containing old "aci" attribute * In the case of global ACIs the DN of the entry is checked to make sure it * is equal to the config DN. If not, the global ACI attribute type is * silently skipped. * @param oldEntry The old entry possibly containing old ACI attribute * values. * @param newEntry The new entry possibly containing new "aci" attribute * @param newEntry The new entry possibly containing new ACI attribute * values. * @param hasAci True if the "aci" attribute type was seen in the entry. * @param hasGlobalAci True if the "ds-cfg-global-aci" attribute type was * seen in the entry. */ public synchronized void modAciOldNewEntry(Entry oldEntry, Entry newEntry) { if((oldEntry.hasOperationalAttribute(AciHandler.aciType)) || (newEntry.hasOperationalAttribute(AciHandler.aciType))) { public synchronized void modAciOldNewEntry(Entry oldEntry, Entry newEntry, boolean hasAci, boolean hasGlobalAci) { // Copy the ACI list. LinkedHashMap<DN,List<Aci>> aciCopy = copyList(); aciCopy.remove(oldEntry.getDN()); List<Attribute> attributeList = newEntry.getOperationalAttribute(AciHandler.aciType); addAciAttributeList(aciCopy,newEntry.getDN(),attributeList); //Process "aci" attribute types. if(hasAci) { aciCopy.remove(oldEntry.getDN()); List<Attribute> attributeList = newEntry.getOperationalAttribute(aciType); addAciAttributeList(aciCopy,newEntry.getDN(),attributeList); } //Process global "ds-cfg-global-aci" attribute type. The oldentry //DN is checked to verify it is equal to the config DN. If not those //attributes are skipped. if(hasGlobalAci && oldEntry.getDN().equals(configDN)) { aciCopy.remove(DN.nullDN()); List<Attribute> attributeList = newEntry.getAttribute(globalAciType); addAciAttributeList(aciCopy, DN.nullDN(), attributeList); } // Replace the ACI list with the copy. aciList = aciCopy; } } /** @@ -251,21 +295,30 @@ } /** * Remove ACIs related to an entry. * @param entry The entry to be removed. * @return True if the ACI set was deleted. * Remove global and regular ACIs from the list. It's possible that an entry * could have both attribute types (aci and ds-cfg-global-aci). Global ACIs * use the NULL DN for the key. In the case of global ACIs the DN of the * entry is checked to make sure it is equal to the config DN. If not, the * global ACI attribute type is silently skipped. * @param entry The entry containing the global ACIs. * @param hasAci True if the "aci" attribute type was seen in the entry. * @param hasGlobalAci True if the "ds-cfg-global-aci" attribute type was * seen in the entry. * @return True if the ACI set was deleted. */ public synchronized boolean removeAci(Entry entry) { // Copy the ACI list. LinkedHashMap<DN,List<Aci>> aciCopy = copyList(); public synchronized boolean removeAci(Entry entry, boolean hasAci, boolean hasGlobalAci) { // Copy the ACI list. LinkedHashMap<DN,List<Aci>> aciCopy = copyList(); boolean deleted = false; if (aciCopy.remove(entry.getDN()) != null) deleted = true; // Replace the ACI list with the copy. aciList = aciCopy; return deleted; if(hasGlobalAci && entry.getDN().equals(configDN) && aciCopy.remove(DN.nullDN()) == null) return false; if(hasAci && aciCopy.remove(entry.getDN()) == null) return false; // Replace the ACI list with the copy. aciList = aciCopy; return true; } /** opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java
@@ -42,7 +42,6 @@ import org.opends.server.types.*; import static org.opends.server.authorization.dseecompat.AciMessages.*; import static org.opends.server.messages.MessageHandler.getMessage; import java.util.LinkedHashSet; import java.util.List; @@ -97,10 +96,12 @@ * @param entry The entry being deleted. */ public void handleDeleteOperation(PostResponseDeleteOperation deleteOperation, Entry entry) { if(entry.hasOperationalAttribute(AciHandler.aciType)) { aciList.removeAci(entry); } deleteOperation, Entry entry) { boolean hasAci, hasGlobalAci=false; //This entry might have both global and aci attribute types. if((hasAci=entry.hasOperationalAttribute(AciHandler.aciType)) || (hasGlobalAci=entry.hasAttribute(AciHandler.globalAciType))) aciList.removeAci(entry, hasAci, hasGlobalAci); } /** @@ -111,10 +112,11 @@ */ public void handleAddOperation(PostResponseAddOperation addOperation, Entry entry) { if(entry.hasOperationalAttribute(AciHandler.aciType)) { aciList.addAci(entry); } boolean hasAci, hasGlobalAci=false; //This entry might have both global and aci attribute types. if((hasAci=entry.hasOperationalAttribute(AciHandler.aciType)) || (hasGlobalAci=entry.hasAttribute(AciHandler.globalAciType))) aciList.addAci(entry, hasAci, hasGlobalAci); } /** @@ -128,23 +130,23 @@ public void handleModifyOperation(PostResponseModifyOperation modOperation, Entry oldEntry, Entry newEntry) { // A change to the ACI list is expensive so let's first make sure that // the modification included changes to the ACI. boolean hasAciMod = false; List<Modification> mods = modOperation.getModifications(); for (Modification mod : mods) { if (mod.getAttribute().getAttributeType().equals(AciHandler.aciType)) { hasAciMod = true; break; // A change to the ACI list is expensive so let's first make sure that // the modification included changes to the ACI. We'll check for //both "aci" attribute types and global "ds-cfg-global-aci" attribute //types. boolean hasAci = false, hasGlobalAci=false; List<Modification> mods = modOperation.getModifications(); for (Modification mod : mods) { AttributeType attributeType=mod.getAttribute().getAttributeType(); if (attributeType.equals(AciHandler.aciType)) hasAci = true; else if(attributeType.equals(AciHandler.globalAciType)) hasGlobalAci=true; if(hasAci && hasGlobalAci) break; } } if (hasAciMod) { aciList.modAciOldNewEntry(oldEntry, newEntry); } if (hasAci || hasGlobalAci) aciList.modAciOldNewEntry(oldEntry, newEntry, hasAci, hasGlobalAci); } /** @@ -191,8 +193,7 @@ null, baseDN, SearchScope.WHOLE_SUBTREE, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, aciFilter, attrs, null); try { try { backend.search(internalSearch); } catch (Exception e) { if (debugEnabled()) opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciMessages.java
@@ -28,6 +28,7 @@ package org.opends.server.authorization.dseecompat; import static org.opends.server.messages.MessageHandler.*; import static org.opends.server.config.ConfigConstants.ATTR_AUTHZ_GLOBAL_ACI; /** * The AciMessages class defines the set of message IDs and default format @@ -653,6 +654,48 @@ CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 63; /** * The message ID for the message that will be used as the description of * the configuration attribute specifying a global ACI. */ public static final int MSGID_ACI_DESCRIPTION_GLOBAL_ACI = CATEGORY_MASK_ACCESS_CONTROL | 64; /** * The message ID for the ACI message that will be generated the server * searches an directory context for Global "aci" attribute types and * finds none. This takes no arguments. */ public static final int MSGID_ACI_ADD_LIST_NO_GLOBAL_ACIS = CATEGORY_MASK_ACCESS_CONTROL | 65; /** * The message ID for the ACI message that will be generated the server * searches the config entry for Global "aci" attribute types and * finds some. This takes one argument, which is the number of * valid Global ACIs decoded. */ public static final int MSGID_ACI_ADD_LIST_GLOBAL_ACIS = CATEGORY_MASK_ACCESS_CONTROL | 66; /** * The message ID for the ACI message that will be generated when the server * searches the config entry for Global "aci" attribute types and * an error occurs. This takes one argument, which is the DN of the * access control configuration entry. */ public static final int MSGID_ACI_HANDLER_FAIL_PROCESS_GLOBAL_ACI = CATEGORY_MASK_ACCESS_CONTROL | 67; /** * The message ID for the ACI message that will be generated when the server * searches the config system for "aci" attribute types and * an error occurs. This takes no arguments. */ public static final int MSGID_ACI_HANDLER_FAIL_PROCESS_ACI = CATEGORY_MASK_ACCESS_CONTROL | 68; /** * Associates a set of generic messages with the message IDs defined in * this class. */ @@ -1033,6 +1076,26 @@ "with an ASCII letter and must contain only ASCII letters," + "digits or the \"-\" character."); registerMessage(MSGID_ACI_DESCRIPTION_GLOBAL_ACI, "Specifies a global Access Control Instruction (ACI) " + "attribute type that can be used to defined ACIs that have " + "global scope accross naming contexts."); registerMessage(MSGID_ACI_ADD_LIST_NO_GLOBAL_ACIS, "No Global Access Control Instruction (ACI) attribute types were" + " found."); registerMessage(MSGID_ACI_ADD_LIST_GLOBAL_ACIS, "Added %s Global Access Control Instruction (ACI) attribute " + "types to the access control evaluation engine."); registerMessage(MSGID_ACI_HANDLER_FAIL_PROCESS_GLOBAL_ACI, "An unexpected error occurred while processing the " + ATTR_AUTHZ_GLOBAL_ACI + " attribute in configuration entry %s."); registerMessage(MSGID_ACI_HANDLER_FAIL_PROCESS_ACI, "An unexpected error occurred while processing the " + " aci attributes in the configuration system."); } } opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciProvider.java
@@ -60,7 +60,7 @@ */ public void initializeAccessControlHandler(ConfigEntry configEntry) throws ConfigException, InitializationException { getInstance(); instance=new AciHandler(configEntry); } /** @@ -68,9 +68,6 @@ * @return A new AciHandler instance. */ public AccessControlHandler getInstance() { if (instance == null) { instance = new AciHandler(); } return instance; } opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java
@@ -440,6 +440,21 @@ return ((skipRights & rights) == rights); } /** * Wrapper class that passes an ACI, an ACI's targets and the specified * target match context's resource entry DN to the main isTargetApplicable * method. * @param aci The ACI currently be matched. * @param matchCtx The target match context to match against. * @return True if the target matched the ACI. */ public static boolean isTargetApplicable(Aci aci, AciTargetMatchContext matchCtx) { return isTargetApplicable(aci, aci.getTargets(), matchCtx.getResourceEntry().getDN()); } /* * TODO Investigate supporting alternative representations of the scope. * @@ -449,24 +464,24 @@ * abbreviations in widespread use for those terms? */ /** * Checks an provided ACI's target information against an target match * context. * Main target isApplicable method. This method performs the target keyword * match functionality, which allows for directory entry "targeting" using * the specifed ACI, ACI targets class and DN. * @param aci The ACI to match the target against. * @param matchCtx The target match context to check the ACI against. * @return True if the target matched the context. * @param targets The targets to use in this evaluation. * @param entryDN The DN to use in this evaluation. * @return True if the ACI matched the target and DN. */ public static boolean isTargetApplicable(Aci aci, AciTargetMatchContext matchCtx) { boolean ret=true; DN entryDN=matchCtx.getResourceEntry().getDN(); DN targetDN=aci.getDN(); AciTargets targets=aci.getTargets(); public static boolean isTargetApplicable(Aci aci, AciTargets targets, DN entryDN) { boolean ret=true; DN targetDN=aci.getDN(); /* * Scoping of the ACI uses either the DN of the entry * containing the ACI (aci.getDN above), or if the ACI item * contains a simple target DN and a equality operator that * target DN is used. * contains a simple target DN and a equality operator, that * simple target DN is used as the target DN. */ if((targets.getTarget() != null) && (!targets.getTarget().isPattern())) { @@ -474,6 +489,7 @@ if(op != EnumTargetOperator.NOT_EQUALITY) targetDN=targets.getTarget().getDN(); } //Check if the scope is correct. switch(targets.getTargetScope()) { case BASE_OBJECT: if(!targetDN.equals(entryDN)) opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java
@@ -2269,6 +2269,13 @@ NAME_PREFIX_CFG + "acl-handler-enabled"; /** * The name of the configuration attribute that specifies a global * attribute access control instruction. */ public static final String ATTR_AUTHZ_GLOBAL_ACI = NAME_PREFIX_CFG + "global-aci"; /** * The name of the configuration attribute that specifies the fully-qualified