mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
30.37.2006 001545b7d1348179cf27693be1e42e5c03adf66a
Update the schema backend so that the attributes used to represent schema
information are treated correctly according to their definitions. In
particular, attributeTypes, objectClasses, matchingRules, and ldapSyntaxes are
now properly treated as operational attributes and not returned unless
explicitly requested. It is possible to override this behavior for backward
compatibility with clients that expect them to always be returned, but this
may be deprecated in the future.

OpenDS Issue Number: 1039
5 files modified
226 ■■■■ changed files
opends/resource/config/config.ldif 1 ●●●● patch | view | raw | blame | history
opends/resource/schema/02-config.ldif 3 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/SchemaBackend.java 163 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/config/ConfigConstants.java 18 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/BackendMessages.java 41 ●●●●● patch | view | raw | blame | history
opends/resource/config/config.ldif
@@ -242,6 +242,7 @@
ds-cfg-backend-id: schema
ds-cfg-backend-writability-mode: enabled
ds-cfg-backend-base-dn: cn=schema
ds-cfg-show-all-attributes: false
dn: ds-cfg-backend-id=tasks,cn=Backends,cn=config
objectClass: top
opends/resource/schema/02-config.ldif
@@ -1038,7 +1038,8 @@
  STRUCTURAL MUST ( ds-cfg-index-attribute $ ds-cfg-index-type )
  MAY ds-cfg-index-entry-limit X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.9 NAME 'ds-cfg-schema-backend'
  SUP ds-cfg-backend STRUCTURAL MAY ds-cfg-schema-entry-dn
  SUP ds-cfg-backend STRUCTURAL
  MAY ( ds-cfg-schema-entry-dn $ ds-cfg-show-all-attributes )
  X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.10 NAME 'ds-cfg-task-backend'
  SUP ds-cfg-backend STRUCTURAL MAY ( ds-cfg-task-backing-file $
opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -54,6 +54,7 @@
import org.opends.server.api.Backend;
import org.opends.server.api.ConfigurableComponent;
import org.opends.server.config.BooleanConfigAttribute;
import org.opends.server.config.ConfigAttribute;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
@@ -120,6 +121,10 @@
  // entry.
  private ArrayList<Attribute> userDefinedAttributes;
  // Indicates whether the attributes of the schema entry should always be
  // treated as user attributes even if they are defined as operational.
  private boolean showAllAttributes;
  // The set of objectclasses that will be used in the schema entry.
  private HashMap<ObjectClass,String> schemaObjectClasses;
@@ -217,6 +222,32 @@
    }
    // Determine whether to show all attributes.
    showAllAttributes = DEFAULT_SCHEMA_SHOW_ALL_ATTRIBUTES;
    int msgID = MSGID_SCHEMA_DESCRIPTION_SHOW_ALL_ATTRIBUTES;
    BooleanConfigAttribute showAllStub =
         new BooleanConfigAttribute(ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES,
                                    getMessage(msgID), false);
    try
    {
      BooleanConfigAttribute showAllAttr =
           (BooleanConfigAttribute) configEntry.getConfigAttribute(showAllStub);
      if (showAllAttr != null)
      {
        showAllAttributes = showAllAttr.activeValue();
      }
    }
    catch (Exception e)
    {
      assert debugException(CLASS_NAME, "applyNewConfiguration", e);
      msgID = MSGID_SCHEMA_CANNOT_DETERMINE_SHOW_ALL;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  stackTraceToSingleLineString(e));
      throw new ConfigException(msgID, message, e);
    }
    // Register each of the suffixes with the Directory Server.  Also, register
    // the first one as the schema base.
    this.baseDNs = baseDNs;
