65 * AccessControlException is 66 * thrown. AccessControlException can also be thrown if the requested 67 * permission is of an incorrect type or contains an invalid value. 68 * Such information is given whenever possible. 69 * 70 * Suppose the current thread traversed m callers, in the order of caller 1 71 * to caller 2 to caller m. Then caller m invoked the 72 * <code>checkPermission</code> method. 73 * The <code>checkPermission </code>method determines whether access 74 * is granted or denied based on the following algorithm: 75 * 76 * <pre> {@code 77 * for (int i = m; i > 0; i--) { 78 * 79 * if (caller i's domain does not have the permission) 80 * throw AccessControlException 81 * 82 * else if (caller i is marked as privileged) { 83 * if (a context was specified in the call to doPrivileged) 84 * context.checkPermission(permission) 85 * return; 86 * } 87 * }; 88 * 89 * // Next, check the context inherited when the thread was created. 90 * // Whenever a new thread is created, the AccessControlContext at 91 * // that time is stored and associated with the new thread, as the 92 * // "inherited" context. 93 * 94 * inheritedContext.checkPermission(permission); 95 * }</pre> 96 * 97 * <p> A caller can be marked as being "privileged" 98 * (see {@link #doPrivileged(PrivilegedAction) doPrivileged} and below). 99 * When making access control decisions, the <code>checkPermission</code> 100 * method stops checking if it reaches a caller that 101 * was marked as "privileged" via a <code>doPrivileged</code> 102 * call without a context argument (see below for information about a 103 * context argument). If that caller's domain has the 104 * specified permission, no further checking is done and 105 * <code>checkPermission</code> 106 * returns quietly, indicating that the requested access is allowed. 107 * If that domain does not have the specified permission, an exception 108 * is thrown, as usual. 109 * 110 * <p> The normal use of the "privileged" feature is as follows. If you 111 * don't need to return a value from within the "privileged" block, do 112 * the following: 113 * 114 * <pre> {@code 115 * somemethod() { 116 * ...normal code here... 117 * AccessController.doPrivileged(new PrivilegedAction<Void>() { 118 * public Void run() { 119 * // privileged code goes here, for example: 120 * System.loadLibrary("awt"); 121 * return null; // nothing to return 122 * } 123 * }); 124 * ...normal code here... 125 * }}</pre> 126 * 127 * <p> 128 * PrivilegedAction is an interface with a single method, named 163 * somemethod() throws FileNotFoundException { 164 * ...normal code here... 165 * try { 166 * FileInputStream fis = AccessController.doPrivileged( 167 * new PrivilegedExceptionAction<FileInputStream>() { 168 * public FileInputStream run() throws FileNotFoundException { 169 * return new FileInputStream("someFile"); 170 * } 171 * }); 172 * } catch (PrivilegedActionException e) { 173 * // e.getException() should be an instance of FileNotFoundException, 174 * // as only "checked" exceptions will be "wrapped" in a 175 * // PrivilegedActionException. 176 * throw (FileNotFoundException) e.getException(); 177 * } 178 * ...normal code here... 179 * }}</pre> 180 * 181 * <p> Be *very* careful in your use of the "privileged" construct, and 182 * always remember to make the privileged code section as small as possible. 183 * 184 * <p> Note that <code>checkPermission</code> always performs security checks 185 * within the context of the currently executing thread. 186 * Sometimes a security check that should be made within a given context 187 * will actually need to be done from within a 188 * <i>different</i> context (for example, from within a worker thread). 189 * The {@link #getContext() getContext} method and 190 * AccessControlContext class are provided 191 * for this situation. The <code>getContext</code> method takes a "snapshot" 192 * of the current calling context, and places 193 * it in an AccessControlContext object, which it returns. A sample call is 194 * the following: 195 * 196 * <pre> 197 * 198 * AccessControlContext acc = AccessController.getContext() 199 * 200 * </pre> 201 * 202 * <p> 203 * AccessControlContext itself has a <code>checkPermission</code> method 204 * that makes access decisions based on the context <i>it</i> encapsulates, 205 * rather than that of the current execution thread. 206 * Code within a different context can thus call that method on the 207 * previously-saved AccessControlContext object. A sample call is the 208 * following: 209 * 210 * <pre> 211 * 212 * acc.checkPermission(permission) 213 * 214 * </pre> 215 * 216 * <p> There are also times where you don't know a priori which permissions 217 * to check the context against. In these cases you can use the 218 * doPrivileged method that takes a context: 219 * 220 * <pre> {@code 221 * somemethod() { 222 * AccessController.doPrivileged(new PrivilegedAction<Object>() { 223 * public Object run() { 224 * // Code goes here. Any permission checks within this 225 * // run method will require that the intersection of the 226 * // callers protection domain and the snapshot's 227 * // context have the desired permission. 228 * } 229 * }, acc); 230 * ...normal code here... 231 * }}</pre> 232 * 233 * @see AccessControlContext 234 * 235 * @author Li Gong 236 * @author Roland Schemers 237 */ 238 239 public final class AccessController { 240 241 /** 242 * Don't allow anyone to instantiate an AccessController 243 */ 244 private AccessController() { } 245 246 /** 247 * Performs the specified <code>PrivilegedAction</code> with privileges 248 * enabled. The action is performed with <i>all</i> of the permissions 249 * possessed by the caller's protection domain. 250 * 251 * <p> If the action's <code>run</code> method throws an (unchecked) 317 * 318 * @param action the action to be performed. 319 * @param context an <i>access control context</i> 320 * representing the restriction to be applied to the 321 * caller's domain's privileges before performing 322 * the specified action. If the context is 323 * <code>null</code>, 324 * then no additional restriction is applied. 325 * 326 * @return the value returned by the action's <code>run</code> method. 327 * 328 * @exception NullPointerException if the action is <code>null</code> 329 * 330 * @see #doPrivileged(PrivilegedAction) 331 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 332 */ 333 @CallerSensitive 334 public static native <T> T doPrivileged(PrivilegedAction<T> action, 335 AccessControlContext context); 336 337 /** 338 * Performs the specified <code>PrivilegedExceptionAction</code> with 339 * privileges enabled. The action is performed with <i>all</i> of the 340 * permissions possessed by the caller's protection domain. 341 * 342 * <p> If the action's <code>run</code> method throws an <i>unchecked</i> 343 * exception, it will propagate through this method. 344 * 345 * <p> Note that any DomainCombiner associated with the current 346 * AccessControlContext will be ignored while the action is performed. 347 * 348 * @param action the action to be performed 349 * 350 * @return the value returned by the action's <code>run</code> method 351 * 352 * @exception PrivilegedActionException if the specified action's 353 * <code>run</code> method threw a <i>checked</i> exception 354 * @exception NullPointerException if the action is <code>null</code> 355 * 356 * @see #doPrivileged(PrivilegedAction) 357 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 373 * exception, it will propagate through this method. 374 * 375 * <p> This method preserves the current AccessControlContext's 376 * DomainCombiner (which may be null) while the action is performed. 377 * 378 * @param action the action to be performed. 379 * 380 * @return the value returned by the action's <code>run</code> method 381 * 382 * @exception PrivilegedActionException if the specified action's 383 * <code>run</code> method threw a <i>checked</i> exception 384 * @exception NullPointerException if the action is <code>null</code> 385 * 386 * @see #doPrivileged(PrivilegedAction) 387 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 388 * @see java.security.DomainCombiner 389 * 390 * @since 1.6 391 */ 392 @CallerSensitive 393 public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action) 394 throws PrivilegedActionException 395 { 396 AccessControlContext acc = getStackAccessControlContext(); 397 if (acc == null) { 398 return AccessController.doPrivileged(action); 399 } 400 DomainCombiner dc = acc.getAssignedCombiner(); 401 return AccessController.doPrivileged(action, 402 preserveCombiner(dc, Reflection.getCallerClass())); 403 } 404 405 /** 406 * preserve the combiner across the doPrivileged call 407 */ 408 private static AccessControlContext preserveCombiner(DomainCombiner combiner, 409 Class<?> caller) 410 { 411 ProtectionDomain callerPd = doPrivileged 412 (new PrivilegedAction<ProtectionDomain>() { 413 public ProtectionDomain run() { 414 return caller.getProtectionDomain(); 415 } 416 }); 417 418 // perform 'combine' on the caller of doPrivileged, 419 // even if the caller is from the bootclasspath 420 ProtectionDomain[] pds = new ProtectionDomain[] {callerPd}; 421 if (combiner == null) { 422 return new AccessControlContext(pds); 423 } else { 424 return new AccessControlContext(combiner.combine(pds, null), 425 combiner); 426 } 427 } 428 429 430 /** 431 * Performs the specified <code>PrivilegedExceptionAction</code> with 432 * privileges enabled and restricted by the specified 433 * <code>AccessControlContext</code>. The action is performed with the 434 * intersection of the permissions possessed by the caller's 435 * protection domain, and those possessed by the domains represented by the 436 * specified <code>AccessControlContext</code>. 437 * <p> 438 * If the action's <code>run</code> method throws an <i>unchecked</i> 439 * exception, it will propagate through this method. 440 * 441 * @param action the action to be performed 442 * @param context an <i>access control context</i> 443 * representing the restriction to be applied to the 444 * caller's domain's privileges before performing 445 * the specified action. If the context is 446 * <code>null</code>, 447 * then no additional restriction is applied. 448 * 449 * @return the value returned by the action's <code>run</code> method 450 * 451 * @exception PrivilegedActionException if the specified action's 452 * <code>run</code> method 453 * threw a <i>checked</i> exception 454 * @exception NullPointerException if the action is <code>null</code> 455 * 456 * @see #doPrivileged(PrivilegedAction) 457 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 458 */ 459 @CallerSensitive 460 public static native <T> T 461 doPrivileged(PrivilegedExceptionAction<T> action, 462 AccessControlContext context) 463 throws PrivilegedActionException; 464 465 /** 466 * Returns the AccessControl context. i.e., it gets 467 * the protection domains of all the callers on the stack, 468 * starting at the first class with a non-null 469 * ProtectionDomain. 470 * 471 * @return the access control context based on the current stack or 472 * null if there was only privileged system code. 473 */ 474 475 private static native AccessControlContext getStackAccessControlContext(); 476 477 /** 478 * Returns the "inherited" AccessControl context. This is the context 479 * that existed when the thread was created. Package private so 480 * AccessControlContext can use it. 481 */ 482 483 static native AccessControlContext getInheritedAccessControlContext(); 484 485 /** 486 * This method takes a "snapshot" of the current calling context, which 487 * includes the current Thread's inherited AccessControlContext, 488 * and places it in an AccessControlContext object. This context may then 489 * be checked at a later point, possibly in another thread. 490 * 491 * @see AccessControlContext 492 * 493 * @return the AccessControlContext based on the current context. 494 */ 495 496 public static AccessControlContext getContext() 497 { 498 AccessControlContext acc = getStackAccessControlContext(); 499 if (acc == null) { 500 // all we had was privileged system code. We don't want 501 // to return null though, so we construct a real ACC. 502 return new AccessControlContext(null, true); 503 } else { 504 return acc.optimize(); 505 } 506 } 507 508 /** 509 * Determines whether the access request indicated by the | 65 * AccessControlException is 66 * thrown. AccessControlException can also be thrown if the requested 67 * permission is of an incorrect type or contains an invalid value. 68 * Such information is given whenever possible. 69 * 70 * Suppose the current thread traversed m callers, in the order of caller 1 71 * to caller 2 to caller m. Then caller m invoked the 72 * <code>checkPermission</code> method. 73 * The <code>checkPermission </code>method determines whether access 74 * is granted or denied based on the following algorithm: 75 * 76 * <pre> {@code 77 * for (int i = m; i > 0; i--) { 78 * 79 * if (caller i's domain does not have the permission) 80 * throw AccessControlException 81 * 82 * else if (caller i is marked as privileged) { 83 * if (a context was specified in the call to doPrivileged) 84 * context.checkPermission(permission) 85 * if (limited permissions were specified in the call to doPrivileged) { 86 * for (each limited permission) { 87 * if (the limited permission implies the requested permission) 88 * return; 89 * } 90 * } else 91 * return; 92 * } 93 * } 94 * 95 * // Next, check the context inherited when the thread was created. 96 * // Whenever a new thread is created, the AccessControlContext at 97 * // that time is stored and associated with the new thread, as the 98 * // "inherited" context. 99 * 100 * inheritedContext.checkPermission(permission); 101 * }</pre> 102 * 103 * <p> A caller can be marked as being "privileged" 104 * (see {@link #doPrivileged(PrivilegedAction) doPrivileged} and below). 105 * When making access control decisions, the <code>checkPermission</code> 106 * method stops checking if it reaches a caller that 107 * was marked as "privileged" via a <code>doPrivileged</code> 108 * call without a context argument (see below for information about a 109 * context argument). If that caller's domain has the 110 * specified permission and at least one limiting permission argument (if any) 111 * implies the requested permission, no further checking is done and 112 * <code>checkPermission</code> 113 * returns quietly, indicating that the requested access is allowed. 114 * If that domain does not have the specified permission, an exception 115 * is thrown, as usual. If the caller's domain had the specified permission 116 * but it was not implied by any limiting permission arguments given in the call 117 * to <code>doPrivileged</code> then the permission checking continues 118 * until there are no more callers or another <code>doPrivileged</code> 119 * call matches the requested permission and returns normally. 120 * 121 * <p> The normal use of the "privileged" feature is as follows. If you 122 * don't need to return a value from within the "privileged" block, do 123 * the following: 124 * 125 * <pre> {@code 126 * somemethod() { 127 * ...normal code here... 128 * AccessController.doPrivileged(new PrivilegedAction<Void>() { 129 * public Void run() { 130 * // privileged code goes here, for example: 131 * System.loadLibrary("awt"); 132 * return null; // nothing to return 133 * } 134 * }); 135 * ...normal code here... 136 * }}</pre> 137 * 138 * <p> 139 * PrivilegedAction is an interface with a single method, named 174 * somemethod() throws FileNotFoundException { 175 * ...normal code here... 176 * try { 177 * FileInputStream fis = AccessController.doPrivileged( 178 * new PrivilegedExceptionAction<FileInputStream>() { 179 * public FileInputStream run() throws FileNotFoundException { 180 * return new FileInputStream("someFile"); 181 * } 182 * }); 183 * } catch (PrivilegedActionException e) { 184 * // e.getException() should be an instance of FileNotFoundException, 185 * // as only "checked" exceptions will be "wrapped" in a 186 * // PrivilegedActionException. 187 * throw (FileNotFoundException) e.getException(); 188 * } 189 * ...normal code here... 190 * }}</pre> 191 * 192 * <p> Be *very* careful in your use of the "privileged" construct, and 193 * always remember to make the privileged code section as small as possible. 194 * You can pass <code>Permission</code> arguments to further limit the 195 * scope of the "privilege" (see below). 196 * 197 * 198 * <p> Note that <code>checkPermission</code> always performs security checks 199 * within the context of the currently executing thread. 200 * Sometimes a security check that should be made within a given context 201 * will actually need to be done from within a 202 * <i>different</i> context (for example, from within a worker thread). 203 * The {@link #getContext() getContext} method and 204 * AccessControlContext class are provided 205 * for this situation. The <code>getContext</code> method takes a "snapshot" 206 * of the current calling context, and places 207 * it in an AccessControlContext object, which it returns. A sample call is 208 * the following: 209 * 210 * <pre> 211 * 212 * AccessControlContext acc = AccessController.getContext() 213 * 214 * </pre> 215 * 216 * <p> 217 * AccessControlContext itself has a <code>checkPermission</code> method 218 * that makes access decisions based on the context <i>it</i> encapsulates, 219 * rather than that of the current execution thread. 220 * Code within a different context can thus call that method on the 221 * previously-saved AccessControlContext object. A sample call is the 222 * following: 223 * 224 * <pre> 225 * 226 * acc.checkPermission(permission) 227 * 228 * </pre> 229 * 230 * <p> There are also times where you don't know a priori which permissions 231 * to check the context against. In these cases you can use the 232 * doPrivileged method that takes a context. You can also limit the scope 233 * of the privileged code by passing additional <code>Permission</code> 234 * parameters. 235 * 236 * <pre> {@code 237 * somemethod() { 238 * AccessController.doPrivileged(new PrivilegedAction<Object>() { 239 * public Object run() { 240 * // Code goes here. Any permission checks within this 241 * // run method will require that the intersection of the 242 * // caller's protection domain and the snapshot's 243 * // context have the desired permission. If a requested 244 * // permission is not implied by the limiting FilePermission 245 * // argument then checking of the thread continues beyond the 246 * // caller of doPrivileged. 247 * } 248 * }, acc, new FilePermission("/temp/*", read)); 249 * ...normal code here... 250 * }}</pre> 251 * <p> Passing a limiting <code>Permission</code> argument of an instance of 252 * <code>AllPermission</code> is equivalent to calling the equivalent 253 * <code>doPrivileged</code> method without limiting <code>Permission</code> 254 * arguments. Passing a zero length array of <code>Permission</code> disables 255 * the code privileges so that checking always continues beyond the caller of 256 * that <code>doPrivileged</code> method. 257 * 258 * @see AccessControlContext 259 * 260 * @author Li Gong 261 * @author Roland Schemers 262 */ 263 264 public final class AccessController { 265 266 /** 267 * Don't allow anyone to instantiate an AccessController 268 */ 269 private AccessController() { } 270 271 /** 272 * Performs the specified <code>PrivilegedAction</code> with privileges 273 * enabled. The action is performed with <i>all</i> of the permissions 274 * possessed by the caller's protection domain. 275 * 276 * <p> If the action's <code>run</code> method throws an (unchecked) 342 * 343 * @param action the action to be performed. 344 * @param context an <i>access control context</i> 345 * representing the restriction to be applied to the 346 * caller's domain's privileges before performing 347 * the specified action. If the context is 348 * <code>null</code>, 349 * then no additional restriction is applied. 350 * 351 * @return the value returned by the action's <code>run</code> method. 352 * 353 * @exception NullPointerException if the action is <code>null</code> 354 * 355 * @see #doPrivileged(PrivilegedAction) 356 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 357 */ 358 @CallerSensitive 359 public static native <T> T doPrivileged(PrivilegedAction<T> action, 360 AccessControlContext context); 361 362 363 /** 364 * Performs the specified <code>PrivilegedAction</code> with privileges 365 * enabled and restricted by the specified 366 * <code>AccessControlContext</code> and with a privilege scope limited 367 * by specified <code>Permission</code> arguments. 368 * 369 * The action is performed with the intersection of the permissions 370 * possessed by the caller's protection domain, and those possessed 371 * by the domains represented by the specified 372 * <code>AccessControlContext</code>. 373 * <p> 374 * If the action's <code>run</code> method throws an (unchecked) exception, 375 * it will propagate through this method. 376 * 377 * @param action the action to be performed. 378 * @param context an <i>access control context</i> 379 * representing the restriction to be applied to the 380 * caller's domain's privileges before performing 381 * the specified action. If the context is 382 * <code>null</code>, 383 * then no additional restriction is applied. 384 * @param perms the <code>Permission</code> arguments which limit the 385 * scope of the caller's privileges. The number of arguments 386 * is variable. 387 * 388 * @return the value returned by the action's <code>run</code> method. 389 * 390 * @exception NullPointerException if action or perms or any element of 391 * perms is <code>null</code> 392 * 393 * @see #doPrivileged(PrivilegedAction) 394 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 395 * 396 * @since 1.8 397 */ 398 @CallerSensitive 399 public static <T> T doPrivileged(PrivilegedAction<T> action, 400 AccessControlContext context, Permission... perms) { 401 402 AccessControlContext parent = getContext(); 403 if (perms == null) { 404 throw new NullPointerException("null permissions parameter"); 405 } 406 Class <?> caller = Reflection.getCallerClass(); 407 return AccessController.doPrivileged(action, createWrapper(null, 408 caller, context, parent, perms)); 409 } 410 411 412 /** 413 * Performs the specified <code>PrivilegedAction</code> with privileges 414 * enabled and restricted by the specified 415 * <code>AccessControlContext</code> and with a privilege scope limited 416 * by specified <code>Permission</code> arguments. 417 * 418 * The action is performed with the intersection of the permissions 419 * possessed by the caller's protection domain, and those possessed 420 * by the domains represented by the specified 421 * <code>AccessControlContext</code>. 422 * <p> 423 * If the action's <code>run</code> method throws an (unchecked) exception, 424 * it will propagate through this method. 425 * 426 * <p> This method preserves the current AccessControlContext's 427 * DomainCombiner (which may be null) while the action is performed. 428 * 429 * @param action the action to be performed. 430 * @param context an <i>access control context</i> 431 * representing the restriction to be applied to the 432 * caller's domain's privileges before performing 433 * the specified action. If the context is 434 * <code>null</code>, 435 * then no additional restriction is applied. 436 * @param perms the <code>Permission</code> arguments which limit the 437 * scope of the caller's privileges. The number of arguments 438 * is variable. 439 * 440 * @return the value returned by the action's <code>run</code> method. 441 * 442 * @exception NullPointerException if action or perms or any element of 443 * perms is <code>null</code> 444 * 445 * @see #doPrivileged(PrivilegedAction) 446 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 447 * @see java.security.DomainCombiner 448 * 449 * @since 1.8 450 */ 451 @CallerSensitive 452 public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action, 453 AccessControlContext context, Permission... perms) { 454 455 AccessControlContext parent = getContext(); 456 DomainCombiner dc = parent.getCombiner(); 457 if (dc == null && context != null) { 458 dc = context.getCombiner(); 459 } 460 if (perms == null) { 461 throw new NullPointerException("null permissions parameter"); 462 } 463 Class <?> caller = Reflection.getCallerClass(); 464 return AccessController.doPrivileged(action, createWrapper(dc, caller, 465 context, parent, perms)); 466 } 467 468 /** 469 * Performs the specified <code>PrivilegedExceptionAction</code> with 470 * privileges enabled. The action is performed with <i>all</i> of the 471 * permissions possessed by the caller's protection domain. 472 * 473 * <p> If the action's <code>run</code> method throws an <i>unchecked</i> 474 * exception, it will propagate through this method. 475 * 476 * <p> Note that any DomainCombiner associated with the current 477 * AccessControlContext will be ignored while the action is performed. 478 * 479 * @param action the action to be performed 480 * 481 * @return the value returned by the action's <code>run</code> method 482 * 483 * @exception PrivilegedActionException if the specified action's 484 * <code>run</code> method threw a <i>checked</i> exception 485 * @exception NullPointerException if the action is <code>null</code> 486 * 487 * @see #doPrivileged(PrivilegedAction) 488 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 504 * exception, it will propagate through this method. 505 * 506 * <p> This method preserves the current AccessControlContext's 507 * DomainCombiner (which may be null) while the action is performed. 508 * 509 * @param action the action to be performed. 510 * 511 * @return the value returned by the action's <code>run</code> method 512 * 513 * @exception PrivilegedActionException if the specified action's 514 * <code>run</code> method threw a <i>checked</i> exception 515 * @exception NullPointerException if the action is <code>null</code> 516 * 517 * @see #doPrivileged(PrivilegedAction) 518 * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) 519 * @see java.security.DomainCombiner 520 * 521 * @since 1.6 522 */ 523 @CallerSensitive 524 public static <T> T doPrivilegedWithCombiner 525 (PrivilegedExceptionAction<T> action) throws PrivilegedActionException { 526 AccessControlContext acc = getStackAccessControlContext(); 527 if (acc == null) { 528 return AccessController.doPrivileged(action); 529 } 530 DomainCombiner dc = acc.getAssignedCombiner(); 531 return AccessController.doPrivileged(action, 532 preserveCombiner(dc, Reflection.getCallerClass())); 533 } 534 535 /** 536 * preserve the combiner across the doPrivileged call 537 */ 538 private static AccessControlContext preserveCombiner( 539 DomainCombiner combiner, Class<?> caller) { 540 541 return createWrapper(combiner, caller, null, null, null); 542 } 543 544 /** 545 * Create a wrapper to contain the limited privilege scope data. 546 */ 547 private static AccessControlContext 548 createWrapper(DomainCombiner combiner, Class<?> caller, 549 AccessControlContext parent, AccessControlContext context, 550 Permission[] perms) { 551 552 return new AccessControlContext(getCallerPD(caller), combiner, parent, 553 context, perms); 554 } 555 556 private static ProtectionDomain getCallerPD(final Class <?> caller) { 557 ProtectionDomain callerPd = doPrivileged 558 (new PrivilegedAction<ProtectionDomain>() { 559 public ProtectionDomain run() { 560 return caller.getProtectionDomain(); 561 } 562 }); 563 564 return callerPd; 565 } 566 567 /** 568 * Performs the specified <code>PrivilegedExceptionAction</code> with 569 * privileges enabled and restricted by the specified 570 * <code>AccessControlContext</code>. The action is performed with the 571 * intersection of the permissions possessed by the caller's 572 * protection domain, and those possessed by the domains represented by the 573 * specified <code>AccessControlContext</code>. 574 * <p> 575 * If the action's <code>run</code> method throws an <i>unchecked</i> 576 * exception, it will propagate through this method. 577 * 578 * @param action the action to be performed 579 * @param context an <i>access control context</i> 580 * representing the restriction to be applied to the 581 * caller's domain's privileges before performing 582 * the specified action. If the context is 583 * <code>null</code>, 584 * then no additional restriction is applied. 585 * 586 * @return the value returned by the action's <code>run</code> method 587 * 588 * @exception PrivilegedActionException if the specified action's 589 * <code>run</code> method 590 * threw a <i>checked</i> exception 591 * @exception NullPointerException if the action is <code>null</code> 592 * 593 * @see #doPrivileged(PrivilegedAction) 594 * @see #doPrivileged(PrivilegedAction,AccessControlContext) 595 */ 596 @CallerSensitive 597 public static native <T> T 598 doPrivileged(PrivilegedExceptionAction<T> action, 599 AccessControlContext context) 600 throws PrivilegedActionException; 601 602 603 /** 604 * Performs the specified <code>PrivilegedExceptionAction</code> with 605 * privileges enabled and restricted by the specified 606 * <code>AccessControlContext</code> and with a privilege scope limited by 607 * specified <code>Permission</code> arguments. 608 * 609 * The action is performed with the intersection of the permissions 610 * possessed by the caller's protection domain, and those possessed 611 * by the domains represented by the specified 612 * <code>AccessControlContext</code>. 613 * <p> 614 * If the action's <code>run</code> method throws an (unchecked) exception, 615 * it will propagate through this method. 616 * 617 * @param action the action to be performed. 618 * @param context an <i>access control context</i> 619 * representing the restriction to be applied to the 620 * caller's domain's privileges before performing 621 * the specified action. If the context is 622 * <code>null</code>, 623 * then no additional restriction is applied. 624 * @param perms the <code>Permission</code> arguments which limit the 625 * scope of the caller's privileges. The number of arguments 626 * is variable. 627 * 628 * @return the value returned by the action's <code>run</code> method. 629 * 630 * @exception PrivilegedActionException if the specified action's 631 * <code>run</code> method 632 * threw a <i>checked</i> exception 633 * @exception NullPointerException if action or perms or any element of 634 * perms is <code>null</code> 635 * 636 * @see #doPrivileged(PrivilegedAction) 637 * @see #doPrivileged(PrivilegedAction,AccessControlContext) 638 * 639 * @since 1.8 640 */ 641 @CallerSensitive 642 public static <T> T doPrivileged(PrivilegedExceptionAction<T> action, 643 AccessControlContext context, Permission... perms) 644 throws PrivilegedActionException 645 { 646 AccessControlContext parent = getContext(); 647 if (perms == null) { 648 throw new NullPointerException("null permissions parameter"); 649 } 650 Class <?> caller = Reflection.getCallerClass(); 651 return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms)); 652 } 653 654 655 /** 656 * Performs the specified <code>PrivilegedExceptionAction</code> with 657 * privileges enabled and restricted by the specified 658 * <code>AccessControlContext</code> and with a privilege scope limited by 659 * specified <code>Permission</code> arguments. 660 * 661 * The action is performed with the intersection of the permissions 662 * possessed by the caller's protection domain, and those possessed 663 * by the domains represented by the specified 664 * <code>AccessControlContext</code>. 665 * <p> 666 * If the action's <code>run</code> method throws an (unchecked) exception, 667 * it will propagate through this method. 668 * 669 * <p> This method preserves the current AccessControlContext's 670 * DomainCombiner (which may be null) while the action is performed. 671 * 672 * @param action the action to be performed. 673 * @param context an <i>access control context</i> 674 * representing the restriction to be applied to the 675 * caller's domain's privileges before performing 676 * the specified action. If the context is 677 * <code>null</code>, 678 * then no additional restriction is applied. 679 * @param perms the <code>Permission</code> arguments which limit the 680 * scope of the caller's privileges. The number of arguments 681 * is variable. 682 * 683 * @return the value returned by the action's <code>run</code> method. 684 * 685 * @exception PrivilegedActionException if the specified action's 686 * <code>run</code> method 687 * threw a <i>checked</i> exception 688 * @exception NullPointerException if action or perms or any element of 689 * perms is <code>null</code> 690 * 691 * @see #doPrivileged(PrivilegedAction) 692 * @see #doPrivileged(PrivilegedAction,AccessControlContext) 693 * @see java.security.DomainCombiner 694 * 695 * @since 1.8 696 */ 697 @CallerSensitive 698 public static <T> T doPrivilegedWithCombiner( 699 PrivilegedExceptionAction<T> action, AccessControlContext context, 700 Permission... perms) 701 throws PrivilegedActionException 702 { 703 AccessControlContext parent = getContext(); 704 DomainCombiner dc = parent.getCombiner(); 705 if (dc == null && context != null) { 706 dc = context.getCombiner(); 707 } 708 if (perms == null) { 709 throw new NullPointerException("null permissions parameter"); 710 } 711 Class <?> caller = Reflection.getCallerClass(); 712 return AccessController.doPrivileged(action, createWrapper(dc, caller, 713 parent, context, perms)); 714 } 715 716 /** 717 * Returns the AccessControl context. i.e., it gets 718 * the protection domains of all the callers on the stack, 719 * starting at the first class with a non-null 720 * ProtectionDomain. 721 * 722 * @return the access control context based on the current stack or 723 * null if there was only privileged system code. 724 */ 725 726 private static native AccessControlContext getStackAccessControlContext(); 727 728 729 /** 730 * Returns the "inherited" AccessControl context. This is the context 731 * that existed when the thread was created. Package private so 732 * AccessControlContext can use it. 733 */ 734 735 static native AccessControlContext getInheritedAccessControlContext(); 736 737 /** 738 * This method takes a "snapshot" of the current calling context, which 739 * includes the current Thread's inherited AccessControlContext and any 740 * limited privilege scope, and places it in an AccessControlContext object. 741 * This context may then be checked at a later point, possibly in another thread. 742 * 743 * @see AccessControlContext 744 * 745 * @return the AccessControlContext based on the current context. 746 */ 747 748 public static AccessControlContext getContext() 749 { 750 AccessControlContext acc = getStackAccessControlContext(); 751 if (acc == null) { 752 // all we had was privileged system code. We don't want 753 // to return null though, so we construct a real ACC. 754 return new AccessControlContext(null, true); 755 } else { 756 return acc.optimize(); 757 } 758 } 759 760 /** 761 * Determines whether the access request indicated by the |