diff --git a/java/org/apache/catalina/mbeans/MBeanUtils.java b/java/org/apache/catalina/mbeans/MBeanUtils.java index 9a3ea4d..c8d1156 100644 --- a/java/org/apache/catalina/mbeans/MBeanUtils.java +++ b/java/org/apache/catalina/mbeans/MBeanUtils.java @@ -787,6 +787,7 @@ public class MBeanUtils { // The database itself ObjectName db = new ObjectName( "Users:type=UserDatabase,database=" + userDatabase); - mserver.unregisterMBean(db); + if( mserver.isRegistered(db) ) + mserver.unregisterMBean(db); } } diff --git a/java/org/apache/catalina/realm/UserDatabaseRealm.java b/java/org/apache/catalina/realm/UserDatabaseRealm.java index d89e43c..5b01a99 100644 --- a/java/org/apache/catalina/realm/UserDatabaseRealm.java +++ b/java/org/apache/catalina/realm/UserDatabaseRealm.java @@ -27,19 +27,19 @@ import java.util.List; import javax.naming.Context; import org.apache.catalina.Group; -import org.apache.catalina.LifecycleException; import org.apache.catalina.Role; import org.apache.catalina.User; import org.apache.catalina.UserDatabase; import org.apache.catalina.Wrapper; +import org.apache.naming.ContextBindings; import org.apache.tomcat.util.ExceptionUtils; /** *

Implementation of {@link org.apache.catalina.Realm} that is based on an implementation of - * {@link UserDatabase} made available through the global JNDI resources + * {@link UserDatabase} made available through the JNDI resources * configured for this instance of Catalina. Set the resourceName - * parameter to the global JNDI resources name for the configured instance + * parameter to the JNDI resources name for the configured instance * of UserDatabase that we should consult.

* * @author Craig R. McClanahan @@ -55,29 +55,27 @@ public class UserDatabaseRealm /** - * The UserDatabase we will use to authenticate users - * and identify associated roles. - */ - protected UserDatabase database = null; - - - /** * Descriptive information about this Realm implementation. */ protected static final String name = "UserDatabaseRealm"; /** - * The global JNDI name of the UserDatabase resource + * The JNDI name of the UserDatabase resource * we will be utilizing. */ protected String resourceName = "UserDatabase"; + + /** + * Context local datasource. + */ + protected boolean localDataSource = false; // ------------------------------------------------------------- Properties /** - * Return the global JNDI name of the UserDatabase resource + * Return the JNDI name of the UserDatabase resource * we will be using. */ public String getResourceName() { @@ -88,7 +86,7 @@ public class UserDatabaseRealm /** - * Set the global JNDI name of the UserDatabase resource + * Set the JNDI name of the UserDatabase resource * we will be using. * * @param resourceName The new global JNDI name @@ -137,7 +135,7 @@ public class UserDatabaseRealm return false; } User user = (User)principal; - Role dbrole = database.findRole(role); + Role dbrole = getDatabase().findRole(role); if(dbrole == null) { return false; } @@ -174,7 +172,7 @@ public class UserDatabaseRealm @Override protected String getPassword(String username) { - User user = database.findUser(username); + User user = getDatabase().findUser(username); if (user == null) { return null; @@ -191,7 +189,7 @@ public class UserDatabaseRealm @Override protected Principal getPrincipal(String username) { - User user = database.findUser(username); + User user = getDatabase().findUser(username); if(user == null) { return null; } @@ -218,52 +216,44 @@ public class UserDatabaseRealm // ------------------------------------------------------ Lifecycle Methods - /** - * Prepare for the beginning of active use of the public methods of this - * component and implement the requirements of - * {@link org.apache.catalina.util.LifecycleBase#startInternal()}. - * - * @exception LifecycleException if this component detects a fatal error - * that prevents this component from being used - */ - @Override - protected void startInternal() throws LifecycleException { - + protected UserDatabase getDatabase() { + try { - Context context = getServer().getGlobalNamingContext(); - database = (UserDatabase) context.lookup(resourceName); + Context context = null; + if (localDataSource) { + context = ContextBindings.getClassLoader(); + context = (Context) context.lookup("comp/env"); + } else { + context = getServer().getGlobalNamingContext(); + } + return (UserDatabase) context.lookup(resourceName); } catch (Throwable e) { ExceptionUtils.handleThrowable(e); containerLog.error(sm.getString("userDatabaseRealm.lookup", resourceName), e); - database = null; - } - if (database == null) { - throw new LifecycleException - (sm.getString("userDatabaseRealm.noDatabase", resourceName)); + return null; } - - super.startInternal(); } /** - * Gracefully terminate the active use of the public methods of this - * component and implement the requirements of - * {@link org.apache.catalina.util.LifecycleBase#stopInternal()}. - * - * @exception LifecycleException if this component detects a fatal error - * that needs to be reported + * Return if the datasource will be looked up in the webapp JNDI Context. */ - @Override - protected void stopInternal() throws LifecycleException { + public boolean getLocalDataSource() { + return localDataSource; + } - // Perform normal superclass finalization - super.stopInternal(); - // Release reference to our user database - database = null; + /** + * Set to true to cause the datasource to be looked up in the webapp JNDI + * Context. + * + * @param localDataSource the new flag value + */ + public void setLocalDataSource(boolean localDataSource) { + this.localDataSource = localDataSource; + } - } + } diff --git a/webapps/docs/config/realm.xml b/webapps/docs/config/realm.xml index cbf0ddf..98cbbc5 100644 --- a/webapps/docs/config/realm.xml +++ b/webapps/docs/config/realm.xml @@ -688,6 +688,13 @@ are defined in web.xml in which case the user must be assigned at least one of those roles.

+ + +

When the realm is nested inside a Context element, this allows the + realm to use a DataSource defined for the Context rather than a global + DataSource. If not specified, the default is false: use a + global DataSource.

+

The name of the global UserDatabase resource