You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by na...@apache.org on 2001/02/04 23:08:24 UTC

cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/aaa JDBCRealm.java

nacho       01/02/04 14:08:24

  Modified:    src/share/org/apache/tomcat/modules/aaa JDBCRealm.java
  Log:
  Cosmetic changes and the ability to select
  when the JDBC connection is started at
  Tomcat init or in first realm access.
  
  Revision  Changes    Path
  1.2       +190 -268  jakarta-tomcat/src/share/org/apache/tomcat/modules/aaa/JDBCRealm.java
  
  Index: JDBCRealm.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/aaa/JDBCRealm.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JDBCRealm.java	2001/01/01 02:01:29	1.1
  +++ JDBCRealm.java	2001/02/04 22:08:24	1.2
  @@ -1,11 +1,11 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/aaa/JDBCRealm.java,v 1.1 2001/01/01 02:01:29 costin Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/01/01 02:01:29 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/aaa/JDBCRealm.java,v 1.2 2001/02/04 22:08:24 nacho Exp $
  + * $Revision: 1.2 $
  + * $Date: 2001/02/04 22:08:24 $
    *
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 1999 The Apache Software Foundation.  All rights 
  + * Copyright (c) 1999 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -13,7 +13,7 @@
    * are met:
    *
    * 1. Redistributions of source code must retain the above copyright
  - *    notice, this list of conditions and the following disclaimer. 
  + *    notice, this list of conditions and the following disclaimer.
    *
    * 2. Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in
  @@ -21,7 +21,7 @@
    *    distribution.
    *
    * 3. The end-user documentation included with the redistribution, if
  - *    any, must include the following acknowlegement:  
  + *    any, must include the following acknowlegement:
    *       "This product includes software developed by the
    *        Apache Software Foundation (http://www.apache.org/)."
    *    Alternately, this acknowlegement may appear in the software itself,
  @@ -64,152 +64,103 @@
   import org.apache.tomcat.core.*;
   import org.apache.tomcat.util.*;
   import java.security.*;
  -import java.security.Principal;
  -import java.io.File;
  -import java.util.Enumeration;
  -import java.util.Hashtable;
  +//import java.security.Principal;
  +//import java.io.File;
  +//import java.util.Enumeration;
  +//import java.util.Hashtable;
   import java.util.Vector;
   import java.io.*;
   import java.net.*;
   import java.util.*;
   import java.sql.*;
   
  -
   /**
  - *
    * Implmentation of <b>Realm</b> that works with any JDBC supported database.
  - * See the JDBCRealm.howto for more details on how to set up the database and
  - * for configuration options.
  - *
  - * TODO:
  - *    - Work on authentication with non-plaintext passwords
  - *
  + * See the JDBCRealm.howto for more details on how to set up the database and for configuration options. TODO:
  + * - Work on authentication with non-plaintext passwords
    * @author Craig R. McClanahan
    * @author Carson McDonald
    * @author Ignacio J. Ortega
    * @author Bip Thelin
  - *
    */
  -
   public final class JDBCRealm extends BaseInterceptor {
  -
  -
  -    ContextManager cm;
       int reqRolesNote;
       int userNote;
       int passwordNote;
       // ----------------------------------------------------- Instance Variables
   
  -    /**
  -     * The connection to the database.
  -     */
  +    /** The connection to the database. */
       private Connection dbConnection = null;
   
  -    /**
  -     * The PreparedStatement to use for authenticating users.
  -     */
  +    /** The PreparedStatement to use for authenticating users. */
       private PreparedStatement preparedAuthenticate = null;
   
  -
  -    /**
  -     * The PreparedStatement to use for identifying the roles for
  -     * a specified user.
  -     */
  +    /** The PreparedStatement to use for identifying the roles for a specified user. */
       private PreparedStatement preparedRoles = null;
  -
   
  -    /**
  -     * The connection URL to use when trying to connect to the databse
  -     */
  +    /** The connection URL to use when trying to connect to the databse */
       private String connectionURL = null;
   
  -    /**
  -     * The connection URL to use when trying to connect to the databse
  -     */
  +    /** The connection URL to use when trying to connect to the databse */
       private String connectionName = null;
   
  -    /**
  -     * The connection URL to use when trying to connect to the databse
  -     */
  +    /** The connection URL to use when trying to connect to the databse */
       private String connectionPassword = null;
   
  -    /**
  -     * The table that holds user data.
  -     */
  +    /** The table that holds user data. */
       private String userTable = null;
   
  -    /**
  -     * The column in the user table that holds the user's name
  -     */
  +    /** The column in the user table that holds the user's name */
       private String userNameCol = null;
   
  -    /**
  -     * The column in the user table that holds the user's credintials
  -     */
  +    /** The column in the user table that holds the user's credintials */
       private String userCredCol = null;
   
  -    /**
  -     * The table that holds the relation between user's and roles
  -     */
  +    /** The table that holds the relation between user's and roles */
       private String userRoleTable = null;
   
  -    /**
  -     * The column in the user role table that names a role
  -     */
  +    /** The column in the user role table that names a role */
       private String roleNameCol = null;
   
  -    /**
  -     * The JDBC driver to use.
  -     */
  +    /** The JDBC driver to use. */
       private String driverName = null;
  -
  -    /**
  -     * The string manager for this package.
  -     */
  -    private static StringManager sm =
  -        StringManager.getManager("org.apache.tomcat.resources");
   
  +    /** The string manager for this package. */
  +    private static StringManager sm = StringManager.getManager("org.apache.tomcat.resources");
   
  -    /**
  -     * Has this component been started?
  -     */
  +    /** Has this component been started? */
       private boolean started = false;
   
  +    /** Has the JDBC connection been started? */
  +    private boolean JDBCstarted = false;
  +
       /**
  -     *
  -     * Digest algorithm used in passwords thit is same values
  -     * accepted by MessageDigest  for algorithm
  +     * Digest algorithm used in passwords thit is same values accepted by MessageDigest  for algorithm
        * plus "No" ( no encode ) that is the default
  -     *
        */
  -
  -    private String digest="No";
  +    private String digest = "No";
   
  -
  +    boolean connectOnInit = false;
       // ------------------------------------------------------------- Properties
   
  -
       /**
        * Set the JDBC driver that will be used.
  -     *
        * @param driverName The driver name
        */
  -    public void setDriverName( String driverName ) {
  -      this.driverName = driverName;
  +    public void setDriverName(String driverName) {
  +        this.driverName = driverName;
       }
   
       /**
        * Set the URL to use to connect to the database.
  -     *
        * @param connectionURL The new connection URL
        */
  -    public void setConnectionURL( String connectionURL ) {
  -      this.connectionURL = connectionURL;
  +    public void setConnectionURL(String connectionURL) {
  +        this.connectionURL = connectionURL;
       }
   
       /**
        * Set the name to use to connect to the database.
  -     *
        * @param connectionName User name
        */
       public void setConnectionName(String connectionName) {
  @@ -218,7 +169,6 @@
   
       /**
        * Set the password to use to connect to the database.
  -     *
        * @param connectionPassword User password
        */
       public void setConnectionPassword(String connectionPassword) {
  @@ -227,229 +177,214 @@
   
       /**
        * Set the table that holds user data.
  -     *
        * @param userTable The table name
        */
  -    public void setUserTable( String userTable ) {
  -      this.userTable = userTable;
  +    public void setUserTable(String userTable) {
  +        this.userTable = userTable;
       }
   
       /**
        * Set the column in the user table that holds the user's name
  -     *
        * @param userNameCol The column name
        */
  -    public void setUserNameCol( String userNameCol ) {
  -       this.userNameCol = userNameCol;
  +    public void setUserNameCol(String userNameCol) {
  +        this.userNameCol = userNameCol;
       }
   
       /**
        * Set the column in the user table that holds the user's credintials
  -     *
        * @param userCredCol The column name
        */
  -    public void setUserCredCol( String userCredCol ) {
  -       this.userCredCol = userCredCol;
  +    public void setUserCredCol(String userCredCol) {
  +        this.userCredCol = userCredCol;
       }
   
       /**
        * Set the table that holds the relation between user's and roles
  -     *
        * @param userRoleTable The table name
        */
  -    public void setUserRoleTable( String userRoleTable ) {
  +    public void setUserRoleTable(String userRoleTable) {
           this.userRoleTable = userRoleTable;
       }
   
       /**
        * Set the column in the user role table that names a role
  -     *
  -     * @param userRoleNameCol The column name
  -     */
  -    public void setRoleNameCol( String roleNameCol ) {
  +     * @param roleNameCol The column name
  + */
  +    public void setRoleNameCol(String roleNameCol) {
           this.roleNameCol = roleNameCol;
       }
  +
       /**
        * Gets the digest algorithm  used for credentials in the database
  -     * could be the same that MessageDigest accepts vor algorithm
  -     * and "No" that is the Default
  -     *
  -     */
  -
  +     * could be the same that MessageDigest accepts vor algorithm and "No" that is the Default
  +     * @return 
  + */
       public String getDigest() {
           return digest;
       }
   
       /**
  -     * Gets the digest algorithm  used for credentials in the database
  -     * could be the same that MessageDigest accepts vor algorithm
  -     * and "No" that is the Default
  -     *
  +     * Sets the digest algorithm  used for credentials in the database
  +     * could be the same that MessageDigest accepts vor algorithm and "No" that is the Default
        * @param algorithm the Encode type
  -     */
  -
  + */
       public void setDigest(String algorithm) {
           digest = algorithm;
       }
  +    
  +/**
  + * When connectOnInit is setted to "true" the JDBC connection is started at tomcat init
  + * if false the connection is started in the first times is needed.
  + * @param s "true" or "false"
  + */    
  +    public void setConnectOnInit(String s) {
  +        connectOnInit = Boolean.valueOf(s).booleanValue();
  +    }
   
       /**
        * If there are any errors with the JDBC connection, executing
  -     * the query or anything we return false (don't authenticate). This
  -     * event is also logged.
  -     *
  +     * the query or anything we return false (don't authenticate). This event is also logged.
        * If there is some SQL exception the connection is set to null.
        * This will allow a retry on the next auth attempt. This might not
  -     * be the best thing to do but it will keep tomcat from needing a
  -     * restart if the database goes down.
  +     * be the best thing to do but it will keep tomcat from needing a restart if the database goes down.
        *
        * @param username Username of the Principal to look up
  -     * @param credentials Password or other credentials to use in
  -     *  authenticating this username
  +     * @param credentials Password or other credentials to use in authenticating this username
        */
  -    public synchronized boolean checkPassword(String username
  -            , String credentials) {
  +    private synchronized boolean checkPassword(String username,String credentials) {
           try {
               if (!checkConnection())
                   return false;
               // Create the authentication search prepared statement if necessary
               if (preparedAuthenticate == null) {
  -                String sql = "SELECT " + userCredCol + " FROM " + userTable +
  -                    " WHERE " + userNameCol + " = ?";
  +                String sql = "SELECT " + userCredCol
  +                    + " FROM " + userTable
  +                    + " WHERE " + userNameCol + " = ?";
                   if (debug >= 1)
                       log("JDBCRealm.authenticate: " + sql);
                   preparedAuthenticate = dbConnection.prepareStatement(sql);
               }
  -
               // Perform the authentication search
               preparedAuthenticate.setString(1, username);
               ResultSet rs1 = preparedAuthenticate.executeQuery();
  -            boolean found = false;
               if (rs1.next()) {
                   if (digest.equalsIgnoreCase("No")) {
  -                    if (credentials.equals(rs1.getString(1))) {
  +                    if (credentials.equals(rs1.getString(1).trim())) {
                           if (debug >= 2)
  -                            log(sm.getString("jdbcRealm.authenticateSuccess",
  -                                     username));
  +                            log(sm.getString("jdbcRealm.authenticateSuccess", username));
                           return true;
                       }
                   } else {
  -                    if (credentials.equals(Digest(rs1.getString(1),digest))) {
  +                    if (credentials.equals(digest(rs1.getString(1), digest))) {
                           if (debug >= 2)
  -                            log(sm.getString("jdbcRealm.authenticateSuccess",
  -                                     username));
  +                            log(sm.getString("jdbcRealm.authenticateSuccess", username));
                           return true;
                       }
                   }
               }
               rs1.close();
               if (debug >= 2)
  -                log(sm.getString("jdbcRealm.authenticateFailure",
  -                         username));
  -
  +                log(sm.getString("jdbcRealm.authenticateFailure", username));
               return false;
  -        } catch( SQLException ex ) {
  -
  +        } catch (SQLException ex) {
               // Log the problem for posterity
  -            log(sm.getString("jdbcRealm.checkPasswordSQLException",
  -                     username),ex);
  -
  +            log(sm.getString("jdbcRealm.checkPasswordSQLException", username), ex);
               // Clean up the JDBC objects so that they get recreated next time
               if (preparedAuthenticate != null) {
  -            try {
  -                preparedAuthenticate.close();
  -            } catch (Throwable t) {
  -                ;
  -            }
  -            preparedAuthenticate = null;
  +                try {
  +                    preparedAuthenticate.close();
  +                } catch (Throwable t) {
  +                    ;
  +                }
  +                preparedAuthenticate = null;
               }
               if (dbConnection != null) {
  -            try {
  -                dbConnection.close();
  -            } catch (Throwable t) {
  -                ;
  -            }
  -            dbConnection = null;
  +                try {
  +                    dbConnection.close();
  +                } catch (Throwable t) {
  +                    ;
  +                }
  +                dbConnection = null;
               }
  -
               // Return "not authenticated" for this request
               return false;
           }
       }
   
  -    private boolean checkConnection(){
  +    private boolean checkConnection() {
           try {
  -            if( (dbConnection == null) || dbConnection.isClosed() ) {
  +            if ((dbConnection == null) || dbConnection.isClosed()) {
                   Class.forName(driverName);
  -                log(sm.getString("jdbcRealm.checkConnectionDBClosed"));
  +                if( JDBCstarted )
  +                        log(sm.getString("jdbcRealm.checkConnectionDBClosed"));
                   if ((connectionName == null || connectionName.equals("")) ||
  -                        (connectionPassword == null || connectionPassword.equals(""))) {
  +                    (connectionPassword == null || connectionPassword.equals(""))) {
                           dbConnection = DriverManager.getConnection(connectionURL);
                   } else {
  -                        dbConnection = DriverManager.getConnection(connectionURL,
  -                                                                   connectionName,
  -                                                                   connectionPassword);
  +                    dbConnection = DriverManager.getConnection(connectionURL, connectionName, connectionPassword);
                   }
  -                if( dbConnection == null || dbConnection.isClosed() ) {
  -                  log(sm.getString("jdbcRealm.checkConnectionDBReOpenFail"));
  -                  return false;
  +                JDBCstarted=true;
  +                if (dbConnection == null || dbConnection.isClosed()) {
  +                    log(sm.getString("jdbcRealm.checkConnectionDBReOpenFail"));
  +                    return false;
                   }
               }
               return true;
  -        }catch (SQLException ex){
  -            log(sm.getString("jdbcRealm.checkConnectionSQLException"),ex);
  +        } catch (SQLException ex) {
  +            log(sm.getString("jdbcRealm.checkConnectionSQLException"), ex);
               return false;
           }
  -        catch( ClassNotFoundException ex ) {
  +        catch (ClassNotFoundException ex) {
               throw new RuntimeException("JDBCRealm.checkConnection: " + ex);
           }
       }
   
  +/**
  + * returns all the roles for a given user.
  + *
  + * @param username the user name
  + * @return the roles array
  + */    
       public synchronized String[] getUserRoles(String username) {
           try {
  -            if ( !checkConnection() )
  +            if (!checkConnection())
                   return null;
               if (preparedRoles == null) {
  -                String sql = "SELECT " + roleNameCol + " FROM " +
  -                    userRoleTable + " WHERE " + userNameCol + " = ?";
  +                String sql = "SELECT " + roleNameCol + " FROM " + userRoleTable + " WHERE " + userNameCol + " = ?";
                   if (debug >= 1)
                       log("JDBCRealm.roles: " + sql);
                   preparedRoles = dbConnection.prepareStatement(sql);
               }
               preparedRoles.clearParameters();
               preparedRoles.setString(1, username);
  -
               ResultSet rs = preparedRoles.executeQuery();
  -
               // Next we convert the resultset into a String[]
  -            Vector vrol=new Vector();
  -
  +            Vector vrol = new Vector();
               while (rs.next()) {
  -              vrol.addElement(rs.getString(1));
  +                vrol.addElement(rs.getString(1).trim());
               }
  -            String[] res=new String[vrol.size() > 0 ? vrol.size() : 1 ];
  -
  +            String[] res = new String[vrol.size() > 0 ? vrol.size() : 1];
               // no roles case
  -            if( vrol.size() == 0 ){
  -                res[0]="";
  +            if (vrol.size() == 0) {
  +                res[0] = "";
                   return res;
               }
  -
  -            for(int i=0 ; i<vrol.size() ; i++ )
  -              res[i]=(String)vrol.elementAt(i);
  +            for (int i = 0; i < vrol.size(); i++)
  +                res[i] = (String)vrol.elementAt(i);
               return res;
           }
  -        catch( SQLException ex ) {
  +        catch (SQLException ex) {
               // Set the connection to null.
               // Next time we will try to get a new connection.
  -            log(sm.getString("jdbcRealm.getUserRolesSQLException",
  -                     username));
  +            log(sm.getString("jdbcRealm.getUserRolesSQLException", username));
               if (preparedRoles != null) {
                   try {
                       preparedRoles.close();
                   } catch (Throwable t) {
                       ;
  -            }
  -            preparedRoles = null;
  +                }
  +                preparedRoles = null;
               }
               if (dbConnection != null) {
                   try {
  @@ -464,134 +399,121 @@
       }
   
       // -------------------- Tomcat hooks --------------------
  -
  -    public void contextInit(Context ctx)
  -            throws org.apache.tomcat.core.TomcatException {
  +    public void contextInit(Context ctx) throws org.apache.tomcat.core.TomcatException {
           super.contextInit(ctx);
           init(ctx.getContextManager());
  -	// Validate and update our current component state
  +        // Validate and update our current component state
       }
   
  -    public void contextShutdown(Context ctx)
  -            throws org.apache.tomcat.core.TomcatException {
  +    public void contextShutdown(Context ctx) throws org.apache.tomcat.core.TomcatException {
           shutdown();
       }
   
  -    public void shutdown()
  -            throws org.apache.tomcat.core.TomcatException {
  -      // Validate and update our current component state
  -      if (started) {
  -        started=false;
  -        try {
  -            if( dbConnection != null && !dbConnection.isClosed())
  -                dbConnection.close();
  -        }catch( SQLException ex ) {
  -            log("dbConnection.close Exception!!!",ex);
  +    public void shutdown() throws org.apache.tomcat.core.TomcatException {
  +        // Validate and update our current component state
  +        if (started) {
  +            started = false;
  +            try {
  +                if (dbConnection != null && !dbConnection.isClosed())
  +                    dbConnection.close();
  +            } catch (SQLException ex) {
  +                log("dbConnection.close Exception!!!", ex);
  +            }
           }
  -      }
       }
   
  -
  -    public int authenticate( Request req, Response response ) {
  -        String user=(String)req.getNote( userNote );
  -        String password=(String)req.getNote( passwordNote );
  -	if( user==null) return DECLINED; 
  -	
  -	if( checkPassword( user, password ) ) {
  -     	    if( debug > 0 ) log( "Auth ok, user=" + user );
  +/**
  + * Hook implementation
  + * @param req
  + * @param response
  + * @return
  + */    
  +    public int authenticate(Request req, Response response) {
  +        String user = (String)req.getNote(userNote);
  +        String password = (String)req.getNote(passwordNote);
  +        if (user == null) return DECLINED;
  +        if (checkPassword(user, password)) {
  +            if (debug > 0) log("Auth ok, user=" + user);
               Context ctx = req.getContext();
               if (ctx != null)
                   req.setAuthType(ctx.getAuthMethod());
  -	    if( user!=null) {
  -		req.setRemoteUser( user );
  -//		req.setNote(reqRealmSignNote,this);
  -		String userRoles[] = getUserRoles( user );
  -		req.setUserRoles( userRoles );
  -		return OK;
  -	    }
  -	}
  -	return DECLINED;
  +            if (user != null) {
  +                req.setRemoteUser(user);
  +                //		req.setNote(reqRealmSignNote,this);
  +                String userRoles[] = getUserRoles(user);
  +                req.setUserRoles(userRoles);
  +                return OK;
  +            }
  +        }
  +        return DECLINED;
       }
   
  -  
       /**
  -     * Digest password using the algorithm especificied and
  -     * convert the result to a corresponding hex string.
  +     * Digest password using the algorithm especificied and convert the result to a corresponding hex string.
        * If exception, the plain credentials string is returned
  -     *
  -     * @param credentials Password or other credentials to use in
  -     *  authenticating this username
  -     *
  +     * @param credentials Password or other credentials to use in authenticating this username
        * @param algorithm Algorithm used to do th digest
  -     *
        */
  -    final public static String Digest(String credentials,String algorithm) {
  +    public final static String digest(String credentials, String algorithm) {
           try {
               // Obtain a new message digest with MD5 encryption
               MessageDigest md = (MessageDigest)MessageDigest.getInstance(algorithm).clone();
               // encode the credentials
  -            md.update( credentials.getBytes() );
  +            md.update(credentials.getBytes());
               // obtain the byte array from the digest
               byte[] dig = md.digest();
               // convert the byte array to hex string
  -//            Base64 enc=new Base64();
  -//            return new String(enc.encode(HexUtils.convert(dig).getBytes()));
  +            //            Base64 enc=new Base64();
  +            //            return new String(enc.encode(HexUtils.convert(dig).getBytes()));
               return HexUtils.convert(dig);
  -
  -        } catch( Exception ex ) {
  -                ex.printStackTrace();
  -                return credentials;
  +        } catch (Exception ex) {
  +            ex.printStackTrace();
  +            return credentials;
           }
       }
   
  -    public static void main(String args[] ) {
  +/**
  + * JDBCRealm can be used as a standalone tool for offline password digest
  + * @param args
  + */    
  +    public static void main(String args[]) {
           if (args.length >= 2) {
  -            if( args[0].equalsIgnoreCase("-a")){
  -                for( int i=2; i < args.length ; i++){
  -                    System.out.print(args[i]+":");
  -                    System.out.println(Digest(args[i],args[1]));
  +            if (args[0].equalsIgnoreCase("-a")) {
  +                for (int i = 2; i < args.length; i++) {
  +                    System.out.print(args[i] + ":");
  +                    System.out.println(digest(args[i], args[1]));
                   }
               }
           }
  -
       }
   
  -    /** Called when the ContextManger is started
  -     */
  +    /** Called when the ContextManger is started */
       public void engineInit(ContextManager cm) throws TomcatException {
           super.engineInit(cm);
           init(cm);
       }
   
       void init(ContextManager cm) {
  -      if (!started) {
  -          started = true;
  -      // set-up a per/container note for maps
  -          try {
  -          // XXX make the name a "global" static - after everything is stable!
  -            reqRolesNote = cm.getNoteId( ContextManager.REQUEST_NOTE
  -                , "required.roles");
  -	    userNote=cm.getNoteId( ContextManager.REQUEST_NOTE,
  -				   "credentials.user");
  -	    passwordNote=cm.getNoteId( ContextManager.REQUEST_NOTE,
  -				       "credentials.password");
  -          }
  -          catch( TomcatException ex ) {
  -            log("setting up note for " + cm, ex);
  -            throw new RuntimeException( "Invalid state ");
  -          }
  -      }
  +        if (!started) {
  +            started = true;
  +            // set-up a per/container note for maps
  +            try {
  +                // XXX make the name a "global" static - after everything is stable!
  +                reqRolesNote = cm.getNoteId(ContextManager.REQUEST_NOTE, "required.roles");
  +                userNote = cm.getNoteId(ContextManager.REQUEST_NOTE, "credentials.user");
  +                passwordNote = cm.getNoteId(ContextManager.REQUEST_NOTE, "credentials.password");
  +                if (connectOnInit && !checkConnection())
  +                        throw new RuntimeException("JDBCRealm cannot be started");
  +            }
  +            catch (TomcatException ex) {
  +                log("setting up note for " + cm, ex);
  +                throw new RuntimeException("Invalid state ");
  +            }
  +        }
       }
   
  -    /** Called before the ContextManager is stoped.
  -     *  You need to stop any threads and remove any resources.
  -     */
       public void engineShutdown(ContextManager cm) throws TomcatException {
  -        //TODO:  Override this org.apache.tomcat.core.BaseInterceptor method
           shutdown();
       }
   
  -
   }
  -
  -