View | Details | Raw Unified | Return to bug 55559
Collapse All | Expand All

(-)a/java/org/apache/catalina/mbeans/MBeanUtils.java (-1 / +2 lines)
Lines 787-792 public class MBeanUtils { Link Here
787
        // The database itself
787
        // The database itself
788
        ObjectName db = new ObjectName(
788
        ObjectName db = new ObjectName(
789
                "Users:type=UserDatabase,database=" + userDatabase);
789
                "Users:type=UserDatabase,database=" + userDatabase);
790
        mserver.unregisterMBean(db);
790
        if( mserver.isRegistered(db) )
791
        	mserver.unregisterMBean(db);
791
    }
792
    }
792
}
793
}
(-)a/java/org/apache/catalina/realm/UserDatabaseRealm.java (-49 / +39 lines)
Lines 27-45 import java.util.List; Link Here
27
import javax.naming.Context;
27
import javax.naming.Context;
28
28
29
import org.apache.catalina.Group;
29
import org.apache.catalina.Group;
30
import org.apache.catalina.LifecycleException;
31
import org.apache.catalina.Role;
30
import org.apache.catalina.Role;
32
import org.apache.catalina.User;
31
import org.apache.catalina.User;
33
import org.apache.catalina.UserDatabase;
32
import org.apache.catalina.UserDatabase;
34
import org.apache.catalina.Wrapper;
33
import org.apache.catalina.Wrapper;
34
import org.apache.naming.ContextBindings;
35
import org.apache.tomcat.util.ExceptionUtils;
35
import org.apache.tomcat.util.ExceptionUtils;
36
36
37
37
38
/**
38
/**
39
 * <p>Implementation of {@link org.apache.catalina.Realm} that is based on an implementation of
39
 * <p>Implementation of {@link org.apache.catalina.Realm} that is based on an implementation of
40
 * {@link UserDatabase} made available through the global JNDI resources
40
 * {@link UserDatabase} made available through the JNDI resources
41
 * configured for this instance of Catalina.  Set the <code>resourceName</code>
41
 * configured for this instance of Catalina.  Set the <code>resourceName</code>
42
 * parameter to the global JNDI resources name for the configured instance
42
 * parameter to the JNDI resources name for the configured instance
43
 * of <code>UserDatabase</code> that we should consult.</p>
43
 * of <code>UserDatabase</code> that we should consult.</p>
44
 *
44
 *
45
 * @author Craig R. McClanahan
45
 * @author Craig R. McClanahan
Lines 55-83 public class UserDatabaseRealm Link Here
55
55
56
56
57
    /**
57
    /**
58
     * The <code>UserDatabase</code> we will use to authenticate users
59
     * and identify associated roles.
60
     */
61
    protected UserDatabase database = null;
62
63
64
    /**
65
     * Descriptive information about this Realm implementation.
58
     * Descriptive information about this Realm implementation.
66
     */
59
     */
67
    protected static final String name = "UserDatabaseRealm";
60
    protected static final String name = "UserDatabaseRealm";
68
61
69
62
70
    /**
63
    /**
71
     * The global JNDI name of the <code>UserDatabase</code> resource
64
     * The JNDI name of the <code>UserDatabase</code> resource
72
     * we will be utilizing.
65
     * we will be utilizing.
73
     */
66
     */
74
    protected String resourceName = "UserDatabase";
67
    protected String resourceName = "UserDatabase";
68
    
69
    /**
70
     * Context local datasource.
71
     */
72
    protected boolean localDataSource = false;
75
73
76
74
77
    // ------------------------------------------------------------- Properties
75
    // ------------------------------------------------------------- Properties
78
76
79
    /**
77
    /**
80
     * Return the global JNDI name of the <code>UserDatabase</code> resource
78
     * Return the JNDI name of the <code>UserDatabase</code> resource
81
     * we will be using.
79
     * we will be using.
82
     */
80
     */
