/* * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.security; import sun.security.util.Debug; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; /** *
The AccessController class is used for access control operations * and decisions. * *
More specifically, the AccessController class is used for * three purposes: * *
*
*
The {@link #checkPermission(Permission) checkPermission} method * determines whether the access request indicated by a specified * permission should be granted or denied. A sample call appears * below. In this example, {@code checkPermission} will determine * whether or not to grant "read" access to the file named "testFile" in * the "/temp" directory. * *
* * FilePermission perm = new FilePermission("/temp/testFile", "read"); * AccessController.checkPermission(perm); * ** *
If a requested access is allowed, * {@code checkPermission} returns quietly. If denied, an * AccessControlException is * thrown. AccessControlException can also be thrown if the requested * permission is of an incorrect type or contains an invalid value. * Such information is given whenever possible. * * Suppose the current thread traversed m callers, in the order of caller 1 * to caller 2 to caller m. Then caller m invoked the * {@code checkPermission} method. * The {@code checkPermission} method determines whether access * is granted or denied based on the following algorithm: * *
{@code * for (int i = m; i > 0; i--) { * * if (caller i's domain does not have the permission) * throw AccessControlException * * else if (caller i is marked as privileged) { * if (a context was specified in the call to doPrivileged) * context.checkPermission(permission) * if (limited permissions were specified in the call to doPrivileged) { * for (each limited permission) { * if (the limited permission implies the requested permission) * return; * } * } else * return; * } * } * * // Next, check the context inherited when the thread was created. * // Whenever a new thread is created, the AccessControlContext at * // that time is stored and associated with the new thread, as the * // "inherited" context. * * inheritedContext.checkPermission(permission); * }* *
A caller can be marked as being "privileged" * (see {@link #doPrivileged(PrivilegedAction) doPrivileged} and below). * When making access control decisions, the {@code checkPermission} * method stops checking if it reaches a caller that * was marked as "privileged" via a {@code doPrivileged} * call without a context argument (see below for information about a * context argument). If that caller's domain has the * specified permission and at least one limiting permission argument (if any) * implies the requested permission, no further checking is done and * {@code checkPermission} * returns quietly, indicating that the requested access is allowed. * If that domain does not have the specified permission, an exception * is thrown, as usual. If the caller's domain had the specified permission * but it was not implied by any limiting permission arguments given in the call * to {@code doPrivileged} then the permission checking continues * until there are no more callers or another {@code doPrivileged} * call matches the requested permission and returns normally. * *
The normal use of the "privileged" feature is as follows. If you * don't need to return a value from within the "privileged" block, do * the following: * *
{@code * somemethod() { * ...normal code here... * AccessController.doPrivileged(new PrivilegedAction* *() { * public Void run() { * // privileged code goes here, for example: * System.loadLibrary("awt"); * return null; // nothing to return * } * }); * ...normal code here... * }}
* PrivilegedAction is an interface with a single method, named * {@code run}. * The above example shows creation of an implementation * of that interface; a concrete implementation of the * {@code run} method is supplied. * When the call to {@code doPrivileged} is made, an * instance of the PrivilegedAction implementation is passed * to it. The {@code doPrivileged} method calls the * {@code run} method from the PrivilegedAction * implementation after enabling privileges, and returns the * {@code run} method's return value as the * {@code doPrivileged} return value (which is * ignored in this example). * *
If you need to return a value, you can do something like the following: * *
{@code * somemethod() { * ...normal code here... * String user = AccessController.doPrivileged( * new PrivilegedAction* *() { * public String run() { * return System.getProperty("user.name"); * } * }); * ...normal code here... * }}
If the action performed in your {@code run} method could * throw a "checked" exception (those listed in the {@code throws} clause * of a method), then you need to use the * {@code PrivilegedExceptionAction} interface instead of the * {@code PrivilegedAction} interface: * *
{@code * somemethod() throws FileNotFoundException { * ...normal code here... * try { * FileInputStream fis = AccessController.doPrivileged( * new PrivilegedExceptionAction* *() { * public FileInputStream run() throws FileNotFoundException { * return new FileInputStream("someFile"); * } * }); * } catch (PrivilegedActionException e) { * // e.getException() should be an instance of FileNotFoundException, * // as only "checked" exceptions will be "wrapped" in a * // PrivilegedActionException. * throw (FileNotFoundException) e.getException(); * } * ...normal code here... * }}
Be *very* careful in your use of the "privileged" construct, and * always remember to make the privileged code section as small as possible. * You can pass {@code Permission} arguments to further limit the * scope of the "privilege" (see below). * * *
Note that {@code checkPermission} always performs security checks * within the context of the currently executing thread. * Sometimes a security check that should be made within a given context * will actually need to be done from within a * different context (for example, from within a worker thread). * The {@link #getContext() getContext} method and * AccessControlContext class are provided * for this situation. The {@code getContext} method takes a "snapshot" * of the current calling context, and places * it in an AccessControlContext object, which it returns. A sample call is * the following: * *
* * AccessControlContext acc = AccessController.getContext() * ** *
* AccessControlContext itself has a {@code checkPermission} method * that makes access decisions based on the context it encapsulates, * rather than that of the current execution thread. * Code within a different context can thus call that method on the * previously-saved AccessControlContext object. A sample call is the * following: * *
* * acc.checkPermission(permission) * ** *
There are also times where you don't know a priori which permissions * to check the context against. In these cases you can use the * doPrivileged method that takes a context. You can also limit the scope * of the privileged code by passing additional {@code Permission} * parameters. * *
{@code * somemethod() { * AccessController.doPrivileged(new PrivilegedAction*
Passing a limiting {@code Permission} argument of an instance of * {@code AllPermission} is equivalent to calling the equivalent * {@code doPrivileged} method without limiting {@code Permission} * arguments. Passing a zero length array of {@code Permission} disables * the code privileges so that checking always continues beyond the caller of * that {@code doPrivileged} method. * * @see AccessControlContext * * @author Li Gong * @author Roland Schemers */ public final class AccessController { /** * Don't allow anyone to instantiate an AccessController */ private AccessController() { } /** * Performs the specified {@code PrivilegedAction} with privileges * enabled. The action is performed with all of the permissions * possessed by the caller's protection domain. * *
If the action's {@code run} method throws an (unchecked) * exception, it will propagate through this method. * *
Note that any DomainCombiner associated with the current
* AccessControlContext will be ignored while the action is performed.
*
* @param action the action to be performed.
*
* @return the value returned by the action's {@code run} method.
*
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
* @see #doPrivileged(PrivilegedExceptionAction)
* @see #doPrivilegedWithCombiner(PrivilegedAction)
* @see java.security.DomainCombiner
*/
@CallerSensitive
public static native If the action's {@code run} method throws an (unchecked)
* exception, it will propagate through this method.
*
* This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
*
* @param action the action to be performed.
*
* @return the value returned by the action's {@code run} method.
*
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see java.security.DomainCombiner
*
* @since 1.6
*/
@CallerSensitive
public static
* If the action's {@code run} method throws an (unchecked) exception,
* it will propagate through this method.
*
* If a security manager is installed and the {@code AccessControlContext}
* was not created by system code and the caller's {@code ProtectionDomain}
* has not been granted the {@literal "createAccessControlContext"}
* {@link java.security.SecurityPermission}, then the action is performed
* with no permissions.
*
* @param action the action to be performed.
* @param context an access control context
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null}, then no additional restriction is applied.
*
* @return the value returned by the action's {@code run} method.
*
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*/
@CallerSensitive
public static native
* If the action's {@code run} method throws an (unchecked) exception,
* it will propagate through this method.
*
* @param action the action to be performed.
* @param context an access control context
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null},
* then no additional restriction is applied.
* @param perms the {@code Permission} arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's {@code run} method.
*
* @throws NullPointerException if action or perms or any element of
* perms is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*
* @since 1.8
*/
@CallerSensitive
public static
* If the action's {@code run} method throws an (unchecked) exception,
* it will propagate through this method.
*
* This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
*
* @param action the action to be performed.
* @param context an access control context
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null},
* then no additional restriction is applied.
* @param perms the {@code Permission} arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's {@code run} method.
*
* @throws NullPointerException if action or perms or any element of
* perms is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
* @see java.security.DomainCombiner
*
* @since 1.8
*/
@CallerSensitive
public static If the action's {@code run} method throws an unchecked
* exception, it will propagate through this method.
*
* Note that any DomainCombiner associated with the current
* AccessControlContext will be ignored while the action is performed.
*
* @param action the action to be performed
*
* @return the value returned by the action's {@code run} method
*
* @exception PrivilegedActionException if the specified action's
* {@code run} method threw a checked exception
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
* @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
* @see java.security.DomainCombiner
*/
@CallerSensitive
public static native If the action's {@code run} method throws an unchecked
* exception, it will propagate through this method.
*
* This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
*
* @param action the action to be performed.
*
* @return the value returned by the action's {@code run} method
*
* @exception PrivilegedActionException if the specified action's
* {@code run} method threw a checked exception
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
* @see java.security.DomainCombiner
*
* @since 1.6
*/
@CallerSensitive
public static
* If the action's {@code run} method throws an unchecked
* exception, it will propagate through this method.
*
* If a security manager is installed and the {@code AccessControlContext}
* was not created by system code and the caller's {@code ProtectionDomain}
* has not been granted the {@literal "createAccessControlContext"}
* {@link java.security.SecurityPermission}, then the action is performed
* with no permissions.
*
* @param action the action to be performed
* @param context an access control context
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null}, then no additional restriction is applied.
*
* @return the value returned by the action's {@code run} method
*
* @exception PrivilegedActionException if the specified action's
* {@code run} method threw a checked exception
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
*/
@CallerSensitive
public static native
* If the action's {@code run} method throws an (unchecked) exception,
* it will propagate through this method.
*
* @param action the action to be performed.
* @param context an access control context
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null},
* then no additional restriction is applied.
* @param perms the {@code Permission} arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's {@code run} method.
*
* @throws PrivilegedActionException if the specified action's
* {@code run} method threw a checked exception
* @throws NullPointerException if action or perms or any element of
* perms is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
*
* @since 1.8
*/
@CallerSensitive
public static
* If the action's {@code run} method throws an (unchecked) exception,
* it will propagate through this method.
*
* This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
*
* @param action the action to be performed.
* @param context an access control context
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null},
* then no additional restriction is applied.
* @param perms the {@code Permission} arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's {@code run} method.
*
* @throws PrivilegedActionException if the specified action's
* {@code run} method threw a checked exception
* @throws NullPointerException if action or perms or any element of
* perms is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
* @see java.security.DomainCombiner
*
* @since 1.8
*/
@CallerSensitive
public static