
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.
*/
// Portions Copyright [2018] [Payara Foundation and/or its affiliates]
package com.sun.enterprise.security.jacc.provider;
import static com.sun.enterprise.security.jacc.provider.JACCRoleMapper.HANDLER_KEY;
import static com.sun.enterprise.security.jacc.provider.SharedState.getLogger;
import static java.lang.System.getSecurityManager;
import static java.security.AccessController.doPrivileged;
import static java.util.logging.Level.SEVERE;
import java.lang.reflect.Constructor;
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.security.SecurityPermission;
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;
/**
* 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.
*
* @author monzillo
*/
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 SecurityPermission("setPolicy");
private String contextId;
private int state = OPEN_STATE;
// Excluded permissions
private PermissionCollection excludedPermissions = null;
// Unchecked permissions
private PermissionCollection uncheckedPermissions = null;
// roleTable maps permissions and principals to roles.
private ArrayList roleTable = null;
// Lock on this PolicyConfiguration onject
private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
private Lock readLock = readWriteLock.readLock();
private Lock writeLock = readWriteLock.writeLock();
static {
// Register a role mapper
try {
String className = System.getProperty(JACCRoleMapper.CLASS_NAME);
if (className != null || !PolicyContext.getHandlerKeys().contains(HANDLER_KEY)) {
if (className == null) {
className = SimplePolicyConfiguration.class.getPackage().getName() + "." + "GlassfishRoleMapper";
}
final Constructor> ctx = Thread.currentThread()
.getContextClassLoader()
.loadClass(className)
.getConstructor(new Class[] { Logger.class });
PolicyContext.registerHandler(HANDLER_KEY, new PolicyContextHandler() {
public Object getContext(String key, Object data) throws PolicyContextException {
if (key.equals(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[] { HANDLER_KEY };
}
public boolean supports(String key) throws PolicyContextException {
return key.equals(HANDLER_KEY);
}
}, false);
}
} catch (Throwable t) {
getLogger().log(SEVERE, "RoleMapper.registration.failed", t);
throw new RuntimeException(t);
}
}
/**
* Creates a new instance of SimplePolicyConfiguration
*/
protected SimplePolicyConfiguration(String contextID) {
contextId = 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 PolicyContextException {
return contextId;
}
/**
* 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 PolicyContextException {
checkSetPolicyPermission();
writeLock.lock();
try {
assertStateIsOpen();
if (roleName != null && permissions != null) {
getRole(roleName).addPermissions(permissions);
}
} finally {
writeLock.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();
writeLock.lock();
try {
assertStateIsOpen();
if (roleName != null && permission != null) {
getRole(roleName).addPermission(permission);
}
} finally {
writeLock.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 PolicyContextException {
checkSetPolicyPermission();
writeLock.lock();
try {
assertStateIsOpen();
if (permissions != null) {
for (Enumeration e = permissions.elements(); e.hasMoreElements();) {
getUncheckedPermissions().add(e.nextElement());
}
}
} finally {
writeLock.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 PolicyContextException {
checkSetPolicyPermission();
writeLock.lock();
try {
assertStateIsOpen();
if (permission != null) {
getUncheckedPermissions().add(permission);
}
} finally {
writeLock.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 PolicyContextException {
checkSetPolicyPermission();
writeLock.lock();
try {
assertStateIsOpen();
if (permissions != null) {
for (Enumeration e = permissions.elements(); e.hasMoreElements();) {
this.getExcludedPermissions().add(e.nextElement());
}
}
} finally {
writeLock.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 PolicyContextException {
checkSetPolicyPermission();
writeLock.lock();
try {
assertStateIsOpen();
if (permission != null) {
getExcludedPermissions().add(permission);
}
} finally {
writeLock.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 PolicyContextException {
checkSetPolicyPermission();
writeLock.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 {
writeLock.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 PolicyContextException {
checkSetPolicyPermission();
writeLock.lock();
try {
assertStateIsOpen();
uncheckedPermissions = null;
} finally {
writeLock.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 PolicyContextException {
checkSetPolicyPermission();
writeLock.lock();
try {
assertStateIsOpen();
excludedPermissions = null;
} finally {
writeLock.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 PolicyContextException {
checkSetPolicyPermission();
readLock.lock();
try {
assertStateIsOpen();
} finally {
readLock.unlock();
}
/*
* If at this point, a simultaneous attempt is made to delete or commit this policy contect,
* we could end up with a corrupted link table.
* Neither event is likely, but we should try to properly serialize those events.
*/
SharedState.link(contextId, 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 PolicyContextException {
checkSetPolicyPermission();
SharedState.removeLinks(contextId);
/*
* Final state will be unlinked and deleted
*/
writeLock.lock();
try {
removePolicy();
} finally {
try {
setState(DELETED_STATE);
} finally {
writeLock.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 PolicyContextException {
checkSetPolicyPermission();
boolean initRoles = false;
writeLock.lock();
try {
if (stateIs(DELETED_STATE)) {
throw new UnsupportedOperationException("pc.invalid_op_for_state_delete");
}
if (stateIs(OPEN_STATE)) {
if (roleTable != null) {
initRoles = true;
}
setState(INSERVICE_STATE);
}
} finally {
writeLock.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 PolicyContextException {
readLock.lock();
try {
return stateIs(INSERVICE_STATE);
} finally {
readLock.unlock();
}
}
// Internal Policy Configuration interfaces start here
protected static SimplePolicyConfiguration getPolicyConfig(String pcid, boolean remove) throws PolicyContextException {
SimplePolicyConfiguration pc = SharedState.getConfig(pcid, remove);
pc.writeLock.lock();
try {
if (remove) {
pc.removePolicy();
}
pc.setState(OPEN_STATE);
} finally {
pc.writeLock.unlock();
}
return pc;
}
protected static boolean inService(String pcid) throws 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)) {
throw new UnsupportedOperationException("Operation invoked on closed or deleted PolicyConfiguration.");
}
}
private void assertStateIsInService() throws UnsupportedOperationException {
if (!stateIs(INSERVICE_STATE)) {
throw new UnsupportedOperationException("Operation invoked on open or deleted PolicyConfiguration.");
}
}
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(HANDLER_KEY);
if (roleMapper == null) {
throw new PolicyContextException("RoleMapper.lookup.null");
}
} catch (Throwable t) {
SharedState.getLogger().log(SEVERE, "RoleMapper.lookup.failed", t);
if (t instanceof PolicyContextException) {
throw (PolicyContextException) t;
} else {
throw new PolicyContextException(t);
}
}
writeLock.lock();
try {
if (roleTable != null) {
for (Role role : roleTable) {
role.setPrincipals(roleMapper.getPrincipalsInRole(contextId, 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 {
writeLock.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 policyConfiguration = SharedState.getActiveConfig();
return policyConfiguration == null ?
basePerms :
policyConfiguration.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 {
readLock.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 {
readLock.unlock();
}
}
private boolean hasExcludedPermissions() {
return excludedPermissions == null || !excludedPermissions.elements().hasMoreElements() ? false : true;
}
private PermissionCollection getPermissions(PermissionCollection basePerms, PermissionCollection domainPerms, Principal[] principals) throws PolicyContextException, UnsupportedOperationException {
readLock.lock();
try {
assertStateIsInService();
Permissions permissions = null;
boolean hasExcludes = hasExcludedPermissions();
if (basePerms != null) {
for (Enumeration e = basePerms.elements(); e.hasMoreElements();) {
Permission permission = e.nextElement();
if (!hasExcludes || !permIsExcluded(permission)) {
if (permissions == null) {
permissions = new Permissions();
}
permissions.add(permission);
}
}
}
if (domainPerms != null) {
for (Enumeration e = domainPerms.elements(); e.hasMoreElements();) {
Permission permission = e.nextElement();
if (!hasExcludes || !permIsExcluded(permission)) {
if (permissions == null) {
permissions = new Permissions();
}
permissions.add(permission);
}
}
}
for (Enumeration e = getUncheckedPermissions().elements(); e.hasMoreElements();) {
Permission permission = e.nextElement();
if (!hasExcludes || !permIsExcluded(permission)) {
if (permissions == null) {
permissions = new Permissions();
}
permissions.add(permission);
}
}
if (principals.length == 0 || roleTable == null) {
return permissions;
}
for (Role role : roleTable) {
if (role.arePrincipalsInRole(principals)) {
PermissionCollection permissionCollection = role.getPermissions();
for (Enumeration e = permissionCollection.elements(); e.hasMoreElements();) {
Permission p = (Permission) e.nextElement();
if (!hasExcludes || !permIsExcluded(p)) {
if (permissions == null) {
permissions = new Permissions();
}
permissions.add(p);
}
}
}
}
return permissions;
} catch (UnsupportedOperationException uso) {
throw new PolicyContextException(uso);
} finally {
readLock.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) {
Logger logger = SharedState.getLogger();
if (logger.isLoggable(level)) {
if (getSecurityManager() == null) {
logger.log(level, msg, params);
} else {
doPrivileged(new PrivilegedAction