Package anvil.server.ldap

Source Code of anvil.server.ldap.LDAPTribe

/*
* $Id: LDAPTribe.java,v 1.10 2002/09/16 08:05:06 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.server.ldap;

import java.security.Permission;
import java.security.Permissions;
import java.security.PermissionCollection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Enumeration;

import anvil.java.util.BindingEnumeration;
import anvil.java.util.EnumerationToIterator;
import anvil.java.security.PermissionCollectionCombiner;
import anvil.core.Any;
import anvil.server.Tribe;
import anvil.server.Citizen;
import anvil.server.Tribe;
import anvil.server.Realm;
import anvil.server.Citizen;
import anvil.server.CitizenNotFoundException;
import anvil.server.OperationFailedException;
import anvil.database.PooledConnection;
import anvil.Log;

import javax.naming.directory.DirContext;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.NamingEnumeration;
import javax.naming.NameClassPair;
import javax.naming.NamingException;
import javax.naming.Name;
import javax.naming.NameParser;
import javax.naming.NameNotFoundException;

/**
* class LDAPTribe
*
* @author: Simo Tuokko
*/

public class LDAPTribe implements Tribe
{
  private LDAPRealm realm;
  private Log log;
  private String name;
  private String dn;
  private String fullDN;
  private boolean isRoot;
  Tribe[] children = null;
  Tribe[] parents = null;
  Citizen[] citizens = null;
  private PermissionCollection permissions = null;
  private PermissionCollection combined = null;
  private boolean hasPermissions = false;
 
  LDAPTribe(LDAPRealm realm, String name) throws OperationFailedException
  {
    this(realm, name, false);
  }
 
  LDAPTribe(LDAPRealm realm, String name, boolean isRoot) throws OperationFailedException
  {
    this.realm = realm;
    this.name = name;
    this.dn = "cn="+name+",ou=groups";
    this.fullDN = realm.createGroupDN(name);
    this.isRoot = isRoot;
    log = realm.getLog();
   
    if (!isRoot) {
      PooledConnection connImpl = null;
      DirContext ctx = null;
      boolean tribeFound = false;
   
      try {
        connImpl = realm.getConnection();
        ctx = (DirContext)connImpl.getConnection();
   
        ctx.getAttributes(dn, new String[] { "cn" });
        tribeFound = true;
      } catch (NameNotFoundException nnfe) {
        //not found
 
      } catch (Exception e) {
        throw new OperationFailedException("Creating of tribe failed", e);
       
      } finally {
        LDAPRealm.cleanupContext(connImpl);
      }
      if (!tribeFound) {     
        throw new CitizenNotFoundException(name);
      }
    }   
  }

 
  public Realm getRealm()
  {
    return realm;
  }

 
  public String getName()
  {
    return name;
  }

 
  public Tribe[] getParents()
  {
    if (parents == null) {
      synchronized(this) {
        if (parents == null) {
          parents = realm.getMemberGroups(fullDN);
        }
      }
    }
    return parents;
  }
 

  public boolean hasChilds()
  {
    if (children == null) {
      getChilds();
    }
    return (children.length > 0);
  }
 

  public Tribe[] getChilds()
  {
    if (children == null) {
      synchronized(this) {
        if (children == null) {
          children = (Tribe[])fetchChildren(true);
        }
      }
    }
    return children;
  }

 
  public Citizen[] getCitizens()
  {
    if (citizens == null) {
      synchronized(this) {
        if (citizens == null) {
          citizens = (Citizen[])fetchChildren(false);
        }
      }
    }
    return citizens;
  }
 
 
  public PermissionCollection getPermissions()
  {
    if (permissions == null) {
      synchronized(this) {
        if (permissions == null) {
          permissions = realm.loadPermissions(dn);
        }
      }
    }
    return permissions;
  }


  public PermissionCollection getCombinedPermissions() {
    if (!hasPermissions) {
      synchronized(this) {
        if (!hasPermissions) {
          hasPermissions = true;
          getParents();
          Permissions perms = new Permissions();
          for (int i=0; i<parents.length; i++) {
            PermissionCollection parentCol = parents[i].getCombinedPermissions();
            if (parentCol != null) {
              for (Enumeration enu = parentCol.elements(); enu.hasMoreElements(); ) {
                perms.add((Permission)enu.nextElement());
              }
            }
          }
          //combine own permissions
          for (Enumeration enu = getPermissions().elements(); enu.hasMoreElements(); ) {
            perms.add((Permission)enu.nextElement());
          }
         
          combined = perms;
        }
      }
    }
   
    return combined;
  }


