1 /*
   2  * Copyright (c) 2000, 2012, 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 com.sun.rmi.rmid;
  27 
  28 import java.security.*;
  29 import java.io.*;
  30 import java.util.*;
  31 
  32 /**
  33  * The ExecPermission class represents permission for rmid to execute
  34  * a specific command to launch an activation group.  An ExecPermission
  35  * consists of a pathname of a command to launch an activation group.
  36  * <P>
  37  * Pathname is the pathname of the file or directory to grant rmid
  38  * execute permission.  A pathname that ends in "/*" (where "/" is
  39  * the file separator character, <code>File.separatorChar</code>) indicates
  40  * all the files and directories contained in that directory. A pathname
  41  * that ends with "/-" indicates (recursively) all files
  42  * and subdirectories contained in that directory. A pathname consisting of
  43  * the special token "{@code <<ALL FILES>>}" matches <b>any</b> file.
  44  * <P>
  45  * Note: A pathname consisting of a single "*" indicates all the files
  46  * in the current directory, while a pathname consisting of a single "-"
  47  * indicates all the files in the current directory and
  48  * (recursively) all files and subdirectories contained in the current
  49  * directory.
  50  *
  51  *
  52  * @author Ann Wollrath
  53  *
  54  * @serial exclude
  55  */
  56 public final class ExecPermission extends Permission
  57 {
  58     /**
  59      * UID for serialization
  60      */
  61     private static final long serialVersionUID = -6208470287358147919L;
  62 
  63     private transient FilePermission fp;
  64 
  65     /**
  66      * Creates a new ExecPermission object with the specified path.
  67      * <i>path</i> is the pathname of a file or directory.
  68      *
  69      * <p>A pathname that ends in "/*" (where "/" is
  70      * the file separator character, <code>File.separatorChar</code>) indicates
  71      * a directory and all the files contained in that directory. A pathname
  72      * that ends with "/-" indicates a directory and (recursively) all files
  73      * and subdirectories contained in that directory. The special pathname
  74      * "{@code <<ALL FILES>>}" matches all files.
  75      *
  76      * <p>A pathname consisting of a single "*" indicates all the files
  77      * in the current directory, while a pathname consisting of a single "-"
  78      * indicates all the files in the current directory and
  79      * (recursively) all files and subdirectories contained in the current
  80      * directory.
  81      *
  82      * @param path the pathname of the file/directory.
  83      */
  84     public ExecPermission(String path) {
  85         super(path);
  86         init(path);
  87     }
  88 
  89     /**
  90      * Creates a new ExecPermission object with the specified path.
  91      * <i>path</i> is the pathname of a file or directory.
  92      *
  93      * <p>A pathname that ends in "/*" (where "/" is
  94      * the file separator character, <code>File.separatorChar</code>) indicates
  95      * a directory and all the files contained in that directory. A pathname
  96      * that ends with "/-" indicates a directory and (recursively) all files
  97      * and subdirectories contained in that directory. The special pathname
  98      * "{@code <<ALL FILES>>}" matches all files.
  99      *
 100      * <p>A pathname consisting of a single "*" indicates all the files
 101      * in the current directory, while a pathname consisting of a single "-"
 102      * indicates all the files in the current directory and
 103      * (recursively) all files and subdirectories contained in the current
 104      * directory.
 105      *
 106      * @param path the pathname of the file/directory.
 107      * @param actions the action string (unused)
 108      */
 109     public ExecPermission(String path, String actions) {
 110         this(path);
 111     }
 112 
 113     /**
 114      * Checks if this ExecPermission object "implies" the specified permission.
 115      * <P>
 116      * More specifically, this method returns true if:
 117      * <ul>
 118      * <li> <i>p</i> is an instanceof ExecPermission, and
 119      * <li> <i>p</i>'s pathname is implied by this object's
 120      *      pathname. For example, "/tmp/*" implies "/tmp/foo", since
 121      *      "/tmp/*" encompasses the "/tmp" directory and all files in that
 122      *      directory, including the one named "foo".
 123      * </ul>
 124      * @param p the permission to check against.
 125      *
 126      * @return true if the specified permission is implied by this object,
 127      * false if not.
 128      */
 129     public boolean implies(Permission p) {
 130         if (!(p instanceof ExecPermission))
 131             return false;
 132 
 133         ExecPermission that = (ExecPermission) p;
 134 
 135         return fp.implies(that.fp);
 136     }
 137 
 138     /**
 139      * Checks two ExecPermission objects for equality.
 140      * Checks that <i>obj</i>'s class is the same as this object's class
 141      * and has the same name as this object.
 142      *
 143      * @param obj the object we are testing for equality with this object.
 144      * @return true if <i>obj</i> is an ExecPermission, and has the same
 145      * pathname as this ExecPermission object, false otherwise.
 146      */
 147     public boolean equals(Object obj) {
 148         if (obj == this)
 149             return true;
 150 
 151         if (! (obj instanceof ExecPermission))
 152             return false;
 153 
 154         ExecPermission that = (ExecPermission) obj;
 155 
 156         return fp.equals(that.fp);
 157     }
 158 
 159     /**
 160      * Returns the hash code value for this object.
 161      *
 162      * @return a hash code value for this object.
 163      */
 164     public int hashCode() {
 165         return this.fp.hashCode();
 166     }
 167 
 168     /**
 169      * Returns the canonical string representation of the actions.
 170      *
 171      * @return the canonical string representation of the actions.
 172      */
 173     public String getActions() {
 174         return "";
 175     }
 176 
 177     /**
 178      * Returns a new PermissionCollection object for storing
 179      * ExecPermission objects.
 180      * <p>
 181      * A ExecPermissionCollection stores a collection of
 182      * ExecPermission permissions.
 183      *
 184      * <p>ExecPermission objects must be stored in a manner that allows
 185      * them to be inserted in any order, but that also enables the
 186      * PermissionCollection <code>implies</code> method
 187      * to be implemented in an efficient (and consistent) manner.
 188      *
 189      * @return a new PermissionCollection object suitable for
 190      * storing ExecPermissions.
 191      */
 192     public PermissionCollection newPermissionCollection() {
 193         return new ExecPermissionCollection();
 194     }
 195 
 196     /**
 197      * readObject is called to restore the state of the ExecPermission
 198      * from a stream.
 199      */
 200     private synchronized void readObject(java.io.ObjectInputStream s)
 201          throws IOException, ClassNotFoundException
 202     {
 203         s.defaultReadObject();
 204         // init is called to initialize the rest of the values.
 205         init(getName());
 206     }
 207 
 208     /**
 209      * Initialize a ExecPermission object. Common to all constructors.
 210      * Also called during de-serialization.
 211      */
 212     private void init(String path) {
 213         this.fp = new FilePermission(path, "execute");
 214     }
 215 
 216     /**
 217      * A ExecPermissionCollection stores a collection
 218      * of ExecPermission permissions. ExecPermission objects
 219      * must be stored in a manner that allows them to be inserted in any
 220      * order, but enable the implies function to evaluate the implies
 221      * method in an efficient (and consistent) manner.
 222      *
 223      * @serial include
 224      */
 225     private static class ExecPermissionCollection
 226         extends PermissionCollection
 227         implements java.io.Serializable
 228     {
 229         private Vector<Permission> permissions;
 230 
 231         private static final long serialVersionUID = -3352558508888368273L;
 232 
 233         /**
 234          * Create an empty ExecPermissionCollection.
 235          */
 236         public ExecPermissionCollection() {
 237             permissions = new Vector<>();
 238         }
 239 
 240         /**
 241          * Adds a permission to the collection.
 242          *
 243          * @param permission the Permission object to add.
 244          *
 245          * @exception IllegalArgumentException - if the permission is not a
 246          *                                       ExecPermission
 247          *
 248          * @exception SecurityException - if this ExecPermissionCollection
 249          *                                object has been marked readonly
 250          */
 251         public void add(Permission permission)
 252         {
 253             if (! (permission instanceof ExecPermission))
 254                 throw new IllegalArgumentException("invalid permission: "+
 255                                                    permission);
 256             if (isReadOnly())
 257                 throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
 258 
 259             permissions.addElement(permission);
 260         }
 261 
 262         /**
 263          * Check and see if this set of permissions implies the permissions
 264          * expressed in "permission".
 265          *
 266          * @param p the Permission object to compare
 267          *
 268          * @return true if "permission" is a proper subset of a permission in
 269          * the set, false if not.
 270          */
 271         public boolean implies(Permission permission)
 272         {
 273             if (! (permission instanceof ExecPermission))
 274                 return false;
 275 
 276             Enumeration<Permission> e = permissions.elements();
 277 
 278             while (e.hasMoreElements()) {
 279                 ExecPermission x = (ExecPermission)e.nextElement();
 280                 if (x.implies(permission)) {
 281                     return true;
 282                 }
 283             }
 284             return false;
 285         }
 286 
 287         /**
 288          * Returns an enumeration of all the ExecPermission objects in the
 289          * container.
 290          *
 291          * @return an enumeration of all the ExecPermission objects.
 292          */
 293         public Enumeration<Permission> elements()
 294         {
 295             return permissions.elements();
 296         }
 297     }
 298 }