/* * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.rmi.registry; import java.io.ObjectInputFilter; import java.nio.file.Path; import java.nio.file.Paths; import java.security.PrivilegedAction; import java.security.Security; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.io.File; import java.io.FilePermission; import java.io.IOException; import java.net.*; import java.rmi.*; import java.rmi.server.ObjID; import java.rmi.server.ServerNotActiveException; import java.rmi.registry.Registry; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; import java.security.AccessControlContext; import java.security.AccessController; import java.security.CodeSource; import java.security.Policy; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.security.PermissionCollection; import java.security.Permissions; import java.security.ProtectionDomain; import java.text.MessageFormat; import jdk.internal.access.SharedSecrets; import sun.rmi.runtime.Log; import sun.rmi.server.UnicastRef; import sun.rmi.server.UnicastServerRef; import sun.rmi.server.UnicastServerRef2; import sun.rmi.transport.LiveRef; /** * A "registry" exists on every node that allows RMI connections to * servers on that node. The registry on a particular node contains a * transient database that maps names to remote objects. When the * node boots, the registry database is empty. The names stored in the * registry are pure and are not parsed. A service storing itself in * the registry may want to prefix its name of the service by a package * name (although not required), to reduce name collisions in the * registry. * * The LocateRegistry class is used to obtain registry for different hosts. *
* The default RegistryImpl exported restricts access to clients on the local host
* for the methods {@link #bind}, {@link #rebind}, {@link #unbind} by checking
* the client host in the skeleton.
*
* @see java.rmi.registry.LocateRegistry
*/
public class RegistryImpl extends java.rmi.server.RemoteServer
implements Registry
{
/* indicate compatibility with JDK 1.1.x version of class */
private static final long serialVersionUID = 4666870661827494597L;
private Hashtable
* The returned Registry is fully functional within the current process and
* is usable for internal and testing purposes.
*
* @param regPort port on which the rmiregistry accepts requests;
* if 0, an implementation specific port is assigned
* @return a RegistryImpl instance
* @exception RemoteException If remote operation failed.
* @since 9
*/
public static RegistryImpl createRegistry(int regPort) throws RemoteException {
// Create and install the security manager if one is not installed
// already.
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
/*
* Fix bugid 4147561: When JDK tools are executed, the value of
* the CLASSPATH environment variable for the shell in which they
* were invoked is no longer incorporated into the application
* class path; CLASSPATH's only effect is to be the value of the
* system property "env.class.path". To preserve the previous
* (JDK1.1 and JDK1.2beta3) behavior of this tool, however, its
* CLASSPATH should still be considered when resolving classes
* being unmarshalled. To effect this old behavior, a class
* loader that loads from the file path specified in the
* "env.class.path" property is created and set to be the context
* class loader before the remote object is exported.
*/
String envcp = System.getProperty("env.class.path");
if (envcp == null) {
envcp = "."; // preserve old default behavior
}
URL[] urls = pathToURLs(envcp);
ClassLoader cl = new URLClassLoader(urls);
/*
* Fix bugid 4242317: Classes defined by this class loader should
* be annotated with the value of the "java.rmi.server.codebase"
* property, not the "file:" URLs for the CLASSPATH elements.
*/
sun.rmi.server.LoaderHandler.registerCodebaseLoader(cl);
Thread.currentThread().setContextClassLoader(cl);
RegistryImpl registryImpl = null;
try {
registryImpl = AccessController.doPrivileged(
new PrivilegedExceptionActionuref
*/
private void setup(UnicastServerRef uref)
throws RemoteException
{
/* Server ref must be created and assigned before remote
* object 'this' can be exported.
*/
ref = uref;
uref.exportObject(this, null, true);
}
/**
* Returns the remote object for specified name in the registry.
* @exception RemoteException If remote operation failed.
* @exception NotBoundException If name is not currently bound.
*/
public Remote lookup(String name)
throws RemoteException, NotBoundException
{
synchronized (bindings) {
Remote obj = bindings.get(name);
if (obj == null)
throw new NotBoundException(name);
return obj;
}
}
/**
* Binds the name to the specified remote object.
* @exception RemoteException If remote operation failed.
* @exception AlreadyBoundException If name is already bound.
*/
public void bind(String name, Remote obj)
throws RemoteException, AlreadyBoundException, AccessException
{
// The access check preventing remote access is done in the skeleton
// and is not applicable to local access.
synchronized (bindings) {
Remote curr = bindings.get(name);
if (curr != null)
throw new AlreadyBoundException(name);
bindings.put(name, obj);
}
}
/**
* Unbind the name.
* @exception RemoteException If remote operation failed.
* @exception NotBoundException If name is not currently bound.
*/
public void unbind(String name)
throws RemoteException, NotBoundException, AccessException
{
// The access check preventing remote access is done in the skeleton
// and is not applicable to local access.
synchronized (bindings) {
Remote obj = bindings.get(name);
if (obj == null)
throw new NotBoundException(name);
bindings.remove(name);
}
}
/**
* Rebind the name to a new object, replaces any existing binding.
* @exception RemoteException If remote operation failed.
*/
public void rebind(String name, Remote obj)
throws RemoteException, AccessException
{
// The access check preventing remote access is done in the skeleton
// and is not applicable to local access.
bindings.put(name, obj);
}
/**
* Returns an enumeration of the names in the registry.
* @exception RemoteException If remote operation failed.
*/
public String[] list()
throws RemoteException
{
String[] names;
synchronized (bindings) {
int i = bindings.size();
names = new String[i];
Enumeration
* The port number can be specified on the command line.
*/
public static void main(String args[])
{
try {
final int regPort = (args.length >= 1) ? Integer.parseInt(args[0])
: Registry.REGISTRY_PORT;
registry = createRegistry(regPort);
// prevent registry from exiting
while (true) {
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
}
}
} catch (NumberFormatException e) {
System.err.println(MessageFormat.format(
getTextResource("rmiregistry.port.badnumber"),
args[0] ));
System.err.println(MessageFormat.format(
getTextResource("rmiregistry.usage"),
"rmiregistry" ));
} catch (Exception e) {
e.printStackTrace();
}
System.exit(1);
}
/**
* Generates an AccessControlContext with minimal permissions.
* The approach used here is taken from the similar method
* getAccessControlContext() in the sun.applet.AppletPanel class.
*/
private static AccessControlContext getAccessControlContext(int port) {
// begin with permissions granted to all code in current policy
PermissionCollection perms = AccessController.doPrivileged(
new java.security.PrivilegedAction