@@ -299,6 +330,8 @@
        attrType.hasName(ATTR_BACKEND_CLASS.toLowerCase()) ||
        attrType.hasName(ATTR_BACKEND_ID.toLowerCase()) ||
        attrType.hasName(ATTR_BACKEND_BASE_DN.toLowerCase()) ||
        attrType.hasName(ATTR_BACKEND_WRITABILITY_MODE.toLowerCase()) ||
        attrType.hasName(ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES.toLowerCase()) ||
        attrType.hasName(ATTR_COMMON_NAME))
    {
      return true;
@@ -426,64 +459,78 @@
    // Add the "attributeTypes" attribute.
    AttributeType attrType =
         DirectoryServer.getAttributeType(ATTR_ATTRIBUTE_TYPES_LC);
    if (attrType == null)
    {
      attrType = DirectoryServer.getDefaultAttributeType(ATTR_ATTRIBUTE_TYPES);
    }
         DirectoryServer.getAttributeType(ATTR_ATTRIBUTE_TYPES_LC, true);
    LinkedHashSet<AttributeValue> valueSet =
         DirectoryServer.getAttributeTypeSet();
    Attribute attr = new Attribute(attrType, ATTR_ATTRIBUTE_TYPES, valueSet);
    ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
    attrList.add(attr);
    userAttrs.put(attrType, attrList);
    if (attrType.isOperational() && (! showAllAttributes))
    {
      operationalAttrs.put(attrType, attrList);
    }
    else
    {
      userAttrs.put(attrType, attrList);
    }
    // Add the "objectClasses" attribute.
    attrType = DirectoryServer.getAttributeType(ATTR_OBJECTCLASSES_LC);
    if (attrType == null)
    {
      attrType = DirectoryServer.getDefaultAttributeType(ATTR_OBJECTCLASSES);
    }
    attrType = DirectoryServer.getAttributeType(ATTR_OBJECTCLASSES_LC, true);
    valueSet = DirectoryServer.getObjectClassSet();
    attr = new Attribute(attrType, ATTR_OBJECTCLASSES, valueSet);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(attr);
    userAttrs.put(attrType, attrList);
    if (attrType.isOperational() && (! showAllAttributes))
    {
      operationalAttrs.put(attrType, attrList);
    }
    else
    {
      userAttrs.put(attrType, attrList);
    }
    // Add the "matchingRules" attribute.
    attrType = DirectoryServer.getAttributeType(ATTR_MATCHING_RULES_LC);
    if (attrType == null)
    {
      attrType = DirectoryServer.getDefaultAttributeType(ATTR_MATCHING_RULES);
    }
    attrType = DirectoryServer.getAttributeType(ATTR_MATCHING_RULES_LC, true);
    valueSet = DirectoryServer.getMatchingRuleSet();
    attr = new Attribute(attrType, ATTR_MATCHING_RULES, valueSet);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(attr);
    userAttrs.put(attrType, attrList);
    if (attrType.isOperational() && (! showAllAttributes))
    {
      operationalAttrs.put(attrType, attrList);
    }
    else
    {
      userAttrs.put(attrType, attrList);
    }
    // Add the "ldapSyntaxes" attribute.
    attrType = DirectoryServer.getAttributeType(ATTR_LDAP_SYNTAXES_LC);
    if (attrType == null)
    {
      attrType = DirectoryServer.getDefaultAttributeType(ATTR_LDAP_SYNTAXES);
    }
    attrType = DirectoryServer.getAttributeType(ATTR_LDAP_SYNTAXES_LC, true);
    valueSet = DirectoryServer.getAttributeSyntaxSet();
    attr = new Attribute(attrType, ATTR_LDAP_SYNTAXES, valueSet);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(attr);
    userAttrs.put(attrType, attrList);
    // Note that we intentionally ignore showAllAttributes for ldapSyntaxes
    // because that attribute isn't allowed in the subschema objectclass, and
    // treating it as a user attribute would cause schema updates to fail.  This
    // means that you'll always have to explicitly request ldapSyntaxes in order
    // to be able to see it.
    if (attrType.isOperational())
    {
      operationalAttrs.put(attrType, attrList);
    }
    else
    {
      userAttrs.put(attrType, attrList);
    }
    // Add all the user-defined attributes.
@@ -1947,6 +1994,13 @@
    attrList.add(new DNConfigAttribute(ATTR_SCHEMA_ENTRY_DN, description,
                                       false, true, false, values));
    description = getMessage(MSGID_SCHEMA_DESCRIPTION_SHOW_ALL_ATTRIBUTES);
    attrList.add(new BooleanConfigAttribute(ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES,
                                            description, false,
                                            showAllAttributes));
    return attrList;
  }
@@ -1998,6 +2052,28 @@
    }
    description = getMessage(MSGID_SCHEMA_DESCRIPTION_SHOW_ALL_ATTRIBUTES);
    BooleanConfigAttribute showAllStub =
         new BooleanConfigAttribute(ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES,
                                    description, false);
    try
    {
      // We don't care what the value is as long as we can parse it.
      BooleanConfigAttribute showAllAttr =
           (BooleanConfigAttribute) configEntry.getConfigAttribute(showAllStub);
    }
    catch (Exception e)
    {
      assert debugException(CLASS_NAME, "initializeBackend", e);
      int msgID = MSGID_SCHEMA_CANNOT_DETERMINE_SHOW_ALL;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  stackTraceToSingleLineString(e));
      unacceptableReasons.add(message);
      configIsAcceptable = false;
    }
    return configIsAcceptable;
  }
