Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/security/AccessController.java
38829 views
1
/*
2
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package java.security;
27
28
import sun.security.util.Debug;
29
import sun.reflect.CallerSensitive;
30
import sun.reflect.Reflection;
31
32
/**
33
* <p> The AccessController class is used for access control operations
34
* and decisions.
35
*
36
* <p> More specifically, the AccessController class is used for
37
* three purposes:
38
*
39
* <ul>
40
* <li> to decide whether an access to a critical system
41
* resource is to be allowed or denied, based on the security policy
42
* currently in effect,
43
* <li>to mark code as being "privileged", thus affecting subsequent
44
* access determinations, and
45
* <li>to obtain a "snapshot" of the current calling context so
46
* access-control decisions from a different context can be made with
47
* respect to the saved context. </ul>
48
*
49
* <p> The {@link #checkPermission(Permission) checkPermission} method
50
* determines whether the access request indicated by a specified
51
* permission should be granted or denied. A sample call appears
52
* below. In this example, {@code checkPermission} will determine
53
* whether or not to grant "read" access to the file named "testFile" in
54
* the "/temp" directory.
55
*
56
* <pre>
57
*
58
* FilePermission perm = new FilePermission("/temp/testFile", "read");
59
* AccessController.checkPermission(perm);
60
*
61
* </pre>
62
*
63
* <p> If a requested access is allowed,
64
* {@code checkPermission} returns quietly. If denied, an
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} method.
73
* The {@code checkPermission} 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}
106
* method stops checking if it reaches a caller that
107
* was marked as "privileged" via a {@code doPrivileged}
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}
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} then the permission checking continues
118
* until there are no more callers or another {@code doPrivileged}
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
140
* {@code run}.
141
* The above example shows creation of an implementation
142
* of that interface; a concrete implementation of the
143
* {@code run} method is supplied.
144
* When the call to {@code doPrivileged} is made, an
145
* instance of the PrivilegedAction implementation is passed
146
* to it. The {@code doPrivileged} method calls the
147
* {@code run} method from the PrivilegedAction
148
* implementation after enabling privileges, and returns the
149
* {@code run} method's return value as the
150
* {@code doPrivileged} return value (which is
151
* ignored in this example).
152
*
153
* <p> If you need to return a value, you can do something like the following:
154
*
155
* <pre> {@code
156
* somemethod() {
157
* ...normal code here...
158
* String user = AccessController.doPrivileged(
159
* new PrivilegedAction<String>() {
160
* public String run() {
161
* return System.getProperty("user.name");
162
* }
163
* });
164
* ...normal code here...
165
* }}</pre>
166
*
167
* <p>If the action performed in your {@code run} method could
168
* throw a "checked" exception (those listed in the {@code throws} clause
169
* of a method), then you need to use the
170
* {@code PrivilegedExceptionAction} interface instead of the
171
* {@code PrivilegedAction} interface:
172
*
173
* <pre> {@code
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} arguments to further limit the
195
* scope of the "privilege" (see below).
196
*
197
*
198
* <p> Note that {@code checkPermission} 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} 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} 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}
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} argument of an instance of
252
* {@code AllPermission} is equivalent to calling the equivalent
253
* {@code doPrivileged} method without limiting {@code Permission}
254
* arguments. Passing a zero length array of {@code Permission} disables
255
* the code privileges so that checking always continues beyond the caller of
256
* that {@code doPrivileged} 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} 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} method throws an (unchecked)
277
* exception, it will propagate through this method.
278
*
279
* <p> Note that any DomainCombiner associated with the current
280
* AccessControlContext will be ignored while the action is performed.
281
*
282
* @param <T> the type of the value returned by the PrivilegedAction's
283
* {@code run} method.
284
*
285
* @param action the action to be performed.
286
*
287
* @return the value returned by the action's {@code run} method.
288
*
289
* @exception NullPointerException if the action is {@code null}
290
*
291
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
292
* @see #doPrivileged(PrivilegedExceptionAction)
293
* @see #doPrivilegedWithCombiner(PrivilegedAction)
294
* @see java.security.DomainCombiner
295
*/
296
297
@CallerSensitive
298
public static native <T> T doPrivileged(PrivilegedAction<T> action);
299
300
/**
301
* Performs the specified {@code PrivilegedAction} with privileges
302
* enabled. The action is performed with <i>all</i> of the permissions
303
* possessed by the caller's protection domain.
304
*
305
* <p> If the action's {@code run} method throws an (unchecked)
306
* exception, it will propagate through this method.
307
*
308
* <p> This method preserves the current AccessControlContext's
309
* DomainCombiner (which may be null) while the action is performed.
310
*
311
* @param <T> the type of the value returned by the PrivilegedAction's
312
* {@code run} method.
313
*
314
* @param action the action to be performed.
315
*
316
* @return the value returned by the action's {@code run} method.
317
*
318
* @exception NullPointerException if the action is {@code null}
319
*
320
* @see #doPrivileged(PrivilegedAction)
321
* @see java.security.DomainCombiner
322
*
323
* @since 1.6
324
*/
325
@CallerSensitive
326
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {
327
AccessControlContext acc = getStackAccessControlContext();
328
if (acc == null) {
329
return AccessController.doPrivileged(action);
330
}
331
DomainCombiner dc = acc.getAssignedCombiner();
332
return AccessController.doPrivileged(action,
333
preserveCombiner(dc, Reflection.getCallerClass()));
334
}
335
336
337
/**
338
* Performs the specified {@code PrivilegedAction} with privileges
339
* enabled and restricted by the specified {@code AccessControlContext}.
340
* The action is performed with the intersection of the permissions
341
* possessed by the caller's protection domain, and those possessed
342
* by the domains represented by the specified {@code AccessControlContext}.
343
* <p>
344
* If the action's {@code run} method throws an (unchecked) exception,
345
* it will propagate through this method.
346
* <p>
347
* If a security manager is installed and the specified
348
* {@code AccessControlContext} was not created by system code and the
349
* caller's {@code ProtectionDomain} has not been granted the
350
* {@literal "createAccessControlContext"}
351
* {@link java.security.SecurityPermission}, then the action is performed
352
* with no permissions.
353
*
354
* @param <T> the type of the value returned by the PrivilegedAction's
355
* {@code run} method.
356
* @param action the action to be performed.
357
* @param context an <i>access control context</i>
358
* representing the restriction to be applied to the
359
* caller's domain's privileges before performing
360
* the specified action. If the context is
361
* {@code null}, then no additional restriction is applied.
362
*
363
* @return the value returned by the action's {@code run} method.
364
*
365
* @exception NullPointerException if the action is {@code null}
366
*
367
* @see #doPrivileged(PrivilegedAction)
368
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
369
*/
370
@CallerSensitive
371
public static native <T> T doPrivileged(PrivilegedAction<T> action,
372
AccessControlContext context);
373
374
375
/**
376
* Performs the specified {@code PrivilegedAction} with privileges
377
* enabled and restricted by the specified
378
* {@code AccessControlContext} and with a privilege scope limited
379
* by specified {@code Permission} arguments.
380
*
381
* The action is performed with the intersection of the permissions
382
* possessed by the caller's protection domain, and those possessed
383
* by the domains represented by the specified
384
* {@code AccessControlContext}.
385
* <p>
386
* If the action's {@code run} method throws an (unchecked) exception,
387
* it will propagate through this method.
388
* <p>
389
* If a security manager is installed and the specified
390
* {@code AccessControlContext} was not created by system code and the
391
* caller's {@code ProtectionDomain} has not been granted the
392
* {@literal "createAccessControlContext"}
393
* {@link java.security.SecurityPermission}, then the action is performed
394
* with no permissions.
395
*
396
* @param <T> the type of the value returned by the PrivilegedAction's
397
* {@code run} method.
398
* @param action the action to be performed.
399
* @param context an <i>access control context</i>
400
* representing the restriction to be applied to the
401
* caller's domain's privileges before performing
402
* the specified action. If the context is
403
* {@code null},
404
* then no additional restriction is applied.
405
* @param perms the {@code Permission} arguments which limit the
406
* scope of the caller's privileges. The number of arguments
407
* is variable.
408
*
409
* @return the value returned by the action's {@code run} method.
410
*
411
* @throws NullPointerException if action or perms or any element of
412
* perms is {@code null}
413
*
414
* @see #doPrivileged(PrivilegedAction)
415
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
416
*
417
* @since 1.8
418
*/
419
@CallerSensitive
420
public static <T> T doPrivileged(PrivilegedAction<T> action,
421
AccessControlContext context, Permission... perms) {
422
423
AccessControlContext parent = getContext();
424
if (perms == null) {
425
throw new NullPointerException("null permissions parameter");
426
}
427
Class <?> caller = Reflection.getCallerClass();
428
DomainCombiner dc = (context == null) ? null : context.getCombiner();
429
return AccessController.doPrivileged(action, createWrapper(dc,
430
caller, parent, context, perms));
431
}
432
433
434
/**
435
* Performs the specified {@code PrivilegedAction} with privileges
436
* enabled and restricted by the specified
437
* {@code AccessControlContext} and with a privilege scope limited
438
* by specified {@code Permission} arguments.
439
*
440
* The action is performed with the intersection of the permissions
441
* possessed by the caller's protection domain, and those possessed
442
* by the domains represented by the specified
443
* {@code AccessControlContext}.
444
* <p>
445
* If the action's {@code run} method throws an (unchecked) exception,
446
* it will propagate through this method.
447
*
448
* <p> This method preserves the current AccessControlContext's
449
* DomainCombiner (which may be null) while the action is performed.
450
* <p>
451
* If a security manager is installed and the specified
452
* {@code AccessControlContext} was not created by system code and the
453
* caller's {@code ProtectionDomain} has not been granted the
454
* {@literal "createAccessControlContext"}
455
* {@link java.security.SecurityPermission}, then the action is performed
456
* with no permissions.
457
*
458
* @param <T> the type of the value returned by the PrivilegedAction's
459
* {@code run} method.
460
* @param action the action to be performed.
461
* @param context an <i>access control context</i>
462
* representing the restriction to be applied to the
463
* caller's domain's privileges before performing
464
* the specified action. If the context is
465
* {@code null},
466
* then no additional restriction is applied.
467
* @param perms the {@code Permission} arguments which limit the
468
* scope of the caller's privileges. The number of arguments
469
* is variable.
470
*
471
* @return the value returned by the action's {@code run} method.
472
*
473
* @throws NullPointerException if action or perms or any element of
474
* perms is {@code null}
475
*
476
* @see #doPrivileged(PrivilegedAction)
477
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
478
* @see java.security.DomainCombiner
479
*
480
* @since 1.8
481
*/
482
@CallerSensitive
483
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action,
484
AccessControlContext context, Permission... perms) {
485
486
AccessControlContext parent = getContext();
487
DomainCombiner dc = parent.getCombiner();
488
if (dc == null && context != null) {
489
dc = context.getCombiner();
490
}
491
if (perms == null) {
492
throw new NullPointerException("null permissions parameter");
493
}
494
Class <?> caller = Reflection.getCallerClass();
495
return AccessController.doPrivileged(action, createWrapper(dc, caller,
496
parent, context, perms));
497
}
498
499
/**
500
* Performs the specified {@code PrivilegedExceptionAction} with
501
* privileges enabled. The action is performed with <i>all</i> of the
502
* permissions possessed by the caller's protection domain.
503
*
504
* <p> If the action's {@code run} method throws an <i>unchecked</i>
505
* exception, it will propagate through this method.
506
*
507
* <p> Note that any DomainCombiner associated with the current
508
* AccessControlContext will be ignored while the action is performed.
509
*
510
* @param <T> the type of the value returned by the
511
* PrivilegedExceptionAction's {@code run} method.
512
*
513
* @param action the action to be performed
514
*
515
* @return the value returned by the action's {@code run} method
516
*
517
* @exception PrivilegedActionException if the specified action's
518
* {@code run} method threw a <i>checked</i> exception
519
* @exception NullPointerException if the action is {@code null}
520
*
521
* @see #doPrivileged(PrivilegedAction)
522
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
523
* @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
524
* @see java.security.DomainCombiner
525
*/
526
@CallerSensitive
527
public static native <T> T
528
doPrivileged(PrivilegedExceptionAction<T> action)
529
throws PrivilegedActionException;
530
531
532
/**
533
* Performs the specified {@code PrivilegedExceptionAction} with
534
* privileges enabled. The action is performed with <i>all</i> of the
535
* permissions possessed by the caller's protection domain.
536
*
537
* <p> If the action's {@code run} method throws an <i>unchecked</i>
538
* exception, it will propagate through this method.
539
*
540
* <p> This method preserves the current AccessControlContext's
541
* DomainCombiner (which may be null) while the action is performed.
542
*
543
* @param <T> the type of the value returned by the
544
* PrivilegedExceptionAction's {@code run} method.
545
*
546
* @param action the action to be performed.
547
*
548
* @return the value returned by the action's {@code run} method
549
*
550
* @exception PrivilegedActionException if the specified action's
551
* {@code run} method threw a <i>checked</i> exception
552
* @exception NullPointerException if the action is {@code null}
553
*
554
* @see #doPrivileged(PrivilegedAction)
555
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
556
* @see java.security.DomainCombiner
557
*
558
* @since 1.6
559
*/
560
@CallerSensitive
561
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action)
562
throws PrivilegedActionException
563
{
564
AccessControlContext acc = getStackAccessControlContext();
565
if (acc == null) {
566
return AccessController.doPrivileged(action);
567
}
568
DomainCombiner dc = acc.getAssignedCombiner();
569
return AccessController.doPrivileged(action,
570
preserveCombiner(dc, Reflection.getCallerClass()));
571
}
572
573
/**
574
* preserve the combiner across the doPrivileged call
575
*/
576
private static AccessControlContext preserveCombiner(DomainCombiner combiner,
577
Class<?> caller)
578
{
579
return createWrapper(combiner, caller, null, null, null);
580
}
581
582
/**
583
* Create a wrapper to contain the limited privilege scope data.
584
*/
585
private static AccessControlContext
586
createWrapper(DomainCombiner combiner, Class<?> caller,
587
AccessControlContext parent, AccessControlContext context,
588
Permission[] perms)
589
{
590
ProtectionDomain callerPD = getCallerPD(caller);
591
// check if caller is authorized to create context
592
if (context != null && !context.isAuthorized() &&
593
System.getSecurityManager() != null &&
594
!callerPD.impliesCreateAccessControlContext())
595
{
596
ProtectionDomain nullPD = new ProtectionDomain(null, null);
597
return new AccessControlContext(new ProtectionDomain[] { nullPD });
598
} else {
599
return new AccessControlContext(callerPD, combiner, parent,
600
context, perms);
601
}
602
}
603
604
private static ProtectionDomain getCallerPD(final Class <?> caller) {
605
ProtectionDomain callerPd = doPrivileged
606
(new PrivilegedAction<ProtectionDomain>() {
607
public ProtectionDomain run() {
608
return caller.getProtectionDomain();
609
}
610
});
611
612
return callerPd;
613
}
614
615
/**
616
* Performs the specified {@code PrivilegedExceptionAction} with
617
* privileges enabled and restricted by the specified
618
* {@code AccessControlContext}. The action is performed with the
619
* intersection of the permissions possessed by the caller's
620
* protection domain, and those possessed by the domains represented by the
621
* specified {@code AccessControlContext}.
622
* <p>
623
* If the action's {@code run} method throws an <i>unchecked</i>
624
* exception, it will propagate through this method.
625
* <p>
626
* If a security manager is installed and the specified
627
* {@code AccessControlContext} was not created by system code and the
628
* caller's {@code ProtectionDomain} has not been granted the
629
* {@literal "createAccessControlContext"}
630
* {@link java.security.SecurityPermission}, then the action is performed
631
* with no permissions.
632
*
633
* @param <T> the type of the value returned by the
634
* PrivilegedExceptionAction's {@code run} method.
635
* @param action the action to be performed
636
* @param context an <i>access control context</i>
637
* representing the restriction to be applied to the
638
* caller's domain's privileges before performing
639
* the specified action. If the context is
640
* {@code null}, then no additional restriction is applied.
641
*
642
* @return the value returned by the action's {@code run} method
643
*
644
* @exception PrivilegedActionException if the specified action's
645
* {@code run} method threw a <i>checked</i> exception
646
* @exception NullPointerException if the action is {@code null}
647
*
648
* @see #doPrivileged(PrivilegedAction)
649
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
650
*/
651
@CallerSensitive
652
public static native <T> T
653
doPrivileged(PrivilegedExceptionAction<T> action,
654
AccessControlContext context)
655
throws PrivilegedActionException;
656
657
658
/**
659
* Performs the specified {@code PrivilegedExceptionAction} with
660
* privileges enabled and restricted by the specified
661
* {@code AccessControlContext} and with a privilege scope limited by
662
* specified {@code Permission} arguments.
663
*
664
* The action is performed with the intersection of the permissions
665
* possessed by the caller's protection domain, and those possessed
666
* by the domains represented by the specified
667
* {@code AccessControlContext}.
668
* <p>
669
* If the action's {@code run} method throws an (unchecked) exception,
670
* it will propagate through this method.
671
* <p>
672
* If a security manager is installed and the specified
673
* {@code AccessControlContext} was not created by system code and the
674
* caller's {@code ProtectionDomain} has not been granted the
675
* {@literal "createAccessControlContext"}
676
* {@link java.security.SecurityPermission}, then the action is performed
677
* with no permissions.
678
*
679
* @param <T> the type of the value returned by the
680
* PrivilegedExceptionAction's {@code run} method.
681
* @param action the action to be performed.
682
* @param context an <i>access control context</i>
683
* representing the restriction to be applied to the
684
* caller's domain's privileges before performing
685
* the specified action. If the context is
686
* {@code null},
687
* then no additional restriction is applied.
688
* @param perms the {@code Permission} arguments which limit the
689
* scope of the caller's privileges. The number of arguments
690
* is variable.
691
*
692
* @return the value returned by the action's {@code run} method.
693
*
694
* @throws PrivilegedActionException if the specified action's
695
* {@code run} method threw a <i>checked</i> exception
696
* @throws NullPointerException if action or perms or any element of
697
* perms is {@code null}
698
*
699
* @see #doPrivileged(PrivilegedAction)
700
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
701
*
702
* @since 1.8
703
*/
704
@CallerSensitive
705
public static <T> T doPrivileged(PrivilegedExceptionAction<T> action,
706
AccessControlContext context, Permission... perms)
707
throws PrivilegedActionException
708
{
709
AccessControlContext parent = getContext();
710
if (perms == null) {
711
throw new NullPointerException("null permissions parameter");
712
}
713
Class <?> caller = Reflection.getCallerClass();
714
DomainCombiner dc = (context == null) ? null : context.getCombiner();
715
return AccessController.doPrivileged(action, createWrapper(dc, caller, parent, context, perms));
716
}
717
718
719
/**
720
* Performs the specified {@code PrivilegedExceptionAction} with
721
* privileges enabled and restricted by the specified
722
* {@code AccessControlContext} and with a privilege scope limited by
723
* specified {@code Permission} arguments.
724
*
725
* The action is performed with the intersection of the permissions
726
* possessed by the caller's protection domain, and those possessed
727
* by the domains represented by the specified
728
* {@code AccessControlContext}.
729
* <p>
730
* If the action's {@code run} method throws an (unchecked) exception,
731
* it will propagate through this method.
732
*
733
* <p> This method preserves the current AccessControlContext's
734
* DomainCombiner (which may be null) while the action is performed.
735
* <p>
736
* If a security manager is installed and the specified
737
* {@code AccessControlContext} was not created by system code and the
738
* caller's {@code ProtectionDomain} has not been granted the
739
* {@literal "createAccessControlContext"}
740
* {@link java.security.SecurityPermission}, then the action is performed
741
* with no permissions.
742
*
743
* @param <T> the type of the value returned by the
744
* PrivilegedExceptionAction's {@code run} method.
745
* @param action the action to be performed.
746
* @param context an <i>access control context</i>
747
* representing the restriction to be applied to the
748
* caller's domain's privileges before performing
749
* the specified action. If the context is
750
* {@code null},
751
* then no additional restriction is applied.
752
* @param perms the {@code Permission} arguments which limit the
753
* scope of the caller's privileges. The number of arguments
754
* is variable.
755
*
756
* @return the value returned by the action's {@code run} method.
757
*
758
* @throws PrivilegedActionException if the specified action's
759
* {@code run} method threw a <i>checked</i> exception
760
* @throws NullPointerException if action or perms or any element of
761
* perms is {@code null}
762
*
763
* @see #doPrivileged(PrivilegedAction)
764
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
765
* @see java.security.DomainCombiner
766
*
767
* @since 1.8
768
*/
769
@CallerSensitive
770
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action,
771
AccessControlContext context,
772
Permission... perms)
773
throws PrivilegedActionException
774
{
775
AccessControlContext parent = getContext();
776
DomainCombiner dc = parent.getCombiner();
777
if (dc == null && context != null) {
778
dc = context.getCombiner();
779
}
780
if (perms == null) {
781
throw new NullPointerException("null permissions parameter");
782
}
783
Class <?> caller = Reflection.getCallerClass();
784
return AccessController.doPrivileged(action, createWrapper(dc, caller,
785
parent, context, perms));
786
}
787
788
/**
789
* Returns the AccessControl context. i.e., it gets
790
* the protection domains of all the callers on the stack,
791
* starting at the first class with a non-null
792
* ProtectionDomain.
793
*
794
* @return the access control context based on the current stack or
795
* null if there was only privileged system code.
796
*/
797
798
private static native AccessControlContext getStackAccessControlContext();
799
800
801
/**
802
* Returns the "inherited" AccessControl context. This is the context
803
* that existed when the thread was created. Package private so
804
* AccessControlContext can use it.
805
*/
806
807
static native AccessControlContext getInheritedAccessControlContext();
808
809
/**
810
* This method takes a "snapshot" of the current calling context, which
811
* includes the current Thread's inherited AccessControlContext and any
812
* limited privilege scope, and places it in an AccessControlContext object.
813
* This context may then be checked at a later point, possibly in another thread.
814
*
815
* @see AccessControlContext
816
*
817
* @return the AccessControlContext based on the current context.
818
*/
819
820
public static AccessControlContext getContext()
821
{
822
AccessControlContext acc = getStackAccessControlContext();
823
if (acc == null) {
824
// all we had was privileged system code. We don't want
825
// to return null though, so we construct a real ACC.
826
return new AccessControlContext(null, true);
827
} else {
828
return acc.optimize();
829
}
830
}
831
832
/**
833
* Determines whether the access request indicated by the
834
* specified permission should be allowed or denied, based on
835
* the current AccessControlContext and security policy.
836
* This method quietly returns if the access request
837
* is permitted, or throws an AccessControlException otherwise. The
838
* getPermission method of the AccessControlException returns the
839
* {@code perm} Permission object instance.
840
*
841
* @param perm the requested permission.
842
*
843
* @exception AccessControlException if the specified permission
844
* is not permitted, based on the current security policy.
845
* @exception NullPointerException if the specified permission
846
* is {@code null} and is checked based on the
847
* security policy currently in effect.
848
*/
849
850
public static void checkPermission(Permission perm)
851
throws AccessControlException
852
{
853
//System.err.println("checkPermission "+perm);
854
//Thread.currentThread().dumpStack();
855
856
if (perm == null) {
857
throw new NullPointerException("permission can't be null");
858
}
859
860
AccessControlContext stack = getStackAccessControlContext();
861
// if context is null, we had privileged system code on the stack.
862
if (stack == null) {
863
Debug debug = AccessControlContext.getDebug();
864
boolean dumpDebug = false;
865
if (debug != null) {
866
dumpDebug = !Debug.isOn("codebase=");
867
dumpDebug &= !Debug.isOn("permission=") ||
868
Debug.isOn("permission=" + perm.getClass().getCanonicalName());
869
}
870
871
if (dumpDebug && Debug.isOn("stack")) {
872
Thread.dumpStack();
873
}
874
875
if (dumpDebug && Debug.isOn("domain")) {
876
debug.println("domain (context is null)");
877
}
878
879
if (dumpDebug) {
880
debug.println("access allowed "+perm);
881
}
882
return;
883
}
884
885
AccessControlContext acc = stack.optimize();
886
acc.checkPermission(perm);
887
}
888
}
889
890