diff options
Diffstat (limited to 'base/util/src/netscape/security/acl')
-rw-r--r-- | base/util/src/netscape/security/acl/AclEntryImpl.java | 182 | ||||
-rw-r--r-- | base/util/src/netscape/security/acl/AclImpl.java | 391 | ||||
-rw-r--r-- | base/util/src/netscape/security/acl/AllPermissionsImpl.java | 43 | ||||
-rw-r--r-- | base/util/src/netscape/security/acl/GroupImpl.java | 173 | ||||
-rw-r--r-- | base/util/src/netscape/security/acl/OwnerImpl.java | 105 | ||||
-rw-r--r-- | base/util/src/netscape/security/acl/PermissionImpl.java | 65 | ||||
-rw-r--r-- | base/util/src/netscape/security/acl/PrincipalImpl.java | 77 | ||||
-rw-r--r-- | base/util/src/netscape/security/acl/WorldGroupImpl.java | 42 |
8 files changed, 1078 insertions, 0 deletions
diff --git a/base/util/src/netscape/security/acl/AclEntryImpl.java b/base/util/src/netscape/security/acl/AclEntryImpl.java new file mode 100644 index 000000000..46365f5d8 --- /dev/null +++ b/base/util/src/netscape/security/acl/AclEntryImpl.java @@ -0,0 +1,182 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.acl; + +import java.security.Principal; +import java.security.acl.AclEntry; +import java.security.acl.Group; +import java.security.acl.Permission; +import java.util.Enumeration; +import java.util.Vector; + +/** + * This is a class that describes one entry that associates users + * or groups with permissions in the ACL. + * The entry may be used as a way of granting or denying permissions. + * + * @author Satish Dharmaraj + */ +public class AclEntryImpl implements AclEntry { + private Principal user = null; + private Vector<Permission> permissionSet = new Vector<Permission>(10, 10); + private boolean negative = false; + + /** + * Construct an ACL entry that associates a user with permissions + * in the ACL. + * + * @param user The user that is associated with this entry. + */ + public AclEntryImpl(Principal user) { + this.user = user; + } + + /** + * Construct a null ACL entry + */ + public AclEntryImpl() { + } + + /** + * Sets the principal in the entity. If a group or a + * principal had already been set, a false value is + * returned, otherwise a true value is returned. + * + * @param user The user that is associated with this entry. + * @return true if the principal is set, false if there is + * one already. + */ + public boolean setPrincipal(Principal user) { + if (this.user != null) + return false; + this.user = user; + return true; + } + + /** + * This method sets the ACL to have negative permissions. + * That is the user or group is denied the permission set + * specified in the entry. + */ + public void setNegativePermissions() { + negative = true; + } + + /** + * Returns true if this is a negative ACL. + */ + public boolean isNegative() { + return negative; + } + + /** + * A principal or a group can be associated with multiple + * permissions. This method adds a permission to the ACL entry. + * + * @param permission The permission to be associated with + * the principal or the group in the entry. + * @return true if the permission was added, false if the + * permission was already part of the permission set. + */ + public boolean addPermission(Permission permission) { + + if (permissionSet.contains(permission)) + return false; + + permissionSet.addElement(permission); + + return true; + } + + /** + * The method disassociates the permission from the Principal + * or the Group in this ACL entry. + * + * @param permission The permission to be disassociated with + * the principal or the group in the entry. + * @return true if the permission is removed, false if the + * permission is not part of the permission set. + */ + public boolean removePermission(Permission permission) { + return permissionSet.removeElement(permission); + } + + /** + * Checks if the passed permission is part of the allowed + * permission set in this entry. + * + * @param permission The permission that has to be part of + * the permission set in the entry. + * @return true if the permission passed is part of the + * permission set in the entry, false otherwise. + */ + public boolean checkPermission(Permission permission) { + return permissionSet.contains(permission); + } + + /** + * return an enumeration of the permissions in this ACL entry. + */ + public Enumeration<Permission> permissions() { + return permissionSet.elements(); + } + + /** + * Return a string representation of the contents of the ACL entry. + */ + public String toString() { + StringBuffer s = new StringBuffer(); + if (negative) + s.append("-"); + else + s.append("+"); + if (user instanceof Group) + s.append("Group."); + else + s.append("User."); + s.append(user + "="); + Enumeration<Permission> e = permissions(); + while (e.hasMoreElements()) { + Permission p = (Permission) e.nextElement(); + s.append(p); + if (e.hasMoreElements()) + s.append(","); + } + return new String(s); + } + + /** + * Clones an AclEntry. + */ + public synchronized Object clone() { + AclEntryImpl cloned; + cloned = new AclEntryImpl(user); + cloned.permissionSet = new Vector<Permission>(permissionSet); + cloned.negative = negative; + return cloned; + } + + /** + * Return the Principal associated in this ACL entry. + * The method returns null if the entry uses a group + * instead of a principal. + */ + public Principal getPrincipal() { + return user; + } +} diff --git a/base/util/src/netscape/security/acl/AclImpl.java b/base/util/src/netscape/security/acl/AclImpl.java new file mode 100644 index 000000000..76750b7b9 --- /dev/null +++ b/base/util/src/netscape/security/acl/AclImpl.java @@ -0,0 +1,391 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.acl; + +import java.security.Principal; +import java.security.acl.Acl; +import java.security.acl.AclEntry; +import java.security.acl.Group; +import java.security.acl.NotOwnerException; +import java.security.acl.Permission; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.NoSuchElementException; +import java.util.Vector; + +/** + * An Access Control List (ACL) is encapsulated by this class. + * + * @author Satish Dharmaraj + */ +public class AclImpl extends OwnerImpl implements Acl { + // + // Maintain four tables. one each for positive and negative + // ACLs. One each depending on whether the entity is a group + // or principal. + // + private Hashtable<Principal, AclEntry> allowedUsersTable = new Hashtable<Principal, AclEntry>(23); + private Hashtable<Principal, AclEntry> allowedGroupsTable = new Hashtable<Principal, AclEntry>(23); + private Hashtable<Principal, AclEntry> deniedUsersTable = new Hashtable<Principal, AclEntry>(23); + private Hashtable<Principal, AclEntry> deniedGroupsTable = new Hashtable<Principal, AclEntry>(23); + private String aclName = null; + private Vector<Permission> zeroSet = new Vector<Permission>(1, 1); + + /** + * Constructor for creating an empty ACL. + */ + public AclImpl(Principal owner, String name) { + super(owner); + try { + setName(owner, name); + } catch (Exception e) { + } + } + + /** + * Sets the name of the ACL. + * + * @param caller the principal who is invoking this method. + * @param name the name of the ACL. + * @exception NotOwnerException if the caller principal is + * not on the owners list of the Acl. + */ + public void setName(Principal caller, String name) + throws NotOwnerException { + if (!isOwner(caller)) + throw new NotOwnerException(); + + aclName = name; + } + + /** + * Returns the name of the ACL. + * + * @return the name of the ACL. + */ + public String getName() { + return aclName; + } + + /** + * Adds an ACL entry to this ACL. An entry associates a + * group or a principal with a set of permissions. Each + * user or group can have one positive ACL entry and one + * negative ACL entry. If there is one of the type (negative + * or positive) already in the table, a false value is returned. + * The caller principal must be a part of the owners list of + * the ACL in order to invoke this method. + * + * @param caller the principal who is invoking this method. + * @param entry the ACL entry that must be added to the ACL. + * @return true on success, false if the entry is already present. + * @exception NotOwnerException if the caller principal + * is not on the owners list of the Acl. + */ + public synchronized boolean addEntry(Principal caller, AclEntry entry) + throws NotOwnerException { + if (!isOwner(caller)) + throw new NotOwnerException(); + + Hashtable<Principal, AclEntry> aclTable = findTable(entry); + Principal key = entry.getPrincipal(); + + if (aclTable.get(key) != null) + return false; + + aclTable.put(key, entry); + return true; + } + + /** + * Removes an ACL entry from this ACL. + * The caller principal must be a part of the owners list of the ACL + * in order to invoke this method. + * + * @param caller the principal who is invoking this method. + * @param entry the ACL entry that must be removed from the ACL. + * @return true on success, false if the entry is not part of the ACL. + * @exception NotOwnerException if the caller principal is not + * the owners list of the Acl. + */ + public synchronized boolean removeEntry(Principal caller, AclEntry entry) + throws NotOwnerException { + if (!isOwner(caller)) + throw new NotOwnerException(); + + Hashtable<Principal, AclEntry> aclTable = findTable(entry); + Object key = entry.getPrincipal(); + + Object o = aclTable.remove(key); + return (o != null); + } + + /** + * This method returns the set of allowed permissions for the + * specified principal. This set of allowed permissions is calculated + * as follows: + * + * If there is no entry for a group or a principal an empty permission + * set is assumed. + * + * The group positive permission set is the union of all + * the positive permissions of each group that the individual belongs to. + * The group negative permission set is the union of all + * the negative permissions of each group that the individual belongs to. + * If there is a specific permission that occurs in both + * the postive permission set and the negative permission set, + * it is removed from both. The group positive and negatoive permission + * sets are calculated. + * + * The individial positive permission set and the individual negative + * permission set is then calculated. Again abscence of an entry means + * the empty set. + * + * The set of permissions granted to the principal is then calculated using + * the simple rule: Individual permissions always override the Group permissions. + * Specifically, individual negative permission set (specific + * denial of permissions) overrides the group positive permission set. + * And the individual positive permission set override the group negative + * permission set. + * + * @param user the principal for which the ACL entry is returned. + * @return The resulting permission set that the principal is allowed. + */ + public synchronized Enumeration<Permission> getPermissions(Principal user) { + + Enumeration<Permission> individualPositive; + Enumeration<Permission> individualNegative; + Enumeration<Permission> groupPositive; + Enumeration<Permission> groupNegative; + + // + // canonicalize the sets. That is remove common permissions from + // positive and negative sets. + // + groupPositive = subtract(getGroupPositive(user), getGroupNegative(user)); + groupNegative = subtract(getGroupNegative(user), getGroupPositive(user)); + individualPositive = subtract(getIndividualPositive(user), getIndividualNegative(user)); + individualNegative = subtract(getIndividualNegative(user), getIndividualPositive(user)); + + // + // net positive permissions is individual positive permissions + // plus (group positive - individual negative). + // + Enumeration<Permission> temp1 = subtract(groupPositive, individualNegative); + Enumeration<Permission> netPositive = union(individualPositive, temp1); + + // recalculate the enumeration since we lost it in performing the + // subtraction + // + individualPositive = subtract(getIndividualPositive(user), getIndividualNegative(user)); + individualNegative = subtract(getIndividualNegative(user), getIndividualPositive(user)); + + // + // net negative permissions is individual negative permissions + // plus (group negative - individual positive). + // + temp1 = subtract(groupNegative, individualPositive); + Enumeration<Permission> netNegative = union(individualNegative, temp1); + + return subtract(netPositive, netNegative); + } + + /** + * This method checks whether or not the specified principal + * has the required permission. If permission is denied + * permission false is returned, a true value is returned otherwise. + * This method does not authenticate the principal. It presumes that + * the principal is a valid authenticated principal. + * + * @param principal the name of the authenticated principal + * @param permission the permission that the principal must have. + * @return true of the principal has the permission desired, false + * otherwise. + */ + public boolean checkPermission(Principal principal, Permission permission) { + Enumeration<Permission> permSet = getPermissions(principal); + while (permSet.hasMoreElements()) { + Permission p = (Permission) permSet.nextElement(); + if (p.equals(permission)) + return true; + } + return false; + } + + /** + * returns an enumeration of the entries in this ACL. + */ + public synchronized Enumeration<AclEntry> entries() { + return new AclEnumerator(this, + allowedUsersTable, allowedGroupsTable, + deniedUsersTable, deniedGroupsTable); + } + + /** + * return a stringified version of the + * ACL. + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + Enumeration<AclEntry> entries = entries(); + while (entries.hasMoreElements()) { + AclEntry entry = (AclEntry) entries.nextElement(); + sb.append(entry.toString().trim()); + sb.append("\n"); + } + + return sb.toString(); + } + + // + // Find the table that this entry belongs to. There are 4 + // tables that are maintained. One each for postive and + // negative ACLs and one each for groups and users. + // This method figures out which + // table is the one that this AclEntry belongs to. + // + private Hashtable<Principal, AclEntry> findTable(AclEntry entry) { + Hashtable<Principal, AclEntry> aclTable = null; + + Principal p = entry.getPrincipal(); + if (p instanceof Group) { + if (entry.isNegative()) + aclTable = deniedGroupsTable; + else + aclTable = allowedGroupsTable; + } else { + if (entry.isNegative()) + aclTable = deniedUsersTable; + else + aclTable = allowedUsersTable; + } + return aclTable; + } + + // + // returns the set e1 U e2. + // + private <T> Enumeration<T> union(Enumeration<T> e1, Enumeration<T> e2) { + Vector<T> v = new Vector<T>(20, 20); + + while (e1.hasMoreElements()) + v.addElement(e1.nextElement()); + + while (e2.hasMoreElements()) { + T o = e2.nextElement(); + if (!v.contains(o)) + v.addElement(o); + } + + return v.elements(); + } + + // + // returns the set e1 - e2. + // + private <T> Enumeration<T> subtract(Enumeration<T> e1, Enumeration<T> e2) { + Vector<T> v = new Vector<T>(20, 20); + + while (e1.hasMoreElements()) + v.addElement(e1.nextElement()); + + while (e2.hasMoreElements()) { + T o = e2.nextElement(); + if (v.contains(o)) + v.removeElement(o); + } + + return v.elements(); + } + + private Enumeration<Permission> getGroupPositive(Principal user) { + Enumeration<Permission> groupPositive = zeroSet.elements(); + Enumeration<Principal> e = allowedGroupsTable.keys(); + while (e.hasMoreElements()) { + Group g = (Group) e.nextElement(); + if (g.isMember(user)) { + AclEntry ae = (AclEntry) allowedGroupsTable.get(g); + groupPositive = union(ae.permissions(), groupPositive); + } + } + return groupPositive; + } + + private Enumeration<Permission> getGroupNegative(Principal user) { + Enumeration<Permission> groupNegative = zeroSet.elements(); + Enumeration<Principal> e = deniedGroupsTable.keys(); + while (e.hasMoreElements()) { + Group g = (Group) e.nextElement(); + if (g.isMember(user)) { + AclEntry ae = (AclEntry) deniedGroupsTable.get(g); + groupNegative = union(ae.permissions(), groupNegative); + } + } + return groupNegative; + } + + private Enumeration<Permission> getIndividualPositive(Principal user) { + Enumeration<Permission> individualPositive = zeroSet.elements(); + AclEntry ae = (AclEntry) allowedUsersTable.get(user); + if (ae != null) + individualPositive = ae.permissions(); + return individualPositive; + } + + private Enumeration<Permission> getIndividualNegative(Principal user) { + Enumeration<Permission> individualNegative = zeroSet.elements(); + AclEntry ae = (AclEntry) deniedUsersTable.get(user); + if (ae != null) + individualNegative = ae.permissions(); + return individualNegative; + } +} + +final class AclEnumerator implements Enumeration<AclEntry> { + Acl acl; + Enumeration<AclEntry> u1, u2, g1, g2; + + AclEnumerator(Acl acl, Hashtable<Principal, AclEntry> u1, Hashtable<Principal, AclEntry> g1, + Hashtable<Principal, AclEntry> u2, Hashtable<Principal, AclEntry> g2) { + this.acl = acl; + this.u1 = u1.elements(); + this.u2 = u2.elements(); + this.g1 = g1.elements(); + this.g2 = g2.elements(); + } + + public boolean hasMoreElements() { + return (u1.hasMoreElements() || + u2.hasMoreElements() || + g1.hasMoreElements() || g2.hasMoreElements()); + } + + public AclEntry nextElement() { + synchronized (acl) { + if (u1.hasMoreElements()) + return u1.nextElement(); + if (u2.hasMoreElements()) + return u2.nextElement(); + if (g1.hasMoreElements()) + return g1.nextElement(); + if (g2.hasMoreElements()) + return g2.nextElement(); + } + throw new NoSuchElementException("Acl Enumerator"); + } +} diff --git a/base/util/src/netscape/security/acl/AllPermissionsImpl.java b/base/util/src/netscape/security/acl/AllPermissionsImpl.java new file mode 100644 index 000000000..f2b57742f --- /dev/null +++ b/base/util/src/netscape/security/acl/AllPermissionsImpl.java @@ -0,0 +1,43 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.acl; + +import java.security.acl.Permission; + +/** + * This class implements the principal interface for the set of all permissions. + * + * @author Satish Dharmaraj + */ +public class AllPermissionsImpl extends PermissionImpl { + + public AllPermissionsImpl(String s) { + super(s); + } + + /** + * This function returns true if the permission passed matches the permission represented in + * this interface. + * + * @param another The Permission object to compare with. + * @return true always + */ + public boolean equals(Permission another) { + return true; + } +} diff --git a/base/util/src/netscape/security/acl/GroupImpl.java b/base/util/src/netscape/security/acl/GroupImpl.java new file mode 100644 index 000000000..ed087a544 --- /dev/null +++ b/base/util/src/netscape/security/acl/GroupImpl.java @@ -0,0 +1,173 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.acl; + +import java.security.Principal; +import java.security.acl.Group; +import java.util.Enumeration; +import java.util.Vector; + +/** + * This class implements a group of principals. + * + * @author Satish Dharmaraj + */ +public class GroupImpl implements Group { + private Vector<Principal> groupMembers = new Vector<Principal>(50, 100); + private String group; + + /** + * Constructs a Group object with no members. + * + * @param groupName the name of the group + */ + public GroupImpl(String groupName) { + this.group = groupName; + } + + /** + * adds the specified member to the group. + * + * @param user The principal to add to the group. + * @return true if the member was added - false if the + * member could not be added. + */ + public boolean addMember(Principal user) { + if (groupMembers.contains(user)) + return false; + + // do not allow groups to be added to itself. + if (group.equals(user.toString())) + throw new IllegalArgumentException(); + + groupMembers.addElement(user); + return true; + } + + /** + * removes the specified member from the group. + * + * @param user The principal to remove from the group. + * @param true if the principal was removed false if + * the principal was not a member + */ + public boolean removeMember(Principal user) { + return groupMembers.removeElement(user); + } + + /** + * returns the enumeration of the members in the group. + */ + public Enumeration<Principal> members() { + return groupMembers.elements(); + } + + /** + * This function returns true if the group passed matches + * the group represented in this interface. + * + * @param another The group to compare this group to. + */ + public boolean equals(Group another) { + return group.equals(another.toString()); + } + + /** + * Prints a stringified version of the group. + */ + public String toString() { + return group; + } + + /** + * return a hashcode for the principal. + */ + public int hashCode() { + return group.hashCode(); + } + + /** + * returns true if the passed principal is a member of the group. + * + * @param member The principal whose membership must be checked for. + * @return true if the principal is a member of this group, + * false otherwise + */ + public boolean isMember(Principal member) { + + // + // if the member is part of the group (common case), return true. + // if not, recursively search depth first in the group looking for the + // principal. + // + if (groupMembers.contains(member)) { + return true; + } else { + Vector<Group> alreadySeen = new Vector<Group>(10); + return isMemberRecurse(member, alreadySeen); + } + } + + /** + * return the name of the principal. + */ + public String getName() { + return group; + } + + // + // This function is the recursive search of groups for this + // implementation of the Group. The search proceeds building up + // a vector of already seen groups. Only new groups are considered, + // thereby avoiding loops. + // + boolean isMemberRecurse(Principal member, Vector<Group> alreadySeen) { + Enumeration<Principal> e = members(); + while (e.hasMoreElements()) { + boolean mem = false; + Principal p = e.nextElement(); + + // if the member is in this collection, return true + if (p.equals(member)) { + return true; + } else if (p instanceof GroupImpl) { + // + // if not recurse if the group has not been checked already. + // Can call method in this package only if the object is an + // instance of this class. Otherwise call the method defined + // in the interface. (This can lead to a loop if a mixture of + // implementations form a loop, but we live with this improbable + // case rather than clutter the interface by forcing the + // implementation of this method.) + // + GroupImpl g = (GroupImpl) p; + alreadySeen.addElement(this); + if (!alreadySeen.contains(g)) + mem = g.isMemberRecurse(member, alreadySeen); + } else if (p instanceof Group) { + Group g = (Group) p; + if (!alreadySeen.contains(g)) + mem = g.isMember(member); + } + + if (mem) + return mem; + } + return false; + } +} diff --git a/base/util/src/netscape/security/acl/OwnerImpl.java b/base/util/src/netscape/security/acl/OwnerImpl.java new file mode 100644 index 000000000..3f47a1dd8 --- /dev/null +++ b/base/util/src/netscape/security/acl/OwnerImpl.java @@ -0,0 +1,105 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.acl; + +import java.security.Principal; +import java.security.acl.Group; +import java.security.acl.LastOwnerException; +import java.security.acl.NotOwnerException; +import java.security.acl.Owner; +import java.util.Enumeration; + +/** + * Class implementing the Owner interface. The + * initial owner principal is configured as + * part of the constructor. + * + * @author Satish Dharmaraj + */ +public class OwnerImpl implements Owner { + private Group ownerGroup; + + public OwnerImpl(Principal owner) { + ownerGroup = new GroupImpl("AclOwners"); + ownerGroup.addMember(owner); + } + + /** + * Adds an owner. Owners can modify ACL contents and can disassociate + * ACLs from the objects they protect in the AclConfig interface. + * The caller principal must be a part of the owners list of the ACL in + * order to invoke this method. The initial owner is configured + * at ACL construction time. + * + * @param caller the principal who is invoking this method. + * @param owner The owner that should be added to the owners list. + * @return true if success, false if already an owner. + * @exception NotOwnerException if the caller principal is not on + * the owners list of the Acl. + */ + public synchronized boolean addOwner(Principal caller, Principal owner) + throws NotOwnerException { + if (!isOwner(caller)) + throw new NotOwnerException(); + + ownerGroup.addMember(owner); + return false; + } + + /** + * Delete owner. If this is the last owner in the ACL, an exception is + * raised. + * The caller principal must be a part of the owners list of the ACL in + * order to invoke this method. + * + * @param caller the principal who is invoking this method. + * @param owner The owner to be removed from the owners list. + * @return true if the owner is removed, false if the owner is not part + * of the owners list. + * @exception NotOwnerException if the caller principal is not on + * the owners list of the Acl. + * @exception LastOwnerException if there is only one owner left in the group, then + * deleteOwner would leave the ACL owner-less. This exception is raised in such a case. + */ + public synchronized boolean deleteOwner(Principal caller, Principal owner) + throws NotOwnerException, LastOwnerException { + if (!isOwner(caller)) + throw new NotOwnerException(); + + Enumeration<? extends Principal> e = ownerGroup.members(); + // + // check if there is atleast 2 members left. + // + e.nextElement(); // consume next element + if (e.hasMoreElements()) + return ownerGroup.removeMember(owner); + else + throw new LastOwnerException(); + + } + + /** + * returns if the given principal belongs to the owner list. + * + * @param owner The owner to check if part of the owners list + * @return true if the passed principal is in the owner list, false if not. + */ + public synchronized boolean isOwner(Principal owner) { + return ownerGroup.isMember(owner); + } +} diff --git a/base/util/src/netscape/security/acl/PermissionImpl.java b/base/util/src/netscape/security/acl/PermissionImpl.java new file mode 100644 index 000000000..2e73d3c7e --- /dev/null +++ b/base/util/src/netscape/security/acl/PermissionImpl.java @@ -0,0 +1,65 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.acl; + +import java.security.acl.Permission; + +/** + * The PermissionImpl class implements the permission + * interface for permissions that are strings. + * + * @author Satish Dharmaraj + */ +public class PermissionImpl implements Permission { + + private String permission; + + /** + * Construct a permission object using a string. + * + * @param permission the stringified version of the permission. + */ + public PermissionImpl(String permission) { + this.permission = permission; + } + + /** + * This function returns true if the object passed matches the permission + * represented in this interface. + * + * @param another The Permission object to compare with. + * @return true if the Permission objects are equal, false otherwise + */ + public boolean equals(Object another) { + if (another instanceof Permission) { + Permission p = (Permission) another; + return permission.equals(p.toString()); + } else { + return false; + } + } + + /** + * Prints a stringified version of the permission. + * + * @return the string representation of the Permission. + */ + public String toString() { + return permission; + } +} diff --git a/base/util/src/netscape/security/acl/PrincipalImpl.java b/base/util/src/netscape/security/acl/PrincipalImpl.java new file mode 100644 index 000000000..25fa11095 --- /dev/null +++ b/base/util/src/netscape/security/acl/PrincipalImpl.java @@ -0,0 +1,77 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.acl; + +import java.security.Principal; + +/** + * This class implements the principal interface. + * + * @author Satish Dharmaraj + */ +public class PrincipalImpl implements Principal { + + private String user; + + /** + * Construct a principal from a string user name. + * + * @param user The string form of the principal name. + */ + public PrincipalImpl(String user) { + this.user = user; + } + + /** + * This function returns true if the object passed matches + * the principal represented in this implementation + * + * @param another the Principal to compare with. + * @return true if the Principal passed is the same as that + * encapsulated in this object, false otherwise + */ + public boolean equals(Object another) { + if (another instanceof PrincipalImpl) { + PrincipalImpl p = (PrincipalImpl) another; + return user.equals(p.toString()); + } else + return false; + } + + /** + * Prints a stringified version of the principal. + */ + public String toString() { + return user; + } + + /** + * return a hashcode for the principal. + */ + public int hashCode() { + return user.hashCode(); + } + + /** + * return the name of the principal. + */ + public String getName() { + return user; + } + +} diff --git a/base/util/src/netscape/security/acl/WorldGroupImpl.java b/base/util/src/netscape/security/acl/WorldGroupImpl.java new file mode 100644 index 000000000..2f885cbec --- /dev/null +++ b/base/util/src/netscape/security/acl/WorldGroupImpl.java @@ -0,0 +1,42 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.acl; + +import java.security.Principal; + +/** + * This class implements a group of principals. + * + * @author Satish Dharmaraj + */ +public class WorldGroupImpl extends GroupImpl { + + public WorldGroupImpl(String s) { + super(s); + } + + /** + * returns true for all passed principals + * + * @param member The principal whose membership must be checked in this Group. + * @return true always since this is the "world" group. + */ + public boolean isMember(Principal member) { + return true; + } +} |