@@ -2073,6 +2149,34 @@
    }
    // Check to see if we should change the behavior regarding whether to show
    // all schema attributes.
    boolean newShowAllAttributes = DEFAULT_SCHEMA_SHOW_ALL_ATTRIBUTES;
    msgID = MSGID_SCHEMA_DESCRIPTION_SHOW_ALL_ATTRIBUTES;
    BooleanConfigAttribute showAllStub =
         new BooleanConfigAttribute(ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES,
                                    getMessage(msgID), false);
    try
    {
      BooleanConfigAttribute showAllAttr =
           (BooleanConfigAttribute) configEntry.getConfigAttribute(showAllStub);
      if (showAllAttr != null)
      {
        newShowAllAttributes = showAllAttr.activeValue();
      }
    }
    catch (Exception e)
    {
      assert debugException(CLASS_NAME, "applyNewConfiguration", e);
      msgID = MSGID_SCHEMA_CANNOT_DETERMINE_SHOW_ALL;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              stackTraceToSingleLineString(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      newBaseDNs = null;
    }
    // Check to see if there is a new set of user-defined attributes.
    ArrayList<Attribute> newUserAttrs = new ArrayList<Attribute>();
    for (List<Attribute> attrs :
@@ -2165,6 +2269,9 @@
      }
      showAllAttributes = newShowAllAttributes;
      userDefinedAttributes = newUserAttrs;
      if (detailedResults)
      {
opends/src/server/org/opends/server/config/ConfigConstants.java
@@ -240,6 +240,24 @@
  /**
   * The name of the configuration attribute that indicates whether the
   * subschema entry should treat all attributes as user attributes or if it
   * should treat them as per their definition in the schema.
   */
  public static final String ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES =
       NAME_PREFIX_CFG + "show-all-attributes";
  /**
   * The default value that will be used regarding treating all subschema entry
   * attributes as user attributes if it is not defined in the configuration.
   */
  public static final boolean DEFAULT_SCHEMA_SHOW_ALL_ATTRIBUTES = false;
  /**
   * The name of the configuration attribute that indicates whether to allow
   * clients to use the startTLS extended operation.
   */
opends/src/server/org/opends/server/messages/BackendMessages.java
@@ -2210,6 +2210,29 @@
  /**
   * The message ID for the message that will be used as the description for the
   * configuration attribute that is used to indicate whether all attributes
   * in the subschema entry should be shown even if they are marked operational.
   * This does not take any arguments.
   */
  public static final int MSGID_SCHEMA_DESCRIPTION_SHOW_ALL_ATTRIBUTES =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_INFORMATIONAL | 208;
  /**
   * The message ID for the message that will be used if an error occurs while
   * trying to determine whether to treat all subschema attributes as user
   * attributes.  This takes two arguments, which are the DN of the
   * configuration entry and a string representation of the exception that was
   * caught.
   */
  public static final int MSGID_SCHEMA_CANNOT_DETERMINE_SHOW_ALL =
       CATEGORY_MASK_BACKEND | SEVERITY_MASK_SEVERE_ERROR | 209;
  /**
   * Associates a set of generic messages with the message IDs defined in this
   * class.
   */
@@ -2402,6 +2425,16 @@
                    "locations for compatibility purposes.  If no value is " +
                    "provided, a default of \"" + DN_DEFAULT_SCHEMA_ROOT +
                    "\" will be used.");
    registerMessage(MSGID_SCHEMA_DESCRIPTION_SHOW_ALL_ATTRIBUTES,
                    "Indicates whether to treat attributes in the subschema " +
                    "entry as user attributes even if they are marked " +
                    "operational.  This may provide compatibility with some " +
                    "applications that expect schema attributes like " +
                    "attributeType and objectClasses to be included by " +
                    "default even if they are not requested.  Note that the " +
                    "ldapSyntaxes attribute will always be treated as " +
                    "operational in order to avoid problems with attempts to " +
                    "modify the schema over protocol.");
    registerMessage(MSGID_SCHEMA_CANNOT_DETERMINE_BASE_DN,
                    "An error occurred while trying to determine the base " +
                    "DNs to use when publishing the Directory Server schema " +
@@ -2409,6 +2442,14 @@
                    " attribute of configuration entry %s:  %s.  The default " +
                    "schema base DN of " + DN_DEFAULT_SCHEMA_ROOT +
                    " will be used.");
    registerMessage(MSGID_SCHEMA_CANNOT_DETERMINE_SHOW_ALL,
                    "An error occurred while trying to determine whether to " +
                    "treat all subschema entry attributes as user attributes " +
                    "regardless of the way they are defined in the schema, " +
                    "as specified in the " + ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES +
                    " attribute of configuration entry %s:  %s.  The default " +
                    "behavior, which is to treat the attribute types as " +
                    "defined in the server schema, will be used.");
    registerMessage(MSGID_SCHEMA_ADD_NOT_SUPPORTED,
                    "Unwilling to add entry \"%s\" because add operations " +
                    "are not supported in the schema backend.");