Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.management/share/classes/javax/management/MBeanPermission.java
41154 views
1
/*
2
* Copyright (c) 2002, 2017, 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 javax.management;
27
28
import java.io.IOException;
29
import java.io.ObjectInputStream;
30
import java.security.Permission;
31
32
/**
33
* <p>Permission controlling access to MBeanServer operations. If a
34
* security manager has been set using {@link
35
* System#setSecurityManager}, most operations on the MBean Server
36
* require that the caller's permissions imply an MBeanPermission
37
* appropriate for the operation. This is described in detail in the
38
* documentation for the {@link MBeanServer} interface.</p>
39
*
40
* <p>As with other {@link Permission} objects, an MBeanPermission can
41
* represent either a permission that you <em>have</em> or a
42
* permission that you <em>need</em>. When a sensitive operation is
43
* being checked for permission, an MBeanPermission is constructed
44
* representing the permission you need. The operation is only
45
* allowed if the permissions you have {@linkplain #implies imply} the
46
* permission you need.</p>
47
*
48
* <p>An MBeanPermission contains four items of information:</p>
49
*
50
* <ul>
51
*
52
* <li><p>The <em>action</em>. For a permission you need,
53
* this is one of the actions in the list <a
54
* href="#action-list">below</a>. For a permission you have, this is
55
* a comma-separated list of those actions, or <code>*</code>,
56
* representing all actions.</p>
57
*
58
* <p>The action is returned by {@link #getActions()}.</p>
59
*
60
* <li><p>The <em>class name</em>.</p>
61
*
62
* <p>For a permission you need, this is the class name of an MBean
63
* you are accessing, as returned by {@link
64
* MBeanServer#getMBeanInfo(ObjectName)
65
* MBeanServer.getMBeanInfo(name)}.{@link MBeanInfo#getClassName()
66
* getClassName()}. Certain operations do not reference a class name,
67
* in which case the class name is null.</p>
68
*
69
* <p>For a permission you have, this is either empty or a <em>class
70
* name pattern</em>. A class name pattern is a string following the
71
* Java conventions for dot-separated class names. It may end with
72
* "<code>.*</code>" meaning that the permission grants access to any
73
* class that begins with the string preceding "<code>.*</code>". For
74
* instance, "<code>javax.management.*</code>" grants access to
75
* <code>javax.management.MBeanServerDelegate</code> and
76
* <code>javax.management.timer.Timer</code>, among other classes.</p>
77
*
78
* <p>A class name pattern can also be empty or the single character
79
* "<code>*</code>", both of which grant access to any class.</p>
80
*
81
* <li><p>The <em>member</em>.</p>
82
*
83
* <p>For a permission you need, this is the name of the attribute or
84
* operation you are accessing. For operations that do not reference
85
* an attribute or operation, the member is null.</p>
86
*
87
* <p>For a permission you have, this is either the name of an attribute
88
* or operation you can access, or it is empty or the single character
89
* "<code>*</code>", both of which grant access to any member.</p>
90
*
91
* <li id="MBeanName"><p>The <em>object name</em>.</p>
92
*
93
* <p>For a permission you need, this is the {@link ObjectName} of the
94
* MBean you are accessing. For operations that do not reference a
95
* single MBean, it is null. It is never an object name pattern.</p>
96
*
97
* <p>For a permission you have, this is the {@link ObjectName} of the
98
* MBean or MBeans you can access. It may be an object name pattern
99
* to grant access to all MBeans whose names match the pattern. It
100
* may also be empty, which grants access to all MBeans whatever their
101
* name.</p>
102
*
103
* </ul>
104
*
105
* <p>If you have an MBeanPermission, it allows operations only if all
106
* four of the items match.</p>
107
*
108
* <p>The class name, member, and object name can be written together
109
* as a single string, which is the <em>name</em> of this permission.
110
* The name of the permission is the string returned by {@link
111
* Permission#getName() getName()}. The format of the string is:</p>
112
*
113
* <blockquote>
114
* <code>className#member[objectName]</code>
115
* </blockquote>
116
*
117
* <p>The object name is written using the usual syntax for {@link
118
* ObjectName}. It may contain any legal characters, including
119
* <code>]</code>. It is terminated by a <code>]</code> character
120
* that is the last character in the string.</p>
121
*
122
* <p>One or more of the <code>className</code>, <code>member</code>,
123
* or <code>objectName</code> may be omitted. If the
124
* <code>member</code> is omitted, the <code>#</code> may be too (but
125
* does not have to be). If the <code>objectName</code> is omitted,
126
* the <code>[]</code> may be too (but does not have to be). It is
127
* not legal to omit all three items, that is to have a <em>name</em>
128
* that is the empty string.</p>
129
*
130
* <p>One or more of the <code>className</code>, <code>member</code>,
131
* or <code>objectName</code> may be the character "<code>-</code>",
132
* which is equivalent to a null value. A null value is implied by
133
* any value (including another null value) but does not imply any
134
* other value.</p>
135
*
136
* <p><a id="action-list">The possible actions are these:</a></p>
137
*
138
* <ul>
139
* <li>addNotificationListener</li>
140
* <li>getAttribute</li>
141
* <li>getClassLoader</li>
142
* <li>getClassLoaderFor</li>
143
* <li>getClassLoaderRepository</li>
144
* <li>getDomains</li>
145
* <li>getMBeanInfo</li>
146
* <li>getObjectInstance</li>
147
* <li>instantiate</li>
148
* <li>invoke</li>
149
* <li>isInstanceOf</li>
150
* <li>queryMBeans</li>
151
* <li>queryNames</li>
152
* <li>registerMBean</li>
153
* <li>removeNotificationListener</li>
154
* <li>setAttribute</li>
155
* <li>unregisterMBean</li>
156
* </ul>
157
*
158
* <p>In a comma-separated list of actions, spaces are allowed before
159
* and after each action.
160
*
161
* @since 1.5
162
*/
163
public class MBeanPermission extends Permission {
164
165
private static final long serialVersionUID = -2416928705275160661L;
166
167
/**
168
* Actions list.
169
*/
170
private static final int AddNotificationListener = 0x00001;
171
private static final int GetAttribute = 0x00002;
172
private static final int GetClassLoader = 0x00004;
173
private static final int GetClassLoaderFor = 0x00008;
174
private static final int GetClassLoaderRepository = 0x00010;
175
private static final int GetDomains = 0x00020;
176
private static final int GetMBeanInfo = 0x00040;
177
private static final int GetObjectInstance = 0x00080;
178
private static final int Instantiate = 0x00100;
179
private static final int Invoke = 0x00200;
180
private static final int IsInstanceOf = 0x00400;
181
private static final int QueryMBeans = 0x00800;
182
private static final int QueryNames = 0x01000;
183
private static final int RegisterMBean = 0x02000;
184
private static final int RemoveNotificationListener = 0x04000;
185
private static final int SetAttribute = 0x08000;
186
private static final int UnregisterMBean = 0x10000;
187
188
/**
189
* No actions.
190
*/
191
private static final int NONE = 0x00000;
192
193
/**
194
* All actions.
195
*/
196
private static final int ALL =
197
AddNotificationListener |
198
GetAttribute |
199
GetClassLoader |
200
GetClassLoaderFor |
201
GetClassLoaderRepository |
202
GetDomains |
203
GetMBeanInfo |
204
GetObjectInstance |
205
Instantiate |
206
Invoke |
207
IsInstanceOf |
208
QueryMBeans |
209
QueryNames |
210
RegisterMBean |
211
RemoveNotificationListener |
212
SetAttribute |
213
UnregisterMBean;
214
215
/**
216
* The actions string.
217
*/
218
private String actions;
219
220
/**
221
* The actions mask.
222
*/
223
private transient int mask;
224
225
/**
226
* The classname prefix that must match. If null, is implied by any
227
* classNamePrefix but does not imply any non-null classNamePrefix.
228
*/
229
private transient String classNamePrefix;
230
231
/**
232
* True if classNamePrefix must match exactly. Otherwise, the
233
* className being matched must start with classNamePrefix.
234
*/
235
private transient boolean classNameExactMatch;
236
237
/**
238
* The member that must match. If null, is implied by any member
239
* but does not imply any non-null member.
240
*/
241
private transient String member;
242
243
/**
244
* The objectName that must match. If null, is implied by any
245
* objectName but does not imply any non-null objectName.
246
*/
247
private transient ObjectName objectName;
248
249
/**
250
* Parse <code>actions</code> parameter.
251
*/
252
private void parseActions() {
253
254
int mask;
255
256
if (actions == null)
257
throw new IllegalArgumentException("MBeanPermission: " +
258
"actions can't be null");
259
if (actions.isEmpty())
260
throw new IllegalArgumentException("MBeanPermission: " +
261
"actions can't be empty");
262
263
mask = getMask(actions);
264
265
if ((mask & ALL) != mask)
266
throw new IllegalArgumentException("Invalid actions mask");
267
if (mask == NONE)
268
throw new IllegalArgumentException("Invalid actions mask");
269
this.mask = mask;
270
}
271
272
/**
273
* Parse <code>name</code> parameter.
274
*/
275
private void parseName() {
276
String name = getName();
277
278
if (name == null)
279
throw new IllegalArgumentException("MBeanPermission name " +
280
"cannot be null");
281
282
if (name.isEmpty())
283
throw new IllegalArgumentException("MBeanPermission name " +
284
"cannot be empty");
285
286
/* The name looks like "class#member[objectname]". We subtract
287
elements from the right as we parse, so after parsing the
288
objectname we have "class#member" and after parsing the
289
member we have "class". Each element is optional. */
290
291
// Parse ObjectName
292
293
int openingBracket = name.indexOf('[');
294
if (openingBracket == -1) {
295
// If "[on]" missing then ObjectName("*:*")
296
//
297
objectName = ObjectName.WILDCARD;
298
} else {
299
if (!name.endsWith("]")) {
300
throw new IllegalArgumentException("MBeanPermission: " +
301
"The ObjectName in the " +
302
"target name must be " +
303
"included in square " +
304
"brackets");
305
} else {
306
// Create ObjectName
307
//
308
try {
309
// If "[]" then ObjectName("*:*")
310
//
311
String on = name.substring(openingBracket + 1,
312
name.length() - 1);
313
if (on.isEmpty())
314
objectName = ObjectName.WILDCARD;
315
else if (on.equals("-"))
316
objectName = null;
317
else
318
objectName = new ObjectName(on);
319
} catch (MalformedObjectNameException e) {
320
throw new IllegalArgumentException("MBeanPermission: " +
321
"The target name does " +
322
"not specify a valid " +
323
"ObjectName", e);
324
}
325
}
326
327
name = name.substring(0, openingBracket);
328
}
329
330
// Parse member
331
332
int poundSign = name.indexOf('#');
333
334
if (poundSign == -1)
335
setMember("*");
336
else {
337
String memberName = name.substring(poundSign + 1);
338
setMember(memberName);
339
name = name.substring(0, poundSign);
340
}
341
342
// Parse className
343
344
setClassName(name);
345
}
346
347
/**
348
* Assign fields based on className, member, and objectName
349
* parameters.
350
*/
351
private void initName(String className, String member,
352
ObjectName objectName) {
353
setClassName(className);
354
setMember(member);
355
this.objectName = objectName;
356
}
357
358
private void setClassName(String className) {
359
if (className == null || className.equals("-")) {
360
classNamePrefix = null;
361
classNameExactMatch = false;
362
} else if (className.isEmpty() || className.equals("*")) {
363
classNamePrefix = "";
364
classNameExactMatch = false;
365
} else if (className.endsWith(".*")) {
366
// Note that we include the "." in the required prefix
367
classNamePrefix = className.substring(0, className.length() - 1);
368
classNameExactMatch = false;
369
} else {
370
classNamePrefix = className;
371
classNameExactMatch = true;
372
}
373
}
374
375
private void setMember(String member) {
376
if (member == null || member.equals("-"))
377
this.member = null;
378
else if (member.isEmpty())
379
this.member = "*";
380
else
381
this.member = member;
382
}
383
384
/**
385
* <p>Create a new MBeanPermission object with the specified target name
386
* and actions.</p>
387
*
388
* <p>The target name is of the form
389
* "<code>className#member[objectName]</code>" where each part is
390
* optional. It must not be empty or null.</p>
391
*
392
* <p>The actions parameter contains a comma-separated list of the
393
* desired actions granted on the target name. It must not be
394
* empty or null.</p>
395
*
396
* @param name the triplet "className#member[objectName]".
397
* @param actions the action string.
398
*
399
* @exception IllegalArgumentException if the <code>name</code> or
400
* <code>actions</code> is invalid.
401
*/
402
public MBeanPermission(String name, String actions) {
403
super(name);
404
405
parseName();
406
407
this.actions = actions;
408
parseActions();
409
}
410
411
/**
412
* <p>Create a new MBeanPermission object with the specified target name
413
* (class name, member, object name) and actions.</p>
414
*
415
* <p>The class name, member and object name parameters define a
416
* target name of the form
417
* "<code>className#member[objectName]</code>" where each part is
418
* optional. This will be the result of {@link #getName()} on the
419
* resultant MBeanPermission.</p>
420
*
421
* <p>The actions parameter contains a comma-separated list of the
422
* desired actions granted on the target name. It must not be
423
* empty or null.</p>
424
*
425
* @param className the class name to which this permission applies.
426
* May be null or <code>"-"</code>, which represents a class name
427
* that is implied by any class name but does not imply any other
428
* class name.
429
* @param member the member to which this permission applies. May
430
* be null or <code>"-"</code>, which represents a member that is
431
* implied by any member but does not imply any other member.
432
* @param objectName the object name to which this permission
433
* applies. May be null, which represents an object name that is
434
* implied by any object name but does not imply any other object
435
* name.
436
* @param actions the action string.
437
*/
438
public MBeanPermission(String className,
439
String member,
440
ObjectName objectName,
441
String actions) {
442
443
super(makeName(className, member, objectName));
444
initName(className, member, objectName);
445
446
this.actions = actions;
447
parseActions();
448
}
449
450
private static String makeName(String className, String member,
451
ObjectName objectName) {
452
final StringBuilder name = new StringBuilder();
453
if (className == null)
454
className = "-";
455
name.append(className);
456
if (member == null)
457
member = "-";
458
name.append('#').append(member);
459
if (objectName == null)
460
name.append("[-]");
461
else
462
name.append('[').append(objectName.getCanonicalName()).append(']');
463
464
/* In the interests of legibility for Permission.toString(), we
465
transform the empty string into "*". */
466
if (name.length() == 0)
467
return "*";
468
else
469
return name.toString();
470
}
471
472
/**
473
* Returns the "canonical string representation" of the actions. That is,
474
* this method always returns present actions in alphabetical order.
475
*
476
* @return the canonical string representation of the actions.
477
*/
478
public String getActions() {
479
480
if (actions == null)
481
actions = getActions(this.mask);
482
483
return actions;
484
}
485
486
/**
487
* Returns the "canonical string representation"
488
* of the actions from the mask.
489
*/
490
private static String getActions(int mask) {
491
final StringBuilder sb = new StringBuilder();
492
boolean comma = false;
493
494
if ((mask & AddNotificationListener) == AddNotificationListener) {
495
comma = true;
496
sb.append("addNotificationListener");
497
}
498
499
if ((mask & GetAttribute) == GetAttribute) {
500
if (comma) sb.append(',');
501
else comma = true;
502
sb.append("getAttribute");
503
}
504
505
if ((mask & GetClassLoader) == GetClassLoader) {
506
if (comma) sb.append(',');
507
else comma = true;
508
sb.append("getClassLoader");
509
}
510
511
if ((mask & GetClassLoaderFor) == GetClassLoaderFor) {
512
if (comma) sb.append(',');
513
else comma = true;
514
sb.append("getClassLoaderFor");
515
}
516
517
if ((mask & GetClassLoaderRepository) == GetClassLoaderRepository) {
518
if (comma) sb.append(',');
519
else comma = true;
520
sb.append("getClassLoaderRepository");
521
}
522
523
if ((mask & GetDomains) == GetDomains) {
524
if (comma) sb.append(',');
525
else comma = true;
526
sb.append("getDomains");
527
}
528
529
if ((mask & GetMBeanInfo) == GetMBeanInfo) {
530
if (comma) sb.append(',');
531
else comma = true;
532
sb.append("getMBeanInfo");
533
}
534
535
if ((mask & GetObjectInstance) == GetObjectInstance) {
536
if (comma) sb.append(',');
537
else comma = true;
538
sb.append("getObjectInstance");
539
}
540
541
if ((mask & Instantiate) == Instantiate) {
542
if (comma) sb.append(',');
543
else comma = true;
544
sb.append("instantiate");
545
}
546
547
if ((mask & Invoke) == Invoke) {
548
if (comma) sb.append(',');
549
else comma = true;
550
sb.append("invoke");
551
}
552
553
if ((mask & IsInstanceOf) == IsInstanceOf) {
554
if (comma) sb.append(',');
555
else comma = true;
556
sb.append("isInstanceOf");
557
}
558
559
if ((mask & QueryMBeans) == QueryMBeans) {
560
if (comma) sb.append(',');
561
else comma = true;
562
sb.append("queryMBeans");
563
}
564
565
if ((mask & QueryNames) == QueryNames) {
566
if (comma) sb.append(',');
567
else comma = true;
568
sb.append("queryNames");
569
}
570
571
if ((mask & RegisterMBean) == RegisterMBean) {
572
if (comma) sb.append(',');
573
else comma = true;
574
sb.append("registerMBean");
575
}
576
577
if ((mask & RemoveNotificationListener) == RemoveNotificationListener) {
578
if (comma) sb.append(',');
579
else comma = true;
580
sb.append("removeNotificationListener");
581
}
582
583
if ((mask & SetAttribute) == SetAttribute) {
584
if (comma) sb.append(',');
585
else comma = true;
586
sb.append("setAttribute");
587
}
588
589
if ((mask & UnregisterMBean) == UnregisterMBean) {
590
if (comma) sb.append(',');
591
else comma = true;
592
sb.append("unregisterMBean");
593
}
594
595
return sb.toString();
596
}
597
598
/**
599
* Returns the hash code value for this object.
600
*
601
* @return a hash code value for this object.
602
*/
603
public int hashCode() {
604
return this.getName().hashCode() + this.getActions().hashCode();
605
}
606
607
/**
608
* Converts an action String to an integer action mask.
609
*
610
* @param action the action string.
611
* @return the action mask.
612
*/
613
private static int getMask(String action) {
614
615
/*
616
* BE CAREFUL HERE! PARSING ORDER IS IMPORTANT IN THIS ALGORITHM.
617
*
618
* The 'string length' test must be performed for the lengthiest
619
* strings first.
620
*
621
* In this permission if the "unregisterMBean" string length test is
622
* performed after the "registerMBean" string length test the algorithm
623
* considers the 'unregisterMBean' action as being the 'registerMBean'
624
* action and a parsing error is returned.
625
*/
626
627
int mask = NONE;
628
629
if (action == null) {
630
return mask;
631
}
632
633
if (action.equals("*")) {
634
return ALL;
635
}
636
637
char[] a = action.toCharArray();
638
639
int i = a.length - 1;
640
if (i < 0)
641
return mask;
642
643
while (i != -1) {
644
char c;
645
646
// skip whitespace
647
while ((i!=-1) && ((c = a[i]) == ' ' ||
648
c == '\r' ||
649
c == '\n' ||
650
c == '\f' ||
651
c == '\t'))
652
i--;
653
654
// check for the known strings
655
int matchlen;
656
657
if (i >= 25 && /* removeNotificationListener */
658
(a[i-25] == 'r') &&
659
(a[i-24] == 'e') &&
660
(a[i-23] == 'm') &&
661
(a[i-22] == 'o') &&
662
(a[i-21] == 'v') &&
663
(a[i-20] == 'e') &&
664
(a[i-19] == 'N') &&
665
(a[i-18] == 'o') &&
666
(a[i-17] == 't') &&
667
(a[i-16] == 'i') &&
668
(a[i-15] == 'f') &&
669
(a[i-14] == 'i') &&
670
(a[i-13] == 'c') &&
671
(a[i-12] == 'a') &&
672
(a[i-11] == 't') &&
673
(a[i-10] == 'i') &&
674
(a[i-9] == 'o') &&
675
(a[i-8] == 'n') &&
676
(a[i-7] == 'L') &&
677
(a[i-6] == 'i') &&
678
(a[i-5] == 's') &&
679
(a[i-4] == 't') &&
680
(a[i-3] == 'e') &&
681
(a[i-2] == 'n') &&
682
(a[i-1] == 'e') &&
683
(a[i] == 'r')) {
684
matchlen = 26;
685
mask |= RemoveNotificationListener;
686
} else if (i >= 23 && /* getClassLoaderRepository */
687
(a[i-23] == 'g') &&
688
(a[i-22] == 'e') &&
689
(a[i-21] == 't') &&
690
(a[i-20] == 'C') &&
691
(a[i-19] == 'l') &&
692
(a[i-18] == 'a') &&
693
(a[i-17] == 's') &&
694
(a[i-16] == 's') &&
695
(a[i-15] == 'L') &&
696
(a[i-14] == 'o') &&
697
(a[i-13] == 'a') &&
698
(a[i-12] == 'd') &&
699
(a[i-11] == 'e') &&
700
(a[i-10] == 'r') &&
701
(a[i-9] == 'R') &&
702
(a[i-8] == 'e') &&
703
(a[i-7] == 'p') &&
704
(a[i-6] == 'o') &&
705
(a[i-5] == 's') &&
706
(a[i-4] == 'i') &&
707
(a[i-3] == 't') &&
708
(a[i-2] == 'o') &&
709
(a[i-1] == 'r') &&
710
(a[i] == 'y')) {
711
matchlen = 24;
712
mask |= GetClassLoaderRepository;
713
} else if (i >= 22 && /* addNotificationListener */
714
(a[i-22] == 'a') &&
715
(a[i-21] == 'd') &&
716
(a[i-20] == 'd') &&
717
(a[i-19] == 'N') &&
718
(a[i-18] == 'o') &&
719
(a[i-17] == 't') &&
720
(a[i-16] == 'i') &&
721
(a[i-15] == 'f') &&
722
(a[i-14] == 'i') &&
723
(a[i-13] == 'c') &&
724
(a[i-12] == 'a') &&
725
(a[i-11] == 't') &&
726
(a[i-10] == 'i') &&
727
(a[i-9] == 'o') &&
728
(a[i-8] == 'n') &&
729
(a[i-7] == 'L') &&
730
(a[i-6] == 'i') &&
731
(a[i-5] == 's') &&
732
(a[i-4] == 't') &&
733
(a[i-3] == 'e') &&
734
(a[i-2] == 'n') &&
735
(a[i-1] == 'e') &&
736
(a[i] == 'r')) {
737
matchlen = 23;
738
mask |= AddNotificationListener;
739
} else if (i >= 16 && /* getClassLoaderFor */
740
(a[i-16] == 'g') &&
741
(a[i-15] == 'e') &&
742
(a[i-14] == 't') &&
743
(a[i-13] == 'C') &&
744
(a[i-12] == 'l') &&
745
(a[i-11] == 'a') &&
746
(a[i-10] == 's') &&
747
(a[i-9] == 's') &&
748
(a[i-8] == 'L') &&
749
(a[i-7] == 'o') &&
750
(a[i-6] == 'a') &&
751
(a[i-5] == 'd') &&
752
(a[i-4] == 'e') &&
753
(a[i-3] == 'r') &&
754
(a[i-2] == 'F') &&
755
(a[i-1] == 'o') &&
756
(a[i] == 'r')) {
757
matchlen = 17;
758
mask |= GetClassLoaderFor;
759
} else if (i >= 16 && /* getObjectInstance */
760
(a[i-16] == 'g') &&
761
(a[i-15] == 'e') &&
762
(a[i-14] == 't') &&
763
(a[i-13] == 'O') &&
764
(a[i-12] == 'b') &&
765
(a[i-11] == 'j') &&
766
(a[i-10] == 'e') &&
767
(a[i-9] == 'c') &&
768
(a[i-8] == 't') &&
769
(a[i-7] == 'I') &&
770
(a[i-6] == 'n') &&
771
(a[i-5] == 's') &&
772
(a[i-4] == 't') &&
773
(a[i-3] == 'a') &&
774
(a[i-2] == 'n') &&
775
(a[i-1] == 'c') &&
776
(a[i] == 'e')) {
777
matchlen = 17;
778
mask |= GetObjectInstance;
779
} else if (i >= 14 && /* unregisterMBean */
780
(a[i-14] == 'u') &&
781
(a[i-13] == 'n') &&
782
(a[i-12] == 'r') &&
783
(a[i-11] == 'e') &&
784
(a[i-10] == 'g') &&
785
(a[i-9] == 'i') &&
786
(a[i-8] == 's') &&
787
(a[i-7] == 't') &&
788
(a[i-6] == 'e') &&
789
(a[i-5] == 'r') &&
790
(a[i-4] == 'M') &&
791
(a[i-3] == 'B') &&
792
(a[i-2] == 'e') &&
793
(a[i-1] == 'a') &&
794
(a[i] == 'n')) {
795
matchlen = 15;
796
mask |= UnregisterMBean;
797
} else if (i >= 13 && /* getClassLoader */
798
(a[i-13] == 'g') &&
799
(a[i-12] == 'e') &&
800
(a[i-11] == 't') &&
801
(a[i-10] == 'C') &&
802
(a[i-9] == 'l') &&
803
(a[i-8] == 'a') &&
804
(a[i-7] == 's') &&
805
(a[i-6] == 's') &&
806
(a[i-5] == 'L') &&
807
(a[i-4] == 'o') &&
808
(a[i-3] == 'a') &&
809
(a[i-2] == 'd') &&
810
(a[i-1] == 'e') &&
811
(a[i] == 'r')) {
812
matchlen = 14;
813
mask |= GetClassLoader;
814
} else if (i >= 12 && /* registerMBean */
815
(a[i-12] == 'r') &&
816
(a[i-11] == 'e') &&
817
(a[i-10] == 'g') &&
818
(a[i-9] == 'i') &&
819
(a[i-8] == 's') &&
820
(a[i-7] == 't') &&
821
(a[i-6] == 'e') &&
822
(a[i-5] == 'r') &&
823
(a[i-4] == 'M') &&
824
(a[i-3] == 'B') &&
825
(a[i-2] == 'e') &&
826
(a[i-1] == 'a') &&
827
(a[i] == 'n')) {
828
matchlen = 13;
829
mask |= RegisterMBean;
830
} else if (i >= 11 && /* getAttribute */
831
(a[i-11] == 'g') &&
832
(a[i-10] == 'e') &&
833
(a[i-9] == 't') &&
834
(a[i-8] == 'A') &&
835
(a[i-7] == 't') &&
836
(a[i-6] == 't') &&
837
(a[i-5] == 'r') &&
838
(a[i-4] == 'i') &&
839
(a[i-3] == 'b') &&
840
(a[i-2] == 'u') &&
841
(a[i-1] == 't') &&
842
(a[i] == 'e')) {
843
matchlen = 12;
844
mask |= GetAttribute;
845
} else if (i >= 11 && /* getMBeanInfo */
846
(a[i-11] == 'g') &&
847
(a[i-10] == 'e') &&
848
(a[i-9] == 't') &&
849
(a[i-8] == 'M') &&
850
(a[i-7] == 'B') &&
851
(a[i-6] == 'e') &&
852
(a[i-5] == 'a') &&
853
(a[i-4] == 'n') &&
854
(a[i-3] == 'I') &&
855
(a[i-2] == 'n') &&
856
(a[i-1] == 'f') &&
857
(a[i] == 'o')) {
858
matchlen = 12;
859
mask |= GetMBeanInfo;
860
} else if (i >= 11 && /* isInstanceOf */
861
(a[i-11] == 'i') &&
862
(a[i-10] == 's') &&
863
(a[i-9] == 'I') &&
864
(a[i-8] == 'n') &&
865
(a[i-7] == 's') &&
866
(a[i-6] == 't') &&
867
(a[i-5] == 'a') &&
868
(a[i-4] == 'n') &&
869
(a[i-3] == 'c') &&
870
(a[i-2] == 'e') &&
871
(a[i-1] == 'O') &&
872
(a[i] == 'f')) {
873
matchlen = 12;
874
mask |= IsInstanceOf;
875
} else if (i >= 11 && /* setAttribute */
876
(a[i-11] == 's') &&
877
(a[i-10] == 'e') &&
878
(a[i-9] == 't') &&
879
(a[i-8] == 'A') &&
880
(a[i-7] == 't') &&
881
(a[i-6] == 't') &&
882
(a[i-5] == 'r') &&
883
(a[i-4] == 'i') &&
884
(a[i-3] == 'b') &&
885
(a[i-2] == 'u') &&
886
(a[i-1] == 't') &&
887
(a[i] == 'e')) {
888
matchlen = 12;
889
mask |= SetAttribute;
890
} else if (i >= 10 && /* instantiate */
891
(a[i-10] == 'i') &&
892
(a[i-9] == 'n') &&
893
(a[i-8] == 's') &&
894
(a[i-7] == 't') &&
895
(a[i-6] == 'a') &&
896
(a[i-5] == 'n') &&
897
(a[i-4] == 't') &&
898
(a[i-3] == 'i') &&
899
(a[i-2] == 'a') &&
900
(a[i-1] == 't') &&
901
(a[i] == 'e')) {
902
matchlen = 11;
903
mask |= Instantiate;
904
} else if (i >= 10 && /* queryMBeans */
905
(a[i-10] == 'q') &&
906
(a[i-9] == 'u') &&
907
(a[i-8] == 'e') &&
908
(a[i-7] == 'r') &&
909
(a[i-6] == 'y') &&
910
(a[i-5] == 'M') &&
911
(a[i-4] == 'B') &&
912
(a[i-3] == 'e') &&
913
(a[i-2] == 'a') &&
914
(a[i-1] == 'n') &&
915
(a[i] == 's')) {
916
matchlen = 11;
917
mask |= QueryMBeans;
918
} else if (i >= 9 && /* getDomains */
919
(a[i-9] == 'g') &&
920
(a[i-8] == 'e') &&
921
(a[i-7] == 't') &&
922
(a[i-6] == 'D') &&
923
(a[i-5] == 'o') &&
924
(a[i-4] == 'm') &&
925
(a[i-3] == 'a') &&
926
(a[i-2] == 'i') &&
927
(a[i-1] == 'n') &&
928
(a[i] == 's')) {
929
matchlen = 10;
930
mask |= GetDomains;
931
} else if (i >= 9 && /* queryNames */
932
(a[i-9] == 'q') &&
933
(a[i-8] == 'u') &&
934
(a[i-7] == 'e') &&
935
(a[i-6] == 'r') &&
936
(a[i-5] == 'y') &&
937
(a[i-4] == 'N') &&
938
(a[i-3] == 'a') &&
939
(a[i-2] == 'm') &&
940
(a[i-1] == 'e') &&
941
(a[i] == 's')) {
942
matchlen = 10;
943
mask |= QueryNames;
944
} else if (i >= 5 && /* invoke */
945
(a[i-5] == 'i') &&
946
(a[i-4] == 'n') &&
947
(a[i-3] == 'v') &&
948
(a[i-2] == 'o') &&
949
(a[i-1] == 'k') &&
950
(a[i] == 'e')) {
951
matchlen = 6;
952
mask |= Invoke;
953
} else {
954
// parse error
955
throw new IllegalArgumentException("Invalid permission: " +
956
action);
957
}
958
959
// make sure we didn't just match the tail of a word
960
// like "ackbarfaccept". Also, skip to the comma.
961
boolean seencomma = false;
962
while (i >= matchlen && !seencomma) {
963
switch(a[i-matchlen]) {
964
case ',':
965
seencomma = true;
966
break;
967
case ' ': case '\r': case '\n':
968
case '\f': case '\t':
969
break;
970
default:
971
throw new IllegalArgumentException("Invalid permission: " +
972
action);
973
}
974
i--;
975
}
976
977
// point i at the location of the comma minus one (or -1).
978
i -= matchlen;
979
}
980
981
return mask;
982
}
983
984
/**
985
* <p>Checks if this MBeanPermission object "implies" the
986
* specified permission.</p>
987
*
988
* <p>More specifically, this method returns true if:</p>
989
*
990
* <ul>
991
*
992
* <li> <i>p</i> is an instance of MBeanPermission; and</li>
993
*
994
* <li> <i>p</i> has a null className or <i>p</i>'s className
995
* matches this object's className; and</li>
996
*
997
* <li> <i>p</i> has a null member or <i>p</i>'s member matches this
998
* object's member; and</li>
999
*
1000
* <li> <i>p</i> has a null object name or <i>p</i>'s
1001
* object name matches this object's object name; and</li>
1002
*
1003
* <li> <i>p</i>'s actions are a subset of this object's actions</li>
1004
*
1005
* </ul>
1006
*
1007
* <p>If this object's className is "<code>*</code>", <i>p</i>'s
1008
* className always matches it. If it is "<code>a.*</code>", <i>p</i>'s
1009
* className matches it if it begins with "<code>a.</code>".</p>
1010
*
1011
* <p>If this object's member is "<code>*</code>", <i>p</i>'s
1012
* member always matches it.</p>
1013
*
1014
* <p>If this object's objectName <i>n1</i> is an object name pattern,
1015
* <i>p</i>'s objectName <i>n2</i> matches it if
1016
* {@link ObjectName#equals <i>n1</i>.equals(<i>n2</i>)} or if
1017
* {@link ObjectName#apply <i>n1</i>.apply(<i>n2</i>)}.</p>
1018
*
1019
* <p>A permission that includes the <code>queryMBeans</code> action
1020
* is considered to include <code>queryNames</code> as well.</p>
1021
*
1022
* @param p the permission to check against.
1023
* @return true if the specified permission is implied by this object,
1024
* false if not.
1025
*/
1026
public boolean implies(Permission p) {
1027
if (!(p instanceof MBeanPermission))
1028
return false;
1029
1030
MBeanPermission that = (MBeanPermission) p;
1031
1032
// Actions
1033
//
1034
// The actions in 'this' permission must be a
1035
// superset of the actions in 'that' permission
1036
//
1037
1038
/* "queryMBeans" implies "queryNames" */
1039
if ((this.mask & QueryMBeans) == QueryMBeans) {
1040
if (((this.mask | QueryNames) & that.mask) != that.mask) {
1041
//System.out.println("action [with QueryNames] does not imply");
1042
return false;
1043
}
1044
} else {
1045
if ((this.mask & that.mask) != that.mask) {
1046
//System.out.println("action does not imply");
1047
return false;
1048
}
1049
}
1050
1051
// Target name
1052
//
1053
// The 'className' check is true iff:
1054
// 1) the className in 'this' permission is omitted or "*", or
1055
// 2) the className in 'that' permission is omitted or "*", or
1056
// 3) the className in 'this' permission does pattern
1057
// matching with the className in 'that' permission.
1058
//
1059
// The 'member' check is true iff:
1060
// 1) the member in 'this' permission is omitted or "*", or
1061
// 2) the member in 'that' permission is omitted or "*", or
1062
// 3) the member in 'this' permission equals the member in
1063
// 'that' permission.
1064
//
1065
// The 'object name' check is true iff:
1066
// 1) the object name in 'this' permission is omitted or "*:*", or
1067
// 2) the object name in 'that' permission is omitted or "*:*", or
1068
// 3) the object name in 'this' permission does pattern
1069
// matching with the object name in 'that' permission.
1070
//
1071
1072
/* Check if this.className implies that.className.
1073
1074
If that.classNamePrefix is empty that means the className is
1075
irrelevant for this permission check. Otherwise, we do not
1076
expect that "that" contains a wildcard, since it is a
1077
needed permission. So we assume that.classNameExactMatch. */
1078
1079
if (that.classNamePrefix == null) {
1080
// bottom is implied
1081
} else if (this.classNamePrefix == null) {
1082
// bottom implies nothing but itself
1083
return false;
1084
} else if (this.classNameExactMatch) {
1085
if (!that.classNameExactMatch)
1086
return false; // exact never implies wildcard
1087
if (!that.classNamePrefix.equals(this.classNamePrefix))
1088
return false; // exact match fails
1089
} else {
1090
// prefix match, works even if "that" is also a wildcard
1091
// e.g. a.* implies a.* and a.b.*
1092
if (!that.classNamePrefix.startsWith(this.classNamePrefix))
1093
return false;
1094
}
1095
1096
/* Check if this.member implies that.member */
1097
1098
if (that.member == null) {
1099
// bottom is implied
1100
} else if (this.member == null) {
1101
// bottom implies nothing but itself
1102
return false;
1103
} else if (this.member.equals("*")) {
1104
// wildcard implies everything (including itself)
1105
} else if (!this.member.equals(that.member)) {
1106
return false;
1107
}
1108
1109
/* Check if this.objectName implies that.objectName */
1110
1111
if (that.objectName == null) {
1112
// bottom is implied
1113
} else if (this.objectName == null) {
1114
// bottom implies nothing but itself
1115
return false;
1116
} else if (!this.objectName.apply(that.objectName)) {
1117
/* ObjectName.apply returns false if that.objectName is a
1118
wildcard so we also allow equals for that case. This
1119
never happens during real permission checks, but means
1120
the implies relation is reflexive. */
1121
if (!this.objectName.equals(that.objectName))
1122
return false;
1123
}
1124
1125
return true;
1126
}
1127
1128
/**
1129
* Checks two MBeanPermission objects for equality. Checks
1130
* that <i>obj</i> is an MBeanPermission, and has the same
1131
* name and actions as this object.
1132
*
1133
* @param obj the object we are testing for equality with this object.
1134
* @return true if obj is an MBeanPermission, and has the
1135
* same name and actions as this MBeanPermission object.
1136
*/
1137
public boolean equals(Object obj) {
1138
if (obj == this)
1139
return true;
1140
1141
if (! (obj instanceof MBeanPermission))
1142
return false;
1143
1144
MBeanPermission that = (MBeanPermission) obj;
1145
1146
return (this.mask == that.mask) &&
1147
(this.getName().equals(that.getName()));
1148
}
1149
1150
/**
1151
* Deserialize this object based on its name and actions.
1152
*/
1153
private void readObject(ObjectInputStream in)
1154
throws IOException, ClassNotFoundException {
1155
in.defaultReadObject();
1156
parseName();
1157
parseActions();
1158
}
1159
}
1160
1161