1 /* AccessControlContext.java --- Access Control Context Class 2 Copyright (C) 1999, 2004 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 package java.security; 39 40 import java.util.HashSet; 41 42 /** 43 * AccessControlContext makes system resource access decsion 44 * based on permission rights. 45 * 46 * It is used for a specific context and has only one method 47 * checkPermission. It is similar to AccessController except 48 * that it makes decsions based on the current context instead 49 * of the the current thread. 50 * 51 * It is created by call AccessController.getContext method. 52 * 53 * @author Mark Benvenuto 54 * @since 1.2 55 */ 56 public final class AccessControlContext 57 { 58 private final ProtectionDomain[] protectionDomains; 59 private final DomainCombiner combiner; 60 61 /** 62 * Construct a new AccessControlContext with the specified 63 * ProtectionDomains. <code>context</code> must not be 64 * null and duplicates will be removed. 65 * 66 * @param context The ProtectionDomains to use 67 */ AccessControlContext(ProtectionDomain[] context)68 public AccessControlContext(ProtectionDomain[] context) 69 { 70 HashSet domains = new HashSet (context.length); 71 for (int i = 0; i < context.length; i++) 72 domains.add (context[i]); 73 protectionDomains = (ProtectionDomain[]) 74 domains.toArray (new ProtectionDomain[domains.size()]); 75 combiner = null; 76 } 77 78 /** 79 * Construct a new AccessControlContext with the specified 80 * {@link ProtectionDomain}s and {@link DomainCombiner}. 81 * 82 * <p>Code calling this constructor must have a {@link 83 * SecurityPermission} of <i>createAccessControlContext</i>.</p> 84 * 85 * @throws SecurityException If the caller does not have permission 86 * to create an access control context. 87 * @since 1.3 88 */ AccessControlContext(AccessControlContext acc, DomainCombiner combiner)89 public AccessControlContext(AccessControlContext acc, 90 DomainCombiner combiner) 91 { 92 AccessControlContext acc2 = null; 93 SecurityManager sm = System.getSecurityManager (); 94 if (sm != null) 95 { 96 Permission perm = 97 new SecurityPermission ("createAccessControlContext"); 98 99 // The default SecurityManager.checkPermission(perm) just calls 100 // AccessController.checkPermission(perm) which in turn just 101 // calls AccessController.getContext().checkPermission(perm). 102 // This means AccessController.getContext() is called twice, 103 // once for the security check and once by us. It's a very 104 // expensive call (on gcj at least) so if we're using the 105 // default security manager we avoid this duplication. 106 if (sm.getClass() == SecurityManager.class) 107 { 108 acc2 = AccessController.getContext (); 109 acc2.checkPermission (perm); 110 } 111 else 112 sm.checkPermission (perm); 113 } 114 if (acc2 == null) 115 acc2 = AccessController.getContext (); 116 protectionDomains = combiner.combine (acc2.protectionDomains, 117 acc.protectionDomains); 118 this.combiner = combiner; 119 } 120 AccessControlContext(ProtectionDomain[] domains, AccessControlContext acc, DomainCombiner combiner)121 AccessControlContext (ProtectionDomain[] domains, AccessControlContext acc, 122 DomainCombiner combiner) 123 { 124 protectionDomains = combiner.combine (domains, acc.protectionDomains); 125 this.combiner = combiner; 126 } 127 128 /** 129 * Returns the Domain Combiner associated with the AccessControlContext 130 * 131 * @return the DomainCombiner 132 */ getDomainCombiner()133 public DomainCombiner getDomainCombiner() 134 { 135 return combiner; 136 } 137 138 /** 139 * Determines whether or not the specific permission is granted 140 * depending on the context it is within. 141 * 142 * @param perm a permission to check 143 * 144 * @throws AccessControlException if the permssion is not permitted 145 */ checkPermission(Permission perm)146 public void checkPermission(Permission perm) throws AccessControlException 147 { 148 if (protectionDomains.length == 0) 149 throw new AccessControlException ("permission " 150 + perm 151 + " not granted: no protection domains"); 152 153 for (int i = 0; i < protectionDomains.length; i++) 154 { 155 final ProtectionDomain domain = protectionDomains[i]; 156 if (!domain.implies(perm)) 157 throw new AccessControlException ("permission " 158 + perm 159 + " not granted: " 160 + domain 161 + " does not imply it."); 162 } 163 } 164 165 /** 166 * Checks if two AccessControlContexts are equal. 167 * 168 * It first checks if obj is an AccessControlContext class, and 169 * then checks if each ProtectionDomain matches. 170 * 171 * @param obj The object to compare this class to 172 * 173 * @return true if equal, false otherwise 174 */ equals(Object obj)175 public boolean equals(Object obj) 176 { 177 if (obj instanceof AccessControlContext) 178 { 179 AccessControlContext acc = (AccessControlContext) obj; 180 181 if (acc.protectionDomains.length != protectionDomains.length) 182 return false; 183 184 int i, j; 185 for (i = 0; i < protectionDomains.length; i++) 186 { 187 for (j = 0; j < acc.protectionDomains.length; j++) 188 { 189 if (acc.protectionDomains[j].equals (protectionDomains[i])) 190 break; 191 } 192 if (j == acc.protectionDomains.length) 193 return false; 194 } 195 return true; 196 } 197 return false; 198 } 199 200 /** 201 * Computes a hash code of this class 202 * 203 * @return a hash code representing this class 204 */ hashCode()205 public int hashCode() 206 { 207 int h = 0; 208 for (int i = 0; i < protectionDomains.length; i++) 209 h ^= protectionDomains[i].hashCode(); 210 211 return h; 212 } 213 getProtectionDomains()214 ProtectionDomain[] getProtectionDomains () 215 { 216 return protectionDomains; 217 } 218 } 219