1 /* 2 * Copyright (c) 1998, 2010, 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 javax.security.auth; 27 28 import java.security.Security; 29 import sun.security.util.Debug; 30 31 /** 32 * <p> This is an abstract class for representing the system policy for 33 * Subject-based authorization. A subclass implementation 34 * of this class provides a means to specify a Subject-based 35 * access control <code>Policy</code>. 36 * 37 * <p> A <code>Policy</code> object can be queried for the set of 38 * Permissions granted to code running as a 39 * <code>Principal</code> in the following manner: 40 * 41 * <pre> 42 * policy = Policy.getPolicy(); 43 * PermissionCollection perms = policy.getPermissions(subject, 44 * codeSource); 45 * </pre> 46 * 47 * The <code>Policy</code> object consults the local policy and returns 48 * and appropriate <code>Permissions</code> object with the 49 * Permissions granted to the Principals associated with the 50 * provided <i>subject</i>, and granted to the code specified 51 * by the provided <i>codeSource</i>. 52 * 53 * <p> A <code>Policy</code> contains the following information. 54 * Note that this example only represents the syntax for the default 55 * <code>Policy</code> implementation. Subclass implementations of this class 56 * may implement alternative syntaxes and may retrieve the 57 * <code>Policy</code> from any source such as files, databases, 58 * or servers. 59 * 60 * <p> Each entry in the <code>Policy</code> is represented as 61 * a <b><i>grant</i></b> entry. Each <b><i>grant</i></b> entry 62 * specifies a codebase, code signers, and Principals triplet, 63 * as well as the Permissions granted to that triplet. 64 * 65 * <pre> 66 * grant CodeBase ["URL"], Signedby ["signers"], 67 * Principal [Principal_Class] "Principal_Name" { 68 * Permission Permission_Class ["Target_Name"] 69 * [, "Permission_Actions"] 70 * [, signedBy "SignerName"]; 71 * }; 72 * </pre> 73 * 74 * The CodeBase and Signedby components of the triplet name/value pairs 75 * are optional. If they are not present, then any any codebase will match, 76 * and any signer (including unsigned code) will match. 77 * For Example, 78 * 79 * <pre> 80 * grant CodeBase "foo.com", Signedby "foo", 81 * Principal com.sun.security.auth.SolarisPrincipal "duke" { 82 * permission java.io.FilePermission "/home/duke", "read, write"; 83 * }; 84 * </pre> 85 * 86 * This <b><i>grant</i></b> entry specifies that code from "foo.com", 87 * signed by "foo', and running as a <code>SolarisPrincipal</code> with the 88 * name, duke, has one <code>Permission</code>. This <code>Permission</code> 89 * permits the executing code to read and write files in the directory, 90 * "/home/duke". 91 * 92 * <p> To "run" as a particular <code>Principal</code>, 93 * code invokes the <code>Subject.doAs(subject, ...)</code> method. 94 * After invoking that method, the code runs as all the Principals 95 * associated with the specified <code>Subject</code>. 96 * Note that this <code>Policy</code> (and the Permissions 97 * granted in this <code>Policy</code>) only become effective 98 * after the call to <code>Subject.doAs</code> has occurred. 99 * 100 * <p> Multiple Principals may be listed within one <b><i>grant</i></b> entry. 101 * All the Principals in the grant entry must be associated with 102 * the <code>Subject</code> provided to <code>Subject.doAs</code> 103 * for that <code>Subject</code> to be granted the specified Permissions. 104 * 105 * <pre> 106 * grant Principal com.sun.security.auth.SolarisPrincipal "duke", 107 * Principal com.sun.security.auth.SolarisNumericUserPrincipal "0" { 108 * permission java.io.FilePermission "/home/duke", "read, write"; 109 * permission java.net.SocketPermission "duke.com", "connect"; 110 * }; 111 * </pre> 112 * 113 * This entry grants any code running as both "duke" and "0" 114 * permission to read and write files in duke's home directory, 115 * as well as permission to make socket connections to "duke.com". 116 * 117 * <p> Note that non Principal-based grant entries are not permitted 118 * in this <code>Policy</code>. Therefore, grant entries such as: 119 * 120 * <pre> 121 * grant CodeBase "foo.com", Signedby "foo" { 122 * permission java.io.FilePermission "/tmp/scratch", "read, write"; 123 * }; 124 * </pre> 125 * 126 * are rejected. Such permission must be listed in the 127 * <code>java.security.Policy</code>. 128 * 129 * <p> The default <code>Policy</code> implementation can be changed by 130 * setting the value of the "auth.policy.provider" security property 131 * (in the Java security properties file) to the fully qualified name of 132 * the desired <code>Policy</code> implementation class. 133 * The Java security properties file is located in the file named 134 * <JAVA_HOME>/lib/security/java.security. 135 * <JAVA_HOME> refers to the value of the java.home system property, 136 * and specifies the directory where the JRE is installed. 137 * 138 * @deprecated as of JDK version 1.4 -- Replaced by java.security.Policy. 139 * java.security.Policy has a method: 140 * <pre> 141 * public PermissionCollection getPermissions 142 * (java.security.ProtectionDomain pd) 143 * 144 * </pre> 145 * and ProtectionDomain has a constructor: 146 * <pre> 147 * public ProtectionDomain 148 * (CodeSource cs, 149 * PermissionCollection permissions, 150 * ClassLoader loader, 151 * Principal[] principals) 152 * </pre> 153 * 154 * These two APIs provide callers the means to query the 155 * Policy for Principal-based Permission entries. 156 * 157 * 158 */ 159 @Deprecated 160 public abstract class Policy { 161 162 private static Policy policy; 163 private static ClassLoader contextClassLoader; 164 165 // true if a custom (not com.sun.security.auth.PolicyFile) system-wide 166 // policy object is set 167 private static boolean isCustomPolicy; 168 169 static { 170 contextClassLoader = java.security.AccessController.doPrivileged 171 (new java.security.PrivilegedAction<ClassLoader>() { 172 public ClassLoader run() { 173 return Thread.currentThread().getContextClassLoader(); 174 } 175 }); 176 }; 177 178 /** 179 * Sole constructor. (For invocation by subclass constructors, typically 180 * implicit.) 181 */ 182 protected Policy() { } 183 184 /** 185 * Returns the installed Policy object. 186 * This method first calls 187 * <code>SecurityManager.checkPermission</code> with the 188 * <code>AuthPermission("getPolicy")</code> permission 189 * to ensure the caller has permission to get the Policy object. 190 * 191 * <p> 192 * 193 * @return the installed Policy. The return value cannot be 194 * <code>null</code>. 195 * 196 * @exception java.lang.SecurityException if the current thread does not 197 * have permission to get the Policy object. 198 * 199 * @see #setPolicy 200 */ 201 public static Policy getPolicy() { 202 java.lang.SecurityManager sm = System.getSecurityManager(); 203 if (sm != null) sm.checkPermission(new AuthPermission("getPolicy")); 204 return getPolicyNoCheck(); 205 } 206 207 /** 208 * Returns the installed Policy object, skipping the security check. 209 * 210 * @return the installed Policy. 211 * 212 */ 213 static Policy getPolicyNoCheck() { 214 if (policy == null) { 215 216 synchronized(Policy.class) { 217 218 if (policy == null) { 219 String policy_class = null; 220 policy_class = java.security.AccessController.doPrivileged 221 (new java.security.PrivilegedAction<String>() { 222 public String run() { 223 return java.security.Security.getProperty 224 ("auth.policy.provider"); 225 } 226 }); 227 if (policy_class == null) { 228 policy_class = "com.sun.security.auth.PolicyFile"; 229 } 230 231 try { 232 final String finalClass = policy_class; 233 policy = java.security.AccessController.doPrivileged 234 (new java.security.PrivilegedExceptionAction<Policy>() { 235 public Policy run() throws ClassNotFoundException, 236 InstantiationException, 237 IllegalAccessException { 238 return (Policy) Class.forName 239 (finalClass, 240 true, 241 contextClassLoader).newInstance(); 242 } 243 }); 244 isCustomPolicy = 245 !finalClass.equals("com.sun.security.auth.PolicyFile"); 246 } catch (Exception e) { 247 throw new SecurityException 248 (sun.security.util.ResourcesMgr.getString 249 ("unable.to.instantiate.Subject.based.policy")); 250 } 251 } 252 } 253 } 254 return policy; 255 } 256 257 258 /** 259 * Sets the system-wide Policy object. This method first calls 260 * <code>SecurityManager.checkPermission</code> with the 261 * <code>AuthPermission("setPolicy")</code> 262 * permission to ensure the caller has permission to set the Policy. 263 * 264 * <p> 265 * 266 * @param policy the new system Policy object. 267 * 268 * @exception java.lang.SecurityException if the current thread does not 269 * have permission to set the Policy. 270 * 271 * @see #getPolicy 272 */ 273 public static void setPolicy(Policy policy) { 274 java.lang.SecurityManager sm = System.getSecurityManager(); 275 if (sm != null) sm.checkPermission(new AuthPermission("setPolicy")); 276 Policy.policy = policy; 277 // all non-null policy objects are assumed to be custom 278 isCustomPolicy = policy != null ? true : false; 279 } 280 281 /** 282 * Returns true if a custom (not com.sun.security.auth.PolicyFile) 283 * system-wide policy object has been set or installed. This method is 284 * called by SubjectDomainCombiner to provide backwards compatibility for 285 * developers that provide their own javax.security.auth.Policy 286 * implementations. 287 * 288 * @return true if a custom (not com.sun.security.auth.PolicyFile) 289 * system-wide policy object has been set; false otherwise 290 */ 291 static boolean isCustomPolicySet(Debug debug) { 292 if (policy != null) { 293 if (debug != null && isCustomPolicy) { 294 debug.println("Providing backwards compatibility for " + 295 "javax.security.auth.policy implementation: " + 296 policy.toString()); 297 } 298 return isCustomPolicy; 299 } 300 // check if custom policy has been set using auth.policy.provider prop 301 String policyClass = java.security.AccessController.doPrivileged 302 (new java.security.PrivilegedAction<String>() { 303 public String run() { 304 return Security.getProperty("auth.policy.provider"); 305 } 306 }); 307 if (policyClass != null 308 && !policyClass.equals("com.sun.security.auth.PolicyFile")) { 309 if (debug != null) { 310 debug.println("Providing backwards compatibility for " + 311 "javax.security.auth.policy implementation: " + 312 policyClass); 313 } 314 return true; 315 } 316 return false; 317 } 318 319 /** 320 * Retrieve the Permissions granted to the Principals associated with 321 * the specified <code>CodeSource</code>. 322 * 323 * <p> 324 * 325 * @param subject the <code>Subject</code> 326 * whose associated Principals, 327 * in conjunction with the provided 328 * <code>CodeSource</code>, determines the Permissions 329 * returned by this method. This parameter 330 * may be <code>null</code>. <p> 331 * 332 * @param cs the code specified by its <code>CodeSource</code> 333 * that determines, in conjunction with the provided 334 * <code>Subject</code>, the Permissions 335 * returned by this method. This parameter may be 336 * <code>null</code>. 337 * 338 * @return the Collection of Permissions granted to all the 339 * <code>Subject</code> and code specified in 340 * the provided <i>subject</i> and <i>cs</i> 341 * parameters. 342 */ 343 public abstract java.security.PermissionCollection getPermissions 344 (Subject subject, 345 java.security.CodeSource cs); 346 347 /** 348 * Refresh and reload the Policy. 349 * 350 * <p>This method causes this object to refresh/reload its current 351 * Policy. This is implementation-dependent. 352 * For example, if the Policy object is stored in 353 * a file, calling <code>refresh</code> will cause the file to be re-read. 354 * 355 * <p> 356 * 357 * @exception SecurityException if the caller does not have permission 358 * to refresh the Policy. 359 */ 360 public abstract void refresh(); 361 }