All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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() { public Object run() { logger.log(level, msg, params); return null; } }); } } } static void doPrivilegedLog(final Level level, final String msg, final Throwable t) { Logger logger = SharedState.getLogger(); if (logger.isLoggable(level)) { if (getSecurityManager() == null) { logger.log(level, msg, t); } else { 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); } }