From 7965fe86169f2b2e1fe3fbee8381105dbb2e8e29 Mon Sep 17 00:00:00 2001
From: coulbeck <coulbeck@localhost>
Date: Thu, 08 Mar 2007 23:08:37 +0000
Subject: [PATCH] Fix for issue #1317: Wrong Error Code For Improperly Formatted ACIs.
---
opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java | 2
opendj-sdk/opends/resource/config/config.ldif | 7
opendj-sdk/opends/resource/schema/00-core.ldif | 4
opendj-sdk/opends/src/server/org/opends/server/schema/AciSyntax.java | 262 ++++++++++++++++++++++++++++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestAccessLogger.java | 2
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java | 148 +++++-------------
opendj-sdk/opends/src/server/org/opends/server/messages/MessageHandler.java | 3
opendj-sdk/opends/src/server/org/opends/server/schema/SchemaConstants.java | 23 ++
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciMessages.java | 28 ---
9 files changed, 342 insertions(+), 137 deletions(-)
diff --git a/opendj-sdk/opends/resource/config/config.ldif b/opendj-sdk/opends/resource/config/config.ldif
index 6b2b2ea..f4ea507 100644
--- a/opendj-sdk/opends/resource/config/config.ldif
+++ b/opendj-sdk/opends/resource/config/config.ldif
@@ -1260,6 +1260,13 @@
ds-cfg-syntax-class: org.opends.server.schema.AbsoluteSubtreeSpecificationSyntax
ds-cfg-syntax-enabled: true
+dn: cn=Sun-defined Access Control Information,cn=Syntaxes,cn=config
+objectClass: top
+objectClass: ds-cfg-attribute-syntax
+cn: Sun-defined Access Control Information
+ds-cfg-syntax-class: org.opends.server.schema.AciSyntax
+ds-cfg-syntax-enabled: true
+
dn: cn=Attribute Type Description,cn=Syntaxes,cn=config
objectClass: top
objectClass: ds-cfg-attribute-syntax
diff --git a/opendj-sdk/opends/resource/schema/00-core.ldif b/opendj-sdk/opends/resource/schema/00-core.ldif
index 5e877b7..cd51e55 100644
--- a/opendj-sdk/opends/resource/schema/00-core.ldif
+++ b/opendj-sdk/opends/resource/schema/00-core.ldif
@@ -357,7 +357,7 @@
USAGE dSAOperation X-ORIGIN 'draft-ietf-ldup-subentry' )
attributeTypes: ( 2.16.840.1.113730.3.1.55 NAME 'aci'
DESC 'Sun-defined access control information attribute type'
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE directoryOperation
+ SYNTAX 1.3.6.1.4.1.26027.1.3.4 USAGE directoryOperation
X-ORIGIN 'Sun Java System Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.542 NAME 'nsUniqueId'
DESC 'Sun-defined unique identifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
@@ -517,7 +517,7 @@
DESC 'named subordinate reference object' STRUCTURAL MUST ref
X-ORIGIN 'RFC 3296' )
objectClasses: ( 2.16.840.1.113719.2.142.6.1.1 NAME 'ldapSubEntry'
- DESC 'LDAP Subentry class, version 1' SUP top STRUCTURAL MAY ( cn )
+ DESC 'LDAP Subentry class, version 1' SUP top STRUCTURAL MAY ( cn )
X-ORIGIN 'draft-ietf-ldup-subentry' )
objectClasses: ( 1.3.6.1.4.1.7628.5.6.1.1 NAME 'inheritableLDAPSubEntry'
DESC 'Inheritable LDAP Subentry class, version 1' SUP ldapSubEntry
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 6341904..3ed8d65 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
@@ -57,7 +57,7 @@
public static AttributeType aciType;
/**
- * Constructor that registers the message catalog, creates the ACI list
+ * 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
@@ -65,7 +65,6 @@
* are initialized/finalized.
*/
public AciHandler() {
- AciMessages.registerMessages();
aciList = new AciList();
AciListenerManager aciListenerMgr =
new AciListenerManager(aciList);
@@ -88,11 +87,30 @@
ModifyOperation operation,
boolean skipAccessCheck) {
Entry resourceEntry=container.getResourceEntry();
- DN dn=resourceEntry.getDN();
List<Modification> modifications=container.getModifications();
for(Modification m : modifications) {
Attribute modAttr=m.getAttribute();
AttributeType modType=modAttr.getAttributeType();
+
+ if(modType.equals(aciType)) {
+ /*
+ * Check that the operation has modify privileges if
+ * it contains an "aci" attribute type.
+ */
+ if (!operation.getClientConnection().
+ hasPrivilege(Privilege.MODIFY_ACL, operation)) {
+ int msgID = MSGID_ACI_MODIFY_FAILED_PRIVILEGE;
+ String message =
+ getMessage(msgID,
+ String.valueOf(container.getResourceDN()),
+ String.valueOf(container.getClientDN()));
+ logError(ErrorLogCategory.ACCESS_CONTROL,
+ ErrorLogSeverity.SEVERE_WARNING,
+ message, msgID);
+ return false;
+ }
+ }
+
switch(m.getModificationType()) {
case DELETE:
case REPLACE:
@@ -157,46 +175,6 @@
}
break;
}
- /*
- Check if the modification type has an "aci" attribute type.
- If so, check the syntax of that attribute value. Fail the
- the operation if the syntax check fails.
- */
- if(modType.equals(aciType)) {
- try {
- /*
- * Check that the operation has modify privileges if
- * it contains an "aci" attribute type. Flip the
- * boolean to false so this check isn't made again
- * if there are several ACI values being added.
- */
- if(checkPrivileges) {
- if (!operation.getClientConnection().
- hasPrivilege(Privilege.MODIFY_ACL, operation)) {
- int msgID =
- MSGID_ACI_MODIFY_FAILED_PRIVILEGE;
- String message = getMessage(msgID,
- String.valueOf(container.getResourceDN()),
- String.valueOf(container.getClientDN()));
- logError(ErrorLogCategory.ACCESS_CONTROL,
- ErrorLogSeverity.SEVERE_WARNING,
- message, msgID);
- return false;
- }
- checkPrivileges=false;
- }
- 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;
- }
- }
}
}
}
@@ -454,63 +432,6 @@
}
/**
- * Evaluate an entry to be added to see if it has any "aci"
- * attribute type. If it does, examines each "aci" attribute type
- * value for syntax errors. All of the "aci" attribute type values
- * must pass syntax check for the add operation to proceed. Any
- * entry with an "aci" attribute type must have "modify-acl"
- * privileges.
- *
- * @param entry The entry to be examined.
- * @param operation The operation to to check privileges on.
- * @param clientDN The authorization DN.
- * @return True if the entry has no ACI attributes or if all of the "aci"
- * attributes values pass ACI syntax checking.
- */
- private boolean
- verifySyntax(Entry entry, Operation operation, DN clientDN) {
- if(entry.hasOperationalAttribute(aciType)) {
- /*
- * Check that the operation has "modify-acl" privileges since the
- * entry to be added has an "aci" attribute type.
- */
- if (!operation.getClientConnection().
- hasPrivilege(Privilege.MODIFY_ACL, operation)) {
- int msgID = MSGID_ACI_ADD_FAILED_PRIVILEGE;
- String message = getMessage(msgID,
- String.valueOf(entry.getDN()),
- String.valueOf(clientDN));
- logError(ErrorLogCategory.ACCESS_CONTROL,
- ErrorLogSeverity.SEVERE_WARNING,
- message, msgID);
- return false;
- }
- List<Attribute> attributeList =
- entry.getOperationalAttribute(aciType, null);
- for (Attribute attribute : attributeList)
- {
- for (AttributeValue value : attribute.getValues())
- {
- try {
- DN dn=entry.getDN();
- Aci.decode(value.getValue(),dn);
- } catch (AciException ex) {
- int msgID = MSGID_ACI_ADD_FAILED_DECODE;
- String message = getMessage(msgID,
- String.valueOf(entry.getDN()),
- ex.getMessage());
- logError(ErrorLogCategory.ACCESS_CONTROL,
- ErrorLogSeverity.SEVERE_WARNING,
- message, msgID);
- return false;
- }
- }
- }
- }
- return true;
- }
-
- /**
* Check access using the accessAllowed method. The
* LDAP add, compare, modify and delete operations use this function.
* The other supported LDAP operations have more specialized checks.
@@ -534,11 +455,28 @@
AciLDAPOperationContainer operationContainer =
new AciLDAPOperationContainer(operation, ACI_ADD);
boolean ret=isAllowed(operationContainer,operation);
- //LDAP add needs a verify ACI syntax step in case any
- //"aci" attribute types are being added.
- if(ret)
- ret=verifySyntax(operation.getEntryToAdd(), operation,
- operationContainer.getClientDN());
+
+ if(ret) {
+ Entry entry = operation.getEntryToAdd();
+ if(entry.hasOperationalAttribute(aciType)) {
+ /*
+ * Check that the operation has "modify-acl" privileges since the
+ * entry to be added has an "aci" attribute type.
+ */
+ if (!operation.getClientConnection().
+ hasPrivilege(Privilege.MODIFY_ACL, operation)) {
+ int msgID = MSGID_ACI_ADD_FAILED_PRIVILEGE;
+ String message =
+ getMessage(msgID,
+ String.valueOf(entry.getDN()),
+ String.valueOf(operationContainer.getClientDN()));
+ logError(ErrorLogCategory.ACCESS_CONTROL,
+ ErrorLogSeverity.SEVERE_WARNING,
+ message, msgID);
+ ret = false;
+ }
+ }
+ }
return ret;
}
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 d75ac45..2015c1c 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
@@ -474,24 +474,6 @@
CATEGORY_MASK_ACCESS_CONTROL | 45;
/**
- * The message ID for the ACI message that will be generated when a client
- * attempts to add an entry with the "aci" attribute type
- * and the ACI decode failed because of an syntax error. This takes one
- * argument, which is the message string thrown by the AciException.
- */
- public static final int MSGID_ACI_ADD_FAILED_DECODE =
- CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 46;
-
- /**
- * The message ID for the ACI message that will be generated when a client
- * attempts to perform a modification on an "aci" attribute type
- * and the ACI decode failed because of a syntax error. This takes one
- * argument, which is the message string thrown by the AciException.
- */
- public static final int MSGID_ACI_MODIFY_FAILED_DECODE =
- CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 47;
-
- /**
* The message ID for the ACI message that will be generated when
* an ACI decode failed because of an syntax error. This message is usually
* generated by an invalid ACI that was added during import which
@@ -876,16 +858,6 @@
"attribute type in the entry \"%s\" failed, because the" +
"authorization DN \"%s\" lacked modify-acl privileges.");
- registerMessage(MSGID_ACI_ADD_FAILED_DECODE,
- "An attempt to add the entry \"%s\" containing" +
- " an aci attribute type failed because of the following" +
- " reason: %s");
-
- registerMessage(MSGID_ACI_MODIFY_FAILED_DECODE,
- "An attempt to modify an aci "+
- "attribute type in the entry \"%s\" failed "+
- "because of the following reason: %s");
-
registerMessage(MSGID_ACI_ADD_LIST_FAILED_DECODE,
"An attempt to decode an Access Control Instruction (ACI)" +
" failed because of the following reason: %s");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
index 5811b66..f90d343 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
@@ -6666,7 +6666,7 @@
registerMessage(MSGID_ADD_OP_INVALID_SYNTAX,
- "Entry \"%s\" contains an value \"%s\" for attribute %s " +
+ "Entry \"%s\" contains a value \"%s\" for attribute %s " +
"that is invalid according to the syntax for that " +
"attribute: %s.");
registerMessage(MSGID_ADD_ATTR_IS_OBSOLETE,
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/MessageHandler.java b/opendj-sdk/opends/src/server/org/opends/server/messages/MessageHandler.java
index 80f92f5..beae01c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/MessageHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/MessageHandler.java
@@ -28,6 +28,8 @@
+import org.opends.server.authorization.dseecompat.AciMessages;
+
import java.util.concurrent.ConcurrentHashMap;
import java.util.IllegalFormatException;
@@ -281,6 +283,7 @@
BackendMessages.registerMessages();
ToolMessages.registerMessages();
TaskMessages.registerMessages();
+ AciMessages.registerMessages();
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/AciSyntax.java b/opendj-sdk/opends/src/server/org/opends/server/schema/AciSyntax.java
new file mode 100644
index 0000000..0082f35
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/AciSyntax.java
@@ -0,0 +1,262 @@
+/*
+ * 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.schema;
+
+
+
+import org.opends.server.api.ApproximateMatchingRule;
+import org.opends.server.api.AttributeSyntax;
+import org.opends.server.api.EqualityMatchingRule;
+import org.opends.server.api.OrderingMatchingRule;
+import org.opends.server.api.SubstringMatchingRule;
+import org.opends.server.config.ConfigEntry;
+import org.opends.server.config.ConfigException;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.ByteString;
+import org.opends.server.types.ErrorLogCategory;
+import org.opends.server.types.ErrorLogSeverity;
+import org.opends.server.types.DN;
+import org.opends.server.types.DebugLogLevel;
+
+import static org.opends.server.loggers.Error.*;
+import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
+import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
+import static org.opends.server.messages.SchemaMessages.*;
+import static org.opends.server.schema.SchemaConstants.*;
+import org.opends.server.authorization.dseecompat.Aci;
+import org.opends.server.authorization.dseecompat.AciException;
+
+
+/**
+ * This class implements the access control information (aci) attribute syntax.
+ */
+public class AciSyntax
+ extends AttributeSyntax
+{
+
+
+
+ // The default approximate matching rule for this syntax.
+ private ApproximateMatchingRule defaultApproximateMatchingRule;
+
+ // The default equality matching rule for this syntax.
+ private EqualityMatchingRule defaultEqualityMatchingRule;
+
+ // The default ordering matching rule for this syntax.
+ private OrderingMatchingRule defaultOrderingMatchingRule;
+
+ // The default substring matching rule for this syntax.
+ private SubstringMatchingRule defaultSubstringMatchingRule;
+
+
+
+ /**
+ * Creates a new instance of this syntax. Note that the only thing that
+ * should be done here is to invoke the default constructor for the
+ * superclass. All initialization should be performed in the
+ * <CODE>initializeSyntax</CODE> method.
+ */
+ public AciSyntax()
+ {
+ super();
+
+ }
+
+
+
+ /**
+ * Initializes this attribute syntax based on the information in the provided
+ * configuration entry.
+ *
+ * @param configEntry The configuration entry that contains the information
+ * to use to initialize this attribute syntax.
+ *
+ * @throws ConfigException If an unrecoverable problem arises in the
+ * process of performing the initialization.
+ */
+ public void initializeSyntax(ConfigEntry configEntry)
+ throws ConfigException
+ {
+ // We don't need an approximate matching rule.
+ defaultApproximateMatchingRule = null;
+
+ defaultEqualityMatchingRule =
+ DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_IA5_OID);
+ if (defaultEqualityMatchingRule == null)
+ {
+ logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
+ MSGID_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE,
+ EMR_CASE_IGNORE_IA5_OID, SYNTAX_ACI_NAME);
+ }
+
+ // We don't need an ordering matching rule.
+ defaultOrderingMatchingRule = null;
+
+ defaultSubstringMatchingRule =
+ DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_IA5_OID);
+ if (defaultSubstringMatchingRule == null)
+ {
+ logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR,
+ MSGID_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE,
+ SMR_CASE_IGNORE_IA5_OID, SYNTAX_ACI_NAME);
+ }
+ }
+
+
+
+ /**
+ * Retrieves the common name for this attribute syntax.
+ *
+ * @return The common name for this attribute syntax.
+ */
+ public String getSyntaxName()
+ {
+ return SYNTAX_ACI_NAME;
+ }
+
+
+
+ /**
+ * Retrieves the OID for this attribute syntax.
+ *
+ * @return The OID for this attribute syntax.
+ */
+ public String getOID()
+ {
+ return SYNTAX_ACI_OID;
+ }
+
+
+
+ /**
+ * Retrieves a description for this attribute syntax.
+ *
+ * @return A description for this attribute syntax.
+ */
+ public String getDescription()
+ {
+ return SYNTAX_ACI_DESCRIPTION;
+ }
+
+
+
+ /**
+ * Retrieves the default equality matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default equality matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if equality
+ * matches will not be allowed for this type by default.
+ */
+ public EqualityMatchingRule getEqualityMatchingRule()
+ {
+ return defaultEqualityMatchingRule;
+ }
+
+
+
+ /**
+ * Retrieves the default ordering matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default ordering matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if ordering
+ * matches will not be allowed for this type by default.
+ */
+ public OrderingMatchingRule getOrderingMatchingRule()
+ {
+ return defaultOrderingMatchingRule;
+ }
+
+
+
+ /**
+ * Retrieves the default substring matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default substring matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if substring
+ * matches will not be allowed for this type by default.
+ */
+ public SubstringMatchingRule getSubstringMatchingRule()
+ {
+ return defaultSubstringMatchingRule;
+ }
+
+
+
+ /**
+ * Retrieves the default approximate matching rule that will be used for
+ * attributes with this syntax.
+ *
+ * @return The default approximate matching rule that will be used for
+ * attributes with this syntax, or <CODE>null</CODE> if approximate
+ * matches will not be allowed for this type by default.
+ */
+ public ApproximateMatchingRule getApproximateMatchingRule()
+ {
+ return defaultApproximateMatchingRule;
+ }
+
+
+
+ /**
+ * Indicates whether the provided value is acceptable for use in an attribute
+ * with this syntax. If it is not, then the reason may be appended to the
+ * provided buffer.
+ *
+ * @param value The value for which to make the determination.
+ * @param invalidReason The buffer to which the invalid reason should be
+ * appended.
+ *
+ * @return <CODE>true</CODE> if the provided value is acceptable for use with
+ * this syntax, or <CODE>false</CODE> if not.
+ */
+ public boolean valueIsAcceptable(ByteString value,
+ StringBuilder invalidReason)
+ {
+ try
+ {
+ Aci.decode(value, DN.nullDN());
+ }
+ catch (AciException e)
+ {
+ if (debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ logError(ErrorLogCategory.ACCESS_CONTROL,
+ ErrorLogSeverity.SEVERE_WARNING,
+ e.getMessage(), e.getMessageID());
+ invalidReason.append(e.getMessage());
+ return false;
+ }
+ return true;
+ }
+}
+
diff --git a/opendj-sdk/opends/src/server/org/opends/server/schema/SchemaConstants.java b/opendj-sdk/opends/src/server/org/opends/server/schema/SchemaConstants.java
index c7c605e..2bfdce4 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/schema/SchemaConstants.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/schema/SchemaConstants.java
@@ -811,6 +811,29 @@
+ /**
+ * The OID for the aci attribute syntax.
+ */
+ public static final String SYNTAX_ACI_OID =
+ OID_OPENDS_SERVER_ATTRIBUTE_SYNTAX_BASE + ".4";
+
+
+
+ /**
+ * The description for aci attribute syntax.
+ */
+ public static final String SYNTAX_ACI_DESCRIPTION =
+ "Sun-defined Access Control Information";
+
+
+
+ /**
+ * The name for the aci attribute syntax.
+ */
+ public static final String SYNTAX_ACI_NAME = "ds-syntax-dseecompat-aci";
+
+
+
/**
* The description for the attribute type description attribute syntax.
*/
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestAccessLogger.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestAccessLogger.java
index 091575e..35f56c4 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestAccessLogger.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/TestAccessLogger.java
@@ -260,7 +260,7 @@
addCommonRequestElements(addOperation, buffer);
buffer.append(" dn=\"");
buffer.append(addOperation.getRawEntryDN());
- buffer.append("\" attibutes={");
+ buffer.append("\" attributes={");
Iterator<LDAPAttribute> attrIterator =
addOperation.getRawAttributes().iterator();
--
Gitblit v1.10.0