com.sun.enterprise.security.jacc.provider.SimplePolicyConfiguration Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.enterprise.security.jacc.provider;
import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.MBeanPermission;
import javax.security.jacc.EJBRoleRefPermission;
import javax.security.jacc.PolicyConfiguration;
import javax.security.jacc.PolicyContext;
import javax.security.jacc.PolicyContextException;
import javax.security.jacc.PolicyContextHandler;
import javax.security.jacc.WebResourcePermission;
import javax.security.jacc.WebRoleRefPermission;
import javax.security.jacc.WebUserDataPermission;
/**
*
* @author monzillo
*
* The methods of this interface are used by containers to
* create policy statements in a Policy provider.
* An object that implements the PolicyConfiguration interface provides the
* policy statement configuration interface for a corresponding policy context
* within the corresponding Policy provider.
*
*/
public class SimplePolicyConfiguration implements PolicyConfiguration {
public static final int OPEN_STATE = 0;
public static final int INSERVICE_STATE = 2;
public static final int DELETED_STATE = 3;
private static final Permission setPolicyPermission =
new java.security.SecurityPermission("setPolicy");
private String id;
private int state = OPEN_STATE;
// Excluded permissions
private PermissionCollection excludedPermissions = null;
// Unchecked permissions
private PermissionCollection uncheckedPermissions = null;
// roleTbale mapps permissions and principals to roles.
private ArrayList roleTable = null;
// Lock on this PolicyConfiguration onject
private ReentrantReadWriteLock pcLock = new ReentrantReadWriteLock(true);
private Lock pcrLock = pcLock.readLock();
private Lock pcwLock = pcLock.writeLock();
static {
// register a role mapper
try {
String className = System.getProperty(JACCRoleMapper.CLASS_NAME);
if (className != null ||
!PolicyContext.getHandlerKeys().contains(JACCRoleMapper.HANDLER_KEY)) {
if (className == null) {
String packageName = SimplePolicyConfiguration.class.getPackage().getName();
className = packageName +"."+ "GlassfishRoleMapper";
}
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = loader.loadClass(className);
final Constructor ctx = clazz.getConstructor(new Class[]{Logger.class});
PolicyContext.registerHandler(
JACCRoleMapper.HANDLER_KEY,
new PolicyContextHandler() {
public Object getContext(String key, Object data)
throws PolicyContextException {
if (key.equals(JACCRoleMapper.HANDLER_KEY)) {
try {
return ctx.newInstance(new Object[]{SharedState.getLogger()});
} catch (Throwable t) {
throw new PolicyContextException(t);
}
}
return null;
}
public String[] getKeys()
throws PolicyContextException {
return new String[]{JACCRoleMapper.HANDLER_KEY};
}
public boolean supports(String key)
throws PolicyContextException {
return key.equals(JACCRoleMapper.HANDLER_KEY);
}
},
false);
}
} catch (Throwable t) {
SharedState.getLogger().log(Level.SEVERE, "RoleMapper.registration.failed", t);
throw new RuntimeException(t);
}
}
/**
* Creates a new instance of SimplePolicyConfiguration
*/
protected SimplePolicyConfiguration(String contextID) {
id = contextID;
}
// Public Policy Configuration Interfaces Start here
/**
* This method returns this object's policy context identifier.
* @return this object's policy context identifier.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the getContextID method signature. The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public String getContextID()
throws javax.security.jacc.PolicyContextException {
return id;
}
/**
* Used to add permissions to a named role in this PolicyConfiguration.
* If the named Role does not exist in the PolicyConfiguration, it is
* created as a result of the call to this function.
*
* It is the job of the Policy provider to ensure that all the permissions
* added to a role are granted to principals "mapped to the role".
*
* @param roleName the name of the Role to which the permissions are
* to be added.
*
* @param permissions the collection of permissions to be added
* to the role. The collection may be either a homogenous or
* heterogenous collection.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws java.lang.UnsupportedOperationException
* if the state of the policy context whose interface is this
* PolicyConfiguration Object is "deleted" or "inService" when this
* method is called.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the addToRole method signature. The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void addToRole(String roleName, PermissionCollection permissions)
throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
pcwLock.lock();
try {
assertStateIsOpen();
if (roleName != null && permissions != null) {
Role role = getRole(roleName);
role.addPermissions(permissions);
}
} finally {
pcwLock.unlock();
}
}
/**
* Used to add a single permission to a named role in this
* PolicyConfiguration.
* If the named Role does not exist in the PolicyConfiguration, it is
* created as a result of the call to this function.
*
* It is the job of the Policy provider to ensure that all the permissions
* added to a role are granted to principals "mapped to the role".
*
* @param roleName the name of the Role to which the permission is
* to be added.
*
* @param permission the permission to be added
* to the role.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws java.lang.UnsupportedOperationException
* if the state of the policy context whose interface is this
* PolicyConfiguration Object is "deleted" or "inService" when this
* method is called.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the addToRole method signature. The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void addToRole(String roleName, Permission permission)
throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
pcwLock.lock();
try {
assertStateIsOpen();
if (roleName != null && permission != null) {
Role role = getRole(roleName);
role.addPermission(permission);
}
} finally {
pcwLock.unlock();
}
}
/**
* Used to add unchecked policy statements to this PolicyConfiguration.
*
* @param permissions the collection of permissions to be added
* as unchecked policy statements. The collection may be either
* a homogenous or heterogenous collection.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws java.lang.UnsupportedOperationException
* if the state of the policy context whose interface is this
* PolicyConfiguration Object is "deleted" or "inService" when this
* method is called.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the addToUncheckedPolicy method signature.
* The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void addToUncheckedPolicy(PermissionCollection permissions)
throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
pcwLock.lock();
try {
assertStateIsOpen();
if (permissions != null) {
for (Enumeration e = permissions.elements();
e.hasMoreElements();) {
this.getUncheckedPermissions().add(
(Permission) e.nextElement());
}
}
} finally {
pcwLock.unlock();
}
}
/**
* Used to add a single unchecked policy statement to this
* PolicyConfiguration.
*
* @param permission the permission to be added
* to the unchecked policy statements.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws java.lang.UnsupportedOperationException
* if the state of the policy context whose interface is this
* PolicyConfiguration Object is "deleted" or "inService" when this
* method is called.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the addToUncheckedPolicy method signature.
* The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void addToUncheckedPolicy(Permission permission)
throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
pcwLock.lock();
try {
assertStateIsOpen();
if (permission != null) {
getUncheckedPermissions().add(permission);
}
} finally {
pcwLock.unlock();
}
}
/**
* Used to add excluded policy statements to this PolicyConfiguration.
*
* @param permissions the collection of permissions to be added
* to the excluded policy statements. The collection may be either
* a homogenous or heterogenous collection.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws java.lang.UnsupportedOperationException
* if the state of the policy context whose interface is this
* PolicyConfiguration Object is "deleted" or "inService" when this
* method is called.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the addToExcludedPolicy method signature.
* The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void addToExcludedPolicy(PermissionCollection permissions)
throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
pcwLock.lock();
try {
assertStateIsOpen();
if (permissions != null) {
for (Enumeration e = permissions.elements();
e.hasMoreElements();) {
this.getExcludedPermissions().add(
(Permission) e.nextElement());
}
}
} finally {
pcwLock.unlock();
}
}
/**
* Used to add a single excluded policy statement to this
* PolicyConfiguration.
*
* @param permission the permission to be added
* to the excluded policy statements.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws java.lang.UnsupportedOperationException
* if the state of the policy context whose interface is this
* PolicyConfiguration Object is "deleted" or "inService" when this
* method is called.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the addToExcludedPolicy method signature.
* The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void addToExcludedPolicy(Permission permission)
throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
pcwLock.lock();
try {
assertStateIsOpen();
if (permission != null) {
getExcludedPermissions().add(permission);
}
} finally {
pcwLock.unlock();
}
}
/**
* Used to remove a role and all its permissions from this
* PolicyConfiguration.
*
* @param roleName the name of the Role to remove from this
* PolicyConfiguration.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws java.lang.UnsupportedOperationException
* if the state of the policy context whose interface is this
* PolicyConfiguration Object is "deleted" or "inService" when this
* method is called.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the removeRole method signature. The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void removeRole(String roleName)
throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
pcwLock.lock();
try {
assertStateIsOpen();
if (roleName != null && roleTable != null) {
if (!roleTable.remove(new Role(roleName))) {
if (roleName.equals("*")) {
roleTable.clear();
roleTable = null;
}
} else if (roleTable.isEmpty()) {
roleTable = null;
}
}
} finally {
pcwLock.unlock();
}
}
/**
* Used to remove any unchecked policy statements from this
* PolicyConfiguration.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws java.lang.UnsupportedOperationException
* if the state of the policy context whose interface is this
* PolicyConfiguration Object is "deleted" or "inService" when this
* method is called.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the removeUncheckedPolicy method signature.
* The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void removeUncheckedPolicy()
throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
pcwLock.lock();
try {
assertStateIsOpen();
uncheckedPermissions =
null;
} finally {
pcwLock.unlock();
}
}
/**
* Used to remove any excluded policy statements from this
* PolicyConfiguration.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws java.lang.UnsupportedOperationException
* if the state of the policy context whose interface is this
* PolicyConfiguration Object is "deleted" or "inService" when this
* method is called.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the removeExcludedPolicy method signature.
* The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void removeExcludedPolicy()
throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
pcwLock.lock();
try {
assertStateIsOpen();
excludedPermissions = null;
} finally {
pcwLock.unlock();
}
}
/**
* Creates a relationship between this configuration and another
* such that they share the same principal-to-role mappings.
* PolicyConfigurations are linked to apply a common principal-to-role
* mapping to multiple seperately manageable PolicyConfigurations,
* as is required when an application is composed of multiple
* modules.
*
* Note that the policy statements which comprise a role, or comprise
* the excluded or unchecked policy collections in a PolicyConfiguration
* are unaffected by the configuration being linked to another.
*
* @param link a reference to a different PolicyConfiguration than this
* PolicyConfiguration.
*
* The relationship formed by this method is symetric, transitive
* and idempotent. If the argument PolicyConfiguration does not have a
* different Policy context identifier than this PolicyConfiguration
* no relationship is formed, and an exception, as described below, is
* thrown.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws java.lang.UnsupportedOperationException
* if the state of the policy context whose interface is this
* PolicyConfiguration Object is "deleted" or "inService" when this
* method is called.
*
* @throws java.lang.IllegalArgumentException
* if called with an argument PolicyConfiguration whose Policy context
* is equivalent to that of this PolicyConfiguration.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the linkConfiguration method signature. The exception
* thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void linkConfiguration(PolicyConfiguration link)
throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
pcrLock.lock();
try {
assertStateIsOpen();
} finally {
pcrLock.unlock();
}
/* if at this point, a simultaneous attempt is made to delete or commit
* this pc, we could end up with a corrupted link table. Niether event
* is likely, but we should try to properly serialize those events.
*/
SharedState.link(id, link.getContextID());
}
/**
* Causes all policy statements to be deleted from this PolicyConfiguration
* and sets its internal state such that calling any method, other than
* delete, getContextID, or inService on the PolicyConfiguration will
* be rejected and cause an UnsupportedOperationException to be thrown.
*
* This operation has no affect on any linked PolicyConfigurations
* other than removing any links involving the deleted PolicyConfiguration.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the delete method signature. The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void delete() throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
SharedState.removeLinks(id);
/* final state will be unlinked and deleted
*/
pcwLock.lock();
try {
removePolicy();
} finally {
try {
setState(DELETED_STATE);
} finally {
pcwLock.unlock();
}
}
}
/**
* This method is used to set to "inService" the state of the policy context
* whose interface is this PolicyConfiguration Object. Only those policy
* contexts whose state is "inService" will be included in the policy
* contexts processed by the Policy.refresh method. A policy context whose
* state is "inService" may be returned to the "owpen" state by calling the
* getPolicyConfiguration method of the PolicyConfiguration factory
* with the policy context identifier of the policy context.
*
* When the state of a policy context is "inService", calling any method
* other than commit, delete, getContextID, or inService on its
* PolicyConfiguration Object will cause an UnsupportedOperationException
* to be thrown.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws java.lang.UnsupportedOperationException
* if the state of the policy context whose interface is this
* PolicyConfiguration Object is "deleted" when this
* method is called.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the commit method signature. The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public void commit()
throws javax.security.jacc.PolicyContextException {
checkSetPolicyPermission();
boolean initRoles = false;
pcwLock.lock();
try {
if (stateIs(DELETED_STATE)) {
String msg = "pc.invalid_op_for_state_delete";
throw new UnsupportedOperationException(msg);
}
if (stateIs(OPEN_STATE)) {
if (roleTable != null) {
initRoles = true;
}
setState(INSERVICE_STATE);
}
} finally {
pcwLock.unlock();
}
if (initRoles) {
commitRoleMapping();
}
}
/**
* This method is used to determine if the policy context whose interface is
* this PolicyConfiguration Object is in the "inService" state.
*
* @return true if the state of the associated policy context is
* "inService"; false otherwise.
*
* @throws java.lang.SecurityException
* if called by an AccessControlContext that has not been
* granted the "setPolicy" SecurityPermission.
*
* @throws javax.security.jacc.PolicyContextException
* if the implementation throws a checked exception that has not been
* accounted for by the inService method signature. The exception thrown
* by the implementation class will be encapsulated (during construction)
* in the thrown PolicyContextException.
*/
public boolean inService()
throws javax.security.jacc.PolicyContextException {
pcrLock.lock();
try {
return stateIs(INSERVICE_STATE);
} finally {
pcrLock.unlock();
}
}
// Internal Policy Configuration interfaces start here
protected static SimplePolicyConfiguration getPolicyConfig(
String pcid, boolean remove) throws PolicyContextException {
SimplePolicyConfiguration pc = SharedState.getConfig(pcid, remove);
pc.pcwLock.lock();
try {
if (remove) {
pc.removePolicy();
}
pc.setState(OPEN_STATE);
} finally {
pc.pcwLock.unlock();
}
return pc;
}
protected static boolean inService(String pcid)
throws javax.security.jacc.PolicyContextException {
SimplePolicyConfiguration pc = SharedState.lookupConfig(pcid);
if (pc == null) {
return false;
}
return pc.inService();
}
protected static void checkSetPolicyPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(setPolicyPermission);
}
}
private void setState(int stateValue) {
this.state = stateValue;
}
private boolean stateIs(int stateValue) {
return this.state == stateValue;
}
private void assertStateIsOpen() throws UnsupportedOperationException {
if (!stateIs(OPEN_STATE)) {
String msg = "Operation invoked on closed or deleted PolicyConfiguration.";
throw new UnsupportedOperationException(msg);
}
}
private void assertStateIsInService() throws UnsupportedOperationException {
if (!stateIs(INSERVICE_STATE)) {
String msg = "Operation invoked on open or deleted PolicyConfiguration.";
throw new UnsupportedOperationException(msg);
}
}
private PermissionCollection getUncheckedPermissions() {
if (uncheckedPermissions == null) {
uncheckedPermissions = new Permissions();
}
return uncheckedPermissions;
}
private PermissionCollection getExcludedPermissions() {
if (excludedPermissions == null) {
excludedPermissions = new Permissions();
}
return excludedPermissions;
}
private Role getRole(String roleName) {
int index = -1;
Role rvalue = new Role(roleName);
if (roleTable == null) {
roleTable = new ArrayList();
} else {
index = roleTable.indexOf(rvalue);
}
if (index < 0) {
roleTable.add(rvalue);
} else {
rvalue = roleTable.get(index);
}
return rvalue;
}
private void removePolicy() {
excludedPermissions = null;
uncheckedPermissions = null;
roleTable = null;
}
/**
* Adds the principal-2-role mapping to the roles in the roleTable
* @throws javax.security.jacc.PolicyContextException
*/
private void commitRoleMapping() throws PolicyContextException {
JACCRoleMapper roleMapper = null;
try {
/**
* NB: when running with a security manager, this method will
* call policy, to check if the policy module is authorized
* to invoke the policy context handler.
*/
roleMapper = (JACCRoleMapper) PolicyContext.getContext(JACCRoleMapper.HANDLER_KEY);
if (roleMapper == null) {
throw new PolicyContextException("RoleMapper.lookup.null");
}
} catch (Throwable t) {
SharedState.getLogger().log(Level.SEVERE, "RoleMapper.lookup.failed", t);
if (t instanceof PolicyContextException) {
throw (PolicyContextException) t;
} else {
throw new PolicyContextException(t);
}
}
pcwLock.lock();
try {
if (roleTable != null) {
for (Role role : roleTable) {
role.setPrincipals(roleMapper.getPrincipalsInRole(id, role.getName()));
}
/**
* JACC MR8 add handling for the any authenticated user role '**'
*/
Role rvalue = new Role("**");
int index = roleTable.indexOf(rvalue);
if (index != -1) {
rvalue = roleTable.get(index);
rvalue.determineAnyAuthenticatedUserRole();
}
}
} finally {
pcwLock.unlock();
}
}
// Public Policy Enforcement Interfaces Start here
/**
* Evaluates the global policy and returns a
* PermissionCollection object specifying the set of
* permissions allowed for code from the specified
* code source.
*
* @param codeSource the CodeSource associated with the caller.
* This encapsulates the original location of the code (where the code
* came from) and the public key(s) of its signer.
*
* @return the set of permissions allowed for code from codesource
* according to the policy.The returned set of permissions must be
* a new mutable instance and it must support heterogeneous
* Permission types.
*
*/
public static PermissionCollection getPermissions(
PermissionCollection basePerms, CodeSource codesource)
throws PolicyContextException {
SimplePolicyConfiguration pc = SharedState.getActiveConfig();
return pc == null ? basePerms : pc.getPermissions(basePerms, (PermissionCollection) null, new Principal[0]);
}
/**
* Evaluates the policy and returns a
* PermissionCollection object specifying the set of
* permissions allowed given the characteristics of the
* protection domain.
*
* @param domain the ProtectionDomain associated with the caller.
*
* @return the set of permissions allowed for the domain
* according to the policy.The returned set of permissions must be
* a new mutable instance and it must support heterogeneous
* Permission types.
*
* @see java.security.ProtectionDomain
* @see java.security.SecureClassLoader
* @since 1.4
*/
public static PermissionCollection getPermissions(
PermissionCollection basePerms, ProtectionDomain domain)
throws PolicyContextException {
SimplePolicyConfiguration pc = SharedState.getActiveConfig();
return pc == null ? basePerms : pc.getPermissions(basePerms, domain.getPermissions(), domain.getPrincipals());
}
/**
* Evaluates the policy to determine whether the permissions is granted to
* the ProtectionDomain.
*
* @param domain the ProtectionDomain to test
* @param permission the Permission object to be tested for implication.
*
* @return integer -1 if excluded, 0 if not implied, 1 if implied
* granted to this ProtectionDomain.
*
*/
public static int implies(ProtectionDomain domain, Permission p)
throws PolicyContextException {
SimplePolicyConfiguration pc = SharedState.getActiveConfig();
return (pc == null ? 0 : pc.doImplies(domain, p));
}
// Internal Policy Enforcement Interfaces Start here
private boolean permIsExcluded(Permission p) {
boolean isExcluded = false;
if (hasExcludedPermissions()) {
if (!getExcludedPermissions().implies(p)) {
/*
* this loop ensures that the tested perm does not imply
* an excluded perm; in which case it must be excluded
*/
Enumeration e = excludedPermissions.elements();
while (e.hasMoreElements()) {
Permission excludedPerm = (Permission) e.nextElement();
if (p.implies(excludedPerm)) {
isExcluded = true;
break;
}
}
} else {
isExcluded = true;
}
}
return isExcluded;
}
/**
* @param d
* @param p
* @return integer -1 if excluded, 0 if not implied, 1 if implied.
* @throws javax.security.jacc.PolicyContextException
*/
private int doImplies(ProtectionDomain d, Permission p)
throws PolicyContextException {
pcrLock.lock();
int rvalue = 0;
try {
assertStateIsInService();
if (permIsExcluded(p)) {
rvalue = -1;
} else if (getUncheckedPermissions().implies(p)) {
rvalue = 1;
} else if (roleTable != null) {
Principal principals[] = d.getPrincipals();
if (principals.length == 0) {
rvalue = 0;
} else {
for (Role role : roleTable) {
if (role.arePrincipalsInRole(principals) && role.implies(p)) {
rvalue = 1;
break;
}
//added as a per role debugging convenience
if (rvalue != 1) {
rvalue = 0;
}
}
//added as an all role debugging convenience
if (rvalue != 1) {
rvalue = 0;
}
}
}
return rvalue;
} catch (UnsupportedOperationException uso) {
throw new PolicyContextException(uso);
} finally {
pcrLock.unlock();
}
}
private boolean hasExcludedPermissions() {
return excludedPermissions == null ||
!excludedPermissions.elements().hasMoreElements() ? false : true;
}
private PermissionCollection getPermissions(PermissionCollection basePerms,
PermissionCollection domainPerms, Principal[] principals)
throws PolicyContextException, UnsupportedOperationException {
pcrLock.lock();
try {
assertStateIsInService();
Permissions c = null;
boolean hasExcludes = hasExcludedPermissions();
if (basePerms != null) {
for (Enumeration e = basePerms.elements();
e.hasMoreElements();) {
Permission p = (Permission) e.nextElement();
if (!hasExcludes || !permIsExcluded(p)) {
if (c == null) {
c = new Permissions();
}
c.add(p);
}
}
}
if (domainPerms != null) {
for (Enumeration e = domainPerms.elements();
e.hasMoreElements();) {
Permission p = (Permission) e.nextElement();
if (!hasExcludes || !permIsExcluded(p)) {
if (c == null) {
c = new Permissions();
}
c.add(p);
}
}
}
for (Enumeration e = getUncheckedPermissions().elements();
e.hasMoreElements();) {
Permission p = (Permission) e.nextElement();
if (!hasExcludes || !permIsExcluded(p)) {
if (c == null) {
c = new Permissions();
}
c.add(p);
}
}
if (principals.length == 0 || roleTable == null) {
return c;
}
for (Role role : roleTable) {
if (role.arePrincipalsInRole(principals)) {
PermissionCollection rc = role.getPermissions();
for (Enumeration e = rc.elements(); e.hasMoreElements();) {
Permission p = (Permission) e.nextElement();
if (!hasExcludes || !permIsExcluded(p)) {
if (c == null) {
c = new Permissions();
}
c.add(p);
}
}
}
}
return c;
} catch (UnsupportedOperationException uso) {
throw new PolicyContextException(uso);
} finally {
pcrLock.unlock();
}
}
/**
* Refreshes/reloads all of the inservice policy configurations.
* The behavior of this method
* depends on the implementation. For example, calling refresh
* on a file-based policy will cause the file to be re-read.
*/
static void refresh() throws PolicyContextException {
}
static void doPrivilegedLog(final Level level,
final String msg, final Object[] params) {
final Logger logger = SharedState.getLogger();
if (logger.isLoggable(level)) {
if (System.getSecurityManager() == null) {
logger.log(level, msg, params);
} else {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
logger.log(level, msg, params);
return null;
}
});
}
}
}
static void doPrivilegedLog(final Level level,
final String msg, final Throwable t) {
final Logger logger = SharedState.getLogger();
if (logger.isLoggable(level)) {
if (System.getSecurityManager() == null) {
logger.log(level, msg, t);
} else {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
logger.log(level, msg, t);
return null;
}
});
}
}
}
// Internal logging interfaces start here
static void logGetPermissionsFailure(final Object o, Throwable t) {
String id = PolicyContext.getContextID();
doPrivilegedLog(Level.INFO, "getPermissions.failure", new Object[]{id, o});
doPrivilegedLog(Level.INFO, "getPermissions.failure", t);
}
private static boolean permissionShouldBeLogged(Permission p) {
return !(p instanceof WebResourcePermission) &&
!(p instanceof WebUserDataPermission) &&
!(p instanceof MBeanPermission) &&
!(p instanceof WebRoleRefPermission) &&
!(p instanceof EJBRoleRefPermission);
}
static void logAccessFailure(ProtectionDomain d, Permission p) {
if (permissionShouldBeLogged(p) || SharedState.getLogger().isLoggable(Level.FINE)) {
String id = PolicyContext.getContextID();
doPrivilegedLog(Level.FINE, "Domain.that.failed",
new Object[]{id, p, d});
}
}
static void logException(Level l, String msg, Throwable t) {
String id = PolicyContext.getContextID();
doPrivilegedLog(l, msg, new Object[]{id});
doPrivilegedLog(l, msg, t);
}
}