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