KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jmx > remote > security > MBeanServerFileAccessController


1 /*
2  * @(#)MBeanServerFileAccessController.java 1.9 04/04/02
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.jmx.remote.security;
9
10 import java.io.FileInputStream JavaDoc;
11 import java.io.IOException JavaDoc;
12 import java.security.AccessControlContext JavaDoc;
13 import java.security.AccessController JavaDoc;
14 import java.security.Principal JavaDoc;
15 import java.security.PrivilegedAction JavaDoc;
16 import java.util.Collection JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.Properties JavaDoc;
19 import java.util.Set JavaDoc;
20 import javax.management.MBeanServer JavaDoc;
21 import javax.security.auth.Subject JavaDoc;
22
23 /**
24  * <p>An object of this class implements the MBeanServerAccessController
25  * interface and, for each of its methods, calls an appropriate checking
26  * method and then forwards the request to a wrapped MBeanServer object.
27  * The checking method may throw a SecurityException if the operation is
28  * not allowed; in this case the request is not forwarded to the
29  * wrapped object.</p>
30  *
31  * <p>This class implements the {@link #checkRead()} and {@link #checkWrite()}
32  * methods based on an access level properties file containing username/access
33  * level pairs. The set of username/access level pairs is passed either as a
34  * filename which denotes a properties file on disk, or directly as an instance
35  * of the {@link Properties} class. In both cases, the name of each property
36  * represents a username, and the value of the property is the associated access
37  * level. Thus, any given username either does not exist in the properties or
38  * has exactly one access level. The same access level can be shared by several
39  * usernames.</p>
40  *
41  * <p>The supported access level values are <i>readonly</i> and
42  * <i>readwrite</i>.</p>
43  */

