From a8a8f5354938c4b5b84debd445a5d8dc0b037bd9 Mon Sep 17 00:00:00 2001
From: dugan <dugan@localhost>
Date: Mon, 19 Mar 2007 22:28:03 +0000
Subject: [PATCH] Add support for:
---
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java | 40 +++-
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciList.java | 183 +++++++++++++-------
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java | 55 +++---
opendj-sdk/opends/resource/config/config.ldif | 1
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java | 176 +++++++++++++++++--
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciProvider.java | 5
opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java | 7
opendj-sdk/opends/resource/schema/02-config.ldif | 9
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciMessages.java | 63 +++++++
9 files changed, 407 insertions(+), 132 deletions(-)
diff --git a/opendj-sdk/opends/resource/config/config.ldif b/opendj-sdk/opends/resource/config/config.ldif
index f4ea507..1eedfcf 100644
--- a/opendj-sdk/opends/resource/config/config.ldif
+++ b/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
diff --git a/opendj-sdk/opends/resource/schema/02-config.ldif b/opendj-sdk/opends/resource/schema/02-config.ldif
index 4d0a77e..4689f35 100644
--- a/opendj-sdk/opends/resource/schema/02-config.ldif
+++ b/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 )
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
index 2522545..b5729db 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
+++ b/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;
+ }
+ }
}
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciList.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciList.java
index d281e3f..bedad92 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciList.java
+++ b/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;
}
/**
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java
index 3690dee..11b0a5e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java
+++ b/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())
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciMessages.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciMessages.java
index 76856ca..b026612 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciMessages.java
+++ b/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.");
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciProvider.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciProvider.java
index be0478b..cfa8f05 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciProvider.java
+++ b/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;
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java
index 3875ca4..e9e5c27 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java
+++ b/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))
diff --git a/opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java b/opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java
index 096ea89..28c167c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/config/ConfigConstants.java
+++ b/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
--
Gitblit v1.10.0