You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2011/08/31 20:46:58 UTC

svn commit: r1163740 - in /db/derby/code/trunk/java: engine/org/apache/derby/diag/ engine/org/apache/derby/loc/ shared/org/apache/derby/shared/common/reference/ testing/org/apache/derbyTesting/functionTests/tests/lang/

Author: rhillegas
Date: Wed Aug 31 18:46:57 2011
New Revision: 1163740

URL: http://svn.apache.org/viewvc?rev=1163740&view=rev
Log:
DERBY-5395: Let only the DBO run certain diagnostic vtis.

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/diag/DiagUtil.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DBOAccessTest.java   (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/diag/ErrorLogReader.java
    db/derby/code/trunk/java/engine/org/apache/derby/diag/StatementCache.java
    db/derby/code/trunk/java/engine/org/apache/derby/diag/StatementDuration.java
    db/derby/code/trunk/java/engine/org/apache/derby/diag/TransactionTable.java
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java

Added: db/derby/code/trunk/java/engine/org/apache/derby/diag/DiagUtil.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/diag/DiagUtil.java?rev=1163740&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/diag/DiagUtil.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/diag/DiagUtil.java Wed Aug 31 18:46:57 2011
@@ -0,0 +1,61 @@
+/*
+
+   Derby - Class org.apache.derby.diag.DiagUtil
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.diag;
+
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.services.context.ContextService;
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+
+/**
+ * Utility methods for the package of diagnostic vtis.
+ */
+abstract    class   DiagUtil
+{
+    /**
+     * Raise an exception if we are running with SQL authorization turned on
+     * but the current user isn't the database owner. This method is used
+     * to restrict access to VTIs which disclose sensitive information.
+     * See DERBY-5395.
+     */
+    static void    checkAccess()   throws StandardException
+    {
+        LanguageConnectionContext lcc = (LanguageConnectionContext)
+            ContextService.getContextOrNull(LanguageConnectionContext.CONTEXT_ID);
+        DataDictionary  dd = lcc.getDataDictionary();
+
+        if ( dd.usesSqlAuthorization() )
+        {
+            String  databaseOwner = dd.getAuthorizationDatabaseOwner();
+            String  currentUser = lcc.getStatementContext().getSQLSessionContext().getCurrentUser();
+
+            if ( !databaseOwner.equals( currentUser ) )
+            {
+                throw StandardException.newException( SQLState.DBO_ONLY );
+            }
+        }
+    }
+
+}
+
+

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/diag/DiagUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/diag/ErrorLogReader.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/diag/ErrorLogReader.java?rev=1163740&r1=1163739&r2=1163740&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/diag/ErrorLogReader.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/diag/ErrorLogReader.java Wed Aug 31 18:46:57 2011
@@ -26,6 +26,8 @@ import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.FileInputStream;
+import java.security.PrivilegedAction;
+import java.security.AccessController;
 
 import java.util.Hashtable;
 import java.util.Enumeration;
@@ -35,8 +37,10 @@ import java.sql.SQLException;
 import java.sql.Types;
 import org.apache.derby.vti.VTITemplate;
 import org.apache.derby.iapi.reference.Limits;
+import org.apache.derby.iapi.reference.Property;
 import org.apache.derby.iapi.util.StringUtil;
 
+import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.sql.ResultColumnDescriptor;
 import org.apache.derby.impl.jdbc.EmbedResultSetMetaData;
 
@@ -117,9 +121,20 @@ public class ErrorLogReader extends VTIT
 		ErrorLogReader('filename') will access the specified
 		file name.
 	 */
-	public ErrorLogReader()
+	public ErrorLogReader() throws StandardException
 	{
-		String home = System.getProperty("derby.system.home");
+        DiagUtil.checkAccess();
+
+        final String home = (String)AccessController.doPrivileged
+            (
+             new PrivilegedAction()
+             {
+                 public Object run()
+                 {
+                     return System.getProperty( Property.SYSTEM_HOME_PROPERTY );
+                 }
+             }
+             );
 
 		inputFileName = "derby.log";
 
@@ -129,8 +144,10 @@ public class ErrorLogReader extends VTIT
 		}
 	}
 
-	public ErrorLogReader(String inputFileName)
+	public ErrorLogReader(String inputFileName) throws StandardException
 	{
+        DiagUtil.checkAccess();
+
 		this.inputFileName = inputFileName;
 	}
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/diag/StatementCache.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/diag/StatementCache.java?rev=1163740&r1=1163739&r2=1163740&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/diag/StatementCache.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/diag/StatementCache.java Wed Aug 31 18:46:57 2011
@@ -29,10 +29,11 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.Vector;
 
+import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.reference.Limits;
 import org.apache.derby.iapi.services.cache.CacheManager;
+import org.apache.derby.iapi.services.context.ContextService;
 import org.apache.derby.iapi.sql.ResultColumnDescriptor;
