From 6265d3b4cc078a6b1671079ca3836d36a3a16771 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Thu, 30 Nov 2006 21:11:22 +0000
Subject: [PATCH] Fix a bug in the server in which the SINGLE-VALUE constraint was not properly enforced for operational attributes.

---
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java |  102 ++++++++++++++++++++++++++++++++++
 opendj-sdk/opends/src/server/org/opends/server/types/Entry.java                                          |   26 ++++++++
 2 files changed, 128 insertions(+), 0 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java b/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
index 6235eea..b0218da 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
@@ -2246,6 +2246,32 @@
     }
 
 
+    // Iterate through all of the operational attributes and make sure
+    // that all of the single-valued attributes only have one value.
+    for (AttributeType t : operationalAttributes.keySet())
+    {
+      if (t.isSingleValue())
+      {
+        List<Attribute> attrList = operationalAttributes.get(t);
+        if (attrList != null)
+        {
+          for (Attribute a : attrList)
+          {
+            if (a.getValues().size() > 1)
+            {
+              int    msgID   = MSGID_ENTRY_SCHEMA_ATTR_SINGLE_VALUED;
+              String message = getMessage(msgID, String.valueOf(dn),
+                                          t.getNameOrOID());
+
+              invalidReason.append(message);
+              return false;
+            }
+          }
+        }
+      }
+    }
+
+
     // Optionally, make sure that the entry contains exactly one
     // structural objectclass.
     AcceptRejectWarn structuralPolicy =
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
index 918a95b..fe55d07 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/ModifyOperationTestCase.java
@@ -867,6 +867,57 @@
 
 
   /**
+   * Tests to ensure that a modify attempt fails if an attempt is made to add a
+   * second value to a single-valued operational attribute.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testFailAddToSingleValuedOperationalAttribute()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    Entry entry = TestCaseUtils.makeEntry(
+         "dn: uid=test.user,o=test",
+         "objectClass: top",
+         "objectClass: person",
+         "objectClass: organizationalPerson",
+         "objectClass: inetOrgPerson",
+         "uid: test.user",
+         "givenName: Test",
+         "sn: User",
+         "cn: Test User",
+         "displayName: Test User",
+         "userPassword: password",
+         "ds-pwp-account-disabled: true");
+
+    InternalClientConnection conn =
+         InternalClientConnection.getRootConnection();
+
+    AddOperation addOperation =
+         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+                         entry.getUserAttributes(),
+                         entry.getOperationalAttributes());
+    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+
+
+    ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+    values.add(new ASN1OctetString("false"));
+    LDAPAttribute attr = new LDAPAttribute("ds-pwp-account-disabled", values);
+
+    ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>();
+    mods.add(new LDAPModification(ModificationType.ADD, attr));
+
+    ModifyOperation modifyOperation =
+         conn.processModify(new ASN1OctetString("uid=test.user,o=test"), mods);
+    assertFalse(modifyOperation.getResultCode() == ResultCode.SUCCESS);
+    retrieveFailedOperationElements(modifyOperation);
+  }
+
+
+
+  /**
    * Tests to ensure that a modify attempt fails if an attempt is made to
    * replace a single-valued attribute with multiple values.
    *
@@ -918,6 +969,57 @@
 
 
   /**
+   * Tests to ensure that a modify attempt fails if an attempt is made to
+   * replace a single-valued operational attribute with multiple values.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void testFailReplaceSingleValuedOperationalAttrWithMultipleValues()
+         throws Exception
+  {
+    TestCaseUtils.initializeTestBackend(true);
+
+    Entry entry = TestCaseUtils.makeEntry(
+         "dn: uid=test.user,o=test",
+         "objectClass: top",
+         "objectClass: person",
+         "objectClass: organizationalPerson",
+         "objectClass: inetOrgPerson",
+         "uid: test.user",
+         "givenName: Test",
+         "sn: User",
+         "cn: Test User",
+         "displayName: Test User",
+         "userPassword: password");
+
+    InternalClientConnection conn =
+         InternalClientConnection.getRootConnection();
+
+    AddOperation addOperation =
+         conn.processAdd(entry.getDN(), entry.getObjectClasses(),
+                         entry.getUserAttributes(),
+                         entry.getOperationalAttributes());
+    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+
+
+    ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>();
+    values.add(new ASN1OctetString("true"));
+    values.add(new ASN1OctetString("false"));
+    LDAPAttribute attr = new LDAPAttribute("ds-pwp-account-disabled", values);
+
+    ArrayList<LDAPModification> mods = new ArrayList<LDAPModification>();
+    mods.add(new LDAPModification(ModificationType.REPLACE, attr));
+
+    ModifyOperation modifyOperation =
+         conn.processModify(new ASN1OctetString("uid=test.user,o=test"), mods);
+    assertFalse(modifyOperation.getResultCode() == ResultCode.SUCCESS);
+    retrieveFailedOperationElements(modifyOperation);
+  }
+
+
+
+  /**
    * Tests to ensure that a modify attempt fails if an attempt is made to add a
    * value that matches one that already exists.
    *

--
Gitblit v1.10.0