2362N/A * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * <p>An object of this class implements the MBeanServerAccessController 0N/A * interface and, for each of its methods, calls an appropriate checking 0N/A * method and then forwards the request to a wrapped MBeanServer object. 0N/A * The checking method may throw a SecurityException if the operation is 0N/A * not allowed; in this case the request is not forwarded to the 0N/A * wrapped object.</p> 1136N/A * <p>This class implements the {@link #checkRead()}, {@link #checkWrite()}, 1136N/A * {@link #checkCreate(String)}, and {@link #checkUnregister(ObjectName)} 0N/A * filename which denotes a properties file on disk, or directly as an instance 0N/A * of the {@link Properties} class. In both cases, the name of each property 0N/A * represents a username, and the value of the property is the associated access 0N/A * level. Thus, any given username either does not exist in the properties or 0N/A * has exactly one access level. The same access level can be shared by several 1136N/A * <p>The supported access level values are {@code readonly} and 1136N/A * {@code readwrite}. The {@code readwrite} access level can be 1136N/A * qualified by one or more <i>clauses</i>, where each clause looks 1136N/A * like <code>create <i>classNamePattern</i></code> or {@code 1136N/A * unregister}. For example:</p> 1136N/A * create javax.management.timer.*,javax.management.monitor.* \ 1136N/A * <p>(The continuation lines with {@code \} come from the parser for 0N/A * <p>Create a new MBeanServerAccessController that forwards all the 0N/A * MBeanServer requests to the MBeanServer set by invoking the {@link 0N/A * #setMBeanServer} method after doing access checks based on read and 0N/A * write permissions.</p> 0N/A * <p>This instance is initialized from the specified properties file.</p> 0N/A * @param accessFileName name of the file which denotes a properties 0N/A * @exception IOException if the file does not exist, is a 0N/A * directory rather than a regular file, or for some other 0N/A * reason cannot be opened for reading. 0N/A * @exception IllegalArgumentException if any of the supplied access 0N/A * level values differs from "readonly" or "readwrite". 0N/A * <p>Create a new MBeanServerAccessController that forwards all the 0N/A * MBeanServer requests to <code>mbs</code> after doing access checks 0N/A * based on read and write permissions.</p> 0N/A * <p>This instance is initialized from the specified properties file.</p> 0N/A * @param accessFileName name of the file which denotes a properties 0N/A * @param mbs the MBeanServer object to which requests will be forwarded. 0N/A * @exception IOException if the file does not exist, is a 0N/A * directory rather than a regular file, or for some other 0N/A * reason cannot be opened for reading. 0N/A * @exception IllegalArgumentException if any of the supplied access 0N/A * level values differs from "readonly" or "readwrite". 0N/A * <p>Create a new MBeanServerAccessController that forwards all the 0N/A * MBeanServer requests to the MBeanServer set by invoking the {@link 0N/A * #setMBeanServer} method after doing access checks based on read and 0N/A * write permissions.</p> 1136N/A * <p>This instance is initialized from the specified properties 1136N/A * instance. This constructor makes a copy of the properties 1136N/A * instance and it is the copy that is consulted to check the 1136N/A * username and access level of an incoming connection. The 1136N/A * original properties object can be modified without affecting 1136N/A * the copy. If the {@link #refresh} method is then called, the 1136N/A * <code>MBeanServerFileAccessController</code> will make a new 1136N/A * copy of the properties object at that time.</p> 0N/A * @exception IllegalArgumentException if <code>accessFileProps</code> is 0N/A * <code>null</code> or if any of the supplied access level values differs 0N/A * from "readonly" or "readwrite". 0N/A * <p>Create a new MBeanServerAccessController that forwards all the 0N/A * MBeanServer requests to the MBeanServer set by invoking the {@link 0N/A * #setMBeanServer} method after doing access checks based on read and 0N/A * write permissions.</p> 1136N/A * <p>This instance is initialized from the specified properties 1136N/A * instance. This constructor makes a copy of the properties 1136N/A * instance and it is the copy that is consulted to check the 1136N/A * username and access level of an incoming connection. The 1136N/A * original properties object can be modified without affecting 1136N/A * the copy. If the {@link #refresh} method is then called, the 1136N/A * <code>MBeanServerFileAccessController</code> will make a new 1136N/A * copy of the properties object at that time.</p> 0N/A * @param mbs the MBeanServer object to which requests will be forwarded. 0N/A * @exception IllegalArgumentException if <code>accessFileProps</code> is 0N/A * <code>null</code> or if any of the supplied access level values differs 0N/A * from "readonly" or "readwrite". 0N/A * Check if the caller can do read operations. This method does 0N/A * nothing if so, otherwise throws SecurityException. 0N/A * Check if the caller can do write operations. This method does 0N/A * nothing if so, otherwise throws SecurityException. 1136N/A * Check if the caller can create MBeans or instances of the given class. 1136N/A * This method does nothing if so, otherwise throws SecurityException. 1136N/A * Check if the caller can do unregister operations. This method does 1136N/A * nothing if so, otherwise throws SecurityException. 0N/A * <p>If this instance was created using the 0N/A * {@link #MBeanServerFileAccessController(String)} or 0N/A * {@link #MBeanServerFileAccessController(String,MBeanServer)} 0N/A * constructors to specify a file from which the entries are read, 0N/A * the file is re-read.</p> 0N/A * <p>If this instance was created using the 0N/A * {@link #MBeanServerFileAccessController(Properties)} or 0N/A * {@link #MBeanServerFileAccessController(Properties,MBeanServer)} 0N/A * constructors then a new copy of the <code>Properties</code> object 0N/A * @exception IOException if the file does not exist, is a 0N/A * directory rather than a regular file, or for some other 0N/A * reason cannot be opened for reading. 0N/A * @exception IllegalArgumentException if any of the supplied access 0N/A * level values differs from "readonly" or "readwrite". 0N/A if (s ==
null)
return;
/* security has not been enabled */ 1136N/A ok =
true;
// all access entries imply read 1136N/A "access level for requested MBeanServer operation.");
1136N/A // Add some more information to help people with deployments that 1136N/A // worked before we required explicit create clauses. We're not giving 1136N/A // any information to the bad guys, other than that the access control 1136N/A // is based on a file, which they could have worked out from the stack 1136N/A // We studiously avoided regexes when parsing the properties file, 1136N/A // because that is done whenever the VM is started with the 1136N/A // appropriate -Dcom.sun.management options, even if nobody ever 1136N/A // creates an MBean. We don't want to incur the overhead of loading 1136N/A // all the regex code whenever those options are specified, but if we 1136N/A // get as far as here then the VM is already running and somebody is 1136N/A // doing the very unusual operation of remotely creating an MBean. 1136N/A // Because that operation is so unusual, we don't try to optimize 1136N/A // by hand-matching or by caching compiled Pattern objects. 1136N/A private final static int EOS = -
1;
// pseudo-codepoint "end of string" 1136N/A // At any point, either c is s.codePointAt(i), or i == len and 1136N/A // c is EOS. We use int rather than char because it is conceivable 1136N/A // (if unlikely) that a classname in a create clause might contain 1136N/A // "supplementary characters", the ones that don't fit in the original 1136N/A // We don't check that classname components begin with suitable 1136N/A // characters (so we accept 1.2.3 for example). This means that 1136N/A // there are only two states, which we can call dotOK and !dotOK 1136N/A // according as a dot (.) is legal or not. Initially we're in 1136N/A // !dotOK since a classname can't start with a dot; after a dot 1136N/A // we're in !dotOK again; and after any other characters we're in 1136N/A // dotOK. The classname is only accepted if we end in dotOK, 1136N/A // so we reject an empty name or a name that ends with a dot. 1136N/A // Advance c and i to the next character, unless already at EOS.