-import org.apache.derby.iapi.sql.conn.ConnectionUtil;
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.util.StringUtil;
 import org.apache.derby.impl.jdbc.EmbedResultSetMetaData;
@@ -73,10 +74,13 @@ public final class StatementCache extend
 	private GenericPreparedStatement currentPs;
 	private boolean wasNull;
 
-	public StatementCache() throws SQLException {
+	public StatementCache() throws StandardException {
 
-		LanguageConnectionContext lcc = ConnectionUtil.getCurrentLCC();
+        DiagUtil.checkAccess();
         
+        LanguageConnectionContext lcc = (LanguageConnectionContext)
+            ContextService.getContextOrNull(LanguageConnectionContext.CONTEXT_ID);
+
         CacheManager statementCache =
             lcc.getLanguageConnectionFactory().getStatementCache();
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/diag/StatementDuration.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/diag/StatementDuration.java?rev=1163740&r1=1163739&r2=1163740&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/diag/StatementDuration.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/diag/StatementDuration.java Wed Aug 31 18:46:57 2011
@@ -26,6 +26,8 @@ import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.FileInputStream;
+import java.security.PrivilegedAction;
+import java.security.AccessController;
 import java.text.SimpleDateFormat;
 import java.util.Hashtable;
 import java.util.Enumeration;
@@ -35,9 +37,11 @@ import java.sql.SQLException;
 import java.sql.Timestamp;
 import java.sql.Types;
 import org.apache.derby.vti.VTITemplate;
+import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.sql.ResultColumnDescriptor;
 import org.apache.derby.impl.jdbc.EmbedResultSetMetaData;
 import org.apache.derby.iapi.reference.Limits;
+import org.apache.derby.iapi.reference.Property;
 import org.apache.derby.iapi.util.StringUtil;
 
 /**
@@ -107,9 +111,20 @@ public class StatementDuration extends V
 		StatementDuration('filename') will access the specified
 		file name.
 	 */
-	public StatementDuration()
+	public StatementDuration()  throws StandardException
 	{
-		String home = System.getProperty("derby.system.home");
+        DiagUtil.checkAccess();
+
+        final String home = (String)AccessController.doPrivileged
+            (
+             new PrivilegedAction()
+             {
+                 public Object run()
+                 {
+                     return System.getProperty( Property.SYSTEM_HOME_PROPERTY );
+                 }
+             }
+             );
 
 		inputFileName = "derby.log";
 
@@ -119,8 +134,10 @@ public class StatementDuration extends V
 		}
 	}
 
-	public StatementDuration(String inputFileName)
+	public StatementDuration(String inputFileName)  throws StandardException
 	{
+        DiagUtil.checkAccess();
+
 		this.inputFileName = inputFileName;
 	}
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/diag/TransactionTable.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/diag/TransactionTable.java?rev=1163740&r1=1163739&r2=1163740&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/diag/TransactionTable.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/diag/TransactionTable.java Wed Aug 31 18:46:57 2011
@@ -21,6 +21,7 @@
 
 package org.apache.derby.diag;
 
+import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.conn.ConnectionUtil;
 import org.apache.derby.iapi.store.access.TransactionInfo;
@@ -86,6 +87,11 @@ public class TransactionTable extends VT
 	int currentRow;
 	private boolean wasNull;
 
+    public  TransactionTable()    throws StandardException
+    {
+        DiagUtil.checkAccess();
+    }
+    
 	/**
 		@see java.sql.ResultSet#getMetaData
 	 */

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=1163740&r1=1163739&r2=1163740&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Wed Aug 31 18:46:57 2011
@@ -1223,6 +1223,11 @@ Guide.
             </msg>
 
             <msg>
+                <name>4251D</name>
+                <text>Only the database owner can view this data.</text>
+            </msg>
+
+            <msg>
                 <name>42601</name>
                 <text>In an ALTER TABLE statement, the column '{0}' has been specified as NOT NULL and either the DEFAULT clause was not specified or was specified as DEFAULT NULL.</text>
                 <arg>columnName</arg>

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=1163740&r1=1163739&r2=1163740&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Wed Aug 31 18:46:57 2011
@@ -773,6 +773,7 @@ public interface SQLState {
     String AUTH_ROLE_DBO_ONLY                                          = "4251A";
 	String AUTH_PUBLIC_ILLEGAL_AUTHORIZATION_ID                        = "4251B";
 	String AUTH_ROLE_GRANT_CIRCULARITY                                 = "4251C";
+	String DBO_ONLY                                                         = "4251D";
 
 	String LANG_DB2_NOT_NULL_COLUMN_INVALID_DEFAULT                    = "42601";
 	String LANG_DB2_INVALID_HEXADECIMAL_CONSTANT                    = "42606";

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DBOAccessTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DBOAccessTest.java?rev=1163740&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DBOAccessTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DBOAccessTest.java Wed Aug 31 18:46:57 2011
@@ -0,0 +1,176 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.tests.lang.DBOAccessTest
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.functionTests.tests.lang;
+
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.DatabasePropertyTestSetup;
+import org.apache.derbyTesting.junit.TestConfiguration;
+import org.apache.derbyTesting.junit.SupportFilesSetup;
+
+/**
+ * Tests that certain operations can only be performed by the DBO.
+ */
+public class DBOAccessTest extends GeneratedColumnsHelper
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    private static  final   String      TEST_DBO = "TEST_DBO";
+    private static  final   String      JANET = "JANET";
+    private static  final   String[]    LEGAL_USERS = { TEST_DBO, JANET };
+
+    // Name of the log file to use when testing VTIs that expect one.
+    private static final String TEST_LOG_FILE = "sys_vti_test_derby.tstlog";
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Create a new instance.
+     */
+
+    public DBOAccessTest( String name )
+    {
+        super( name );
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // OVERRIDABLE BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  boolean authorizationIsOn() { return true; }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // NESTED CLASSES
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  static  final   class   NoAuthorization extends DBOAccessTest
+    {
+        public NoAuthorization( String name )
+        {
+            super( name );
+        }
+
+        public  boolean authorizationIsOn() { return false; }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // JUnit BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Construct top level suite in this JUnit test
+     */
+    public static Test suite()
+    {
+        String[]    testFiles = new String[] { "functionTests/tests/lang/" + TEST_LOG_FILE };
+        
+        Test    authorizedRun = TestConfiguration.embeddedSuite( DBOAccessTest.class );
+        authorizedRun = DatabasePropertyTestSetup.builtinAuthentication
+            ( authorizedRun, LEGAL_USERS, "authorizationOnDBOAccessTest" );
+        authorizedRun = new SupportFilesSetup( authorizedRun, testFiles );
+        authorizedRun = TestConfiguration.sqlAuthorizationDecorator( authorizedRun );
+
+        Test    unauthorizedRun = TestConfiguration.embeddedSuite( NoAuthorization.class );
+        unauthorizedRun = new SupportFilesSetup( unauthorizedRun, testFiles );
+
+        TestSuite suite = new TestSuite();
+        suite.addTest( authorizedRun );
+        suite.addTest( unauthorizedRun );
+
+        return suite;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // TESTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Tests that only the DBO can run diagnostic VTIs which return sensitive information.
+     * See DERBY-5395.
+     * </p>
+     */
+    public  void    test_5395() throws Exception
+    {
+        println( "authorizationIsOn() = " + authorizationIsOn() );
+        
+        Connection  dboConnection = openUserConnection( TEST_DBO );
+        Connection  janetConnection = openUserConnection( JANET );
+
+        minion_5395( dboConnection, true );
+        minion_5395( janetConnection, !authorizationIsOn() );
+    }
+    private void    minion_5395( Connection conn, boolean shouldSucceed ) throws Exception
+    {
+        vet_5395( conn, shouldSucceed, "select * from syscs_diag.statement_cache" );
+        vet_5395( conn, shouldSucceed, "select * from syscs_diag.transaction_table" );
+        vet_5395( conn, shouldSucceed, "select * from table( syscs_diag.error_log_reader( ) ) s" );
+        vet_5395( conn, shouldSucceed, "select * from table( syscs_diag.statement_duration() ) s" );
+        
+        java.net.URL logURL = SupportFilesSetup.getReadOnlyURL( TEST_LOG_FILE );
+        String vtiArg = "'" + logURL.getFile() + "'";
+
+        vet_5395( conn, shouldSucceed, "select * from table( syscs_diag.error_log_reader( " + vtiArg + " ) ) s" );
+        vet_5395( conn, shouldSucceed, "select * from table( syscs_diag.statement_duration( " + vtiArg + " ) ) s" );
+    }
+    private void    vet_5395( Connection conn, boolean shouldSucceed, String query ) throws Exception
+    {
+        if ( shouldSucceed ) { goodStatement( conn, query ); }
+        else
+        {
+            expectCompilationError( conn, "4251D", query );
+        }
+    }
+
+}
+
+
+
+

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DBOAccessTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java?rev=1163740&r1=1163739&r2=1163740&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java Wed Aug 31 18:46:57 2011
@@ -216,6 +216,7 @@ public class _Suite extends BaseTestCase
         suite.addTest(SequenceTest.suite());
         suite.addTest(SequencePermsTest.suite());
         suite.addTest(SequenceGeneratorTest.suite());
+        suite.addTest(DBOAccessTest.suite());
         suite.addTest(OLAPTest.suite());
         suite.addTest(OrderByAndOffsetFetchInSubqueries.suite());
         suite.addTest(Derby5005Test.suite());