📄 ditsubtree.java
字号:
/*
* Copyright (c) 2000-2005, University of Salford
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the University of Salford nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package issrg.pba.rbac.policies;
import issrg.pba.rbac.LDAPDNPrincipal;
import issrg.utils.RFC2253ParsingException;
import issrg.utils.repository.Entry;
/**
* This is the object that represents a subtree of entries in LDAP DIT. It can
* specify a
* subtree, excluding subtrees, and does object class match.
*
* @author A Otenko
* @version 1.0
*/
public class DITSubtree implements Subtree {
/**
* This is the subtree root node.
*/
protected LDAPDNPrincipal subtree;
protected int min;
protected int max;
/**
* This is an array of object classes, allowed in this subtree. Can be null,
* if no restrictions on object class are applied.
*/
protected String [] objectclasses;
/**
* This is an array of exclusion subtrees. Can be null, if no exclusion
* subtrees have been specified.
*/
protected Subtree [] exclusive;
protected DITSubtree(){}
/**
* This constructor can build an object out of the full subtree specification.
*
* @param subtree is the LDAP DN of the root node of the subtree; if null,
* means "any DN is a subtree": the World
* @param min is the integer lower margin of the subtree; cannot be less than
* 0; see also max
* @param max is the integer higher margin of the subtree; together with min
* they define the minimum and maximum length of the matching DN,
* relative
* to the subtree DN; value of -1 means "unlimited length", no other
* negative values
* are accepted for max
* @param objectClass is the array of LDAP object classes that the subtree
* entry can be of; if null, no restrictions on the objectClass are
* applied
* @param exclude is an array of subtrees that an entry cannot be a part of;
* if null, no subtrees are excluded
*/
public DITSubtree(LDAPDNPrincipal subtree, int min, int max,
String [] objectClass, Subtree [] exclude) {
this.subtree = subtree;
objectclasses = objectClass;
exclusive = exclude;
this.min=min;
this.max=max;
if (min<0 || max<-1){
throw new IllegalArgumentException("Subtree margins exceed the allowed range");
}
}
/**
* This method tests whether or not the given entry belongs to this subtree.
* If the entry's DN maps below the subtree root node and its object class is
* at least one of the allowed object classes, and the entry is not an entry
* of any of the exclusion subtrees, the method returns true. It returns false
* otherwise.
*
* @param entry is the LDAPEntry; it can tell the DN and the objectClass of
* the entry
*
* @return true, if the entry is included in the subtree and is of one of the
* objectClasses, specified at the construction time, and it is not
* contained in any of the exclusion subtrees
*/
public boolean contains(LDAPEntry entry){
boolean result=false;
if (subtree!=null){
String [][][] alien = entry.getDN().getParsedDN();
String [][][] subtree = this.subtree.getParsedDN();
int o = alien.length-subtree.length;
if (o>=min && (max==-1 || o<=max)){
result=true;
match_DN:
for (int i=subtree.length; i-->0; ){ // for each RDN
int i1=o+i;
if (alien[i1].length!=subtree[i].length){
result=false;
break;
}
for (int j=0; j<subtree[i].length; j++){ // for each AVA in the RDN of the subtree
String s = subtree[i][j][0].toUpperCase().intern(); // attribute name
int k;
for (k=0; k<alien[i1].length; k++){ // find matching AVA in the RDN of the alien
if (s==alien[i1][k][0].toUpperCase().intern()){
break; // found the right attribute in the DN
}
}
// k still points into the right row in the alien[i] array
if (k>=alien[i1].length){ // no matching attribute found
result=false;
break match_DN;
}
// the values are in real string representation so they must be just compared
// as case-insensitive strings
/*
* TODO: what about comparing binary values? (toUpperCase might spoil them...)
*/
if (subtree[i][j][1].toUpperCase().intern()!=alien[i1][k][1].toUpperCase().intern()){
result=false;
break match_DN;
}
}
}
// if gone through the loop up to this point, then the DN matched the subtree specification
//System.out.println("\t\t*** SUBTREE MATCHING ***\n\t"+s+" < "+s1); //*****
//System.out.println("\t"+result); //*****
}
}
if (objectclasses!=null && result){
result=false;
for (int i=0; i<objectclasses.length; i++){
if (!(result=entry.isObjectClass(objectclasses[i]))){ // this makes it loop as long as the target matches the object class
// the result will either always be true, or will become false and the loop breaks the same instant
break;
}
//System.out.println("\tis object class: "+oc[i]); //*****
}
}
if (exclusive!=null && result){
//System.out.println("\tsome exclusions"); //*****
for (int i=0; i<exclusive.length; i++){
if (!(result=!exclusive[i].contains(entry))){ // note, that it is not a != comparison; result is assigned the inversion of the method return value
/* so: the loop must go through all exclusive trees, and break as soon as
* either of the exclusion trees contains an entry, assigning false to the result
*/
//System.out.println("\tone exclusion matches. Excluded "+entry.getDN().getName()); //*****
break;
}
}
}
//System.out.println("\ttotal: "+result); //*****
return result;
}
/**
* This method checks whether this Subtree contains a given Entry. If the
* entry is not an LDAPEntry, returns false; otherwise returns the same result
* as contains(LDAPEntry e)
*/
public boolean contains(Entry e){
return (e instanceof LDAPEntry)? contains((LDAPEntry)e): false;
}
public String toString(){
String exclude=null;
if (exclusive!=null){
exclude=", excluding [";
for (int i=0; i<exclusive.length; i++){
exclude+=(i==0?"":", ")+exclusive[i].toString();
}
exclude+="]";
}
String objClasses=null;
if (objectclasses!=null){
objClasses=", objectClasses {";
for (int i=0; i<objectclasses.length; i++){
objClasses+=(i==0?"":", ")+objectclasses[i];
}
objClasses="}";
}
return "DITSubtree with base DN="+subtree.getName()+", min="+min+", max="+max+
(exclude==null?"":exclude)+(objClasses==null?"":objClasses);
}
/**
* This method excludes the specified Entry from the Subtree, if it is an
* LDAPEntry; otherwise does nothing.
*/
public void excludeEntry(Entry e) {
if (!(e instanceof LDAPEntry)) return;
Subtree[] r;
if (exclusive == null) {
r = new Subtree[1];
r[0]=new DITSubtree(((LDAPEntry)e).getDN(), 0, -1, null, null);
exclusive = r;
} else {
r = new Subtree[exclusive.length];
System.arraycopy(exclusive, 0, r, 0, exclusive.length);
exclusive = new Subtree[r.length + 1];
System.arraycopy(r, 0, exclusive, 0, r.length);
exclusive[r.length] = new DITSubtree(((LDAPEntry) e).getDN(), 0, -1, null, null);
}
}
public Object clone() {
String[] a = null;
if (objectclasses != null) {
a = new String[objectclasses.length];
System.arraycopy(objectclasses, 0, a, 0, a.length);
}
Subtree[] b = null;
if (exclusive != null) {
b = new Subtree[exclusive.length];
System.arraycopy(exclusive, 0, b, 0, b.length);
}
try {
return new DITSubtree(new LDAPDNPrincipal(subtree.getName()), min, max, a, b);
} catch (RFC2253ParsingException pe) {pe.printStackTrace(); return null;}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -