mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 04:24:49 +02:00
6747899: jmx namespaces: hooks for permission checks should be defined in HandlerInterceptor
Reviewed-by: emcmanus
This commit is contained in:
parent
a1e4e3ec94
commit
38e8cbedc6
2 changed files with 174 additions and 151 deletions
|
@ -135,7 +135,11 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
public AttributeList getAttributes(ObjectName name, String[] attributes)
|
||||
throws InstanceNotFoundException, ReflectionException {
|
||||
try {
|
||||
return super.getAttributes(name, attributes);
|
||||
final String[] authorized =
|
||||
checkAttributes(name,attributes,"getAttribute");
|
||||
final AttributeList attrList =
|
||||
super.getAttributes(name,authorized);
|
||||
return attrList;
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"getAttributes",name,attributes);
|
||||
}
|
||||
|
@ -185,6 +189,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
public void removeNotificationListener(ObjectName name, ObjectName listener)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
super.removeNotificationListener(name,listener);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"removeNotificationListener",name,listener);
|
||||
|
@ -205,7 +210,9 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
@Override
|
||||
public String[] getDomains() {
|
||||
try {
|
||||
return super.getDomains();
|
||||
check(null,null,"getDomains");
|
||||
final String[] domains = super.getDomains();
|
||||
return checkDomains(domains,"getDomains");
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"getDomains");
|
||||
}
|
||||
|
@ -228,6 +235,9 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
InvalidAttributeValueException, MBeanException,
|
||||
ReflectionException {
|
||||
try {
|
||||
check(name,
|
||||
(attribute==null?null:attribute.getName()),
|
||||
"setAttribute");
|
||||
super.setAttribute(name,attribute);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"setAttribute",name, attribute);
|
||||
|
@ -237,7 +247,9 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
|
||||
if (name == null) name=ObjectName.WILDCARD;
|
||||
try {
|
||||
checkPattern(name,null,"queryNames");
|
||||
return super.queryNames(name,query);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"queryNames",name, query);
|
||||
|
@ -247,7 +259,9 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
|
||||
if (name == null) name=ObjectName.WILDCARD;
|
||||
try {
|
||||
checkPattern(name,null,"queryMBeans");
|
||||
return super.queryMBeans(name,query);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"queryMBeans",name, query);
|
||||
|
@ -259,6 +273,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
public boolean isInstanceOf(ObjectName name, String className)
|
||||
throws InstanceNotFoundException {
|
||||
try {
|
||||
check(name, null, "isInstanceOf");
|
||||
return super.isInstanceOf(name, className);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"isInstanceOf",name, className);
|
||||
|
@ -272,6 +287,8 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException {
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return super.createMBean(className, name);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"createMBean",className, name);
|
||||
|
@ -286,6 +303,8 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException, InstanceNotFoundException {
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return super.createMBean(className, name, loaderName);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"createMBean",className, name, loaderName);
|
||||
|
@ -298,6 +317,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
throws MBeanException, AttributeNotFoundException,
|
||||
InstanceNotFoundException, ReflectionException {
|
||||
try {
|
||||
check(name, attribute, "getAttribute");
|
||||
return super.getAttribute(name, attribute);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"getAttribute",name, attribute);
|
||||
|
@ -310,6 +330,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
NotificationFilter filter, Object handback)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
super.removeNotificationListener(name, listener, filter, handback);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"removeNotificationListener",name,
|
||||
|
@ -324,6 +345,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
Object handback)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
super.removeNotificationListener(name, listener, filter, handback);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"removeNotificationListener",name,
|
||||
|
@ -337,6 +359,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
NotificationListener listener)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
super.removeNotificationListener(name, listener);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"removeNotificationListener",name,
|
||||
|
@ -350,6 +373,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
NotificationListener listener, NotificationFilter filter,
|
||||
Object handback) throws InstanceNotFoundException {
|
||||
try {
|
||||
check(name,null,"addNotificationListener");
|
||||
super.addNotificationListener(name, listener, filter, handback);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"addNotificationListener",name,
|
||||
|
@ -363,6 +387,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
NotificationFilter filter, Object handback)
|
||||
throws InstanceNotFoundException {
|
||||
try {
|
||||
check(name,null,"addNotificationListener");
|
||||
super.addNotificationListener(name, listener, filter, handback);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"addNotificationListener",name,
|
||||
|
@ -385,6 +410,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
public void unregisterMBean(ObjectName name)
|
||||
throws InstanceNotFoundException, MBeanRegistrationException {
|
||||
try {
|
||||
check(name, null, "unregisterMBean");
|
||||
super.unregisterMBean(name);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"unregisterMBean",name);
|
||||
|
@ -397,6 +423,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
throws InstanceNotFoundException, IntrospectionException,
|
||||
ReflectionException {
|
||||
try {
|
||||
check(name, null, "getMBeanInfo");
|
||||
return super.getMBeanInfo(name);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"getMBeanInfo",name);
|
||||
|
@ -408,6 +435,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
public ObjectInstance getObjectInstance(ObjectName name)
|
||||
throws InstanceNotFoundException {
|
||||
try {
|
||||
check(name, null, "getObjectInstance");
|
||||
return super.getObjectInstance(name);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"getObjectInstance",name);
|
||||
|
@ -422,6 +450,8 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException {
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return super.createMBean(className, name, params, signature);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"createMBean",className, name,
|
||||
|
@ -437,6 +467,8 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException, InstanceNotFoundException {
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return super.createMBean(className, name, loaderName, params,
|
||||
signature);
|
||||
} catch (IOException ex) {
|
||||
|
@ -450,7 +482,9 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
public AttributeList setAttributes(ObjectName name,AttributeList attributes)
|
||||
throws InstanceNotFoundException, ReflectionException {
|
||||
try {
|
||||
return super.setAttributes(name, attributes);
|
||||
final AttributeList authorized =
|
||||
checkAttributes(name, attributes, "setAttribute");
|
||||
return super.setAttributes(name, authorized);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"setAttributes",name, attributes);
|
||||
}
|
||||
|
@ -462,6 +496,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
String[] signature)
|
||||
throws InstanceNotFoundException, MBeanException, ReflectionException {
|
||||
try {
|
||||
check(name, operationName, "invoke");
|
||||
return super.invoke(name, operationName, params, signature);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"invoke",name, operationName,
|
||||
|
@ -582,4 +617,118 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
|||
"Not supported in this namespace: "+namespace));
|
||||
}
|
||||
|
||||
/**
|
||||
* A result might be excluded for security reasons.
|
||||
*/
|
||||
@Override
|
||||
boolean excludesFromResult(ObjectName targetName, String queryMethod) {
|
||||
return !checkQuery(targetName, queryMethod);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Hooks for checking permissions
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* A subclass may override this method and throw a {@link
|
||||
* SecurityException} if the permission is denied.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param member The {@link
|
||||
* javax.management.namespace.JMXNamespacePermission#getMember member}
|
||||
* name.
|
||||
* @param action The {@link
|
||||
* javax.management.namespace.JMXNamespacePermission#getActions action}
|
||||
* name.
|
||||
* @throws SecurityException if the caller doesn't have the permission
|
||||
* to perform the given action on the MBean pointed to
|
||||
* by routingName.
|
||||
*/
|
||||
abstract void check(ObjectName routingName,
|
||||
String member, String action);
|
||||
|
||||
// called in createMBean and registerMBean
|
||||
abstract void checkCreate(ObjectName routingName, String className,
|
||||
String action);
|
||||
|
||||
/**
|
||||
* This is a hook to implement permission checking in subclasses.
|
||||
*
|
||||
* Checks that the caller has sufficient permission for returning
|
||||
* information about {@code sourceName} in {@code action}.
|
||||
*
|
||||
* Subclass may override this method and return false if the caller
|
||||
* doesn't have sufficient permissions.
|
||||
*
|
||||
* @param routingName The name of the MBean to include or exclude from
|
||||
* the query, expressed in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param action one of "queryNames" or "queryMBeans"
|
||||
* @return true if {@code sourceName} can be returned.
|
||||
*/
|
||||
abstract boolean checkQuery(ObjectName routingName, String action);
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param attributes The list of attributes to check permission for.
|
||||
* @param action one of "getAttribute" or "setAttribute"
|
||||
* @return The list of attributes for which the callers has the
|
||||
* appropriate {@link
|
||||
* javax.management.namespace.JMXNamespacePermission}.
|
||||
* @throws SecurityException if the caller doesn't have the permission
|
||||
* to perform {@code action} on the MBean pointed to by routingName.
|
||||
*/
|
||||
abstract String[] checkAttributes(ObjectName routingName,
|
||||
String[] attributes, String action);
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param attributes The list of attributes to check permission for.
|
||||
* @param action one of "getAttribute" or "setAttribute"
|
||||
* @return The list of attributes for which the callers has the
|
||||
* appropriate {@link
|
||||
* javax.management.namespace.JMXNamespacePermission}.
|
||||
* @throws SecurityException if the caller doesn't have the permission
|
||||
* to perform {@code action} on the MBean pointed to by routingName.
|
||||
*/
|
||||
abstract AttributeList checkAttributes(ObjectName routingName,
|
||||
AttributeList attributes, String action);
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* Checks that the caller as the necessary permissions to view the
|
||||
* given domain. If not remove the domains for which the caller doesn't
|
||||
* have permission from the list.
|
||||
* <p>
|
||||
* By default, this method always returns {@code domains}
|
||||
*
|
||||
* @param domains The domains to return.
|
||||
* @param action "getDomains"
|
||||
* @return a filtered list of domains.
|
||||
*/
|
||||
String[] checkDomains(String[] domains, String action) {
|
||||
return domains;
|
||||
}
|
||||
|
||||
// A priori check for queryNames/queryMBeans/
|
||||
void checkPattern(ObjectName routingPattern,
|
||||
String member, String action) {
|
||||
// pattern is checked only at posteriori by checkQuery.
|
||||
// checking it a priori usually doesn't work, because ObjectName.apply
|
||||
// does not work between two patterns.
|
||||
// We only check that we have the permission requested for 'action'.
|
||||
check(null,null,action);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -161,11 +161,7 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
throws InstanceNotFoundException, ReflectionException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
final String[] authorized =
|
||||
checkAttributes(name,attributes,"getAttribute");
|
||||
final AttributeList attrList =
|
||||
source().getAttributes(sourceName,authorized);
|
||||
return attrList;
|
||||
return source().getAttributes(sourceName, attributes);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
}
|
||||
|
@ -178,7 +174,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, operationName, "invoke");
|
||||
final Object result =
|
||||
source().invoke(sourceName,operationName,params,
|
||||
signature);
|
||||
|
@ -194,7 +189,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, null, "unregisterMBean");
|
||||
source().unregisterMBean(sourceName);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
|
@ -207,7 +201,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
ReflectionException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, null, "getMBeanInfo");
|
||||
return source().getMBeanInfo(sourceName);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
|
@ -219,7 +212,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
throws InstanceNotFoundException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, null, "getObjectInstance");
|
||||
return processOutputInstance(
|
||||
source().getObjectInstance(sourceName));
|
||||
} catch (RuntimeException ex) {
|
||||
|
@ -246,9 +238,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
ReflectionException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name,
|
||||
(attribute==null?null:attribute.getName()),
|
||||
"setAttribute");
|
||||
source().setAttribute(sourceName,attribute);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
|
@ -266,8 +255,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
// Loader Name is already a sourceLoaderName.
|
||||
final ObjectName sourceLoaderName = loaderName;
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
final ObjectInstance instance =
|
||||
source().createMBean(className,sourceName,
|
||||
sourceLoaderName,
|
||||
|
@ -286,8 +273,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
NotCompliantMBeanException, IOException {
|
||||
final ObjectName sourceName = newSourceMBeanName(name);
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return processOutputInstance(source().createMBean(className,
|
||||
sourceName,params,signature));
|
||||
} catch (RuntimeException ex) {
|
||||
|
@ -305,8 +290,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
// Loader Name is already a source Loader Name.
|
||||
final ObjectName sourceLoaderName = loaderName;
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return processOutputInstance(source().createMBean(className,
|
||||
sourceName,sourceLoaderName));
|
||||
} catch (RuntimeException ex) {
|
||||
|
@ -321,8 +304,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
NotCompliantMBeanException, IOException {
|
||||
final ObjectName sourceName = newSourceMBeanName(name);
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return processOutputInstance(source().
|
||||
createMBean(className,sourceName));
|
||||
} catch (RuntimeException ex) {
|
||||
|
@ -336,7 +317,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
InstanceNotFoundException, ReflectionException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, attribute, "getAttribute");
|
||||
return source().getAttribute(sourceName,attribute);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
|
@ -348,7 +328,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
throws InstanceNotFoundException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, null, "isInstanceOf");
|
||||
return source().isInstanceOf(sourceName,className);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
|
@ -360,10 +339,8 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
throws InstanceNotFoundException, ReflectionException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
final AttributeList authorized =
|
||||
checkAttributes(name, attributes, "setAttribute");
|
||||
return source().
|
||||
setAttributes(sourceName,authorized);
|
||||
setAttributes(sourceName,attributes);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
}
|
||||
|
@ -376,7 +353,7 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
for (ObjectInstance i : sources) {
|
||||
try {
|
||||
final ObjectInstance target = processOutputInstance(i);
|
||||
if (!checkQuery(target.getObjectName(), "queryMBeans"))
|
||||
if (excludesFromResult(target.getObjectName(), "queryMBeans"))
|
||||
continue;
|
||||
result.add(target);
|
||||
} catch (Exception x) {
|
||||
|
@ -415,7 +392,7 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
for (ObjectName n : sourceNames) {
|
||||
try {
|
||||
final ObjectName targetName = toTarget(n);
|
||||
if (!checkQuery(targetName, "queryNames")) continue;
|
||||
if (excludesFromResult(targetName, "queryNames")) continue;
|
||||
names.add(targetName);
|
||||
} catch (Exception x) {
|
||||
if (LOG.isLoggable(Level.FINE)) {
|
||||
|
@ -435,7 +412,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
if (name == null) name=ObjectName.WILDCARD;
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
checkPattern(name,null,"queryMBeans");
|
||||
return processOutputInstances(
|
||||
source().queryMBeans(sourceName,query));
|
||||
} catch (RuntimeException ex) {
|
||||
|
@ -450,7 +426,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
if (name == null) name=ObjectName.WILDCARD;
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
checkPattern(name,null,"queryNames");
|
||||
final Set<ObjectName> tmp = source().queryNames(sourceName,query);
|
||||
final Set<ObjectName> out = processOutputNames(tmp);
|
||||
//System.err.println("queryNames: out: "+out);
|
||||
|
@ -467,7 +442,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
ListenerNotFoundException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
source().removeNotificationListener(sourceName,listener);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
|
@ -481,7 +455,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
// Listener name is already a source listener name.
|
||||
try {
|
||||
check(name,null,"addNotificationListener");
|
||||
source().addNotificationListener(sourceName,listener,
|
||||
filter,handback);
|
||||
} catch (RuntimeException ex) {
|
||||
|
@ -495,7 +468,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
Object handback) throws InstanceNotFoundException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name,null,"addNotificationListener");
|
||||
source().addNotificationListener(sourceName, listener, filter,
|
||||
handback);
|
||||
} catch (RuntimeException ex) {
|
||||
|
@ -512,7 +484,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
source().removeNotificationListener(sourceName,listener,filter,
|
||||
handback);
|
||||
} catch (RuntimeException ex) {
|
||||
|
@ -527,7 +498,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
source().removeNotificationListener(sourceName,listener,
|
||||
filter,handback);
|
||||
} catch (RuntimeException ex) {
|
||||
|
@ -543,7 +513,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
// listener name is already a source name...
|
||||
final ObjectName sourceListener = listener;
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
source().removeNotificationListener(sourceName,sourceListener);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
|
@ -562,9 +531,7 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
// from MBeanServerConnection
|
||||
public String[] getDomains() throws IOException {
|
||||
try {
|
||||
check(null,null,"getDomains");
|
||||
final String[] domains = source().getDomains();
|
||||
return checkDomains(domains,"getDomains");
|
||||
return source().getDomains();
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
}
|
||||
|
@ -579,115 +546,22 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Hooks for checking permissions
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* By default, this method does nothing and simply returns
|
||||
* {@code attribute}.
|
||||
* Returns true if the given targetName must be excluded from the
|
||||
* query result.
|
||||
* In this base class, always return {@code false}.
|
||||
* By default all object names returned by the sources are
|
||||
* transmitted to the caller - there is no filtering.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param attributes The list of attributes to check permission for.
|
||||
* @param action one of "getAttribute" or "setAttribute"
|
||||
* @return The list of attributes for which the callers has the
|
||||
* appropriate {@link
|
||||
* javax.management.namespace.JMXNamespacePermission}.
|
||||
* @param name A target object name expressed in the caller's
|
||||
* context. In the case of cascading, where the source
|
||||
* is a sub agent mounted on e.g. namespace "foo",
|
||||
* that would be a name prefixed by "foo//"...
|
||||
* @param queryMethod either "queryNames" or "queryMBeans".
|
||||
* @return true if the name must be excluded.
|
||||
*/
|
||||
String[] checkAttributes(ObjectName routingName,
|
||||
String[] attributes, String action) {
|
||||
check(routingName,null,action);
|
||||
return attributes;
|
||||
boolean excludesFromResult(ObjectName targetName, String queryMethod) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* By default, this method does nothing and simply returns
|
||||
* {@code attribute}.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param attributes The list of attributes to check permission for.
|
||||
* @param action one of "getAttribute" or "setAttribute"
|
||||
* @return The list of attributes for which the callers has the
|
||||
* appropriate {@link
|
||||
* javax.management.namespace.JMXNamespacePermission}.
|
||||
*/
|
||||
AttributeList checkAttributes(ObjectName routingName,
|
||||
AttributeList attributes, String action) {
|
||||
check(routingName,null,action);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* By default, this method does nothing.
|
||||
* A subclass may override this method and throw a {@link
|
||||
* SecurityException} if the permission is denied.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param member The {@link
|
||||
* javax.management.namespace.JMXNamespacePermission#getMember member}
|
||||
* name.
|
||||
* @param action The {@link
|
||||
* javax.management.namespace.JMXNamespacePermission#getActions action}
|
||||
* name.
|
||||
*/
|
||||
void check(ObjectName routingName,
|
||||
String member, String action) {
|
||||
}
|
||||
|
||||
// called in createMBean and registerMBean
|
||||
void checkCreate(ObjectName routingName, String className,
|
||||
String action) {
|
||||
}
|
||||
|
||||
// A priori check for queryNames/queryMBeans/
|
||||
void checkPattern(ObjectName routingPattern,
|
||||
String member, String action) {
|
||||
// pattern is checked only at posteriori by checkQuery.
|
||||
// checking it a priori usually doesn't work, because ObjectName.apply
|
||||
// does not work between two patterns.
|
||||
// We only check that we have the permission requested for 'action'.
|
||||
check(null,null,action);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is a hook to implement permission checking in subclasses.
|
||||
*
|
||||
* Checks that the caller has sufficient permission for returning
|
||||
* information about {@code sourceName} in {@code action}.
|
||||
*
|
||||
* By default always return true. Subclass may override this method
|
||||
* and return false if the caller doesn't have sufficient permissions.
|
||||
*
|
||||
* @param routingName The name of the MBean to include or exclude from
|
||||
* the query, expressed in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param action one of "queryNames" or "queryMBeans"
|
||||
* @return true if {@code sourceName} can be returned.
|
||||
*/
|
||||
boolean checkQuery(ObjectName routingName, String action) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* Checks that the caller as the necessary permissions to view the
|
||||
* given domain. If not remove the domains for which the caller doesn't
|
||||
* have permission from the list.
|
||||
* <p>
|
||||
* By default, this method always returns {@code domains}
|
||||
*
|
||||
* @param domains The domains to return.
|
||||
* @param action "getDomains"
|
||||
* @return a filtered list of domains.
|
||||
*/
|
||||
String[] checkDomains(String[] domains, String action) {
|
||||
return domains;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue