1. /*
  2. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  3. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  4. */
  5. package javax.security.auth;
  6. /**
  7. * <p> This is an abstract class for representing the system policy for
  8. * Subject-based authorization. A subclass implementation
  9. * of this class provides a means to specify a Subject-based
  10. * access control <code>Policy</code>.
  11. *
  12. * <p> A <code>Policy</code> object can be queried for the set of
  13. * Permissions granted to code running as a
  14. * <code>Principal</code> in the following manner:
  15. *
  16. * <pre>
  17. * policy = Policy.getPolicy();
  18. * PermissionCollection perms = policy.getPermissions(subject,
  19. * codeSource);
  20. * </pre>
  21. *
  22. * The <code>Policy</code> object consults the local policy and returns
  23. * and appropriate <code>Permissions</code> object with the
  24. * Permissions granted to the Principals associated with the
  25. * provided <i>subject</i>, and granted to the code specified
  26. * by the provided <i>codeSource</i>.
  27. *
  28. * <p> A <code>Policy</code> contains the following information.
  29. * Note that this example only represents the syntax for the default
  30. * <code>Policy</code> implementation. Subclass implementations of this class
  31. * may implement alternative syntaxes and may retrieve the
  32. * <code>Policy</code> from any source such as files, databases,
  33. * or servers.
  34. *
  35. * <p> Each entry in the <code>Policy</code> is represented as
  36. * a <b><i>grant</i></b> entry. Each <b><i>grant</i></b> entry
  37. * specifies a codebase, code signers, and Principals triplet,
  38. * as well as the Permissions granted to that triplet.
  39. *
  40. * <pre>
  41. * grant CodeBase ["URL"], Signedby ["signers"],
  42. * Principal [Principal_Class] "Principal_Name" {
  43. * Permission Permission_Class ["Target_Name"]
  44. * [, "Permission_Actions"]
  45. * [, signedBy "SignerName"];
  46. * };
  47. * </pre>
  48. *
  49. * The CodeBase and Signedby components of the triplet name/value pairs
  50. * are optional. If they are not present, then any any codebase will match,
  51. * and any signer (including unsigned code) will match.
  52. * For Example,
  53. *
  54. * <pre>
  55. * grant CodeBase "foo.com", Signedby "foo",
  56. * Principal com.sun.security.auth.SolarisPrincipal "duke" {
  57. * permission java.io.FilePermission "/home/duke", "read, write";
  58. * };
  59. * </pre>
  60. *
  61. * This <b><i>grant</i></b> entry specifies that code from "foo.com",
  62. * signed by "foo', and running as a <code>SolarisPrincipal</code> with the
  63. * name, duke, has one <code>Permission</code>. This <code>Permission</code>
  64. * permits the executing code to read and write files in the directory,
  65. * "/home/duke".
  66. *
  67. * <p> To "run" as a particular <code>Principal</code>,
  68. * code invokes the <code>Subject.doAs(subject, ...)</code> method.
  69. * After invoking that method, the code runs as all the Principals
  70. * associated with the specified <code>Subject</code>.
  71. * Note that this <code>Policy</code> (and the Permissions
  72. * granted in this <code>Policy</code>) only become effective
  73. * after the call to <code>Subject.doAs</code> has occurred.
  74. *
  75. * <p> Multiple Principals may be listed within one <b><i>grant</i></b> entry.
  76. * All the Principals in the grant entry must be associated with
  77. * the <code>Subject</code> provided to <code>Subject.doAs</code>
  78. * for that <code>Subject</code> to be granted the specified Permissions.
  79. *
  80. * <pre>
  81. * grant Principal com.sun.security.auth.SolarisPrincipal "duke",
  82. * Principal com.sun.security.auth.SolarisNumericUserPrincipal "0" {
  83. * permission java.io.FilePermission "/home/duke", "read, write";
  84. * permission java.net.SocketPermission "duke.com", "connect";
  85. * };
  86. * </pre>
  87. *
  88. * This entry grants any code running as both "duke" and "0"
  89. * permission to read and write files in duke's home directory,
  90. * as well as permission to make socket connections to "duke.com".
  91. *
  92. * <p> Note that non Principal-based grant entries are not permitted
  93. * in this <code>Policy</code>. Therefore, grant entries such as:
  94. *
  95. * <pre>
  96. * grant CodeBase "foo.com", Signedby "foo" {
  97. * permission java.io.FilePermission "/tmp/scratch", "read, write";
  98. * };
  99. * </pre>
  100. *
  101. * are rejected. Such permission must be listed in the
  102. * <code>java.security.Policy</code>.
  103. *
  104. * <p> The default <code>Policy</code> implementation can be changed by
  105. * setting the value of the "auth.policy.provider" security property
  106. * (in the Java security properties file) to the fully qualified name of
  107. * the desired <code>Policy</code> implementation class.
  108. * The Java security properties file is located in the file named
  109. * <JAVA_HOME>/lib/security/java.security, where <JAVA_HOME>
  110. * refers to the directory where the JDK was installed.
  111. *
  112. * @version 1.39, 01/25/00
  113. */
  114. public abstract class Policy {
  115. // XXX
  116. // there are two approaches for the JAAS policy implementation:
  117. //
  118. // 1) make this a subclass implementation of java.security.Policy,
  119. // where getPermissions takes a SubjectCodeSource,
  120. // and SubjectCodeSource is a public class
  121. //
  122. // this would work, but it would require people to
  123. // reconfigure the standard policy.provider to be
  124. // javax.security.auth.Policy.
  125. //
  126. // it also requires SubjectCodeSource to be a public class.
  127. // because of the way getPermissions is implemented in
  128. // the JDK, there's some ugliness in SubjectCodeSource.
  129. // it represents a runtime Subject as a Subject object,
  130. // but it must represent Subject from the policy as
  131. // a linked list of Principals (because it can't reliably
  132. // instantiate a Principal from the information contained
  133. // in the Policy). either exposing this ugliness or
  134. // finding a workaround is not palatable.
  135. //
  136. // finally, because of bug 4202504, policy implementations
  137. // in standard extensions can't even be specified in
  138. // the policy.provider property.
  139. //
  140. // 2) have an abstract javax.security.auth.Policy,
  141. // where getPermissions takes a Subject and a CodeSource
  142. //
  143. // the upside of this is that no one has to fiddle with
  144. // policy.provider, we can keep the SubjectCodeSource
  145. // package private, and we can ignore bug 4202504.
  146. //
  147. // the downside is that until JAAS goes into core,
  148. // developers that want to provide their own Policy
  149. // implementation will need to provide two subclass
  150. // implementations (one for java.security.Policy,
  151. // and one for javax.security.auth.Policy).
  152. private static final java.util.ResourceBundle rb =
  153. java.util.ResourceBundle.getBundle("com.sun.security.auth.Resources");
  154. private static Policy policy;
  155. private static ClassLoader sysClassLoader;
  156. static {
  157. sysClassLoader =
  158. (ClassLoader)java.security.AccessController.doPrivileged
  159. (new java.security.PrivilegedAction() {
  160. public Object run() {
  161. return ClassLoader.getSystemClassLoader();
  162. }
  163. });
  164. };
  165. /**
  166. * Sole constructor. (For invocation by subclass constructors, typically
  167. * implicit.)
  168. */
  169. protected Policy() { }
  170. /**
  171. * Returns the installed Policy object.
  172. * This method first calls
  173. * <code>SecurityManager.checkPermission</code> with the
  174. * <code>AuthPermission("getPolicy")</code> permission
  175. * to ensure the caller has permission to get the Policy object.
  176. *
  177. * <p>
  178. *
  179. * @return the installed Policy. The return value can not be
  180. * <code>null</code>.
  181. *
  182. * @exception java.lang.SecurityException if the current thread does not
  183. * have permission to get the Policy object.
  184. */
  185. public static Policy getPolicy() {
  186. java.lang.SecurityManager sm = System.getSecurityManager();
  187. if (sm != null) sm.checkPermission(new AuthPermission("getPolicy"));
  188. return getPolicyNoCheck();
  189. }
  190. /**
  191. * Returns the installed Policy object, skipping the security check.
  192. *
  193. * @return the installed Policy.
  194. *
  195. */
  196. static Policy getPolicyNoCheck() {
  197. if (policy == null) {
  198. synchronized(Policy.class) {
  199. if (policy == null) {
  200. String policy_class = null;
  201. policy_class = (String)
  202. java.security.AccessController.doPrivileged
  203. (new java.security.PrivilegedAction() {
  204. public Object run() {
  205. return java.security.Security.getProperty
  206. ("auth.policy.provider");
  207. }
  208. });
  209. if (policy_class == null) {
  210. policy_class = "com.sun.security.auth.PolicyFile";
  211. }
  212. try {
  213. final String finalClass = policy_class;
  214. policy = (Policy)
  215. java.security.AccessController.doPrivileged
  216. (new java.security.PrivilegedExceptionAction() {
  217. public Object run() throws ClassNotFoundException,
  218. InstantiationException,
  219. IllegalAccessException {
  220. return Class.forName
  221. (finalClass,
  222. true,
  223. sysClassLoader).newInstance();
  224. }
  225. });
  226. } catch (Exception e) {
  227. throw new SecurityException
  228. (rb.getString
  229. ("unable to instantiate Subject-based policy"));
  230. }
  231. }
  232. }
  233. }
  234. return policy;
  235. }
  236. /**
  237. * Sets the system-wide Policy object. This method first calls
  238. * <code>SecurityManager.checkPermission</code> with the
  239. * <code>AuthPermission("setPolicy")</code>
  240. * permission to ensure the caller has permission to set the Policy.
  241. *
  242. * <p>
  243. *
  244. * @param policy the new system Policy object.
  245. *
  246. * @exception java.lang.SecurityException if the current thread does not
  247. * have permission to set the Policy.
  248. */
  249. public static void setPolicy(Policy policy) {
  250. java.lang.SecurityManager sm = System.getSecurityManager();
  251. if (sm != null) sm.checkPermission(new AuthPermission("setPolicy"));
  252. Policy.policy = policy;
  253. }
  254. /**
  255. * Retrieve the Permissions granted to the Principals associated with
  256. * the specified <code>CodeSource</code>.
  257. *
  258. * <p>
  259. *
  260. * @param subject the <code>Subject</code>
  261. * whose associated Principals,
  262. * in conjunction with the provided
  263. * <code>CodeSource</code>, determines the Permissions
  264. * returned by this method. This parameter
  265. * may be <code>null</code>. <p>
  266. *
  267. * @param cs the code specified by its <code>CodeSource</code>
  268. * that determines, in conjunction with the provided
  269. * <code>Subject</code>, the Permissions
  270. * returned by this method. This parameter may be
  271. * <code>null</code>.
  272. *
  273. * @return the Collection of Permissions granted to all the
  274. * <code>Subject</code> and code specified in
  275. * the provided <i>subject</i> and <i>cs</i>
  276. * parameters.
  277. */
  278. public abstract java.security.PermissionCollection getPermissions
  279. (Subject subject,
  280. java.security.CodeSource cs);
  281. /**
  282. * Refresh and reload the Policy.
  283. *
  284. * <p>This method causes this object to refresh/reload its current
  285. * Policy. This is implementation-dependent.
  286. * For example, if the Policy object is stored in
  287. * a file, calling <code>refresh</code> will cause the file to be re-read.
  288. *
  289. * <p>
  290. *
  291. * @exception SecurityException if the caller does not have permission
  292. * to refresh the Policy.
  293. */
  294. public abstract void refresh();
  295. }