blob: dd486bef8d6e9075ae9a1734fa8118de75dd6056 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.rmi.rmid;
27
28import java.security.*;
29import java.io.*;
30import java.util.*;
31
32/**
33 * The ExecOptionPermission class represents permission for rmid to use
34 * a specific command-line option when launching an activation group.
35 * <P>
36 *
37 * @author Ann Wollrath
38 *
39 * @serial exclude
40 */
41public final class ExecOptionPermission extends Permission
42{
43 /**
44 * does this permission have a wildcard at the end?
45 */
46 private transient boolean wildcard;
47
48 /**
49 * the name without the wildcard on the end
50 */
51 private transient String name;
52
53 /**
54 * UID for serialization
55 */
56 private static final long serialVersionUID = 5842294756823092756L;
57
58 public ExecOptionPermission(String name) {
59 super(name);
60 init(name);
61 }
62
63 public ExecOptionPermission(String name, String actions) {
64 this(name);
65 }
66
67 /**
68 * Checks if the specified permission is "implied" by
69 * this object.
70 * <P>
71 * More specifically, this method returns true if:<p>
72 * <ul>
73 * <li> <i>p</i>'s class is the same as this object's class, and<p>
74 * <li> <i>p</i>'s name equals or (in the case of wildcards)
75 * is implied by this object's
76 * name. For example, "a.b.*" implies "a.b.c", and
77 * "a.b=*" implies "a.b=c"
78 * </ul>
79 *
80 * @param p the permission to check against.
81 *
82 * @return true if the passed permission is equal to or
83 * implied by this permission, false otherwise.
84 */
85 public boolean implies(Permission p) {
86 if (!(p instanceof ExecOptionPermission))
87 return false;
88
89 ExecOptionPermission that = (ExecOptionPermission) p;
90
91 if (this.wildcard) {
92 if (that.wildcard) {
93 // one wildcard can imply another
94 return that.name.startsWith(name);
95 } else {
96 // make sure p.name is longer so a.b.* doesn't imply a.b
97 return (that.name.length() > this.name.length()) &&
98 that.name.startsWith(this.name);
99 }
100 } else {
101 if (that.wildcard) {
102 // a non-wildcard can't imply a wildcard
103 return false;
104 } else {
105 return this.name.equals(that.name);
106 }
107 }
108 }
109
110 /**
111 * Checks two ExecOptionPermission objects for equality.
112 * Checks that <i>obj</i>'s class is the same as this object's class
113 * and has the same name as this object.
114 * <P>
115 * @param obj the object we are testing for equality with this object.
116 * @return true if <i>obj</i> is an ExecOptionPermission, and has the same
117 * name as this ExecOptionPermission object, false otherwise.
118 */
119 public boolean equals(Object obj) {
120 if (obj == this)
121 return true;
122
123 if ((obj == null) || (obj.getClass() != getClass()))
124 return false;
125
126 ExecOptionPermission that = (ExecOptionPermission) obj;
127
128 return this.getName().equals(that.getName());
129 }
130
131
132 /**
133 * Returns the hash code value for this object.
134 * The hash code used is the hash code of the name, that is,
135 * <code>getName().hashCode()</code>, where <code>getName</code> is
136 * from the Permission superclass.
137 *
138 * @return a hash code value for this object.
139 */
140 public int hashCode() {
141 return this.getName().hashCode();
142 }
143
144 /**
145 * Returns the canonical string representation of the actions.
146 *
147 * @return the canonical string representation of the actions.
148 */
149 public String getActions() {
150 return "";
151 }
152
153 /**
154 * Returns a new PermissionCollection object for storing
155 * ExecOptionPermission objects.
156 * <p>
157 * A ExecOptionPermissionCollection stores a collection of
158 * ExecOptionPermission permissions.
159 *
160 * <p>ExecOptionPermission objects must be stored in a manner that allows
161 * them to be inserted in any order, but that also enables the
162 * PermissionCollection <code>implies</code> method
163 * to be implemented in an efficient (and consistent) manner.
164 *
165 * @return a new PermissionCollection object suitable for
166 * storing ExecOptionPermissions.
167 */
168 public PermissionCollection newPermissionCollection() {
169 return new ExecOptionPermissionCollection();
170 }
171
172 /**
173 * readObject is called to restore the state of the ExecOptionPermission
174 * from a stream.
175 */
176 private synchronized void readObject(java.io.ObjectInputStream s)
177 throws IOException, ClassNotFoundException
178 {
179 s.defaultReadObject();
180 // init is called to initialize the rest of the values.
181 init(getName());
182 }
183
184 /**
185 * Initialize a ExecOptionPermission object. Common to all constructors.
186 * Also called during de-serialization.
187 */
188 private void init(String name)
189 {
190 if (name == null)
191 throw new NullPointerException("name can't be null");
192
193 if (name.equals("")) {
194 throw new IllegalArgumentException("name can't be empty");
195 }
196
197 if (name.endsWith(".*") || name.endsWith("=*") || name.equals("*")) {
198 wildcard = true;
199 if (name.length() == 1) {
200 this.name = "";
201 } else {
202 this.name = name.substring(0, name.length()-1);
203 }
204 } else {
205 this.name = name;
206 }
207 }
208
209 /**
210 * A ExecOptionPermissionCollection stores a collection
211 * of ExecOptionPermission permissions. ExecOptionPermission objects
212 * must be stored in a manner that allows them to be inserted in any
213 * order, but enable the implies function to evaluate the implies
214 * method in an efficient (and consistent) manner.
215 *
216 * A ExecOptionPermissionCollection handles comparing a permission like
217 * "a.b.c.d.e" * with a Permission such as "a.b.*", or "*".
218 *
219 * @serial include
220 */
221 private static class ExecOptionPermissionCollection
222 extends PermissionCollection
223 implements java.io.Serializable
224 {
225
226 private Hashtable permissions;
227 private boolean all_allowed; // true if "*" is in the collection
228 private static final long serialVersionUID = -1242475729790124375L;
229
230 /**
231 * Create an empty ExecOptionPermissionCollection.
232 */
233 public ExecOptionPermissionCollection() {
234 permissions = new Hashtable(11);
235 all_allowed = false;
236 }
237
238 /**
239 * Adds a permission to the collection. The key for the hash is
240 * permission.name.
241 *
242 * @param permission the Permission object to add.
243 *
244 * @exception IllegalArgumentException - if the permission is not a
245 * ExecOptionPermission
246 *
247 * @exception SecurityException - if this ExecOptionPermissionCollection
248 * object has been marked readonly
249 */
250
251 public void add(Permission permission)
252 {
253 if (! (permission instanceof ExecOptionPermission))
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 ExecOptionPermission p = (ExecOptionPermission) permission;
260
261 permissions.put(p.getName(), permission);
262 if (!all_allowed) {
263 if (p.getName().equals("*"))
264 all_allowed = true;
265 }
266 }
267
268 /**
269 * Check and see if this set of permissions implies the permissions
270 * expressed in "permission".
271 *
272 * @param p the Permission object to compare
273 *
274 * @return true if "permission" is a proper subset of a permission in
275 * the set, false if not.
276 */
277 public boolean implies(Permission permission)
278 {
279 if (! (permission instanceof ExecOptionPermission))
280 return false;
281
282 ExecOptionPermission p = (ExecOptionPermission) permission;
283
284 // short circuit if the "*" Permission was added
285 if (all_allowed)
286 return true;
287
288 // strategy:
289 // Check for full match first. Then work our way up the
290 // name looking for matches on a.b.*
291
292 String pname = p.getName();
293
294 Permission x = (Permission) permissions.get(pname);
295
296 if (x != null)
297 // we have a direct hit!
298 return x.implies(permission);
299
300
301 // work our way up the tree...
302 int last, offset;
303
304 offset = pname.length() - 1;
305
306 while ((last = pname.lastIndexOf(".", offset)) != -1) {
307
308 pname = pname.substring(0, last+1) + "*";
309 x = (Permission) permissions.get(pname);
310
311 if (x != null) {
312 return x.implies(permission);
313 }
314 offset = last - 1;
315 }
316
317 // check for "=*" wildcard match
318 pname = p.getName();
319 offset = pname.length() - 1;
320
321 while ((last = pname.lastIndexOf("=", offset)) != -1) {
322
323 pname = pname.substring(0, last+1) + "*";
324 x = (Permission) permissions.get(pname);
325
326 if (x != null) {
327 return x.implies(permission);
328 }
329 offset = last - 1;
330 }
331
332 // we don't have to check for "*" as it was already checked
333 // at the top (all_allowed), so we just return false
334 return false;
335 }
336
337 /**
338 * Returns an enumeration of all the ExecOptionPermission objects in the
339 * container.
340 *
341 * @return an enumeration of all the ExecOptionPermission objects.
342 */
343
344 public Enumeration elements()
345 {
346 return permissions.elements();
347 }
348 }
349}