44 public class MBeanServerFileAccessController
45     extends MBeanServerAccessController {
46
47     public static final String JavaDoc READONLY = "readonly";
48     public static final String JavaDoc READWRITE = "readwrite";
49
50     /**
51      * <p>Create a new MBeanServerAccessController that forwards all the
52      * MBeanServer requests to the MBeanServer set by invoking the {@link
53      * #setMBeanServer} method after doing access checks based on read and
54      * write permissions.</p>
55      *
56      * <p>This instance is initialized from the specified properties file.</p>
57      *
58      * @param accessFileName name of the file which denotes a properties
59      * file on disk containing the username/access level entries.
60      *
61      * @exception IOException if the file does not exist, is a
62      * directory rather than a regular file, or for some other
63      * reason cannot be opened for reading.
64      *
65      * @exception IllegalArgumentException if any of the supplied access
66      * level values differs from "readonly" or "readwrite".
67      */

68     public MBeanServerFileAccessController(String JavaDoc accessFileName)
69         throws IOException JavaDoc {
70         super();
71         this.accessFileName = accessFileName;
72         props = propertiesFromFile(accessFileName);
73         checkValues(props);
74     }
75
76     /**
77      * <p>Create a new MBeanServerAccessController that forwards all the
78      * MBeanServer requests to <code>mbs</code> after doing access checks
79      * based on read and write permissions.</p>
80      *
81      * <p>This instance is initialized from the specified properties file.</p>
82      *
83      * @param accessFileName name of the file which denotes a properties
84      * file on disk containing the username/access level entries.
85      *
86      * @param mbs the MBeanServer object to which requests will be forwarded.
87      *
88      * @exception IOException if the file does not exist, is a
89      * directory rather than a regular file, or for some other
90      * reason cannot be opened for reading.
91      *
92      * @exception IllegalArgumentException if any of the supplied access
93      * level values differs from "readonly" or "readwrite".
94      */

95     public MBeanServerFileAccessController(String JavaDoc accessFileName,
96                                            MBeanServer JavaDoc mbs)
97         throws IOException JavaDoc {
98         this(accessFileName);
99         setMBeanServer(mbs);
100     }
101
102     /**
103      * <p>Create a new MBeanServerAccessController that forwards all the
104      * MBeanServer requests to the MBeanServer set by invoking the {@link
105      * #setMBeanServer} method after doing access checks based on read and
106      * write permissions.</p>
107      *
108      * <p>This instance is initialized from the specified properties instance.
109      * This constructor makes a copy of the properties instance using its
110      * <code>clone</code> method and it is the copy that is consulted to check
111      * the username and access level of an incoming connection. The original
112      * properties object can be modified without affecting the copy. If the
113      * {@link #refresh} method is then called, the
114      * <code>MBeanServerFileAccessController</code> will make a new copy of the
115      * properties object at that time.</p>
116      *
117      * @param accessFileProps properties list containing the username/access
118      * level entries.
119      *
120      * @exception IllegalArgumentException if <code>accessFileProps</code> is
121      * <code>null</code> or if any of the supplied access level values differs
122      * from "readonly" or "readwrite".
123      */

124     public MBeanServerFileAccessController(Properties JavaDoc accessFileProps)
125         throws IOException JavaDoc {
126         super();
127         if (accessFileProps == null)
128             throw new IllegalArgumentException JavaDoc("Null properties");
129         originalProps = accessFileProps;
130         props = (Properties JavaDoc) accessFileProps.clone();
131         checkValues(props);
132     }
133
134     /**
135      * <p>Create a new MBeanServerAccessController that forwards all the
136      * MBeanServer requests to the MBeanServer set by invoking the {@link
137      * #setMBeanServer} method after doing access checks based on read and
138      * write permissions.</p>
139      *
140      * <p>This instance is initialized from the specified properties instance.
141      * This constructor makes a copy of the properties instance using its
142      * <code>clone</code> method and it is the copy that is consulted to check
143      * the username and access level of an incoming connection. The original
144      * properties object can be modified without affecting the copy. If the
145      * {@link #refresh} method is then called, the
146      * <code>MBeanServerFileAccessController</code> will make a new copy of the
147      * properties object at that time.</p>
148      *
149      * @param accessFileProps properties list containing the username/access
150      * level entries.
151      *
152      * @param mbs the MBeanServer object to which requests will be forwarded.
153      *
154      * @exception IllegalArgumentException if <code>accessFileProps</code> is
155      * <code>null</code> or if any of the supplied access level values differs
156      * from "readonly" or "readwrite".
157      */

158     public MBeanServerFileAccessController(Properties JavaDoc accessFileProps,
159                                            MBeanServer JavaDoc mbs)
160         throws IOException JavaDoc {
161         this(accessFileProps);
162         setMBeanServer(mbs);
163     }
164
165     /**
166      * Check if the caller can do read operations. This method does
167      * nothing if so, otherwise throws SecurityException.
168      */

169     public void checkRead() {
170         checkAccessLevel(READONLY);
171     }
172
173     /**
174      * Check if the caller can do write operations. This method does
175      * nothing if so, otherwise throws SecurityException.
176      */

177     public void checkWrite() {
178         checkAccessLevel(READWRITE);
179     }
180
181     /**
182      * <p>Refresh the set of username/access level entries.</p>
183      *
184      * <p>If this instance was created using the
185      * {@link #MBeanServerFileAccessController(String)} or
186      * {@link #MBeanServerFileAccessController(String,MBeanServer)}
187      * constructors to specify a file from which the entries are read,
188      * the file is re-read.</p>
189      *
190      * <p>If this instance was created using the
191      * {@link #MBeanServerFileAccessController(Properties)} or
192      * {@link #MBeanServerFileAccessController(Properties,MBeanServer)}
193      * constructors then a new copy of the <code>Properties</code> object
194      * is made.</p>
195      *
196      * @exception IOException if the file does not exist, is a
197      * directory rather than a regular file, or for some other
198      * reason cannot be opened for reading.
199      *
200      * @exception IllegalArgumentException if any of the supplied access
201      * level values differs from "readonly" or "readwrite".
202      */

203     public void refresh() throws IOException JavaDoc {
204         synchronized (props) {
205             if (accessFileName == null)
206                 props = (Properties JavaDoc) originalProps.clone();
207             else
208                 props = propertiesFromFile(accessFileName);
209             checkValues(props);
210         }
211     }
212
213     private static Properties JavaDoc propertiesFromFile(String JavaDoc fname)
214         throws IOException JavaDoc {
215         FileInputStream JavaDoc fin = new FileInputStream JavaDoc(fname);
216         Properties JavaDoc p = new Properties JavaDoc();
217         p.load(fin);
218         fin.close();
219         return p;
220     }
221
222     private void checkAccessLevel(String JavaDoc accessLevel) {
223         final AccessControlContext JavaDoc acc = AccessController.getContext();
224         final Subject JavaDoc s = (Subject JavaDoc)
225             AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
226                     public Object JavaDoc run() {
227                         return Subject.getSubject(acc);
228                     }
229                 });
230         if (s == null) return; /* security has not been enabled */
231         final Set JavaDoc principals = s.getPrincipals();
232         for (Iterator JavaDoc i = principals.iterator(); i.hasNext(); ) {
233             final Principal JavaDoc p = (Principal JavaDoc) i.next();
234             String JavaDoc grantedAccessLevel;
235             synchronized (props) {
236                 grantedAccessLevel = props.getProperty(p.getName());
237             }
238             if (grantedAccessLevel != null) {
239                 if (accessLevel.equals(READONLY) &&
240                     (grantedAccessLevel.equals(READONLY) ||
241                      grantedAccessLevel.equals(READWRITE)))
242                     return;
243                 if (accessLevel.equals(READWRITE) &&
244                     grantedAccessLevel.equals(READWRITE))
245                     return;
246             }
247         }
248         throw new SecurityException JavaDoc("Access denied! Invalid access level for " +
249                                     "requested MBeanServer operation.");
250     }
251
252     private void checkValues(Properties JavaDoc props) {
253         Collection JavaDoc c = props.values();
254         for (Iterator JavaDoc i = c.iterator(); i.hasNext(); ) {
255             final String JavaDoc accessLevel = (String JavaDoc) i.next();
256             if (!accessLevel.equals(READONLY) &&
257                 !accessLevel.equals(READWRITE)) {
258                 throw new IllegalArgumentException JavaDoc(
259                     "Syntax error in access level entry [" + accessLevel + "]");
260             }
261         }
262     }
263
264     private Properties JavaDoc props;
265     private Properties JavaDoc originalProps;
266     private String JavaDoc accessFileName;
267 }
268
Popular Tags