From 09b2bb485c8939161985e4542ec791b695e88ed9 Mon Sep 17 00:00:00 2001
From: dugan <dugan@localhost>
Date: Fri, 15 Jun 2007 22:59:08 +0000
Subject: [PATCH] Fix userattr bind rule GROUPDN keyword when using a url search failure . Issue 1596.
---
opends/src/server/org/opends/server/authorization/dseecompat/ParentInheritance.java | 55 ++++++++++++++++--
opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java | 3
opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java | 17 ++++-
opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java | 39 +++++++++++++
opends/src/server/org/opends/server/authorization/dseecompat/GroupDN.java | 8 ++
opends/src/server/org/opends/server/messages/AciMessages.java | 47 +++++++++++++++
6 files changed, 156 insertions(+), 13 deletions(-)
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/GroupDN.java b/opends/src/server/org/opends/server/authorization/dseecompat/GroupDN.java
index 1107f83..7ffe140 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/GroupDN.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/GroupDN.java
@@ -143,16 +143,22 @@
* @param evalCtx The evaluation context to use in the evaluation.
* @param attributeType The attribute type of the entry to use to get the
* values for the groupd DNs.
+ * @param suffixDN The suffix that the groupDN must be under. If it's null,
+ * then the groupDN can be anywhere in the DIT.
* @return Enumeration evaluation result.
*/
public static EnumEvalResult evaluate (Entry e, AciEvalContext evalCtx,
- AttributeType attributeType) {
+ AttributeType attributeType,
+ DN suffixDN) {
EnumEvalResult matched= EnumEvalResult.FALSE;
List<Attribute> attrs = e.getAttribute(attributeType);
LinkedHashSet<AttributeValue> vals = attrs.get(0).getValues();
for(AttributeValue v : vals) {
try {
DN groupDN=DN.decode(v.getStringValue());
+ if(suffixDN != null &&
+ !groupDN.isDescendantOf(suffixDN))
+ continue;
Group group = groupManager.getGroupInstance(groupDN);
if((group != null) && (evalCtx.isMemberOf(group))) {
matched=EnumEvalResult.TRUE;
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/ParentInheritance.java b/opends/src/server/org/opends/server/authorization/dseecompat/ParentInheritance.java
index 612e677..3b8a76e 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/ParentInheritance.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/ParentInheritance.java
@@ -31,11 +31,15 @@
import static org.opends.server.authorization.dseecompat.Aci.*;
import static org.opends.server.messages.MessageHandler.getMessage;
import java.util.StringTokenizer;
+import java.util.LinkedHashSet;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.AttributeType;
+import org.opends.server.types.DN;
+import org.opends.server.types.LDAPURL;
+import org.opends.server.types.DirectoryException;
/**
* This class is used by USERDN and GROUPDN userattr types
@@ -75,6 +79,13 @@
*/
private String attrTypeStr;
+ /*
+ * The base DN of a URL parsed from the rule. Used to make sure groupdn
+ * are under this suffix. Originally a way to search all nested groups
+ * under this suffix, so the behavior is slightly different.
+ */
+ private DN baseDN=null;
+
/**
* Construct a class from the inheritance pattern. The skipParsing boolean
@@ -181,12 +192,35 @@
}
}
} else {
- if((this.attributeType =
- DirectoryServer.getAttributeType(pattern)) == null)
- this.attributeType =
- DirectoryServer.getDefaultAttributeType(pattern);
- numLevels=1;
- levels[0]=0;
+ attrTypeStr=pattern;
+ if(pattern.startsWith(NULL_LDAP_URL)) {
+ try {
+ LDAPURL url=LDAPURL.decode(pattern, true);
+ LinkedHashSet<String>attrs=url.getAttributes();
+ if(attrs.size() != 1) {
+ int msgID = MSGID_ACI_SYNTAX_INVALID_USERATTR_ATTR_URL;
+ String message = getMessage(msgID, pattern);
+ throw new AciException(msgID, pattern);
+ }
+ baseDN=url.getBaseDN();
+ if(baseDN.isNullDN()){
+ int msgID = MSGID_ACI_SYNTAX_INVALID_USERATTR_BASEDN_URL;
+ String message = getMessage(msgID, pattern);
+ throw new AciException(msgID, message);
+ }
+ attrTypeStr=attrs.iterator().next();
+ } catch (DirectoryException ex) {
+ int msgID = MSGID_ACI_SYNTAX_INVALID_USERATTR_URL;
+ String message = getMessage(msgID, ex.getErrorMessage());
+ throw new AciException(msgID, message);
+ }
+ }
+ if((this.attributeType =
+ DirectoryServer.getAttributeType(attrTypeStr)) == null)
+ this.attributeType =
+ DirectoryServer.getDefaultAttributeType(attrTypeStr);
+ numLevels=1;
+ levels[0]=0;
}
}
@@ -221,5 +255,14 @@
public String getAttrTypeStr() {
return attrTypeStr;
}
+
+ /**
+ * Return the DN that groupdn must be under.
+ *
+ * @return DN that groupdn must be under.
+ */
+ public DN getBaseDN() {
+ return baseDN;
+ }
}
diff --git a/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java b/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java
index e50670c..5a10f8b 100644
--- a/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java
+++ b/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java
@@ -323,6 +323,12 @@
int numLevels=parentInheritance.getNumLevels();
int[] levels=parentInheritance.getLevels();
AttributeType attrType=parentInheritance.getAttributeType();
+ DN baseDN=parentInheritance.getBaseDN();
+ if(baseDN != null) {
+ if (evalCtx.getResourceEntry().hasAttribute(attrType))
+ matched=GroupDN.evaluate(evalCtx.getResourceEntry(),
+ evalCtx,attrType, baseDN);
+ } else {
for(int i=0;((i < numLevels) && !stop); i++ ) {
//The ROLEDN keyword will always enter this statement. The others
//might. For the add operation, the resource itself (level 0)
@@ -332,9 +338,9 @@
undefined=true;
} else if (evalCtx.getResourceEntry().hasAttribute(attrType)) {
matched =
- evalEntryAttr(evalCtx.getResourceEntry(),
- evalCtx,attrType);
- if(matched.equals(EnumEvalResult.TRUE))
+ evalEntryAttr(evalCtx.getResourceEntry(),
+ evalCtx,attrType);
+ if(matched.equals(EnumEvalResult.TRUE))
stop=true;
}
} else {
@@ -362,7 +368,8 @@
}
}
}
- return matched.getRet(type, undefined);
+ }
+ return matched.getRet(type, undefined);
}
/**
@@ -405,7 +412,7 @@
break;
}
case GROUPDN: {
- result=GroupDN.evaluate(e, evalCtx, attributeType);
+ result=GroupDN.evaluate(e, evalCtx, attributeType, null);
break;
}
}
diff --git a/opends/src/server/org/opends/server/messages/AciMessages.java b/opends/src/server/org/opends/server/messages/AciMessages.java
index 811b377..1b366b6 100644
--- a/opends/src/server/org/opends/server/messages/AciMessages.java
+++ b/opends/src/server/org/opends/server/messages/AciMessages.java
@@ -778,6 +778,35 @@
/**
+ * The message ID for the message that will be used if an "aci" attribute
+ * type value parse failed because a bind rule userattr LDAP URL failed
+ * to decode. This takes one argument the message from the LDAP
+ * URL decode DirectoryException.
+ */
+ public static final int MSGID_ACI_SYNTAX_INVALID_USERATTR_URL =
+ CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 78;
+
+
+ /**
+ * The message ID for the message that will be used if an "aci" attribute
+ * type value parse failed because a bind rule userattr LDAP URL contained
+ * a null base DN. This takes one argument the ldap URL from the bind rule
+ * expression.
+ */
+ public static final int MSGID_ACI_SYNTAX_INVALID_USERATTR_BASEDN_URL =
+ CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 79;
+
+
+ /**
+ * The message ID for the message that will be used if an "aci" attribute
+ * type value parse failed because a bind rule userattr LDAP URL attribute
+ * field either contained more than one attribute or the field was null.
+ * This takes one argument the ldap URL from the bind rule expression.
+ */
+ public static final int MSGID_ACI_SYNTAX_INVALID_USERATTR_ATTR_URL =
+ CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 80;
+
+ /**
* Associates a set of generic messages with the message IDs defined in
* this class.
*/
@@ -1220,5 +1249,23 @@
"invalid ACIs rules were detected either when the server " +
"was started or during a backend initialization");
+
+ registerMessage(MSGID_ACI_SYNTAX_INVALID_USERATTR_URL,
+ "The provided Access Control Instruction (ACI) bind rule " +
+ "userattr expression value failed to URL decode for " +
+ "the following reason: %s");
+
+
+ registerMessage(MSGID_ACI_SYNTAX_INVALID_USERATTR_BASEDN_URL,
+ "The provided Access Control Instruction (ACI) bind rule " +
+ "userattr expression value failed to parse because the " +
+ "ldap URL \"%s\" contains an empty base DN");
+
+
+ registerMessage(MSGID_ACI_SYNTAX_INVALID_USERATTR_ATTR_URL,
+ "The provided Access Control Instruction (ACI) bind rule " +
+ "userattr expression value failed to parse because the " +
+ "attribute field of the ldap URL \"%s\" either contains more " +
+ "than one description or the field is empty");
}
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java
index 5d6d9c7..ed2b4be 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java
@@ -211,7 +211,7 @@
"objectclass: top",
"objectclass: groupOfNames",
"cn: group",
- "member: uid=user.1,ou=People,o=test",
+ "member: uid=user.3,ou=People,o=test",
"",
"dn: uid=superuser,ou=admins,o=test",
"objectClass: top",
@@ -246,6 +246,7 @@
"sn: 1",
"cn: User1",
"l: Austin",
+ "manager: cn=group,ou=People,o=test",
"userPassword: password",
"",
"dn: uid=user.2,ou=People,o=test",
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
index cfc978b..deb0662 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
@@ -46,6 +46,19 @@
private static final
+ String grpAttrAci = "(targetattr=\"*\")" +
+ "(version 3.0; acl \"user attr URL example\"; " +
+ "allow (search,read) " +
+ "userattr=\"ldap:///ou=People,o=test?manager#GROUPDN\";)";
+
+
+ private static final
+ String grp1AttrAci = "(targetattr=\"*\")" +
+ "(version 3.0; acl \"user attr1 URL example\"; " +
+ "allow (search,read) " +
+ "userattr=\"ldap:///ou=People1,o=test?manager#GROUPDN\";)";
+
+ private static final
String starAciAttrs = "(targetattr=\"* || aci\")" +
"(version 3.0;acl \"read/search all user, aci op\";" +
"allow (search, read) " +
@@ -323,6 +336,32 @@
deleteAttrFromEntry(user1, "aci");
}
+ /**
+ * Test two scenerios with userattr LDAP URL and groupdn keyword.
+ *
+ * @throws Exception Exception If test result is unexpected.
+ */
+ @Test()
+ public void testTargetAttrGrpDN() throws Exception {
+ String aciLdif=makeAddAciLdif("aci", user1, grpAttrAci);
+ modEntries(aciLdif, DIR_MGR_DN, PWD);
+ String userResults =
+ LDAPSearchParams(user3, PWD, null, null, null,
+ user1, filter, attrList);
+ Assert.assertFalse(userResults.equals(""));
+ HashMap<String, String> attrMap=getAttrMap(userResults);
+ Assert.assertTrue(attrMap.containsKey("l"));
+ Assert.assertTrue(attrMap.containsKey("sn"));
+ Assert.assertTrue(attrMap.containsKey("uid"));
+ deleteAttrFromEntry(user1, "aci");
+ String aciLdif1=makeAddAciLdif("aci", user1, grp1AttrAci);
+ modEntries(aciLdif1, DIR_MGR_DN, PWD);
+ String userResults1 =
+ LDAPSearchParams(user3, PWD, null, null, null,
+ user1, filter, attrList);
+ //This search should return nothing since the URL has a bogus DN.
+ Assert.assertTrue(userResults1.equals(""));
+ }
private void
checkAttributeVal(HashMap<String, String> attrMap, String attr,
--
Gitblit v1.10.0