diff options
Diffstat (limited to 'java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java')
-rw-r--r-- | java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java index a0ecc2bd85..0ee5763d91 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java @@ -20,16 +20,24 @@ */ package org.apache.qpid.server.management; -import org.apache.qpid.server.security.access.management.UserManagement; +import org.apache.qpid.management.common.mbeans.ConfigurationManagement; +import org.apache.qpid.management.common.mbeans.LoggingManagement; +import org.apache.qpid.management.common.mbeans.UserManagement; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.actors.ManagementActor; +import org.apache.qpid.server.logging.messages.ManagementConsoleMessages; import org.apache.log4j.Logger; import javax.management.remote.MBeanServerForwarder; import javax.management.remote.JMXPrincipal; +import javax.management.remote.JMXConnectionNotification; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.JMException; +import javax.management.NotificationListener; +import javax.management.Notification; import javax.security.auth.Subject; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; @@ -37,6 +45,7 @@ import java.lang.reflect.Method; import java.security.AccessController; import java.security.Principal; import java.security.AccessControlContext; +import java.util.HashSet; import java.util.Set; import java.util.Properties; @@ -45,7 +54,7 @@ import java.util.Properties; * the logic for allowing the users to invoke MBean operations and implements the restrictions for readOnly, readWrite * and admin users. */ -public class MBeanInvocationHandlerImpl implements InvocationHandler +public class MBeanInvocationHandlerImpl implements InvocationHandler, NotificationListener { private static final Logger _logger = Logger.getLogger(MBeanInvocationHandlerImpl.class); @@ -53,14 +62,25 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler public final static String READWRITE = "readwrite"; public final static String READONLY = "readonly"; private final static String DELEGATE = "JMImplementation:type=MBeanServerDelegate"; - private MBeanServer mbs; + private MBeanServer _mbs; private static Properties _userRoles = new Properties(); + private static ManagementActor _logActor; + private static HashSet<String> _adminOnlyMethods = new HashSet<String>(); + { + _adminOnlyMethods.add(UserManagement.TYPE); + _adminOnlyMethods.add(LoggingManagement.TYPE); + _adminOnlyMethods.add(ConfigurationManagement.TYPE); + } + public static MBeanServerForwarder newProxyInstance() { final InvocationHandler handler = new MBeanInvocationHandlerImpl(); final Class[] interfaces = new Class[]{MBeanServerForwarder.class}; + + _logActor = new ManagementActor(CurrentActor.get().getRootMessageLogger()); + Object proxy = Proxy.newProxyInstance(MBeanServerForwarder.class.getClassLoader(), interfaces, handler); return MBeanServerForwarder.class.cast(proxy); } @@ -71,7 +91,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler if (methodName.equals("getMBeanServer")) { - return mbs; + return _mbs; } if (methodName.equals("setMBeanServer")) @@ -80,11 +100,11 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler { throw new IllegalArgumentException("Null MBeanServer"); } - if (mbs != null) + if (_mbs != null) { throw new IllegalArgumentException("MBeanServer object already initialized"); } - mbs = (MBeanServer) args[0]; + _mbs = (MBeanServer) args[0]; return null; } @@ -95,12 +115,12 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler // Allow operations performed locally on behalf of the connector server itself if (subject == null) { - return method.invoke(mbs, args); + return method.invoke(_mbs, args); } if (args == null || DELEGATE.equals(args[0])) { - return method.invoke(mbs, args); + return method.invoke(_mbs, args); } // Restrict access to "createMBean" and "unregisterMBean" to any user @@ -124,7 +144,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler { if (isAdmin(identity)) { - return method.invoke(mbs, args); + return method.invoke(_mbs, args); } else { @@ -135,14 +155,14 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler // Following users can perform any operation other than "createMBean" and "unregisterMBean" if (isAllowedToModify(identity)) { - return method.invoke(mbs, args); + return method.invoke(_mbs, args); } // These users can only call "getAttribute" on the MBeanServerDelegate MBean // Here we can add other fine grained permissions like specific method for a particular mbean if (isReadOnlyUser(identity) && isReadOnlyMethod(method, args)) { - return method.invoke(mbs, args); + return method.invoke(_mbs, args); } throw new SecurityException("Access denied"); @@ -153,9 +173,9 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler if (args[0] instanceof ObjectName) { ObjectName object = (ObjectName) args[0]; - return UserManagement.TYPE.equals(object.getKeyProperty("type")); + + return _adminOnlyMethods.contains(object.getKeyProperty("type")); } - return false; } @@ -196,7 +216,10 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler private boolean isReadOnlyMethod(Method method, Object[] args) { String methodName = method.getName(); - if (methodName.startsWith("query") || methodName.startsWith("get")) + + //handle standard get/set/query and select 'is' methods from MBeanServer + if (methodName.startsWith("query") || methodName.startsWith("get") + ||methodName.startsWith("isInstanceOf") || methodName.startsWith("isRegistered")) { return true; } @@ -205,8 +228,11 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler return false; } + //handle invocation of other methods on mbeans if ((args[0] instanceof ObjectName) && (methodName.equals("invoke"))) { + + //get invoked method name String mbeanMethod = (args.length > 1) ? (String) args[1] : null; if (mbeanMethod == null) { @@ -215,7 +241,8 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler try { - MBeanInfo mbeanInfo = mbs.getMBeanInfo((ObjectName) args[0]); + //check if the given method is tagged with an INFO impact attribute + MBeanInfo mbeanInfo = _mbs.getMBeanInfo((ObjectName) args[0]); if (mbeanInfo != null) { MBeanOperationInfo[] opInfos = mbeanInfo.getOperations(); @@ -236,4 +263,23 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler return false; } + + public void handleNotification(Notification notification, Object handback) + { + // only RMI Connections are serviced here, Local API atta + // rmi://169.24.29.116 guest 3 + String[] connectionData = ((JMXConnectionNotification) notification).getConnectionId().split(" "); + String user = connectionData[1]; + + if (notification.getType().equals(JMXConnectionNotification.OPENED)) + { + _logActor.message(ManagementConsoleMessages.MNG_OPEN(user)); + } + else if (notification.getType().equals(JMXConnectionNotification.CLOSED) || + notification.getType().equals(JMXConnectionNotification.FAILED)) + { + _logActor.message(ManagementConsoleMessages.MNG_CLOSE()); + } + } } + |