From 4bddd152a9e15207d8003f6f74e70ebc6f07cc7e Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Mon, 05 Aug 2024 13:48:27 +0000
Subject: [PATCH] [#84] FIX incorrect entry-Based ACIs is defined with only "deny" permission without "allow" (#372)

---
 opendj-server-legacy/src/test/java/org/openidentityplatform/opendj/Issue84TestSuite.java      |  112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java |    3 +
 2 files changed, 114 insertions(+), 1 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java
index 76f6d76..17e6720 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -14,6 +14,7 @@
  * Copyright 2008-2010 Sun Microsystems, Inc.
  * Portions Copyright 2011-2016 ForgeRock AS.
  * Portions Copyright 2013 Manuel Gaupp
+ * Portions Copyright 2024 3A Systems, LLC.
  */
 package org.opends.server.authorization.dseecompat;
 
@@ -1032,7 +1033,7 @@
   {
     evalCtx.setEvaluationResult(NO_REASON, null);
 
-    if (evalCtx.getAllowList().isEmpty()
+    if (evalCtx.getAllowList().isEmpty() && evalCtx.getDenyList().isEmpty()
         && (!evalCtx.isGetEffectiveRightsEval()
             || evalCtx.hasRights(ACI_SELF)
             || !evalCtx.isTargAttrFilterMatchAciEmpty()))
diff --git a/opendj-server-legacy/src/test/java/org/openidentityplatform/opendj/Issue84TestSuite.java b/opendj-server-legacy/src/test/java/org/openidentityplatform/opendj/Issue84TestSuite.java
new file mode 100644
index 0000000..10af17e
--- /dev/null
+++ b/opendj-server-legacy/src/test/java/org/openidentityplatform/opendj/Issue84TestSuite.java
@@ -0,0 +1,112 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development and
+ * Distribution License (the License). You may not use this file except in compliance with the
+ * License.
+ *
+ * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
+ * specific language governing permission and limitations under the License.
+ *
+ * When distributing Covered Software, include this CDDL Header Notice in each file and include
+ * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
+ * Header, with the fields enclosed by brackets [] replaced by your own identifying
+ * information: "Portions Copyright [year] [name of copyright owner]".
+ *
+ * Copyright 2024 3A Systems, LLC.
+ */
+package org.openidentityplatform.opendj;
+
+import org.forgerock.opendj.ldap.*;
+import org.forgerock.opendj.ldap.requests.Requests;
+import org.forgerock.opendj.ldap.requests.SearchRequest;
+import org.forgerock.opendj.ldap.responses.SearchResultEntry;
+import org.forgerock.opendj.ldif.ConnectionEntryReader;
+import org.opends.server.DirectoryServerTestCase;
+import org.opends.server.TestCaseUtils;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@Test(sequential = true)
+public class Issue84TestSuite extends DirectoryServerTestCase {
+
+    @BeforeClass
+    public void startServer() throws Exception {
+        TestCaseUtils.startServer();
+        TestCaseUtils.initializeTestBackend(true);
+
+        TestCaseUtils.addEntries(
+                "dn: ou=People,o=test",
+                "objectClass: organizationalUnit",
+                "objectClass: top",
+                "ou: People",
+                "",
+                "dn: uid=user.1,ou=People,o=test",
+                "objectClass: person",
+                "objectClass: organizationalPerson",
+                "objectClass: inetOrgPerson",
+                "objectClass: top",
+                "cn: Aaren Atp",
+                "sn: Atp",
+                "uid: user.1",
+                "userPassword: password",
+                "",
+                "dn: ou=Services,o=test",
+                "objectClass: organizationalUnit",
+                "objectClass: top",
+                "ou: Services",
+                "aci: (version 3.0; acl \"Test ACI\"; deny (all) userdn =\"ldap:///uid=user.1,ou=People,o=test\";)",
+                "",
+                "dn: uid=service.1,ou=Services,o=test",
+                "objectClass: top",
+                "objectClass: account",
+                "objectClass: simpleSecurityObject",
+                "uid: service.1",
+                "userPassword: password",
+                ""
+        );
+    }
+
+    Connection getConnection(final String user,final String password) throws LdapException {
+        final LDAPConnectionFactory factory =new LDAPConnectionFactory("localhost", TestCaseUtils.getServerLdapPort());
+        final Connection connection = factory.getConnection();
+        connection.bind(user, password.toCharArray());
+        assertThat(connection.isValid()).isTrue();
+        return connection;
+    }
+
+    public void test_user() throws LdapException {
+        try(Connection connection=getConnection("uid=user.1,ou=People,o=test","password")){
+            final SearchRequest request =Requests.newSearchRequest("ou=Services,o=test", SearchScope.WHOLE_SUBTREE,"(&)");
+            System.out.println("---------------------------------------------------------------------------------------");
+            System.out.println(request);
+
+            final ConnectionEntryReader reader = connection.search(request);
+            assertThat(reader.hasNext()).isFalse();
+        }
+    }
+
+    public void test_service() throws LdapException, SearchResultReferenceIOException {
+        try(Connection connection=getConnection("uid=service.1,ou=Services,o=test","password")){
+            final SearchRequest request =Requests.newSearchRequest("ou=Services,o=test", SearchScope.WHOLE_SUBTREE,"(&)");
+            System.out.println("---------------------------------------------------------------------------------------");
+            System.out.println(request);
+
+            final ConnectionEntryReader reader = connection.search(request);
+
+            assertThat(reader.hasNext()).isTrue();
+            SearchResultEntry entry=reader.readEntry();
+            System.out.println(entry);
+            assertThat(entry).isNotNull();
+            assertThat(entry.getName().toString()).isEqualTo("ou=Services,o=test");
+
+            assertThat(reader.hasNext()).isTrue();
+            entry=reader.readEntry();
+            System.out.println(entry);
+            assertThat(entry).isNotNull();
+            assertThat(entry.getName().toString()).isEqualTo("uid=service.1,ou=Services,o=test");
+        }
+    }
+}

--
Gitblit v1.10.0