  public void addPermission(Permission perm) throws OperationFailedException {
    if (isRoot) {
      throw new OperationFailedException("addPermission operation isn't allowed for synthetic root tribe!");
    }
    permissions = realm.addPermission(perm, dn);
  }
 
 
  public void removePermission(Permission perm) throws OperationFailedException {
    permissions = realm.removePermission(perm, dn);
  }


  public Iterator listPermissions() {
    if (permissions != null) {
      return new EnumerationToIterator(permissions.elements());
    } else {
      return BindingEnumeration.EMPTY;
    }
  }

 
  public void commit() throws OperationFailedException
  {
  }

 
  private Object fetchChildren(boolean isTribe)
  {
    PooledConnection connImpl = null;
    DirContext ctx = null;
    ArrayList result = new ArrayList();
 
    try {
      connImpl = realm.getConnection();
      ctx = (DirContext)connImpl.getConnection();
 
      if (isRoot) {
        NamingEnumeration enu = ctx.list(isTribe? "ou=groups" : "ou=users");
 
        while (enu.hasMore()) {
          String name = ((NameClassPair)enu.next()).getName();
          name = name.substring(name.indexOf("=")+1);
          if (isTribe) {
            result.add( realm.getTribe(name) );
          } else {
            result.add( realm.getCitizen(name) );
          }
         
        }
      } else {

        Attributes a = ctx.getAttributes(dn, new String[] { "uniquemember" });
        Attribute memberAttr = a.get("uniquemember");
       
        if (memberAttr != null) {
          for (NamingEnumeration de=memberAttr.getAll(); de.hasMore(); ) {
            String val = (String)de.next();
            String name = val.substring(val.indexOf("=")+1, val.indexOf(",")).trim();
           
            if (isTribe) {
              if (val.startsWith("cn")) {
                result.add( realm.getTribe(name) );
              }
            } else {
              if (val.startsWith("uid")) {
                result.add( realm.getCitizen(name) );
              }
            }
          } //for
        }
      } //if isRoot 
     
    } catch (Exception e) {
      log.error("LDAPTribe.fetchChildren() failed: "+e);
     
    } finally {
      LDAPRealm.cleanupContext(connImpl);
    }
   
    int l = result.size();
    if (isTribe) {
      return (Tribe[])result.toArray(new Tribe[l]);
    } else {
      return (Citizen[])result.toArray(new Citizen[l]);
    }
  }


  //Namespace stuff
  public Any setVariable(String name, Any value)
  {
    return null;
  }
 
 
  public boolean deleteVariable(String name)
  {
    return false;
  }
 

  public Any getVariable(String name)
  {
    return null;
  }
 
 
  public Any checkVariable(String name)
  {
    return null;
  }
 
 
  public BindingEnumeration getVariables()
  {
    return null;
  }
 

  //Mutable stuff
  public void attach(Tribe tribe) throws OperationFailedException
  {
    LDAPTribe t = (LDAPTribe)tribe;
    if (attach(t.getFullDN(), tribe)) {
      //refresh
      children = null;
      t.refreshPermissions();
    }
  }

 
  public void attach(Citizen citizen) throws OperationFailedException
  {
    LDAPCitizen c = (LDAPCitizen)citizen;
    if (attach(c.getFullDN(), citizen)) {
      //refresh
      citizens = null;
      c.refreshPermissions();
    }
  }


