40 * <p>As with other {@link Permission} objects, an MBeanPermission can |
41 * <p>As with other {@link Permission} objects, an MBeanPermission can |
41 * represent either a permission that you <em>have</em> or a |
42 * represent either a permission that you <em>have</em> or a |
42 * permission that you <em>need</em>. When a sensitive operation is |
43 * permission that you <em>need</em>. When a sensitive operation is |
43 * being checked for permission, an MBeanPermission is constructed |
44 * being checked for permission, an MBeanPermission is constructed |
44 * representing the permission you need. The operation is only |
45 * representing the permission you need. The operation is only |
45 * allowed if the permissions you have {@link #implies imply} the |
46 * allowed if the permissions you have {@linkplain #implies imply} the |
46 * permission you need.</p> |
47 * permission you need.</p> |
47 * |
48 * |
48 * <p>An MBeanPermission contains four items of information:</p> |
49 * <p>An MBeanPermission contains five items of information:</p> |
49 * |
50 * |
50 * <ul> |
51 * <ul> |
51 * |
52 * |
52 * <li><p>The <em>action</em>. For a permission you need, |
53 * <li><p>The <em>action</em>. For a permission you need, |
53 * this is one of the actions in the list <a |
54 * this is one of the actions in the list <a |
54 * href="#action-list">below</a>. For a permission you have, this is |
55 * href="#action-list">below</a>. For a permission you have, this is |
55 * a comma-separated list of those actions, or <code>*</code>, |
56 * a comma-separated list of those actions, or <code>*</code>, |
56 * representing all actions.</p> |
57 * representing all actions.</p> |
57 * |
58 * |
58 * <p>The action is returned by {@link #getActions()}.</p> |
59 * <p>The action is returned by {@link #getActions()}.</p> |
|
60 * |
|
61 * <li id="MBeanServerName"><p>The <em>MBean Server name</em>.</p> |
|
62 * |
|
63 * <p>For a permission you need, this is the {@linkplain |
|
64 * javax.management.MBeanServerFactory#getMBeanServerName |
|
65 * name of the MBeanServer} |
|
66 * containing the <a href="#MBeanName">MBean</a> for which the MBean |
|
67 * permission is checked.</p> |
|
68 * |
|
69 * <p>For a permission you have, this is either the {@linkplain |
|
70 * javax.management.MBeanServerFactory#getMBeanServerName |
|
71 * name of the MBeanServer} in which the <a href="#MBeanName">MBean</a> |
|
72 * you have this permission for must be registered, |
|
73 * or a pattern against which that MBean Server name will be matched.<br> |
|
74 * An {@code mbeanServerName} pattern can also be empty or the single |
|
75 * character {@code "*"}, both of which will match any {@code MBeanServer} name. |
|
76 * </p> |
59 * |
77 * |
60 * <li><p>The <em>class name</em>.</p> |
78 * <li><p>The <em>class name</em>.</p> |
61 * |
79 * |
62 * <p>For a permission you need, this is the class name of an MBean |
80 * <p>For a permission you need, this is the class name of an MBean |
63 * you are accessing, as returned by {@link |
81 * you are accessing, as returned by {@link |
86 * |
104 * |
87 * <p>For a permission you have, this is either the name of an attribute |
105 * <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 |
106 * 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> |
107 * "<code>*</code>", both of which grant access to any member.</p> |
90 * |
108 * |
91 * <li><p>The <em>object name</em>.</p> |
109 * <li id="MBeanName"><p>The <em>object name</em>.</p> |
92 * |
110 * |
93 * <p>For a permission you need, this is the {@link ObjectName} of the |
111 * <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 |
112 * 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> |
113 * single MBean, it is null. It is never an object name pattern.</p> |
96 * |
114 * |
101 * name.</p> |
119 * name.</p> |
102 * |
120 * |
103 * </ul> |
121 * </ul> |
104 * |
122 * |
105 * <p>If you have an MBeanPermission, it allows operations only if all |
123 * <p>If you have an MBeanPermission, it allows operations only if all |
106 * four of the items match.</p> |
124 * five of the items match.</p> |
107 * |
125 * |
108 * <p>The class name, member, and object name can be written together |
126 * <p>The MBean Server name, class name, member, and object name can be written |
109 * as a single string, which is the <em>name</em> of this permission. |
127 * together 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 |
128 * The name of the permission is the string returned by {@link |
111 * Permission#getName() getName()}. The format of the string is:</p> |
129 * Permission#getName() getName()}. The format of the string is:</p> |
112 * |
130 * |
113 * <blockquote> |
131 * <blockquote> |
114 * <code>className#member[objectName]</code> |
132 * <code>mbeanServerName::className#member[objectName]</code> |
115 * </blockquote> |
133 * </blockquote> |
116 * |
134 * |
117 * <p>The object name is written using the usual syntax for {@link |
135 * <p>The object name is written using the usual syntax for {@link |
118 * ObjectName}. It may contain any legal characters, including |
136 * ObjectName}. It may contain any legal characters, including |
119 * <code>]</code>. It is terminated by a <code>]</code> character |
137 * <code>]</code>. It is terminated by a <code>]</code> character |
120 * that is the last character in the string.</p> |
138 * that is the last character in the string.</p> |
121 * |
139 * |
122 * <p>One or more of the <code>className</code>, <code>member</code>, |
140 * <p>One or more of the <code>mbeanServerName</code>, <code>className</code>, |
123 * or <code>objectName</code> may be omitted. If the |
141 * <code>member</code>, or <code>objectName</code> may be omitted. If the |
124 * <code>member</code> is omitted, the <code>#</code> may be too (but |
142 * <code>mbeanServerName</code> is omitted, the <code>::</code> may be too (but |
|
143 * does not have to be). |
|
144 * If the <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, |
145 * 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 |
146 * 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> |
147 * not legal to omit all four items, that is to have a <em>name</em> |
128 * that is the empty string.</p> |
148 * that is the empty string.</p> |
129 * |
149 * |
130 * <p>One or more of the <code>className</code>, <code>member</code>, |
150 * <p>One or more of the <code>mbeanServerName</code>, <code>className</code>, |
|
151 * <code>member</code>, |
131 * or <code>objectName</code> may be the character "<code>-</code>", |
152 * or <code>objectName</code> may be the character "<code>-</code>", |
132 * which is equivalent to a null value. A null value is implied by |
153 * 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 |
154 * any value (including another null value) but does not imply any |
134 * other value.</p> |
155 * other value.</p> |
135 * |
156 * |
281 |
309 |
282 if (name.equals("")) |
310 if (name.equals("")) |
283 throw new IllegalArgumentException("MBeanPermission name " + |
311 throw new IllegalArgumentException("MBeanPermission name " + |
284 "cannot be empty"); |
312 "cannot be empty"); |
285 |
313 |
|
314 final int sepIndex = name.indexOf("::"); |
|
315 if (sepIndex < 0) { |
|
316 setMBeanServerName("*"); |
|
317 } else { |
|
318 setMBeanServerName(name.substring(0,sepIndex)); |
|
319 } |
|
320 |
286 /* The name looks like "class#member[objectname]". We subtract |
321 /* The name looks like "class#member[objectname]". We subtract |
287 elements from the right as we parse, so after parsing the |
322 elements from the right as we parse, so after parsing the |
288 objectname we have "class#member" and after parsing the |
323 objectname we have "class#member" and after parsing the |
289 member we have "class". Each element is optional. */ |
324 member we have "class". Each element is optional. */ |
290 |
325 |
291 // Parse ObjectName |
326 // Parse ObjectName |
292 |
327 |
293 int openingBracket = name.indexOf("["); |
328 |
|
329 final int start = (sepIndex<0)?0:sepIndex+2; |
|
330 int openingBracket = name.indexOf("[",start); |
294 if (openingBracket == -1) { |
331 if (openingBracket == -1) { |
295 // If "[on]" missing then ObjectName("*:*") |
332 // If "[on]" missing then ObjectName("*:*") |
296 // |
333 // |
297 objectName = ObjectName.WILDCARD; |
334 objectName = ObjectName.WILDCARD; |
|
335 name = name.substring(start); |
298 } else { |
336 } else { |
299 if (!name.endsWith("]")) { |
337 if (!name.endsWith("]")) { |
300 throw new IllegalArgumentException("MBeanPermission: " + |
338 throw new IllegalArgumentException("MBeanPermission: " + |
301 "The ObjectName in the " + |
339 "The ObjectName in the " + |
302 "target name must be " + |
340 "target name must be " + |
303 "included in square " + |
341 "included in square " + |
304 "brackets"); |
342 "brackets"); |
305 } else { |
343 } else { |
306 // Create ObjectName |
344 // Create ObjectName |
307 // |
345 // |
|
346 String on = name.substring(openingBracket + 1, |
|
347 name.length() - 1); |
308 try { |
348 try { |
309 // If "[]" then ObjectName("*:*") |
349 // If "[]" then ObjectName("*:*") |
310 // |
350 // |
311 String on = name.substring(openingBracket + 1, |
|
312 name.length() - 1); |
|
313 if (on.equals("")) |
351 if (on.equals("")) |
314 objectName = ObjectName.WILDCARD; |
352 objectName = ObjectName.WILDCARD; |
315 else if (on.equals("-")) |
353 else if (on.equals("-")) |
316 objectName = null; |
354 objectName = null; |
317 else |
355 else |
318 objectName = new ObjectName(on); |
356 objectName = new ObjectName(on); |
319 } catch (MalformedObjectNameException e) { |
357 } catch (MalformedObjectNameException e) { |
320 throw new IllegalArgumentException("MBeanPermission: " + |
358 throw new IllegalArgumentException("MBeanPermission: " + |
321 "The target name does " + |
359 "The target name does " + |
322 "not specify a valid " + |
360 "not specify a valid " + |
323 "ObjectName"); |
361 "ObjectName", e); |
324 } |
362 } |
325 } |
363 } |
326 |
364 |
327 name = name.substring(0, openingBracket); |
365 name = name.substring(start, openingBracket); |
328 } |
366 } |
329 |
367 |
330 // Parse member |
368 // Parse member |
331 |
369 |
332 int poundSign = name.indexOf("#"); |
370 int poundSign = name.indexOf("#"); |
346 |
384 |
347 /** |
385 /** |
348 * Assign fields based on className, member, and objectName |
386 * Assign fields based on className, member, and objectName |
349 * parameters. |
387 * parameters. |
350 */ |
388 */ |
351 private void initName(String className, String member, |
389 private void initName(String mbeanServerName, String className, |
352 ObjectName objectName) { |
390 String member, ObjectName objectName) { |
|
391 setMBeanServerName(mbeanServerName); |
353 setClassName(className); |
392 setClassName(className); |
354 setMember(member); |
393 setMember(member); |
355 this.objectName = objectName; |
394 this.objectName = objectName; |
356 } |
395 } |
357 |
396 |
379 this.member = "*"; |
418 this.member = "*"; |
380 else |
419 else |
381 this.member = member; |
420 this.member = member; |
382 } |
421 } |
383 |
422 |
|
423 private void setMBeanServerName(String mbeanServerName) { |
|
424 if (mbeanServerName == null || mbeanServerName.equals("-")) { |
|
425 this.mbeanServerName = null; |
|
426 } else if (mbeanServerName.equals("")) { |
|
427 this.mbeanServerName = "*"; |
|
428 } else { |
|
429 this.mbeanServerName = mbeanServerName; |
|
430 } |
|
431 } |
|
432 |
|
433 |
384 /** |
434 /** |
385 * <p>Create a new MBeanPermission object with the specified target name |
435 * <p>Create a new MBeanPermission object with the specified target name |
386 * and actions.</p> |
436 * and actions.</p> |
387 * |
437 * |
388 * <p>The target name is of the form |
438 * <p>The target name is of the form |
389 * "<code>className#member[objectName]</code>" where each part is |
439 * "<code>mbeanServerName::className#member[objectName]</code>" where |
390 * optional. It must not be empty or null.</p> |
440 * each part is optional. It must not be empty or null.</p> |
391 * |
441 * |
392 * <p>The actions parameter contains a comma-separated list of the |
442 * <p>The actions parameter contains a comma-separated list of the |
393 * desired actions granted on the target name. It must not be |
443 * desired actions granted on the target name. It must not be |
394 * empty or null.</p> |
444 * empty or null.</p> |
395 * |
445 * |
396 * @param name the triplet "className#member[objectName]". |
446 * @param name the quadruplet "mbeanServerName::className#member[objectName]". |
397 * @param actions the action string. |
447 * @param actions the action string. |
398 * |
448 * |
399 * @exception IllegalArgumentException if the <code>name</code> or |
449 * @exception IllegalArgumentException if the <code>name</code> or |
400 * <code>actions</code> is invalid. |
450 * <code>actions</code> is invalid. |
401 */ |
451 */ |
415 * <p>The class name, member and object name parameters define a |
465 * <p>The class name, member and object name parameters define a |
416 * target name of the form |
466 * target name of the form |
417 * "<code>className#member[objectName]</code>" where each part is |
467 * "<code>className#member[objectName]</code>" where each part is |
418 * optional. This will be the result of {@link #getName()} on the |
468 * optional. This will be the result of {@link #getName()} on the |
419 * resultant MBeanPermission.</p> |
469 * resultant MBeanPermission.</p> |
|
470 * |
|
471 * <p>This corresponds to a permission granted for all |
|
472 * MBean servers present in the JVM and is equivalent to |
|
473 * {@link #MBeanPermission(String,String,String,ObjectName,String) |
|
474 * MBeanPermission("*",className,member,objectName,actions)}. |
|
475 * </p> |
420 * |
476 * |
421 * <p>The actions parameter contains a comma-separated list of the |
477 * <p>The actions parameter contains a comma-separated list of the |
422 * desired actions granted on the target name. It must not be |
478 * desired actions granted on the target name. It must not be |
423 * empty or null.</p> |
479 * empty or null.</p> |
424 * |
480 * |
437 */ |
493 */ |
438 public MBeanPermission(String className, |
494 public MBeanPermission(String className, |
439 String member, |
495 String member, |
440 ObjectName objectName, |
496 ObjectName objectName, |
441 String actions) { |
497 String actions) { |
442 |
498 this("*",className,member,objectName,actions); |
443 super(makeName(className, member, objectName)); |
499 } |
444 initName(className, member, objectName); |
500 |
|
501 /** |
|
502 * <p>Create a new MBeanPermission object with the specified target name |
|
503 * (MBean Server name, class name, member, object name) and actions.</p> |
|
504 * |
|
505 * <p>The MBean Server name, class name, member and object name |
|
506 * parameters define a target name of the form |
|
507 * "<code>mbeanServerName::className#member[objectName]</code>" where each |
|
508 * part is optional. This will be the result of {@link #getName()} on the |
|
509 * resultant MBeanPermission. |
|
510 * If the <code>mbeanServerName</code> is empty or exactly {@code "*"}, then |
|
511 * "{@code mbeanServerName::}" is omitted in that result. |
|
512 * </p> |
|
513 * |
|
514 * <p>The actions parameter contains a comma-separated list of the |
|
515 * desired actions granted on the target name. It must not be |
|
516 * empty or null.</p> |
|
517 * |
|
518 * @param mbeanServerName the name of the {@code MBeanServer} to which this |
|
519 * permission applies. |
|
520 * May be null or <code>"-"</code>, which represents an MBeanServer name |
|
521 * that is implied by any MBeanServer name but does not imply any other |
|
522 * MBeanServer name. |
|
523 * @param className the class name to which this permission applies. |
|
524 * May be null or <code>"-"</code>, which represents a class name |
|
525 * that is implied by any class name but does not imply any other |
|
526 * class name. |
|
527 * @param member the member to which this permission applies. May |
|
528 * be null or <code>"-"</code>, which represents a member that is |
|
529 * implied by any member but does not imply any other member. |
|
530 * @param objectName the object name to which this permission |
|
531 * applies. May be null, which represents an object name that is |
|
532 * implied by any object name but does not imply any other object |
|
533 * name. |
|
534 * @param actions the action string. |
|
535 * |
|
536 * @since 1.7 |
|
537 */ |
|
538 public MBeanPermission(String mbeanServerName, |
|
539 String className, |
|
540 String member, |
|
541 ObjectName objectName, |
|
542 String actions) { |
|
543 |
|
544 super(makeName(mbeanServerName,className, member, objectName)); |
|
545 initName(mbeanServerName,className, member, objectName); |
445 |
546 |
446 this.actions = actions; |
547 this.actions = actions; |
447 parseActions(); |
548 parseActions(); |
448 } |
549 } |
449 |
550 |
450 private static String makeName(String className, String member, |
551 private static String makeName(String mbeanServerName, String className, |
|
552 String member, |
451 ObjectName objectName) { |
553 ObjectName objectName) { |
452 final StringBuilder name = new StringBuilder(); |
554 final StringBuilder name = new StringBuilder(); |
|
555 if (mbeanServerName == null) |
|
556 mbeanServerName = "-"; |
|
557 if (!mbeanServerName.equals("") && !mbeanServerName.equals("*")) |
|
558 name.append(mbeanServerName).append("::"); |
453 if (className == null) |
559 if (className == null) |
454 className = "-"; |
560 className = "-"; |
455 name.append(className); |
561 name.append(className); |
456 if (member == null) |
562 if (member == null) |
457 member = "-"; |
563 member = "-"; |
1001 * object name matches this object's object name; and</li> |
1110 * object name matches this object's object name; and</li> |
1002 * |
1111 * |
1003 * <li> <i>p</i>'s actions are a subset of this object's actions</li> |
1112 * <li> <i>p</i>'s actions are a subset of this object's actions</li> |
1004 * |
1113 * |
1005 * </ul> |
1114 * </ul> |
|
1115 * |
|
1116 * <p>If this object's mbeanServerName is a pattern, then <i>p</i>'s |
|
1117 * mbeanServerName is matched against that pattern. An empty |
|
1118 * mbeanServerName is equivalent to "{@code *}". A null |
|
1119 * mbeanServerName is equivalent to "{@code -}".</p> |
|
1120 * <p>If this object's mbeanServerName is "<code>*</code>" or is |
|
1121 * empty, <i>p</i>'s mbeanServerName always matches it.</p> |
1006 * |
1122 * |
1007 * <p>If this object's className is "<code>*</code>", <i>p</i>'s |
1123 * <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 |
1124 * 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> |
1125 * className matches it if it begins with "<code>a.</code>".</p> |
1010 * |
1126 * |
1047 return false; |
1163 return false; |
1048 } |
1164 } |
1049 } |
1165 } |
1050 |
1166 |
1051 // Target name |
1167 // Target name |
|
1168 // |
|
1169 // The 'mbeanServerName' check is true iff: |
|
1170 // 1) the mbeanServerName in 'this' permission is omitted or "*", or |
|
1171 // 2) the mbeanServerName in 'that' permission is omitted or "*", or |
|
1172 // 3) the mbeanServerName in 'this' permission does pattern |
|
1173 // matching with the mbeanServerName in 'that' permission. |
1052 // |
1174 // |
1053 // The 'className' check is true iff: |
1175 // The 'className' check is true iff: |
1054 // 1) the className in 'this' permission is omitted or "*", or |
1176 // 1) the className in 'this' permission is omitted or "*", or |
1055 // 2) the className in 'that' permission is omitted or "*", or |
1177 // 2) the className in 'that' permission is omitted or "*", or |
1056 // 3) the className in 'this' permission does pattern |
1178 // 3) the className in 'this' permission does pattern |
1074 If that.classNamePrefix is empty that means the className is |
1196 If that.classNamePrefix is empty that means the className is |
1075 irrelevant for this permission check. Otherwise, we do not |
1197 irrelevant for this permission check. Otherwise, we do not |
1076 expect that "that" contains a wildcard, since it is a |
1198 expect that "that" contains a wildcard, since it is a |
1077 needed permission. So we assume that.classNameExactMatch. */ |
1199 needed permission. So we assume that.classNameExactMatch. */ |
1078 |
1200 |
|
1201 if (that.mbeanServerName == null) { |
|
1202 // bottom is implied |
|
1203 } else if (this.mbeanServerName == null) { |
|
1204 // bottom implies nothing but itself |
|
1205 return false; |
|
1206 } else if (that.mbeanServerName.equals(this.mbeanServerName)) { |
|
1207 // exact match |
|
1208 } else if (!Util.wildmatch(that.mbeanServerName,this.mbeanServerName)) { |
|
1209 return false; // no match |
|
1210 } |
|
1211 |
1079 if (that.classNamePrefix == null) { |
1212 if (that.classNamePrefix == null) { |
1080 // bottom is implied |
1213 // bottom is implied |
1081 } else if (this.classNamePrefix == null) { |
1214 } else if (this.classNamePrefix == null) { |
1082 // bottom implies nothing but itself |
1215 // bottom implies nothing but itself |
1083 return false; |
1216 return false; |