jdk/src/share/classes/javax/management/MBeanPermission.java
changeset 1156 bbc2d15aaf7a
parent 2 90ce3da70b43
child 1247 b4c26443dee5
equal deleted inserted replaced
1155:a9a142fcf1b5 1156:bbc2d15aaf7a
    23  * have any questions.
    23  * have any questions.
    24  */
    24  */
    25 
    25 
    26 package javax.management;
    26 package javax.management;
    27 
    27 
       
    28 import com.sun.jmx.mbeanserver.Util;
    28 import java.io.IOException;
    29 import java.io.IOException;
    29 import java.io.ObjectInputStream;
    30 import java.io.ObjectInputStream;
    30 import java.security.Permission;
    31 import java.security.Permission;
    31 
    32 
    32 /**
    33 /**
    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  *
   245      * objectName but does not imply any non-null objectName.
   266      * objectName but does not imply any non-null objectName.
   246      */
   267      */
   247     private transient ObjectName objectName;
   268     private transient ObjectName objectName;
   248 
   269 
   249     /**
   270     /**
       
   271      * The name of the MBeanServer in which this permission is checked, or
       
   272      * granted.  If null, is implied by any MBean Server name
       
   273      * but does not imply any non-null MBean Server name.
       
   274      */
       
   275     private transient String mbeanServerName;
       
   276 
       
   277     /**
   250      * Parse <code>actions</code> parameter.
   278      * Parse <code>actions</code> parameter.
   251      */
   279      */
   252     private void parseActions() {
   280     private void parseActions() {
   253 
   281 
   254         int mask;
   282         int mask;
   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 = "-";
   989      *
  1095      *
   990      * <ul>
  1096      * <ul>
   991      *
  1097      *
   992      * <li> <i>p</i> is an instance of MBeanPermission; and</li>
  1098      * <li> <i>p</i> is an instance of MBeanPermission; and</li>
   993      *
  1099      *
       
  1100      * <li> <i>p</i> has a null mbeanServerName or <i>p</i>'s mbeanServerName
       
  1101      * matches this object's mbeanServerName; and</li>
       
  1102      *
   994      * <li> <i>p</i> has a null className or <i>p</i>'s className
  1103      * <li> <i>p</i> has a null className or <i>p</i>'s className
   995      * matches this object's className; and</li>
  1104      * matches this object's className; and</li>
   996      *
  1105      *
   997      * <li> <i>p</i> has a null member or <i>p</i>'s member matches this
  1106      * <li> <i>p</i> has a null member or <i>p</i>'s member matches this
   998      * object's member; and</li>
  1107      * object's member; and</li>
  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;