Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/security/AccessController.java
38829 views
/*1* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.security;2627import sun.security.util.Debug;28import sun.reflect.CallerSensitive;29import sun.reflect.Reflection;3031/**32* <p> The AccessController class is used for access control operations33* and decisions.34*35* <p> More specifically, the AccessController class is used for36* three purposes:37*38* <ul>39* <li> to decide whether an access to a critical system40* resource is to be allowed or denied, based on the security policy41* currently in effect,42* <li>to mark code as being "privileged", thus affecting subsequent43* access determinations, and44* <li>to obtain a "snapshot" of the current calling context so45* access-control decisions from a different context can be made with46* respect to the saved context. </ul>47*48* <p> The {@link #checkPermission(Permission) checkPermission} method49* determines whether the access request indicated by a specified50* permission should be granted or denied. A sample call appears51* below. In this example, {@code checkPermission} will determine52* whether or not to grant "read" access to the file named "testFile" in53* the "/temp" directory.54*55* <pre>56*57* FilePermission perm = new FilePermission("/temp/testFile", "read");58* AccessController.checkPermission(perm);59*60* </pre>61*62* <p> If a requested access is allowed,63* {@code checkPermission} returns quietly. If denied, an64* AccessControlException is65* thrown. AccessControlException can also be thrown if the requested66* permission is of an incorrect type or contains an invalid value.67* Such information is given whenever possible.68*69* Suppose the current thread traversed m callers, in the order of caller 170* to caller 2 to caller m. Then caller m invoked the71* {@code checkPermission} method.72* The {@code checkPermission} method determines whether access73* is granted or denied based on the following algorithm:74*75* <pre> {@code76* for (int i = m; i > 0; i--) {77*78* if (caller i's domain does not have the permission)79* throw AccessControlException80*81* else if (caller i is marked as privileged) {82* if (a context was specified in the call to doPrivileged)83* context.checkPermission(permission)84* if (limited permissions were specified in the call to doPrivileged) {85* for (each limited permission) {86* if (the limited permission implies the requested permission)87* return;88* }89* } else90* return;91* }92* }93*94* // Next, check the context inherited when the thread was created.95* // Whenever a new thread is created, the AccessControlContext at96* // that time is stored and associated with the new thread, as the97* // "inherited" context.98*99* inheritedContext.checkPermission(permission);100* }</pre>101*102* <p> A caller can be marked as being "privileged"103* (see {@link #doPrivileged(PrivilegedAction) doPrivileged} and below).104* When making access control decisions, the {@code checkPermission}105* method stops checking if it reaches a caller that106* was marked as "privileged" via a {@code doPrivileged}107* call without a context argument (see below for information about a108* context argument). If that caller's domain has the109* specified permission and at least one limiting permission argument (if any)110* implies the requested permission, no further checking is done and111* {@code checkPermission}112* returns quietly, indicating that the requested access is allowed.113* If that domain does not have the specified permission, an exception114* is thrown, as usual. If the caller's domain had the specified permission115* but it was not implied by any limiting permission arguments given in the call116* to {@code doPrivileged} then the permission checking continues117* until there are no more callers or another {@code doPrivileged}118* call matches the requested permission and returns normally.119*120* <p> The normal use of the "privileged" feature is as follows. If you121* don't need to return a value from within the "privileged" block, do122* the following:123*124* <pre> {@code125* somemethod() {126* ...normal code here...127* AccessController.doPrivileged(new PrivilegedAction<Void>() {128* public Void run() {129* // privileged code goes here, for example:130* System.loadLibrary("awt");131* return null; // nothing to return132* }133* });134* ...normal code here...135* }}</pre>136*137* <p>138* PrivilegedAction is an interface with a single method, named139* {@code run}.140* The above example shows creation of an implementation141* of that interface; a concrete implementation of the142* {@code run} method is supplied.143* When the call to {@code doPrivileged} is made, an144* instance of the PrivilegedAction implementation is passed145* to it. The {@code doPrivileged} method calls the146* {@code run} method from the PrivilegedAction147* implementation after enabling privileges, and returns the148* {@code run} method's return value as the149* {@code doPrivileged} return value (which is150* ignored in this example).151*152* <p> If you need to return a value, you can do something like the following:153*154* <pre> {@code155* somemethod() {156* ...normal code here...157* String user = AccessController.doPrivileged(158* new PrivilegedAction<String>() {159* public String run() {160* return System.getProperty("user.name");161* }162* });163* ...normal code here...164* }}</pre>165*166* <p>If the action performed in your {@code run} method could167* throw a "checked" exception (those listed in the {@code throws} clause168* of a method), then you need to use the169* {@code PrivilegedExceptionAction} interface instead of the170* {@code PrivilegedAction} interface:171*172* <pre> {@code173* somemethod() throws FileNotFoundException {174* ...normal code here...175* try {176* FileInputStream fis = AccessController.doPrivileged(177* new PrivilegedExceptionAction<FileInputStream>() {178* public FileInputStream run() throws FileNotFoundException {179* return new FileInputStream("someFile");180* }181* });182* } catch (PrivilegedActionException e) {183* // e.getException() should be an instance of FileNotFoundException,184* // as only "checked" exceptions will be "wrapped" in a185* // PrivilegedActionException.186* throw (FileNotFoundException) e.getException();187* }188* ...normal code here...189* }}</pre>190*191* <p> Be *very* careful in your use of the "privileged" construct, and192* always remember to make the privileged code section as small as possible.193* You can pass {@code Permission} arguments to further limit the194* scope of the "privilege" (see below).195*196*197* <p> Note that {@code checkPermission} always performs security checks198* within the context of the currently executing thread.199* Sometimes a security check that should be made within a given context200* will actually need to be done from within a201* <i>different</i> context (for example, from within a worker thread).202* The {@link #getContext() getContext} method and203* AccessControlContext class are provided204* for this situation. The {@code getContext} method takes a "snapshot"205* of the current calling context, and places206* it in an AccessControlContext object, which it returns. A sample call is207* the following:208*209* <pre>210*211* AccessControlContext acc = AccessController.getContext()212*213* </pre>214*215* <p>216* AccessControlContext itself has a {@code checkPermission} method217* that makes access decisions based on the context <i>it</i> encapsulates,218* rather than that of the current execution thread.219* Code within a different context can thus call that method on the220* previously-saved AccessControlContext object. A sample call is the221* following:222*223* <pre>224*225* acc.checkPermission(permission)226*227* </pre>228*229* <p> There are also times where you don't know a priori which permissions230* to check the context against. In these cases you can use the231* doPrivileged method that takes a context. You can also limit the scope232* of the privileged code by passing additional {@code Permission}233* parameters.234*235* <pre> {@code236* somemethod() {237* AccessController.doPrivileged(new PrivilegedAction<Object>() {238* public Object run() {239* // Code goes here. Any permission checks within this240* // run method will require that the intersection of the241* // caller's protection domain and the snapshot's242* // context have the desired permission. If a requested243* // permission is not implied by the limiting FilePermission244* // argument then checking of the thread continues beyond the245* // caller of doPrivileged.246* }247* }, acc, new FilePermission("/temp/*", read));248* ...normal code here...249* }}</pre>250* <p> Passing a limiting {@code Permission} argument of an instance of251* {@code AllPermission} is equivalent to calling the equivalent252* {@code doPrivileged} method without limiting {@code Permission}253* arguments. Passing a zero length array of {@code Permission} disables254* the code privileges so that checking always continues beyond the caller of255* that {@code doPrivileged} method.256*257* @see AccessControlContext258*259* @author Li Gong260* @author Roland Schemers261*/262263public final class AccessController {264265/**266* Don't allow anyone to instantiate an AccessController267*/268private AccessController() { }269270/**271* Performs the specified {@code PrivilegedAction} with privileges272* enabled. The action is performed with <i>all</i> of the permissions273* possessed by the caller's protection domain.274*275* <p> If the action's {@code run} method throws an (unchecked)276* exception, it will propagate through this method.277*278* <p> Note that any DomainCombiner associated with the current279* AccessControlContext will be ignored while the action is performed.280*281* @param <T> the type of the value returned by the PrivilegedAction's282* {@code run} method.283*284* @param action the action to be performed.285*286* @return the value returned by the action's {@code run} method.287*288* @exception NullPointerException if the action is {@code null}289*290* @see #doPrivileged(PrivilegedAction,AccessControlContext)291* @see #doPrivileged(PrivilegedExceptionAction)292* @see #doPrivilegedWithCombiner(PrivilegedAction)293* @see java.security.DomainCombiner294*/295296@CallerSensitive297public static native <T> T doPrivileged(PrivilegedAction<T> action);298299/**300* Performs the specified {@code PrivilegedAction} with privileges301* enabled. The action is performed with <i>all</i> of the permissions302* possessed by the caller's protection domain.303*304* <p> If the action's {@code run} method throws an (unchecked)305* exception, it will propagate through this method.306*307* <p> This method preserves the current AccessControlContext's308* DomainCombiner (which may be null) while the action is performed.309*310* @param <T> the type of the value returned by the PrivilegedAction's311* {@code run} method.312*313* @param action the action to be performed.314*315* @return the value returned by the action's {@code run} method.316*317* @exception NullPointerException if the action is {@code null}318*319* @see #doPrivileged(PrivilegedAction)320* @see java.security.DomainCombiner321*322* @since 1.6323*/324@CallerSensitive325public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {326AccessControlContext acc = getStackAccessControlContext();327if (acc == null) {328return AccessController.doPrivileged(action);329}330DomainCombiner dc = acc.getAssignedCombiner();331return AccessController.doPrivileged(action,332preserveCombiner(dc, Reflection.getCallerClass()));333}334335336/**337* Performs the specified {@code PrivilegedAction} with privileges338* enabled and restricted by the specified {@code AccessControlContext}.339* The action is performed with the intersection of the permissions340* possessed by the caller's protection domain, and those possessed341* by the domains represented by the specified {@code AccessControlContext}.342* <p>343* If the action's {@code run} method throws an (unchecked) exception,344* it will propagate through this method.345* <p>346* If a security manager is installed and the specified347* {@code AccessControlContext} was not created by system code and the348* caller's {@code ProtectionDomain} has not been granted the349* {@literal "createAccessControlContext"}350* {@link java.security.SecurityPermission}, then the action is performed351* with no permissions.352*353* @param <T> the type of the value returned by the PrivilegedAction's354* {@code run} method.355* @param action the action to be performed.356* @param context an <i>access control context</i>357* representing the restriction to be applied to the358* caller's domain's privileges before performing359* the specified action. If the context is360* {@code null}, then no additional restriction is applied.361*362* @return the value returned by the action's {@code run} method.363*364* @exception NullPointerException if the action is {@code null}365*366* @see #doPrivileged(PrivilegedAction)367* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)368*/369@CallerSensitive370public static native <T> T doPrivileged(PrivilegedAction<T> action,371AccessControlContext context);372373374/**375* Performs the specified {@code PrivilegedAction} with privileges376* enabled and restricted by the specified377* {@code AccessControlContext} and with a privilege scope limited378* by specified {@code Permission} arguments.379*380* The action is performed with the intersection of the permissions381* possessed by the caller's protection domain, and those possessed382* by the domains represented by the specified383* {@code AccessControlContext}.384* <p>385* If the action's {@code run} method throws an (unchecked) exception,386* it will propagate through this method.387* <p>388* If a security manager is installed and the specified389* {@code AccessControlContext} was not created by system code and the390* caller's {@code ProtectionDomain} has not been granted the391* {@literal "createAccessControlContext"}392* {@link java.security.SecurityPermission}, then the action is performed393* with no permissions.394*395* @param <T> the type of the value returned by the PrivilegedAction's396* {@code run} method.397* @param action the action to be performed.398* @param context an <i>access control context</i>399* representing the restriction to be applied to the400* caller's domain's privileges before performing401* the specified action. If the context is402* {@code null},403* then no additional restriction is applied.404* @param perms the {@code Permission} arguments which limit the405* scope of the caller's privileges. The number of arguments406* is variable.407*408* @return the value returned by the action's {@code run} method.409*410* @throws NullPointerException if action or perms or any element of411* perms is {@code null}412*413* @see #doPrivileged(PrivilegedAction)414* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)415*416* @since 1.8417*/418@CallerSensitive419public static <T> T doPrivileged(PrivilegedAction<T> action,420AccessControlContext context, Permission... perms) {421422AccessControlContext parent = getContext();423if (perms == null) {424throw new NullPointerException("null permissions parameter");425}426Class <?> caller = Reflection.getCallerClass();427DomainCombiner dc = (context == null) ? null : context.getCombiner();428return AccessController.doPrivileged(action, createWrapper(dc,429caller, parent, context, perms));430}431432433/**434* Performs the specified {@code PrivilegedAction} with privileges435* enabled and restricted by the specified436* {@code AccessControlContext} and with a privilege scope limited437* by specified {@code Permission} arguments.438*439* The action is performed with the intersection of the permissions440* possessed by the caller's protection domain, and those possessed441* by the domains represented by the specified442* {@code AccessControlContext}.443* <p>444* If the action's {@code run} method throws an (unchecked) exception,445* it will propagate through this method.446*447* <p> This method preserves the current AccessControlContext's448* DomainCombiner (which may be null) while the action is performed.449* <p>450* If a security manager is installed and the specified451* {@code AccessControlContext} was not created by system code and the452* caller's {@code ProtectionDomain} has not been granted the453* {@literal "createAccessControlContext"}454* {@link java.security.SecurityPermission}, then the action is performed455* with no permissions.456*457* @param <T> the type of the value returned by the PrivilegedAction's458* {@code run} method.459* @param action the action to be performed.460* @param context an <i>access control context</i>461* representing the restriction to be applied to the462* caller's domain's privileges before performing463* the specified action. If the context is464* {@code null},465* then no additional restriction is applied.466* @param perms the {@code Permission} arguments which limit the467* scope of the caller's privileges. The number of arguments468* is variable.469*470* @return the value returned by the action's {@code run} method.471*472* @throws NullPointerException if action or perms or any element of473* perms is {@code null}474*475* @see #doPrivileged(PrivilegedAction)476* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)477* @see java.security.DomainCombiner478*479* @since 1.8480*/481@CallerSensitive482public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action,483AccessControlContext context, Permission... perms) {484485AccessControlContext parent = getContext();486DomainCombiner dc = parent.getCombiner();487if (dc == null && context != null) {488dc = context.getCombiner();489}490if (perms == null) {491throw new NullPointerException("null permissions parameter");492}493Class <?> caller = Reflection.getCallerClass();494return AccessController.doPrivileged(action, createWrapper(dc, caller,495parent, context, perms));496}497498/**499* Performs the specified {@code PrivilegedExceptionAction} with500* privileges enabled. The action is performed with <i>all</i> of the501* permissions possessed by the caller's protection domain.502*503* <p> If the action's {@code run} method throws an <i>unchecked</i>504* exception, it will propagate through this method.505*506* <p> Note that any DomainCombiner associated with the current507* AccessControlContext will be ignored while the action is performed.508*509* @param <T> the type of the value returned by the510* PrivilegedExceptionAction's {@code run} method.511*512* @param action the action to be performed513*514* @return the value returned by the action's {@code run} method515*516* @exception PrivilegedActionException if the specified action's517* {@code run} method threw a <i>checked</i> exception518* @exception NullPointerException if the action is {@code null}519*520* @see #doPrivileged(PrivilegedAction)521* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)522* @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)523* @see java.security.DomainCombiner524*/525@CallerSensitive526public static native <T> T527doPrivileged(PrivilegedExceptionAction<T> action)528throws PrivilegedActionException;529530531/**532* Performs the specified {@code PrivilegedExceptionAction} with533* privileges enabled. The action is performed with <i>all</i> of the534* permissions possessed by the caller's protection domain.535*536* <p> If the action's {@code run} method throws an <i>unchecked</i>537* exception, it will propagate through this method.538*539* <p> This method preserves the current AccessControlContext's540* DomainCombiner (which may be null) while the action is performed.541*542* @param <T> the type of the value returned by the543* PrivilegedExceptionAction's {@code run} method.544*545* @param action the action to be performed.546*547* @return the value returned by the action's {@code run} method548*549* @exception PrivilegedActionException if the specified action's550* {@code run} method threw a <i>checked</i> exception551* @exception NullPointerException if the action is {@code null}552*553* @see #doPrivileged(PrivilegedAction)554* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)555* @see java.security.DomainCombiner556*557* @since 1.6558*/559@CallerSensitive560public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action)561throws PrivilegedActionException562{563AccessControlContext acc = getStackAccessControlContext();564if (acc == null) {565return AccessController.doPrivileged(action);566}567DomainCombiner dc = acc.getAssignedCombiner();568return AccessController.doPrivileged(action,569preserveCombiner(dc, Reflection.getCallerClass()));570}571572/**573* preserve the combiner across the doPrivileged call574*/575private static AccessControlContext preserveCombiner(DomainCombiner combiner,576Class<?> caller)577{578return createWrapper(combiner, caller, null, null, null);579}580581/**582* Create a wrapper to contain the limited privilege scope data.583*/584private static AccessControlContext585createWrapper(DomainCombiner combiner, Class<?> caller,586AccessControlContext parent, AccessControlContext context,587Permission[] perms)588{589ProtectionDomain callerPD = getCallerPD(caller);590// check if caller is authorized to create context591if (context != null && !context.isAuthorized() &&592System.getSecurityManager() != null &&593!callerPD.impliesCreateAccessControlContext())594{595ProtectionDomain nullPD = new ProtectionDomain(null, null);596return new AccessControlContext(new ProtectionDomain[] { nullPD });597} else {598return new AccessControlContext(callerPD, combiner, parent,599context, perms);600}601}602603private static ProtectionDomain getCallerPD(final Class <?> caller) {604ProtectionDomain callerPd = doPrivileged605(new PrivilegedAction<ProtectionDomain>() {606public ProtectionDomain run() {607return caller.getProtectionDomain();608}609});610611return callerPd;612}613614/**615* Performs the specified {@code PrivilegedExceptionAction} with616* privileges enabled and restricted by the specified617* {@code AccessControlContext}. The action is performed with the618* intersection of the permissions possessed by the caller's619* protection domain, and those possessed by the domains represented by the620* specified {@code AccessControlContext}.621* <p>622* If the action's {@code run} method throws an <i>unchecked</i>623* exception, it will propagate through this method.624* <p>625* If a security manager is installed and the specified626* {@code AccessControlContext} was not created by system code and the627* caller's {@code ProtectionDomain} has not been granted the628* {@literal "createAccessControlContext"}629* {@link java.security.SecurityPermission}, then the action is performed630* with no permissions.631*632* @param <T> the type of the value returned by the633* PrivilegedExceptionAction's {@code run} method.634* @param action the action to be performed635* @param context an <i>access control context</i>636* representing the restriction to be applied to the637* caller's domain's privileges before performing638* the specified action. If the context is639* {@code null}, then no additional restriction is applied.640*641* @return the value returned by the action's {@code run} method642*643* @exception PrivilegedActionException if the specified action's644* {@code run} method threw a <i>checked</i> exception645* @exception NullPointerException if the action is {@code null}646*647* @see #doPrivileged(PrivilegedAction)648* @see #doPrivileged(PrivilegedAction,AccessControlContext)649*/650@CallerSensitive651public static native <T> T652doPrivileged(PrivilegedExceptionAction<T> action,653AccessControlContext context)654throws PrivilegedActionException;655656657/**658* Performs the specified {@code PrivilegedExceptionAction} with659* privileges enabled and restricted by the specified660* {@code AccessControlContext} and with a privilege scope limited by661* specified {@code Permission} arguments.662*663* The action is performed with the intersection of the permissions664* possessed by the caller's protection domain, and those possessed665* by the domains represented by the specified666* {@code AccessControlContext}.667* <p>668* If the action's {@code run} method throws an (unchecked) exception,669* it will propagate through this method.670* <p>671* If a security manager is installed and the specified672* {@code AccessControlContext} was not created by system code and the673* caller's {@code ProtectionDomain} has not been granted the674* {@literal "createAccessControlContext"}675* {@link java.security.SecurityPermission}, then the action is performed676* with no permissions.677*678* @param <T> the type of the value returned by the679* PrivilegedExceptionAction's {@code run} method.680* @param action the action to be performed.681* @param context an <i>access control context</i>682* representing the restriction to be applied to the683* caller's domain's privileges before performing684* the specified action. If the context is685* {@code null},686* then no additional restriction is applied.687* @param perms the {@code Permission} arguments which limit the688* scope of the caller's privileges. The number of arguments689* is variable.690*691* @return the value returned by the action's {@code run} method.692*693* @throws PrivilegedActionException if the specified action's694* {@code run} method threw a <i>checked</i> exception695* @throws NullPointerException if action or perms or any element of696* perms is {@code null}697*698* @see #doPrivileged(PrivilegedAction)699* @see #doPrivileged(PrivilegedAction,AccessControlContext)700*701* @since 1.8702*/703@CallerSensitive704public static <T> T doPrivileged(PrivilegedExceptionAction<T> action,705AccessControlContext context, Permission... perms)706throws PrivilegedActionException707{708AccessControlContext parent = getContext();709if (perms == null) {710throw new NullPointerException("null permissions parameter");711}712Class <?> caller = Reflection.getCallerClass();713DomainCombiner dc = (context == null) ? null : context.getCombiner();714return AccessController.doPrivileged(action, createWrapper(dc, caller, parent, context, perms));715}716717718/**719* Performs the specified {@code PrivilegedExceptionAction} with720* privileges enabled and restricted by the specified721* {@code AccessControlContext} and with a privilege scope limited by722* specified {@code Permission} arguments.723*724* The action is performed with the intersection of the permissions725* possessed by the caller's protection domain, and those possessed726* by the domains represented by the specified727* {@code AccessControlContext}.728* <p>729* If the action's {@code run} method throws an (unchecked) exception,730* it will propagate through this method.731*732* <p> This method preserves the current AccessControlContext's733* DomainCombiner (which may be null) while the action is performed.734* <p>735* If a security manager is installed and the specified736* {@code AccessControlContext} was not created by system code and the737* caller's {@code ProtectionDomain} has not been granted the738* {@literal "createAccessControlContext"}739* {@link java.security.SecurityPermission}, then the action is performed740* with no permissions.741*742* @param <T> the type of the value returned by the743* PrivilegedExceptionAction's {@code run} method.744* @param action the action to be performed.745* @param context an <i>access control context</i>746* representing the restriction to be applied to the747* caller's domain's privileges before performing748* the specified action. If the context is749* {@code null},750* then no additional restriction is applied.751* @param perms the {@code Permission} arguments which limit the752* scope of the caller's privileges. The number of arguments753* is variable.754*755* @return the value returned by the action's {@code run} method.756*757* @throws PrivilegedActionException if the specified action's758* {@code run} method threw a <i>checked</i> exception759* @throws NullPointerException if action or perms or any element of760* perms is {@code null}761*762* @see #doPrivileged(PrivilegedAction)763* @see #doPrivileged(PrivilegedAction,AccessControlContext)764* @see java.security.DomainCombiner765*766* @since 1.8767*/768@CallerSensitive769public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action,770AccessControlContext context,771Permission... perms)772throws PrivilegedActionException773{774AccessControlContext parent = getContext();775DomainCombiner dc = parent.getCombiner();776if (dc == null && context != null) {777dc = context.getCombiner();778}779if (perms == null) {780throw new NullPointerException("null permissions parameter");781}782Class <?> caller = Reflection.getCallerClass();783return AccessController.doPrivileged(action, createWrapper(dc, caller,784parent, context, perms));785}786787/**788* Returns the AccessControl context. i.e., it gets789* the protection domains of all the callers on the stack,790* starting at the first class with a non-null791* ProtectionDomain.792*793* @return the access control context based on the current stack or794* null if there was only privileged system code.795*/796797private static native AccessControlContext getStackAccessControlContext();798799800/**801* Returns the "inherited" AccessControl context. This is the context802* that existed when the thread was created. Package private so803* AccessControlContext can use it.804*/805806static native AccessControlContext getInheritedAccessControlContext();807808/**809* This method takes a "snapshot" of the current calling context, which810* includes the current Thread's inherited AccessControlContext and any811* limited privilege scope, and places it in an AccessControlContext object.812* This context may then be checked at a later point, possibly in another thread.813*814* @see AccessControlContext815*816* @return the AccessControlContext based on the current context.817*/818819public static AccessControlContext getContext()820{821AccessControlContext acc = getStackAccessControlContext();822if (acc == null) {823// all we had was privileged system code. We don't want824// to return null though, so we construct a real ACC.825return new AccessControlContext(null, true);826} else {827return acc.optimize();828}829}830831/**832* Determines whether the access request indicated by the833* specified permission should be allowed or denied, based on834* the current AccessControlContext and security policy.835* This method quietly returns if the access request836* is permitted, or throws an AccessControlException otherwise. The837* getPermission method of the AccessControlException returns the838* {@code perm} Permission object instance.839*840* @param perm the requested permission.841*842* @exception AccessControlException if the specified permission843* is not permitted, based on the current security policy.844* @exception NullPointerException if the specified permission845* is {@code null} and is checked based on the846* security policy currently in effect.847*/848849public static void checkPermission(Permission perm)850throws AccessControlException851{852//System.err.println("checkPermission "+perm);853//Thread.currentThread().dumpStack();854855if (perm == null) {856throw new NullPointerException("permission can't be null");857}858859AccessControlContext stack = getStackAccessControlContext();860// if context is null, we had privileged system code on the stack.861if (stack == null) {862Debug debug = AccessControlContext.getDebug();863boolean dumpDebug = false;864if (debug != null) {865dumpDebug = !Debug.isOn("codebase=");866dumpDebug &= !Debug.isOn("permission=") ||867Debug.isOn("permission=" + perm.getClass().getCanonicalName());868}869870if (dumpDebug && Debug.isOn("stack")) {871Thread.dumpStack();872}873874if (dumpDebug && Debug.isOn("domain")) {875debug.println("domain (context is null)");876}877878if (dumpDebug) {879debug.println("access allowed "+perm);880}881return;882}883884AccessControlContext acc = stack.optimize();885acc.checkPermission(perm);886}887}888889890