00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 package org.objectweb.cjdbc.controller.jmx;
00026
00027 import java.util.ArrayList;
00028 import java.util.Arrays;
00029 import java.util.Iterator;
00030 import java.util.List;
00031 import java.util.Set;
00032
00033 import javax.management.InstanceNotFoundException;
00034 import javax.management.MBeanException;
00035 import javax.management.MBeanServer;
00036 import javax.management.ObjectName;
00037 import javax.management.ReflectionException;
00038 import javax.security.auth.Subject;
00039
00040 import org.objectweb.cjdbc.common.jmx.JmxConstants;
00041 import org.objectweb.cjdbc.common.log.Trace;
00042 import org.objectweb.cjdbc.common.users.AbstractDatabaseUser;
00043
00044
00045
00046
00047
00048
00049
00050
00051 public class AuthenticatingMBeanServer extends ChainedMBeanServer
00052 {
00053
00054
00055 static Trace logger = Trace
00056 .getLogger("org.objectweb.cjdbc.controller.jmx.AuthenticatingMBeanServer");
00057
00058
00059
00060
00061
00062
00063
00064 public void setMBeanServer(MBeanServer server)
00065 {
00066 super.setMBeanServer(server);
00067 }
00068
00069
00070
00071
00072
00073 public Object invoke(ObjectName name, String operationName, Object[] params,
00074 String[] signature) throws InstanceNotFoundException, MBeanException,
00075 ReflectionException
00076 {
00077 if (JmxConstants.mbeanNeedAuthentication(name)
00078 && (operationName.equalsIgnoreCase("checkAdminAuthentication") == false))
00079 {
00080
00081
00082
00083 boolean authenticationOk = false;
00084 String username = null;
00085 String password = null;
00086
00087 Subject subject = Subject.getSubject(java.security.AccessController
00088 .getContext());
00089 if (subject == null || subject.getPrincipals().size() == 0)
00090 {
00091 username = (String) params[0];
00092 password = (String) params[1];
00093 authenticationOk = authenticate(name, username, password);
00094 if (!authenticationOk)
00095 throw new MBeanException(new Exception(
00096 "Authentication failed (username,password) invalid"));
00097
00098 if (logger.isDebugEnabled())
00099 logger
00100 .debug("Authentication with username and password was successfull");
00101
00102
00103
00104 return super.invoke(name, operationName, cleanO(params),
00105 cleanS(signature));
00106 }
00107 else
00108 {
00109 Set principals = subject.getPrincipals(AbstractDatabaseUser.class);
00110 for (Iterator it = principals.iterator(); it.hasNext();)
00111 {
00112 AbstractDatabaseUser user = (AbstractDatabaseUser) it.next();
00113 username = user.getName();
00114 password = user.getPassword();
00115 authenticationOk = authenticate(name, username, password);
00116 if (authenticationOk)
00117 break;
00118 }
00119
00120 if (principals.size() == 0 && logger.isDebugEnabled())
00121 throw new MBeanException(new Exception(
00122 "Authentication failed : no principal"));
00123
00124 if (!authenticationOk)
00125 throw new MBeanException(new Exception(
00126 "Authentication failed : principal invalid"));
00127 if (logger.isDebugEnabled())
00128 logger.debug("Authentication with principal was successfull");
00129 return super.invoke(name, operationName, params, signature);
00130 }
00131 }
00132 else
00133 {
00134 if (logger.isDebugEnabled())
00135 logger.debug("no authentication required");
00136
00137 return super.invoke(name, operationName, params, signature);
00138 }
00139 }
00140
00141 private boolean authenticate(ObjectName name, String username, String password)
00142 {
00143 try
00144 {
00145 boolean vdb = name.toString().indexOf(
00146 JmxConstants.CJDBC_TYPE_VIRTUALDATABASE) != -1;
00147 if (vdb)
00148 return ((Boolean) invoke(name, "checkAdminAuthentication",
00149 new Object[]{username, password}, new String[]{"java.lang.String",
00150 "java.lang.String"})).booleanValue();
00151 else
00152 {
00153 boolean backend = name.toString().indexOf(
00154 JmxConstants.CJDBC_TYPE_BACKEND) != -1;
00155 if (backend)
00156 {
00157
00158 ObjectName vdbName = JmxConstants
00159 .getVirtualDbObjectNameFromBackend(name);
00160 return ((Boolean) invoke(vdbName, "checkAdminAuthentication",
00161 new Object[]{username, password}, new String[]{
00162 "java.lang.String", "java.lang.String"})).booleanValue();
00163 }
00164 else
00165
00166 return true;
00167 }
00168 }
00169 catch (Exception e)
00170 {
00171 if (logger.isDebugEnabled())
00172 {
00173 logger.debug("authentication failed with exception ", e);
00174 }
00175 return false;
00176 }
00177 }
00178
00179 private static Object[] cleanO(Object[] params)
00180 {
00181 List o = Arrays.asList(params);
00182 o = o.subList(2, o.size());
00183 return (new ArrayList(o).toArray());
00184 }
00185
00186 private static String[] cleanS(String[] params)
00187 {
00188 List o = Arrays.asList(params);
00189 o = o.subList(2, o.size());
00190 String[] s = new String[o.size()];
00191 return (String[]) new ArrayList(o).toArray(s);
00192 }
00193 }