  private synchronized boolean attach(String dn, Object res) throws OperationFailedException
  {
    if (isRoot) {
      throw new OperationFailedException("Attach operation isn't allowed for synthetic root tribe!");
    }
    PooledConnection connImpl = null;
    DirContext ctx = null;
 
    try {
      connImpl = realm.getConnection();
      ctx = (DirContext)connImpl.getConnection();
 
      //check that this tribe isn't a member of the tribe being attached
      if (res instanceof LDAPTribe) {
        LDAPTribe parentCand = (LDAPTribe)res;
        String parentFail = parentCand.containsName(ctx, parentCand.fetchMembers(ctx), this.dn);
        if (parentFail != null) {
          throw new OperationFailedException("Loops not allowed, '"+dn+"' is parent of of '"+this.dn+"'");
        }
      }
     
      Attribute currMembers = fetchMembers(ctx);
      String failer = containsName(ctx, currMembers, dn);
      if (failer == null) {
        currMembers.add(dn);
        Attributes attrs = new BasicAttributes();
        attrs.put(currMembers);
       
        ctx.modifyAttributes(this.dn, DirContext.REPLACE_ATTRIBUTE, attrs);
        return true;
      }
 
    } catch (Exception e) {
      throw new OperationFailedException(e);
     
    } finally {
      LDAPRealm.cleanupContext(connImpl);
    }
    return false;
  }

 
  public void detach(Tribe tribe) throws OperationFailedException
  {
    LDAPTribe t = (LDAPTribe)tribe;
    if (detach(t.getFullDN())) {
      //refresh
      children = null;
      t.refreshPermissions();
    }
  }

 
  public void detach(Citizen citizen) throws OperationFailedException
  {
    LDAPCitizen c = (LDAPCitizen)citizen;
    if (detach(c.getFullDN())) {
      //refresh
      citizens = null;
      c.refreshPermissions();
    }
  }

 
  private synchronized boolean detach(String dn) throws OperationFailedException
  {
    if (isRoot) {
      throw new OperationFailedException("Detach operation isn't allowed for synthetic root tribe!");
    }
    PooledConnection connImpl = null;
    DirContext ctx = null;
 
    try {
      connImpl = realm.getConnection();
      ctx = (DirContext)connImpl.getConnection();
 
      Attribute currMembers = fetchMembers(ctx);
      String result = containsName(ctx, currMembers, dn);
      if (result != null) {
        currMembers.remove(result);
        Attributes attrs = new BasicAttributes();
        attrs.put(currMembers);
     
        ctx.modifyAttributes(this.dn, DirContext.REPLACE_ATTRIBUTE, attrs);
       
        return true;
      }
 
    } catch (Exception e) {
      throw new OperationFailedException(e);
     
    } finally {
      LDAPRealm.cleanupContext(connImpl);
    }
    return false;
  }


  private Attribute fetchMembers(DirContext ctx) throws NamingException
  {
    return fetchMembers(ctx, dn);
  }
 
 
  private Attribute fetchMembers(DirContext ctx, String fetchDN) throws NamingException
  {
    Attributes attrs = ctx.getAttributes(fetchDN, new String[] { "uniquemember" });
    Attribute members = attrs.get("uniquemember");
    return (members == null)? new BasicAttribute("uniquemember") : members;
  }


  private String containsName(DirContext ctx, Attribute attr, String dn) throws NamingException, OperationFailedException
  {
    NameParser parser = ctx.getNameParser(realm.getPrefix());
    Name name = parser.parse(dn);
   
    for (NamingEnumeration e=attr.getAll(); e.hasMore(); ) {
      String cand = (String)e.next();
      Name candName = parser.parse(cand);
     
      if ( name.equals(candName) ) {
        e.close();
        return cand;
      }
     
      //toimiiko jos prefixi� ei ole???
      if (cand.toLowerCase().startsWith("cn")) {
        String res = containsName(ctx, fetchMembers(ctx, candName.getSuffix(candName.size()-2).toString()), dn);
        if (res != null) {
          throw new OperationFailedException("Loops not allowed, '"+dn+"' is already a member of '"+cand+"'");
        }
      }
    }
    return null;
  }


  public void remove() throws OperationFailedException
  {
    PooledConnection connImpl = null;
    DirContext ctx = null;
 
    try {
      connImpl = realm.getConnection();
      ctx = (DirContext)connImpl.getConnection();
 
      ctx.unbind(dn);
 
    } catch (NameNotFoundException e) {
      throw new OperationFailedException("Tribe '"+name+"' not found!");

    } catch (Exception e) {
      throw new OperationFailedException(e.getMessage());
     
    } finally {
      LDAPRealm.cleanupContext(connImpl);
    }
  }


  String getDN()
  {
    return dn;
  }


  String getFullDN()
  {
    return fullDN;
  }
 
 
  void refreshCitizens() {
    citizens = null;
  }
 
 
  void refreshPermissions() {
    hasPermissions = false;
    parents = null;
   
    if (citizens != null) {
      for (int i=0,l=citizens.length; i<l; i++) {
        ((LDAPCitizen)citizens[i]).refreshPermissions();
      }
    }

    if (children != null) {
      for (int i=0,l=children.length; i<l; i++) {
        ((LDAPTribe)children[i]).refreshPermissions();
      }
    }
  }


  public boolean equals(Object o) {
    if (o instanceof LDAPTribe) {
      LDAPTribe c = (LDAPTribe)o;
      return (c.name.equals(name) && c.realm.equals(realm));
    }
    return false;
  }


  public String toString()
  {
    return "LDAPTribe ("+name+")";
  }
}
TOP

Related Classes of anvil.server.ldap.LDAPTribe

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.