Index: java/org/apache/tomcat/jdbc/pool/PooledConnection.java =================================================================== --- java/org/apache/tomcat/jdbc/pool/PooledConnection.java (revision 1054684) +++ java/org/apache/tomcat/jdbc/pool/PooledConnection.java (working copy) @@ -20,6 +20,7 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.HashMap; +import java.util.Properties; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.juli.logging.Log; @@ -40,6 +41,10 @@ */ private static final Log log = LogFactory.getLog(PooledConnection.class); + public static final String PROP_USER = "user"; + + public static final String PROP_PASSWORD = "password"; + /** * Validate when connection is borrowed flag */ @@ -122,6 +127,24 @@ this.parent = parent; } + public boolean checkUser(String username, String password) { + if (username==null) username = poolProperties.getUsername(); + if (password==null) password = poolProperties.getPassword(); + + String storedUsr = (String)getAttributes().get(PROP_USER); + String storedPwd = (String)getAttributes().get(PROP_PASSWORD); + + boolean result = (username==null && storedUsr==null); + result = (result || (username!=null && username.equals(storedUsr))); + + result = result && ((password==null && storedPwd==null) || (password!=null && password.equals(storedPwd))); + + if (username==null) getAttributes().remove(PROP_USER); else getAttributes().put(PROP_USER, username); + if (password==null) getAttributes().remove(PROP_PASSWORD); else getAttributes().put(PROP_PASSWORD, password); + + return result; + } + /** * Connects the underlying connection to the database. * @throws SQLException if the method {@link #release()} has been called. @@ -162,10 +185,24 @@ } protected void connectUsingDataSource() throws SQLException { + String usr = null; + String pwd = null; + if (getAttributes().containsKey(PROP_USER)) { + usr = (String) getAttributes().get(PROP_USER); + } else { + usr = poolProperties.getUsername(); + getAttributes().put(PROP_USER, usr); + } + if (getAttributes().containsKey(PROP_PASSWORD)) { + pwd = (String) getAttributes().get(PROP_PASSWORD); + } else { + pwd = poolProperties.getPassword(); + getAttributes().put(PROP_PASSWORD, pwd); + } if (poolProperties.getDataSource() instanceof javax.sql.XADataSource) { javax.sql.XADataSource xds = (javax.sql.XADataSource)poolProperties.getDataSource(); - if (poolProperties.getUsername()!=null && poolProperties.getPassword()!=null) { - xaConnection = xds.getXAConnection(poolProperties.getUsername(), poolProperties.getPassword()); + if (usr!=null && pwd!=null) { + xaConnection = xds.getXAConnection(usr, pwd); connection = xaConnection.getConnection(); } else { xaConnection = xds.getXAConnection(); @@ -173,15 +210,15 @@ } } else if (poolProperties.getDataSource() instanceof javax.sql.DataSource){ javax.sql.DataSource ds = (javax.sql.DataSource)poolProperties.getDataSource(); - if (poolProperties.getUsername()!=null && poolProperties.getPassword()!=null) { - connection = ds.getConnection(poolProperties.getUsername(), poolProperties.getPassword()); + if (usr!=null && pwd!=null) { + connection = ds.getConnection(usr, pwd); } else { connection = ds.getConnection(); } } else if (poolProperties.getDataSource() instanceof javax.sql.ConnectionPoolDataSource){ javax.sql.ConnectionPoolDataSource ds = (javax.sql.ConnectionPoolDataSource)poolProperties.getDataSource(); - if (poolProperties.getUsername()!=null && poolProperties.getPassword()!=null) { - connection = ds.getPooledConnection(poolProperties.getUsername(), poolProperties.getPassword()).getConnection(); + if (usr!=null && pwd!=null) { + connection = ds.getPooledConnection(usr, pwd).getConnection(); } else { connection = ds.getPooledConnection().getConnection(); } @@ -203,17 +240,26 @@ throw ex; } String driverURL = poolProperties.getUrl(); - String usr = poolProperties.getUsername(); - String pwd = poolProperties.getPassword(); - if (usr != null) { - poolProperties.getDbProperties().setProperty("user", usr); + String usr = null; + String pwd = null; + if (getAttributes().containsKey(PROP_USER)) { + usr = (String) getAttributes().get(PROP_USER); + } else { + usr = poolProperties.getUsername(); + getAttributes().put(PROP_USER, usr); } - if (pwd != null) { - poolProperties.getDbProperties().setProperty("password", pwd); + if (getAttributes().containsKey(PROP_PASSWORD)) { + pwd = (String) getAttributes().get(PROP_PASSWORD); + } else { + pwd = poolProperties.getPassword(); + getAttributes().put(PROP_PASSWORD, pwd); } - + Properties properties = clone(poolProperties.getDbProperties()); + if (usr != null) properties.setProperty(PROP_USER, usr); + if (pwd != null) properties.setProperty(PROP_PASSWORD, pwd); + try { - connection = driver.connect(driverURL, poolProperties.getDbProperties()); + connection = connection = driver.connect(driverURL, properties); } catch (Exception x) { if (log.isDebugEnabled()) { log.debug("Unable to connect to database.", x); @@ -235,6 +281,12 @@ } } + private Properties clone(Properties p) { + Properties c = new Properties(); + c.putAll(p); + return c; + } + /** * * @return true if connect() was called successfully and disconnect has not yet been called Index: java/org/apache/tomcat/jdbc/pool/ConnectionPool.java =================================================================== --- java/org/apache/tomcat/jdbc/pool/ConnectionPool.java (revision 1054684) +++ java/org/apache/tomcat/jdbc/pool/ConnectionPool.java (working copy) @@ -161,10 +161,29 @@ */ public Connection getConnection() throws SQLException { //check out a connection - PooledConnection con = borrowConnection(-1); + PooledConnection con = borrowConnection(-1,null,null); return setupConnection(con); } + + /** + * Borrows a connection from the pool. If a connection is available (in the + * idle queue) or the pool has not reached {@link PoolProperties#maxActive + * maxActive} connections a connection is returned immediately. If no + * connection is available, the pool will attempt to fetch a connection for + * {@link PoolProperties#maxWait maxWait} milliseconds. + * + * @return Connection - a java.sql.Connection/javax.sql.PooledConnection + * reflection proxy, wrapping the underlying object. + * @throws SQLException + * - if the wait times out or a failure occurs creating a + * connection + */ + public Connection getConnection(String username, String password) throws SQLException { + // check out a connection + PooledConnection con = borrowConnection(-1, username, password); + return setupConnection(con); + } /** * Returns the name of this pool @@ -422,7 +441,7 @@ PooledConnection[] initialPool = new PooledConnection[poolProperties.getInitialSize()]; try { for (int i = 0; i < initialPool.length; i++) { - initialPool[i] = this.borrowConnection(0); //don't wait, should be no contention + initialPool[i] = this.borrowConnection(0, null, null); //don't wait, should be no contention } //for } catch (SQLException x) { @@ -529,7 +548,7 @@ * @return PooledConnection * @throws SQLException */ - private PooledConnection borrowConnection(int wait) throws SQLException { + private PooledConnection borrowConnection(int wait, String username, String password) throws SQLException { if (isClosed()) { throw new SQLException("Connection pool closed."); @@ -543,7 +562,7 @@ while (true) { if (con!=null) { //configure the connection and return it - PooledConnection result = borrowConnection(now, con); + PooledConnection result = borrowConnection(now, con, username, password); //null should never be returned, but was in a previous impl. if (result!=null) return result; } @@ -559,7 +578,7 @@ size.decrementAndGet(); } else { //create a connection, we're below the limit - return createConnection(now, con); + return createConnection(now, con, username, password); } } //end if @@ -608,10 +627,11 @@ * @return a PooledConnection that has been connected * @throws SQLException */ - protected PooledConnection createConnection(long now, - PooledConnection notUsed) throws SQLException { + protected PooledConnection createConnection(long now, PooledConnection notUsed, String username, String password) throws SQLException { //no connections where available we'll create one PooledConnection con = create(); + if (username!=null) con.getAttributes().put(con.PROP_USER, username); + if (password!=null) con.getAttributes().put(con.PROP_PASSWORD, password); boolean error = false; try { //connect and validate the connection @@ -660,13 +680,14 @@ * @return con * @throws SQLException if a validation error happens */ - protected PooledConnection borrowConnection(long now, PooledConnection con) throws SQLException { + protected PooledConnection borrowConnection(long now, PooledConnection con, String username, String password) throws SQLException { //we have a connection, lets set it up //flag to see if we need to nullify boolean setToNull = false; try { con.lock(); + boolean usercheck = con.checkUser(username, password); if (con.isReleased()) { return null; @@ -676,20 +697,23 @@ //attempt to connect con.connect(); } - if ((!con.isDiscarded()) && con.validate(PooledConnection.VALIDATE_BORROW)) { - //set the timestamp - con.setTimestamp(now); - if (getPoolProperties().isLogAbandoned()) { - //set the stack trace for this pool - con.setStackTrace(getThreadDump()); + + if (usercheck) { + if ((!con.isDiscarded()) && con.validate(PooledConnection.VALIDATE_BORROW)) { + //set the timestamp + con.setTimestamp(now); + if (getPoolProperties().isLogAbandoned()) { + //set the stack trace for this pool + con.setStackTrace(getThreadDump()); + } + if (!busy.offer(con)) { + log.debug("Connection doesn't fit into busy array, connection will not be traceable."); + } + return con; } - if (!busy.offer(con)) { - log.debug("Connection doesn't fit into busy array, connection will not be traceable."); - } - return con; } //if we reached here, that means the connection - //is either discarded or validation failed. + //is either has another principal, is discarded or validation failed. //we will make one more attempt //in order to guarantee that the thread that just acquired //the connection shouldn't have to poll again. @@ -1051,7 +1075,7 @@ if (result!=null) return result; if (configured.compareAndSet(false, true)) { try { - pc = borrowConnection(System.currentTimeMillis(),pc); + pc = borrowConnection(System.currentTimeMillis(),pc, null, null); result = ConnectionPool.this.setupConnection(pc); } catch (SQLException x) { cause = x; Index: java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java =================================================================== --- java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java (revision 1054684) +++ java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java (working copy) @@ -74,7 +74,9 @@ * {@link javax.sql.DataSource#getConnection()} */ public Connection getConnection(String username, String password) throws SQLException { - return getConnection(); + if (pool == null) + return createPool().getConnection(username,password); + return pool.getConnection(username,password); } public PoolConfiguration getPoolProperties() {