| | |
| | | public static final int TARGATTRFILTERS_DELETE = 0x2000; |
| | | |
| | | /** |
| | | * ACI_ATTR_STAR_MATCHED is the flag set when the evaluation reason of a |
| | | * AciHandler.maysend ACI_READ access evaluation was the result of an |
| | | * ACI targetattr all attributes expression (targetattr="*") target match. |
| | | * For this flag to be set, there must be only one ACI matching. |
| | | * |
| | | * This flag and ACI_FOUND_ATTR_RULE are used in the |
| | | * AciHandler.filterEntry.accessAllowedAttrs method to skip access |
| | | * evaluation if the flag is ACI_ATTR_STAR_MATCHED (all attributes match) |
| | | * and the attribute type is not operational. |
| | | */ |
| | | public static final int ACI_ATTR_STAR_MATCHED = 0x0008; |
| | | |
| | | /** |
| | | * ACI_FOUND_ATTR_RULE is the flag set when the evaluation reason of a |
| | | * AciHandler.maysend ACI_READ access evaluation was the result of an |
| | | * ACI targetattr specific attribute expression |
| | | * (targetattr="some attribute type") target match. |
| | | */ |
| | | public static final int ACI_FOUND_ATTR_RULE = 0x0010; |
| | | |
| | | /** |
| | | * ACI_NULL is used to set the container rights to all zeros. Used |
| | | * by LDAP modify. |
| | | */ |
| | |
| | | * The entry being evaluated (resource entry). |
| | | */ |
| | | private Entry resourceEntry; |
| | | |
| | | /* |
| | | * Saves the resource entry. Used in geteffectiverights evaluation to |
| | | * restore the current resource entry state after a read right was |
| | | * evaluated. |
| | | */ |
| | | private Entry saveResourceEntry; |
| | | |
| | | /* |
| | |
| | | */ |
| | | private String summaryString=null; |
| | | |
| | | /* |
| | | * Flag used to determine if ACI all attributes target matched. |
| | | */ |
| | | private int evalAllAttributes=0; |
| | | |
| | | /** |
| | | * This constructor is used by all currently supported LDAP operations. |
| | | * |
| | |
| | | this.specificAttrs=getEffectiveRightsControl.getAttributes(); |
| | | fullEntry=(Entry)operation.getAttachment(ALL_ATTRS_RESOURCE_ENTRY); |
| | | } |
| | | String allAttrs=(String)operation.getAttachment(ALL_ATTRS_MATCHED); |
| | | if(allAttrs != null) |
| | | evalAllAttributes = ACI_ATTR_STAR_MATCHED; |
| | | } |
| | | //Reference the current authorization entry, so it can be put back |
| | | //if an access proxy check was performed. |
| | |
| | | return "selfwrite"; |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void setACIEvalAttributesRule(int v) { |
| | | if(operation instanceof SearchOperation && (rights == ACI_READ)) { |
| | | if(v == ACI_FOUND_ATTR_RULE) { |
| | | evalAllAttributes |= ACI_FOUND_ATTR_RULE; |
| | | evalAllAttributes &= ~ACI_ATTR_STAR_MATCHED; |
| | | } else |
| | | evalAllAttributes |= Aci.ACI_ATTR_STAR_MATCHED; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean hasACIEvalAttributes() { |
| | | return (evalAllAttributes == 0) || |
| | | (evalAllAttributes & ACI_FOUND_ATTR_RULE) == ACI_FOUND_ATTR_RULE; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void clearACIEvalAttributesRule(int v) { |
| | | evalAllAttributes &= ~v; |
| | | } |
| | | } |
| | |
| | | public static String ALL_ATTRS_RESOURCE_ENTRY = "allAttrsResourceEntry"; |
| | | |
| | | /** |
| | | * String used to indicate that the evaluating ACI had a all attributes |
| | | * targetattr match (targetattr="*"). |
| | | */ |
| | | public static String ALL_ATTRS_MATCHED = "allAttrsMatched"; |
| | | |
| | | |
| | | /** |
| | | * This constructor instantiates the ACI handler class that performs the |
| | | * main processing for the dseecompat ACI package. It does the following |
| | | * initializations: |
| | |
| | | return ret; |
| | | } |
| | | |
| | | /** |
| | | * Check if the specified attribute type is a DN by checking if its syntax |
| | | * OID is equal to the DN syntax OID. |
| | | * @param attribute The attribute type to check. |
| | | * @return True if the attribute type syntax OID is equal to a DN syntax OID. |
| | | */ |
| | | private boolean isAttributeDN(AttributeType attribute) { |
| | | return (attribute.getSyntaxOID().equals(SYNTAX_DN_OID)); |
| | | } |
| | | |
| | | /** |
| | | * Check if the specified attribute type is a DN by checking if its syntax |
| | | * OID is equal to the DN syntax OID. |
| | | * @param attribute The attribute type to check. |
| | | * @return True if the attribute type syntax OID is equal to a DN syntax |
| | | * OID. |
| | | */ |
| | | private boolean isAttributeDN(AttributeType attribute) { |
| | | return (attribute.getSyntaxOID().equals(SYNTAX_DN_OID)); |
| | | } |
| | | |
| | | /** |
| | | * Performs an access check against all of the attributes of an entry. |
| | |
| | | */ |
| | | private SearchResultEntry |
| | | accessAllowedAttrs(AciLDAPOperationContainer container) { |
| | | Entry e=container.getResourceEntry(); |
| | | List<AttributeType> typeList=getAllAttrs(e); |
| | | for(AttributeType attrType : typeList) { |
| | | container.setCurrentAttributeType(attrType); |
| | | if(!accessAllowed(container)) { |
| | | e.removeAttribute(attrType); |
| | | } |
| | | Entry e=container.getResourceEntry(); |
| | | List<AttributeType> typeList=getAllAttrs(e); |
| | | for(AttributeType attrType : typeList) { |
| | | if(!container.hasACIEvalAttributes() && !attrType.isOperational()) |
| | | continue; |
| | | container.setCurrentAttributeType(attrType); |
| | | if(!accessAllowed(container)) { |
| | | e.removeAttribute(attrType); |
| | | } |
| | | return container.getSearchResultEntry(); |
| | | } |
| | | return container.getSearchResultEntry(); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | private List<AttributeType> getAllAttrs(Entry e) { |
| | | Map<AttributeType,List<Attribute>> attrMap = e.getUserAttributes(); |
| | | Map<AttributeType,List<Attribute>> opAttrMap = |
| | | e.getOperationalAttributes(); |
| | | List<AttributeType> typeList=new LinkedList<AttributeType>(); |
| | | Attribute attr=e.getObjectClassAttribute(); |
| | | /* |
| | |
| | | typeList.add(ocType); |
| | | } |
| | | typeList.addAll(attrMap.keySet()); |
| | | typeList.addAll(opAttrMap.keySet()); |
| | | return typeList; |
| | | } |
| | | |
| | |
| | | if (ret) { |
| | | operationContainer.setRights(ACI_READ); |
| | | ret=accessAllowedEntry(operationContainer); |
| | | if(ret && !operationContainer.hasACIEvalAttributes()) |
| | | operation.setAttachment(ALL_ATTRS_MATCHED, ALL_ATTRS_MATCHED); |
| | | } |
| | | } |
| | | if(ret && operation.getAttachment(OID_GET_EFFECTIVE_RIGHTS) != null) |
| | |
| | | * @return True if a match context is evaluating geteffectiverights. |
| | | */ |
| | | boolean isGetEffectiveRightsEval(); |
| | | |
| | | /** |
| | | * This method toggles a mask that indicates that access checking of |
| | | * individual non-operational attributes may or may not be skipped depending |
| | | * on if there is a single ACI containing a targetattr all attributes rule |
| | | * (targetattr="*"). |
| | | * |
| | | * The only case where individual non-operational attribute access checking |
| | | * can be skipped, is when a single ACI matched using a targetattr |
| | | * all attributes rule. |
| | | * |
| | | * @param v The flag to set the mask to. |
| | | */ |
| | | void setACIEvalAttributesRule(int v); |
| | | |
| | | /** |
| | | * Return true if the evaluating ACI either contained an explicitly defined |
| | | * attribute type in a targeattr target rule or both a targetattr all |
| | | * attributes rule matched and a explictly defined targetattr target rule |
| | | * matched. |
| | | * |
| | | * @return True if the above condition was seen. |
| | | */ |
| | | boolean hasACIEvalAttributes(); |
| | | |
| | | |
| | | /** |
| | | * Used to clear the mask used to detect if access checking needs to be |
| | | * performed on individual non-operational attributes types. |
| | | * |
| | | * @param v The flag to clear (always ACI_ATTR_STAR_MATCHED) |
| | | */ |
| | | public void clearACIEvalAttributesRule(int v); |
| | | } |
| | | |
| | | |
| | |
| | | AttributeType a=targetMatchCtx.getCurrentAttributeType(); |
| | | int rights=targetMatchCtx.getRights(); |
| | | boolean isFirstAttr=targetMatchCtx.isFirstAttribute(); |
| | | if((a != null) && (targets.getTargetAttr() != null)) |
| | | ret=TargetAttr.isApplicable(a, targets.getTargetAttr()); |
| | | else if((a != null) || (targets.getTargetAttr() != null)) { |
| | | if((a != null) && (targets.getTargetAttr() != null)) { |
| | | ret=TargetAttr.isApplicable(a,targets.getTargetAttr()); |
| | | targetMatchCtx.clearACIEvalAttributesRule(ACI_ATTR_STAR_MATCHED); |
| | | /* |
| | | If a explicitly defined targetattr's match rule has not |
| | | been seen (~ACI_FOUND_ATTR_RULE) and the current attribute type |
| | | is applicable because of a targetattr all attributes rule match, |
| | | set a flag to indicate this situation (ACI_ATTR_STAR_MATCHED). |
| | | Else the attributes is applicable because it is operational or |
| | | not a targetattr's all attribute match. |
| | | */ |
| | | if(ret && targets.getTargetAttr().isAllAttributes() && |
| | | !targetMatchCtx.hasACIEvalAttributes()) |
| | | targetMatchCtx.setACIEvalAttributesRule(ACI_ATTR_STAR_MATCHED); |
| | | else |
| | | targetMatchCtx.setACIEvalAttributesRule(ACI_FOUND_ATTR_RULE); |
| | | } else if((a != null) || (targets.getTargetAttr() != null)) { |
| | | if((aci.hasRights(skipRights)) && |
| | | (skipRightsHasRights(rights))) |
| | | ret=true; |
| | |
| | | */ |
| | | public EnumEvalResult evaluate(AciEvalContext evalCtx) { |
| | | EnumEvalResult matched; |
| | | boolean undefined=false; |
| | | |
| | | switch(userAttrType) { |
| | | case ROLEDN: |
| | |
| | | default: |
| | | matched=evalVAL(evalCtx); |
| | | } |
| | | if(matched == EnumEvalResult.ERR) |
| | | undefined=true; |
| | | return matched.getRet(type, undefined); |
| | | return matched; |
| | | } |
| | | |
| | | /** Evaluate a VALUE userattr type. Look in client entry for an |
| New file |
| | |
| | | /* |
| | | * 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 2007 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.opends.server.authorization.dseecompat; |
| | | |
| | | import org.opends.server.DirectoryServerTestCase; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.tools.LDAPModify; |
| | | import org.opends.server.tools.LDAPSearch; |
| | | import static org.opends.server.util.ServerConstants.EOL; |
| | | import org.testng.annotations.Test; |
| | | import org.testng.Assert; |
| | | |
| | | import java.io.*; |
| | | import java.util.Map; |
| | | import java.util.HashMap; |
| | | import java.util.ArrayList; |
| | | |
| | | @Test(groups = { "precommit", "dseecompat" }) |
| | | public abstract class AciTestCase extends DirectoryServerTestCase { |
| | | public static final String DIR_MGR_DN = "cn=Directory Manager"; |
| | | public static final String PWD = "password"; |
| | | public static final String filter = "(objectclass=*)"; |
| | | public static final String ACCESS_HANDLER_DN = |
| | | "cn=Access Control Handler,cn=config"; |
| | | |
| | | private static ByteArrayOutputStream oStream = new ByteArrayOutputStream(); |
| | | private static ThreadLocal<Map<String,File>> tempLdifFile = |
| | | new ThreadLocal<Map<String,File>>(); |
| | | |
| | | protected String LDAPSearchCtrl(String bindDn, String bindPassword, |
| | | String proxyDN, String controlStr, |
| | | String base, String filter, String attr) |
| | | throws Exception { |
| | | ArrayList<String> argList=new ArrayList<String>(20); |
| | | argList.add("-h"); |
| | | argList.add("127.0.0.1"); |
| | | argList.add("-p"); |
| | | argList.add(String.valueOf(TestCaseUtils.getServerLdapPort())); |
| | | argList.add("-D"); |
| | | argList.add(bindDn); |
| | | argList.add("-w"); |
| | | argList.add(bindPassword); |
| | | argList.add("-T"); |
| | | if(proxyDN != null) { |
| | | argList.add("-Y"); |
| | | argList.add("dn:" + proxyDN); |
| | | } |
| | | if(controlStr != null) { |
| | | argList.add("-J"); |
| | | argList.add(controlStr); |
| | | } |
| | | argList.add("-b"); |
| | | argList.add(base); |
| | | argList.add("-s"); |
| | | argList.add("sub"); |
| | | argList.add(filter); |
| | | String[] attrs=attr.split("\\s+"); |
| | | for(String a : attrs) |
| | | argList.add(a); |
| | | String[] args = new String[argList.size()]; |
| | | oStream.reset(); |
| | | int retVal = |
| | | LDAPSearch.mainSearch(argList.toArray(args), false, oStream, oStream); |
| | | Assert.assertEquals(0, retVal, "Returned error: " + oStream.toString()); |
| | | return oStream.toString(); |
| | | } |
| | | |
| | | protected String LDAPSearchParams(String bindDn, String bindPassword, |
| | | String proxyDN, String authzid, String[] attrList, |
| | | String base, String filter ,String attr) |
| | | throws Exception { |
| | | ArrayList<String> argList=new ArrayList<String>(20); |
| | | argList.add("-h"); |
| | | argList.add("127.0.0.1"); |
| | | argList.add("-p"); |
| | | argList.add(String.valueOf(TestCaseUtils.getServerLdapPort())); |
| | | argList.add("-D"); |
| | | argList.add(bindDn); |
| | | argList.add("-w"); |
| | | argList.add(bindPassword); |
| | | argList.add("-T"); |
| | | if(proxyDN != null) { |
| | | argList.add("-Y"); |
| | | argList.add("dn:" + proxyDN); |
| | | } |
| | | if(authzid != null) { |
| | | argList.add("-g"); |
| | | argList.add(authzid); |
| | | } |
| | | if(attrList != null) { |
| | | for(String a : attrList) { |
| | | argList.add("-e"); |
| | | argList.add(a); |
| | | } |
| | | } |
| | | argList.add("-b"); |
| | | argList.add(base); |
| | | argList.add("-s"); |
| | | argList.add("sub"); |
| | | argList.add(filter); |
| | | String[] attrs=attr.split("\\s+"); |
| | | for(String a : attrs) |
| | | argList.add(a); |
| | | String[] args = new String[argList.size()]; |
| | | oStream.reset(); |
| | | int retVal = |
| | | LDAPSearch.mainSearch(argList.toArray(args), false, oStream, oStream); |
| | | Assert.assertEquals(0, retVal, "Returned error: " + oStream.toString()); |
| | | return oStream.toString(); |
| | | } |
| | | |
| | | protected void modEntries(String ldif, String bindDn, String bindPassword) |
| | | throws Exception { |
| | | File tempFile = getTemporaryLdifFile(); |
| | | TestCaseUtils.writeFile(tempFile, ldif); |
| | | ArrayList<String> argList=new ArrayList<String>(20); |
| | | argList.add("-h"); |
| | | argList.add("127.0.0.1"); |
| | | argList.add("-p"); |
| | | argList.add(String.valueOf(TestCaseUtils.getServerLdapPort())); |
| | | argList.add("-D"); |
| | | argList.add(bindDn); |
| | | argList.add("-w"); |
| | | argList.add(bindPassword); |
| | | argList.add("-f"); |
| | | argList.add(tempFile.getAbsolutePath()); |
| | | String[] args = new String[argList.size()]; |
| | | ldapModify(argList.toArray(args)); |
| | | } |
| | | |
| | | protected void ldapModify(String[] args) { |
| | | oStream.reset(); |
| | | LDAPModify.mainModify(args, false, oStream, oStream); |
| | | } |
| | | |
| | | protected void deleteAttrFromEntry(String dn, String attr) |
| | | throws Exception { |
| | | StringBuilder ldif = new StringBuilder(); |
| | | ldif.append(TestCaseUtils.makeLdif( |
| | | "dn: " + dn, |
| | | "changetype: modify", |
| | | "delete: " + attr)); |
| | | modEntries(ldif.toString(), DIR_MGR_DN, PWD); |
| | | } |
| | | |
| | | protected static String makeAddAciLdif(String attr, String dn, String... acis) { |
| | | StringBuilder ldif = new StringBuilder(); |
| | | ldif.append("dn: ").append(dn).append(EOL); |
| | | ldif.append("changetype: modify").append(EOL); |
| | | ldif.append("add: ").append(attr).append(EOL); |
| | | for(String aci : acis) |
| | | ldif.append(attr).append(":").append(aci).append(EOL); |
| | | ldif.append(EOL); |
| | | return ldif.toString(); |
| | | } |
| | | |
| | | protected File getTemporaryLdifFile() throws IOException { |
| | | Map<String,File> tempFilesForThisThread = tempLdifFile.get(); |
| | | if (tempFilesForThisThread == null) { |
| | | tempFilesForThisThread = new HashMap<String,File>(); |
| | | tempLdifFile.set(tempFilesForThisThread); |
| | | } |
| | | File tempFile = tempFilesForThisThread.get("effectiverights-tests"); |
| | | if (tempFile == null) { |
| | | tempFile = File.createTempFile("effectiverights-tests", ".ldif"); |
| | | tempFile.deleteOnExit(); |
| | | tempFilesForThisThread.put("effectiverights-tests", tempFile); |
| | | } |
| | | return tempFile; |
| | | } |
| | | |
| | | protected void addEntries() throws Exception { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: ou=admins,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: admins", |
| | | "", |
| | | "dn: cn=group,ou=People,o=test", |
| | | "objectclass: top", |
| | | "objectclass: groupOfNames", |
| | | "cn: group", |
| | | "member: uid=user.1,ou=People,o=test", |
| | | "", |
| | | "dn: uid=superuser,ou=admins,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: superuser", |
| | | "givenName: superuser", |
| | | "sn: 1", |
| | | "cn: User 1", |
| | | "userPassword: password", |
| | | "ds-privilege-name: proxied-auth", |
| | | "", |
| | | "dn: uid=proxyuser,ou=admins,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: proxyuser", |
| | | "givenName: proxyuser", |
| | | "sn: 1", |
| | | "cn: User 1", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=user.1,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: user.1", |
| | | "givenName: User 1", |
| | | "sn: 1", |
| | | "cn: User1", |
| | | "l: Austin", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=user.2,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: user.2", |
| | | "givenName: User 2", |
| | | "sn: 2", |
| | | "cn: User 2", |
| | | "l: dallas", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=user.3,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: user.3", |
| | | "givenName: User 3", |
| | | "sn: 3", |
| | | "mail: user.3@test", |
| | | "description: user.3 description", |
| | | "cn: User 3", |
| | | "l: Austin", |
| | | "userPassword: password"); |
| | | } |
| | | |
| | | protected HashMap<String, String> |
| | | getAttrMap(String resultString) throws Exception { |
| | | StringReader r=new StringReader(resultString); |
| | | BufferedReader br=new BufferedReader(r); |
| | | HashMap<String, String> attrMap = new HashMap<String,String>(); |
| | | try { |
| | | while(true) { |
| | | String s = br.readLine(); |
| | | if(s == null) |
| | | break; |
| | | if(s.startsWith("dn:")) |
| | | continue; |
| | | String[] a=s.split(": "); |
| | | if(a.length != 2) |
| | | break; |
| | | attrMap.put(a[0],a[1]); |
| | | } |
| | | } catch (IOException e) { |
| | | Assert.assertEquals(0, 1, e.getMessage()); |
| | | } |
| | | return attrMap; |
| | | } |
| | | } |
| | |
| | | import org.testng.annotations.BeforeMethod; |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | import org.testng.Assert; |
| | | import static org.testng.Assert.assertEquals; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.Attribute; |
| | | import org.opends.server.tools.LDAPSearch; |
| | | import org.opends.server.tools.LDAPModify; |
| | | import static org.opends.server.util.ServerConstants.OID_GET_EFFECTIVE_RIGHTS; |
| | | import static org.opends.server.util.ServerConstants.EOL; |
| | | |
| | | import java.io.*; |
| | | import java.util.ArrayList; |
| | | import java.util.Map; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | |
| | | public class GetEffectiveRightsTestCase { |
| | | private static ByteArrayOutputStream oStream = new ByteArrayOutputStream(); |
| | | private static final String DIR_MGR_DN = "cn=Directory Manager"; |
| | | private static final String PWD = "password"; |
| | | private static final String filter = "(objectclass=*)"; |
| | | public class GetEffectiveRightsTestCase extends AciTestCase { |
| | | private static final String base="uid=user.3,ou=People,o=test"; |
| | | private static final String user1="uid=user.1,ou=People,o=test"; |
| | | private static final String superUser="uid=superuser,ou=admins,o=test"; |
| | |
| | | private static final |
| | | String allRights = "add:1,delete:1,read:1,write:1,proxy:1"; |
| | | |
| | | private static final |
| | | String ACCESS_HANDLER_DN = "cn=Access Control Handler,cn=config"; |
| | | |
| | | //Results for attributeLevel searches |
| | | private static final String srwMailAttrRights = |
| | | "search:1,read:1,compare:0,write:1," + |
| | |
| | | String retRightsStr=attrMap.get(entryLevel); |
| | | Assert.assertTrue(retRightsStr.equals(reqRightsStr)); |
| | | } |
| | | |
| | | private HashMap<String, String> |
| | | getAttrMap(String resultString) throws Exception { |
| | | StringReader r=new StringReader(resultString); |
| | | BufferedReader br=new BufferedReader(r); |
| | | HashMap<String, String> attrMap = new HashMap<String,String>(); |
| | | try { |
| | | while(true) { |
| | | String s = br.readLine(); |
| | | if(s == null) |
| | | break; |
| | | if(s.startsWith("dn:")) |
| | | continue; |
| | | String[] a=s.split(": "); |
| | | if(a.length != 2) |
| | | break; |
| | | attrMap.put(a[0],a[1]); |
| | | } |
| | | } catch (IOException e) { |
| | | Assert.assertEquals(0, 1, e.getMessage()); |
| | | } |
| | | return attrMap; |
| | | } |
| | | |
| | | |
| | | private void addEntries() throws Exception { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: ou=admins,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: admins", |
| | | "", |
| | | "dn: cn=group,ou=People,o=test", |
| | | "objectclass: top", |
| | | "objectclass: groupOfNames", |
| | | "cn: group", |
| | | "member: uid=user.1,ou=People,o=test", |
| | | "", |
| | | "dn: uid=superuser,ou=admins,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: superuser", |
| | | "givenName: superuser", |
| | | "sn: 1", |
| | | "cn: User 1", |
| | | "userPassword: password", |
| | | "ds-privilege-name: proxied-auth", |
| | | "", |
| | | "dn: uid=proxyuser,ou=admins,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: proxyuser", |
| | | "givenName: proxyuser", |
| | | "sn: 1", |
| | | "cn: User 1", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=user.1,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: user.1", |
| | | "givenName: User", |
| | | "sn: 1", |
| | | "cn: User 1", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=user.2,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: user.2", |
| | | "givenName: User", |
| | | "sn: 2", |
| | | "cn: User 2", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=user.3,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: user.3", |
| | | "givenName: User", |
| | | "sn: 3", |
| | | "mail: user.3@test", |
| | | "description: user.3 description", |
| | | "cn: User 3", |
| | | "userPassword: password"); |
| | | } |
| | | |
| | | private String LDAPSearchCtrl(String bindDn, String bindPassword, |
| | | String proxyDN, String controlStr, |
| | | String base, String filter, String attr) |
| | | throws Exception { |
| | | ArrayList<String> argList=new ArrayList<String>(20); |
| | | argList.add("-h"); |
| | | argList.add("127.0.0.1"); |
| | | argList.add("-p"); |
| | | argList.add(String.valueOf(TestCaseUtils.getServerLdapPort())); |
| | | argList.add("-D"); |
| | | argList.add(bindDn); |
| | | argList.add("-w"); |
| | | argList.add(bindPassword); |
| | | argList.add("-T"); |
| | | if(proxyDN != null) { |
| | | argList.add("-Y"); |
| | | argList.add("dn:" + proxyDN); |
| | | } |
| | | if(controlStr != null) { |
| | | argList.add("-J"); |
| | | argList.add(controlStr); |
| | | } |
| | | argList.add("-b"); |
| | | argList.add(base); |
| | | argList.add("-s"); |
| | | argList.add("sub"); |
| | | argList.add(filter); |
| | | String[] attrs=attr.split("\\s+"); |
| | | for(String a : attrs) |
| | | argList.add(a); |
| | | String[] args = new String[argList.size()]; |
| | | oStream.reset(); |
| | | int retVal = |
| | | LDAPSearch.mainSearch(argList.toArray(args), false, oStream, oStream); |
| | | Assert.assertEquals(0, retVal, "Returned error: " + oStream.toString()); |
| | | return oStream.toString(); |
| | | } |
| | | |
| | | private String LDAPSearchParams(String bindDn, String bindPassword, |
| | | String proxyDN, String authzid, String[] attrList, |
| | | String base, String filter ,String attr) |
| | | throws Exception { |
| | | ArrayList<String> argList=new ArrayList<String>(20); |
| | | argList.add("-h"); |
| | | argList.add("127.0.0.1"); |
| | | argList.add("-p"); |
| | | argList.add(String.valueOf(TestCaseUtils.getServerLdapPort())); |
| | | argList.add("-D"); |
| | | argList.add(bindDn); |
| | | argList.add("-w"); |
| | | argList.add(bindPassword); |
| | | argList.add("-T"); |
| | | if(proxyDN != null) { |
| | | argList.add("-Y"); |
| | | argList.add("dn:" + proxyDN); |
| | | } |
| | | if(authzid != null) { |
| | | argList.add("-g"); |
| | | argList.add(authzid); |
| | | } |
| | | if(attrList != null) { |
| | | for(String a : attrList) { |
| | | argList.add("-e"); |
| | | argList.add(a); |
| | | } |
| | | } |
| | | argList.add("-b"); |
| | | argList.add(base); |
| | | argList.add("-s"); |
| | | argList.add("sub"); |
| | | argList.add(filter); |
| | | String[] attrs=attr.split("\\s+"); |
| | | for(String a : attrs) |
| | | argList.add(a); |
| | | String[] args = new String[argList.size()]; |
| | | oStream.reset(); |
| | | int retVal = |
| | | LDAPSearch.mainSearch(argList.toArray(args), false, oStream, oStream); |
| | | Assert.assertEquals(0, retVal, "Returned error: " + oStream.toString()); |
| | | return oStream.toString(); |
| | | } |
| | | |
| | | |
| | | private void modEntries(String ldif, String bindDn, String bindPassword) |
| | | throws Exception { |
| | | File tempFile = getTemporaryLdifFile(); |
| | | TestCaseUtils.writeFile(tempFile, ldif); |
| | | ArrayList<String> argList=new ArrayList<String>(20); |
| | | argList.add("-h"); |
| | | argList.add("127.0.0.1"); |
| | | argList.add("-p"); |
| | | argList.add(String.valueOf(TestCaseUtils.getServerLdapPort())); |
| | | argList.add("-D"); |
| | | argList.add(bindDn); |
| | | argList.add("-w"); |
| | | argList.add(bindPassword); |
| | | argList.add("-f"); |
| | | argList.add(tempFile.getAbsolutePath()); |
| | | String[] args = new String[argList.size()]; |
| | | ldapModify(argList.toArray(args)); |
| | | } |
| | | |
| | | |
| | | private void ldapModify(String[] args) { |
| | | oStream.reset(); |
| | | LDAPModify.mainModify(args, false, oStream, oStream); |
| | | } |
| | | |
| | | private void deleteAttrFromEntry(String dn, String attr) |
| | | throws Exception { |
| | | StringBuilder ldif = new StringBuilder(); |
| | | ldif.append(TestCaseUtils.makeLdif( |
| | | "dn: " + dn, |
| | | "changetype: modify", |
| | | "delete: " + attr)); |
| | | modEntries(ldif.toString(), DIR_MGR_DN, PWD); |
| | | } |
| | | |
| | | private static ThreadLocal<Map<String,File>> tempLdifFile = |
| | | new ThreadLocal<Map<String,File>>(); |
| | | |
| | | private File getTemporaryLdifFile() throws IOException { |
| | | Map<String,File> tempFilesForThisThread = tempLdifFile.get(); |
| | | if (tempFilesForThisThread == null) { |
| | | tempFilesForThisThread = new HashMap<String,File>(); |
| | | tempLdifFile.set(tempFilesForThisThread); |
| | | } |
| | | File tempFile = tempFilesForThisThread.get("effectiverights-tests"); |
| | | if (tempFile == null) { |
| | | tempFile = File.createTempFile("effectiverights-tests", ".ldif"); |
| | | tempFile.deleteOnExit(); |
| | | tempFilesForThisThread.put("effectiverights-tests", tempFile); |
| | | } |
| | | return tempFile; |
| | | } |
| | | |
| | | private static String makeAddAciLdif(String attr, String dn, String... acis) { |
| | | StringBuilder ldif = new StringBuilder(); |
| | | ldif.append("dn: ").append(dn).append(EOL); |
| | | ldif.append("changetype: modify").append(EOL); |
| | | ldif.append("add: ").append(attr).append(EOL); |
| | | for(String aci : acis) |
| | | ldif.append(attr).append(":").append(aci).append(EOL); |
| | | ldif.append(EOL); |
| | | return ldif.toString(); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * 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 2007 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.opends.server.authorization.dseecompat; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.Test; |
| | | import org.testng.Assert; |
| | | import org.opends.server.TestCaseUtils; |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | |
| | | import java.util.HashMap; |
| | | |
| | | public class TargetAttrTestCase extends AciTestCase { |
| | | |
| | | private static String attrList="sn uid l"; |
| | | private static String opAttrList="sn uid aci"; |
| | | private static final String user1="uid=user.1,ou=People,o=test"; |
| | | private static final String user3="uid=user.3,ou=People,o=test"; |
| | | public static final String aciFilter = "(aci=*)"; |
| | | |
| | | private static final |
| | | String userAttrAci = "(targetattr=\"*\")" + |
| | | "(version 3.0;acl \"read/search userattr\";" + |
| | | "allow (search, read) " + |
| | | "userattr=\"l#Austin\";)"; |
| | | |
| | | private static final |
| | | String userAttrAci1 = "(targetattr=\"*\")" + |
| | | "(version 3.0;acl \"read/search userattr\";" + |
| | | "allow (search, read) " + |
| | | "userattr!=\"l#New York\";)"; |
| | | |
| | | private static final |
| | | String nonOpAttrAci = "(targetattr=\"*\")" + |
| | | "(version 3.0;acl \"read/search non-operational attr\";" + |
| | | "allow (search, read) " + |
| | | "userdn=\"ldap:///uid=user.3,ou=People,o=test\";)"; |
| | | |
| | | private static final |
| | | String opAttrAci = "(targetattr=\"aci\")" + |
| | | "(version 3.0;acl \"read/search operational attr\";" + |
| | | "allow (search, read) " + |
| | | "userdn=\"ldap:///uid=user.3,ou=People,o=test\";)"; |
| | | |
| | | @BeforeClass |
| | | public void setupClass() throws Exception { |
| | | TestCaseUtils.startServer(); |
| | | deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI); |
| | | addEntries(); |
| | | } |
| | | |
| | | /** |
| | | * Test targetattr behavior using userattr bind rule. |
| | | * |
| | | * @throws Exception If a test result is unexpected. |
| | | */ |
| | | @Test() |
| | | public void testTargetAttrUserAttr() throws Exception { |
| | | String aciLdif=makeAddAciLdif("aci", user1, userAttrAci); |
| | | 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); |
| | | checkAttributeVal(attrMap, "l", "Austin"); |
| | | checkAttributeVal(attrMap, "sn", "1"); |
| | | checkAttributeVal(attrMap, "uid", "user.1"); |
| | | deleteAttrFromEntry(user1, "aci"); |
| | | String aciLdif1=makeAddAciLdif("aci", user1, userAttrAci1); |
| | | modEntries(aciLdif1, DIR_MGR_DN, PWD); |
| | | String userResults1 = |
| | | LDAPSearchParams(user3, PWD, null, null, null, |
| | | user1, filter, attrList); |
| | | Assert.assertFalse(userResults1.equals("")); |
| | | HashMap<String, String> attrMap1=getAttrMap(userResults1); |
| | | checkAttributeVal(attrMap1, "l", "Austin"); |
| | | checkAttributeVal(attrMap1, "sn", "1"); |
| | | checkAttributeVal(attrMap1, "uid", "user.1"); |
| | | deleteAttrFromEntry(user1, "aci"); |
| | | } |
| | | |
| | | /** |
| | | * Test targetattr and operational attribute behavior. See comments. |
| | | * |
| | | * @throws Exception If a test result is unexpected. |
| | | */ |
| | | @Test() |
| | | public void testTargetAttrOpAttr() throws Exception { |
| | | //Add aci that only allows non-operational attributes search/read. |
| | | String aciLdif=makeAddAciLdif("aci", user1, nonOpAttrAci); |
| | | modEntries(aciLdif, DIR_MGR_DN, PWD); |
| | | String userResults = |
| | | LDAPSearchParams(user3, PWD, null, null, null, |
| | | user1, filter, opAttrList); |
| | | Assert.assertFalse(userResults.equals("")); |
| | | HashMap<String, String> attrMap=getAttrMap(userResults); |
| | | //The aci attribute type is operational, it should not be there. |
| | | //The other two should be there. |
| | | Assert.assertFalse(attrMap.containsKey("aci")); |
| | | Assert.assertTrue(attrMap.containsKey("sn")); |
| | | Assert.assertTrue(attrMap.containsKey("uid")); |
| | | deleteAttrFromEntry(user1, "aci"); |
| | | //Add aci that allows both non-operational attributes and the operational |
| | | //attribute "aci" search/read. |
| | | String aciLdif1=makeAddAciLdif("aci", user1, nonOpAttrAci, opAttrAci); |
| | | modEntries(aciLdif1, DIR_MGR_DN, PWD); |
| | | String userResults1 = |
| | | LDAPSearchParams(user3, PWD, null, null, null, |
| | | user1, filter, opAttrList); |
| | | Assert.assertFalse(userResults1.equals("")); |
| | | HashMap<String, String> attrMap1=getAttrMap(userResults1); |
| | | //All three attributes should be there. |
| | | Assert.assertTrue(attrMap1.containsKey("aci")); |
| | | Assert.assertTrue(attrMap1.containsKey("sn")); |
| | | Assert.assertTrue(attrMap1.containsKey("uid")); |
| | | deleteAttrFromEntry(user1, "aci"); |
| | | //Add ACI that only allows only aci operational attribute search/read. |
| | | String aciLdif2=makeAddAciLdif("aci", user1, opAttrAci); |
| | | modEntries(aciLdif2, DIR_MGR_DN, PWD); |
| | | String userResults2 = |
| | | LDAPSearchParams(user3, PWD, null, null, null, |
| | | user1, aciFilter, opAttrList); |
| | | Assert.assertFalse(userResults2.equals("")); |
| | | HashMap<String, String> attrMap2=getAttrMap(userResults2); |
| | | //Only operational attribute aci should be there, the other two should |
| | | //not. |
| | | Assert.assertTrue(attrMap2.containsKey("aci")); |
| | | Assert.assertFalse(attrMap2.containsKey("sn")); |
| | | Assert.assertFalse(attrMap2.containsKey("uid")); |
| | | deleteAttrFromEntry(user1, "aci"); |
| | | } |
| | | |
| | | private void |
| | | checkAttributeVal(HashMap<String, String> attrMap, String attr, |
| | | String val) throws Exception { |
| | | String mapVal=attrMap.get(attr); |
| | | Assert.assertTrue(mapVal.equals(val)); |
| | | } |
| | | |
| | | } |