00001
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
00051 public class AuthenticatingMBeanServer extends ChainedMBeanServer
00052 {
00053
00055 static Trace
logger = Trace
00056 .getLogger(
"org.objectweb.cjdbc.controller.jmx.AuthenticatingMBeanServer");
00057
00064 public void setMBeanServer(MBeanServer server)
00065 {
00066 super.setMBeanServer(server);
00067 }
00068
00073 public Object
invoke(ObjectName name, String operationName, Object[] params,
00074 String[] signature)
throws InstanceNotFoundException, MBeanException,
00075 ReflectionException
00076 {
00077
00078
boolean mbeanNeedAuthentication = name.toString().indexOf(
00079
JmxConstants.CJDBC_TYPE_VIRTUALDATABASE) != -1
00080 || name.toString().indexOf(
JmxConstants.CJDBC_TYPE_BACKEND) != -1;
00081
if (mbeanNeedAuthentication
00082 && (operationName.equalsIgnoreCase(
"checkAdminAuthentication") ==
false))
00083 {
00084
00085
00086
00087
boolean authenticationOk =
false;
00088 String username = null;
00089 String password = null;
00090
00091 Subject subject = Subject.getSubject(java.security.AccessController
00092 .getContext());
00093
if (subject == null || subject.getPrincipals().size() == 0)
00094 {
00095 username = (String) params[0];
00096 password = (String) params[1];
00097 authenticationOk =
authenticate(name, username, password);
00098
if (!authenticationOk)
00099
throw new MBeanException(
new Exception(
00100
"Authentication failed (username,password) invalid"));
00101
00102
if (
logger.isDebugEnabled())
00103
logger
00104 .debug(
"Authentication with username and password was successfull");
00105
00106
00107
00108
return super.invoke(name, operationName,
cleanO(params),
00109
cleanS(signature));
00110 }
00111
else
00112 {
00113 Set principals = subject.getPrincipals(
AbstractDatabaseUser.class);
00114
for (Iterator it = principals.iterator(); it.hasNext();)
00115 {
00116
AbstractDatabaseUser user = (
AbstractDatabaseUser) it.next();
00117 username = user.
getName();
00118 password = user.
getPassword();
00119 authenticationOk =
authenticate(name, username, password);
00120
if (authenticationOk)
00121
break;
00122 }
00123
00124
if (principals.size() == 0 &&
logger.isDebugEnabled())
00125
throw new MBeanException(
new Exception(
00126
"Authentication failed : no principal"));
00127
00128
if (!authenticationOk)
00129
throw new MBeanException(
new Exception(
00130
"Authentication failed : principal invalid"));
00131
if (
logger.isDebugEnabled())
00132
logger.debug(
"Authentication with principal was successfull");
00133
return super.invoke(name, operationName, params, signature);
00134 }
00135 }
00136
else
00137 {
00138
if (
logger.isDebugEnabled())
00139
logger.debug(
"no authentication required");
00140
00141
return super.invoke(name, operationName, params, signature);
00142 }
00143 }
00144
00145 private boolean authenticate(ObjectName name, String username, String password)
00146 {
00147
try
00148 {
00149
boolean vdb = name.toString().indexOf(
00150
JmxConstants.CJDBC_TYPE_VIRTUALDATABASE) != -1;
00151
if (vdb)
00152
return ((Boolean)
invoke(name,
"checkAdminAuthentication",
00153
new Object[]{username, password},
new String[]{
"java.lang.String",
00154
"java.lang.String"})).booleanValue();
00155
else
00156 {
00157
boolean backend = name.toString().indexOf(
00158
JmxConstants.CJDBC_TYPE_BACKEND) != -1;
00159
if (backend)
00160 {
00161
00162 ObjectName vdbName =
JmxConstants
00163 .getVirtualDbObjectNameFromBackend(name);
00164
return ((Boolean)
invoke(vdbName,
"checkAdminAuthentication",
00165
new Object[]{username, password},
new String[]{
00166
"java.lang.String",
"java.lang.String"})).booleanValue();
00167 }
00168
else
00169
00170
return true;
00171 }
00172 }
00173
catch (Exception e)
00174 {
00175
if (
logger.isDebugEnabled())
00176 {
00177
logger.debug(
"authentication failed with exception ", e);
00178 }
00179
return false;
00180 }
00181 }
00182
00183 private static Object[]
cleanO(Object[] params)
00184 {
00185 List o = Arrays.asList(params);
00186 o = o.subList(2, o.size());
00187
return (
new ArrayList(o).toArray());
00188 }
00189
00190 private static String[]
cleanS(String[] params)
00191 {
00192 List o = Arrays.asList(params);
00193 o = o.subList(2, o.size());
00194 String[] s =
new String[o.size()];
00195
return (String[])
new ArrayList(o).toArray(s);
00196 }
00197 }