83
    public String getResourceName() {
81
    public String getResourceName() {
Lines 88-94 public class UserDatabaseRealm Link Here
88
86
89
87
90
    /**
88
    /**
91
     * Set the global JNDI name of the <code>UserDatabase</code> resource
89
     * Set the JNDI name of the <code>UserDatabase</code> resource
92
     * we will be using.
90
     * we will be using.
93
     *
91
     *
94
     * @param resourceName The new global JNDI name
92
     * @param resourceName The new global JNDI name
Lines 137-143 public class UserDatabaseRealm Link Here
137
            return false;
135
            return false;
138
        }
136
        }
139
        User user = (User)principal;
137
        User user = (User)principal;
140
        Role dbrole = database.findRole(role);
138
        Role dbrole = getDatabase().findRole(role);
141
        if(dbrole == null) {
139
        if(dbrole == null) {
142
            return false;
140
            return false;
143
        }
141
        }
Lines 174-180 public class UserDatabaseRealm Link Here
174
    @Override
172
    @Override
175
    protected String getPassword(String username) {
173
    protected String getPassword(String username) {
176
174
177
        User user = database.findUser(username);
175
        User user = getDatabase().findUser(username);
178
176
179
        if (user == null) {
177
        if (user == null) {
180
            return null;
178
            return null;
Lines 191-197 public class UserDatabaseRealm Link Here
191
    @Override
189
    @Override
192
    protected Principal getPrincipal(String username) {
190
    protected Principal getPrincipal(String username) {
193
191
194
        User user = database.findUser(username);
192
        User user = getDatabase().findUser(username);
195
        if(user == null) {
193
        if(user == null) {
196
            return null;
194
            return null;
197
        }
195
        }
Lines 218-269 public class UserDatabaseRealm Link Here
218
    // ------------------------------------------------------ Lifecycle Methods
216
    // ------------------------------------------------------ Lifecycle Methods
219
217
220
218
221
    /**
219
    protected UserDatabase getDatabase() {
222
     * Prepare for the beginning of active use of the public methods of this
220
    
223
     * component and implement the requirements of
224
     * {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
225
     *
226
     * @exception LifecycleException if this component detects a fatal error
227
     *  that prevents this component from being used
228
     */
229
    @Override
230
    protected void startInternal() throws LifecycleException {
231
232
        try {
221
        try {
233
            Context context = getServer().getGlobalNamingContext();
222
        	Context context = null;
234
            database = (UserDatabase) context.lookup(resourceName);
223
            if (localDataSource) {
224
                context = ContextBindings.getClassLoader();
225
                context = (Context) context.lookup("comp/env");
226
            } else {
227
                context = getServer().getGlobalNamingContext();
228
            }
229
            return (UserDatabase) context.lookup(resourceName);
235
        } catch (Throwable e) {
230
        } catch (Throwable e) {
236
            ExceptionUtils.handleThrowable(e);
231
            ExceptionUtils.handleThrowable(e);
237
            containerLog.error(sm.getString("userDatabaseRealm.lookup",
232
            containerLog.error(sm.getString("userDatabaseRealm.lookup",
238
                                            resourceName),
233
                                            resourceName),
239
                               e);
234
                               e);
240
            database = null;
235
            return null;
241
        }
242
        if (database == null) {
243
            throw new LifecycleException
244
                (sm.getString("userDatabaseRealm.noDatabase", resourceName));
245
        }
236
        }
246
247
        super.startInternal();
248
    }
237
    }
249
238
250
239
251
    /**
240
    /**
252
     * Gracefully terminate the active use of the public methods of this
241
     * Return if the datasource will be looked up in the webapp JNDI Context.
253
     * component and implement the requirements of
254
     * {@link org.apache.catalina.util.LifecycleBase#stopInternal()}.
255
     *
256
     * @exception LifecycleException if this component detects a fatal error
257
     *  that needs to be reported
258
     */
242
     */
259
    @Override
243
	public boolean getLocalDataSource() {
260
    protected void stopInternal() throws LifecycleException {
244
		return localDataSource;
245
	}
261
246
262
        // Perform normal superclass finalization
263
        super.stopInternal();
264
247
265
        // Release reference to our user database
248
	/**
266
        database = null;
249
     * Set to true to cause the datasource to be looked up in the webapp JNDI
250
     * Context.
251
     *
252
     * @param localDataSource the new flag value
253
     */
254
	public void setLocalDataSource(boolean localDataSource) {
255
		this.localDataSource = localDataSource;
256
	}
267
257
268
    }
258
    
269
}
259
}
(-)a/webapps/docs/config/realm.xml (+7 lines)
Lines 688-693 Link Here
688
        are defined in web.xml in which case the user must be assigned at least
688
        are defined in web.xml in which case the user must be assigned at least
689
        one of those roles.</p>
689
        one of those roles.</p>
690
      </attribute>
690
      </attribute>
691
      
692
      <attribute name="localDataSource" required="false">
693
        <p>When the realm is nested inside a Context element, this allows the
694
        realm to use a DataSource defined for the Context rather than a global
695
        DataSource.  If not specified, the default is <code>false</code>: use a
696
        global DataSource.</p>
697
      </attribute>
691
698
692
      <attribute name="resourceName" required="true">
699
      <attribute name="resourceName" required="true">
693
        <p>The name of the global <code>UserDatabase</code> resource
700
        <p>The name of the global <code>UserDatabase</code> resource

Return to bug 55559