db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r1558387 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/sql/compile/ engine/org/apache/derby/impl/sql/compile/ testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Wed, 15 Jan 2014 14:03:51 GMT
Author: rhillegas
Date: Wed Jan 15 14:03:50 2014
New Revision: 1558387

URL: http://svn.apache.org/r1558387
Log:
DERBY-6434: Correct privilege checks for DELETE statements; commit derby-6434-02-ac-correctDeletePrivs.diff.

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/ScopeFilter.java   (with
props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GrantRevokeDDLTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java?rev=1558387&r1=1558386&r2=1558387&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java
Wed Jan 15 14:03:50 2014
@@ -132,6 +132,8 @@ public interface CompilerContext extends
 	public	static	final	int			CONDITIONAL_RESTRICTION		= NEXT_VALUE_FOR_ILLEGAL;
 	public	static	final	int			GROUP_BY_RESTRICTION		= NEXT_VALUE_FOR_ILLEGAL;
 
+    public  static  final   String  WHERE_SCOPE = "whereScope";
+    
 	/////////////////////////////////////////////////////////////////////////////////////
 	//
 	//	BEHAVIOR
@@ -604,5 +606,25 @@ public interface CompilerContext extends
      */
     public  boolean passesPrivilegeFilters( Visitable visitable )
         throws StandardException;
+
+    /**
+     * Record that the compiler is entering a named scope. Increment the
+     * depth counter for that scope.
+     */
+    public  void    beginScope( String scopeName );
+    
+    /**
+     * Record that the compiler is exiting a named scope. Decrement the
+     * depth counter for that scope.
+     */
+    public  void    endScope( String scopeName );
+
+    /**
+     * Get the current depth for the named scope. For instance, if
+     * we are processing a WHERE clause inside a subquery which is
+     * invoked inside an outer WHERE clause, the depth of the whereScope
+     * would be 2. Returns 0 if the compiler isn't inside any such scope.
+     */
+    public  int     scopeDepth( String scopeName );
     
 }

Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/ScopeFilter.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/ScopeFilter.java?rev=1558387&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/ScopeFilter.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/ScopeFilter.java Wed
Jan 15 14:03:50 2014
@@ -0,0 +1,82 @@
+/*
+
+   Derby - Class org.apache.derby.iapi.sql.compile.ScopeFilter
+
+   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.iapi.sql.compile;
+
+import java.util.List;
+
+import org.apache.derby.iapi.error.StandardException;
+
+/**
+ * Filter which passes Visitables only if the compiler is inside
+ * a named scope.
+ *
+ */
+public class ScopeFilter implements VisitableFilter
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////
+
+    private CompilerContext _compilerContext;
+    private String  _scopeName;
+    private int     _minDepth;
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////
+
+    /** Construct a filter for the given scope and minimal expected depth. */
+    public  ScopeFilter
+        (
+         CompilerContext    compilerContext,
+         String                 scopeName,
+         int                    minDepth
+         )
+    {
+        _compilerContext = compilerContext;
+        _scopeName = scopeName;
+        _minDepth = minDepth;
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  VisitableFilter BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    
+	public  boolean accept( Visitable visitable ) 
+		throws StandardException
+    {
+        return (_compilerContext.scopeDepth( _scopeName ) >= _minDepth);
+    }
+    
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/ScopeFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java?rev=1558387&r1=1558386&r2=1558387&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java
Wed Jan 15 14:03:50 2014
@@ -78,6 +78,8 @@ import org.apache.derby.iapi.util.ReuseF
 public class CompilerContextImpl extends ContextImpl
 	implements CompilerContext {
 
+    private static  final   int SCOPE_CELL = 0;
+    
 	//
 	// Context interface       
 	//
@@ -143,6 +145,7 @@ public class CompilerContextImpl extends
 		defaultSchemaStack = null;
         referencedSequences = null;
         privilegeCheckFilters =  null;
+        namedScopes = null;
 	}
 
 	//
@@ -1001,8 +1004,44 @@ public class CompilerContextImpl extends
         return true;
     }
     
+    public  void    beginScope( String scopeName )
+    {
+        if ( namedScopes == null ) { namedScopes = new HashMap<String,int[]>(); }
+        
+        int[]   scopeDepth = namedScopes.get( scopeName );
+        if ( scopeDepth == null )
+        {
+            scopeDepth = new int[ SCOPE_CELL + 1 ];
+            namedScopes.put( scopeName, scopeDepth );
+        }
+
+        scopeDepth[ SCOPE_CELL ]++;
+    }
+    
+    public  void    endScope( String scopeName )
+    {
+        if ( namedScopes == null ) { return; }
+
+        int[]   scopeDepth = namedScopes.get( scopeName );
+        if ( scopeDepth == null )   { return; }
+
+        scopeDepth[ SCOPE_CELL ]--;
+
+        if ( scopeDepth[ SCOPE_CELL ] <= 0 ) { namedScopes.remove( scopeName ); }
+    }
+
+    public  int     scopeDepth( String scopeName )
+    {
+        if ( namedScopes == null ) { return 0; }
+
+        int[]   scopeDepth = namedScopes.get( scopeName );
+        if ( scopeDepth == null )   { return 0; }
+        else { return scopeDepth[ SCOPE_CELL ]; }
+    }
+
+
 	/*
-	** Context state must be reset in restContext()
+	** Context state must be reset in resetContext()
 	*/
 
 	private final Parser 		parser;
@@ -1024,6 +1063,8 @@ public class CompilerContextImpl extends
 	private List<Object>				savedObjects;
 	private String				classPrefix;
 	private SchemaDescriptor	compilationSchema;
+    private ArrayList<VisitableFilter> privilegeCheckFilters;
+    private HashMap<String,int[]> namedScopes;
 
 	/**
 	 * Saved execution time default schema, if we need to change it
@@ -1060,7 +1101,5 @@ public class CompilerContextImpl extends
 	private HashMap<UUID,String> requiredUsagePrivileges;
 	private HashMap<StatementRolePermission,StatementRolePermission> requiredRolePrivileges;
     private HashMap<UUID,SequenceDescriptor> referencedSequences;
-
-    private ArrayList<VisitableFilter> privilegeCheckFilters;
     
 } // end of class CompilerContextImpl

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java?rev=1558387&r1=1558386&r2=1558387&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java Wed
Jan 15 14:03:50 2014
@@ -40,6 +40,9 @@ import org.apache.derby.iapi.services.io
 import org.apache.derby.shared.common.sanity.SanityManager;
 import org.apache.derby.iapi.sql.ResultDescription;
 import org.apache.derby.iapi.sql.StatementType;
+import org.apache.derby.iapi.sql.compile.CompilerContext;
+import org.apache.derby.iapi.sql.compile.IgnoreFilter;
+import org.apache.derby.iapi.sql.compile.ScopeFilter;
 import org.apache.derby.iapi.sql.conn.Authorizer;
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
@@ -137,6 +140,14 @@ class DeleteNode extends DMLModStatement
 			TableName					cursorTargetTableName = null;
 			CurrentOfNode       		currentOfNode = null;
 
+            //
+            // Don't add privilege requirements for the UDT types of columns.
+            // The compiler will attempt to add these when generating the full column list
during
+            // binding of the tables.
+            //
+            IgnoreFilter    ignorePermissions = new IgnoreFilter();
+            getCompilerContext().addPrivilegeFilter( ignorePermissions );
+            
 			DataDictionary dataDictionary = getDataDictionary();
             // for DELETE clause of a MERGE statement, the tables have already been bound
 			if ( !inMatchingClause() ) { super.bindTables(dataDictionary); }
@@ -277,9 +288,21 @@ class DeleteNode extends DMLModStatement
 				resultSet.setResultColumns(resultColumnList);
 			}
 
+            // done excluding column types from privilege checking
+            getCompilerContext().removePrivilegeFilter( ignorePermissions );
+
 			/* Bind the expressions before the ResultColumns are bound */
+
+            // only add privileges when we're inside the WHERE clause
+            ScopeFilter scopeFilter = new ScopeFilter( getCompilerContext(), CompilerContext.WHERE_SCOPE,
1 );
+            getCompilerContext().addPrivilegeFilter( scopeFilter );
 			super.bindExpressions();
 
+            //
+            // Don't remove the WHERE scopeFilter. Pre-processing may try to
+            // add other privileges which we don't need.
+            //
+
 			/* Bind untyped nulls directly under the result columns */
 			resultSet.getResultColumns().
 				bindUntypedNullsToResultColumns(resultColumnList);
@@ -369,12 +392,11 @@ class DeleteNode extends DMLModStatement
 
 				}
 			}
-			if (isPrivilegeCollectionRequired())
-			{
-				getCompilerContext().pushCurrentPrivType( getPrivType());
-				getCompilerContext().addRequiredTablePriv( targetTableDescriptor);
-				getCompilerContext().popCurrentPrivType();
-			}
+
+            // add need for DELETE privilege on the target table
+            getCompilerContext().pushCurrentPrivType( getPrivType());
+            getCompilerContext().addRequiredTablePriv( targetTableDescriptor);
+            getCompilerContext().popCurrentPrivType();
 		}
 		finally
 		{

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java?rev=1558387&r1=1558386&r2=1558387&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java Wed
Jan 15 14:03:50 2014
@@ -590,6 +590,7 @@ class SelectNode extends ResultSetNode
         
 		if (whereClause != null)
 		{
+            cc.beginScope( CompilerContext.WHERE_SCOPE );
 			cc.pushCurrentPrivType( Authorizer.SELECT_PRIV);
 
             int previousReliability = orReliability( CompilerContext.WHERE_CLAUSE_RESTRICTION
);
@@ -619,6 +620,7 @@ class SelectNode extends ResultSetNode
 			
 			whereClause = whereClause.checkIsBoolean();
 			getCompilerContext().popCurrentPrivType();
+            cc.endScope( CompilerContext.WHERE_SCOPE );
 
 			checkNoWindowFunctions(whereClause, "WHERE");
 		}

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GrantRevokeDDLTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GrantRevokeDDLTest.java?rev=1558387&r1=1558386&r2=1558387&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GrantRevokeDDLTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GrantRevokeDDLTest.java
Wed Jan 15 14:03:50 2014
@@ -11500,7 +11500,7 @@ public final class GrantRevokeDDLTest ex
      * Test that INSERT statements require the correct privileges as
      * described on DERBY-6434.
      */
-    public void test_6434_tables()
+    public void test_6434_insert()
         throws Exception
     {
         Connection  dboConnection = openUserConnection( TEST_DBO );
@@ -11748,4 +11748,235 @@ public final class GrantRevokeDDLTest ex
              );
     }
     
+    /**
+     * Test that DELETE statements require the correct privileges as
+     * described on DERBY-6434.
+     */
+    public void test_6434_delete()
+        throws Exception
+    {
+        Connection  dboConnection = openUserConnection( TEST_DBO );
+        Connection  ruthConnection = openUserConnection( RUTH );
+
+        //
+        // Schema
+        //
+        goodStatement
+            (
+             dboConnection,
+             "create type SelectType_6434_2 external name 'java.util.HashMap' language java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type BeforeTriggerType_6434_2 external name 'java.util.HashMap' language
java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type AfterTriggerType_6434_2 external name 'java.util.HashMap' language
java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function selectFunction_6434_2( hashMap SelectType_6434_2, hashKey varchar(
32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function beforeTriggerFunction_6434_2( hashMap BeforeTriggerType_6434_2,
hashKey varchar( 32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function afterTriggerFunction_6434_2( hashMap AfterTriggerType_6434_2,
hashKey varchar( 32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create derby aggregate selectAggregate_6434_2 for int\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.ModeAggregate'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create procedure addHistoryRow_6434_2\n" +
+             "(\n" +
+             "    actionString varchar( 20 ),\n" +
+             "    actionValue int\n" +
+             ")\n" +
+             "language java parameter style java reads sql data\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.MergeStatementTest.addHistoryRow'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table primaryTable_6434_2\n" +
+             "(\n" +
+             "    key1 int primary key\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table selectTable_6434_2\n" +
+             "(\n" +
+             "    selectColumn int,\n" +
+             "    selectColumn2 SelectType_6434_2\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table deleteTable_6434_2\n" +
+             "(\n" +
+             "    privateForeignColumn int references primaryTable_6434_2( key1 ),\n" +
+             "    privatePrimaryColumn int primary key,\n" +
+             "    privateBeforeTriggerSource BeforeTriggerType_6434_2,\n" +
+             "    privateAfterTriggerSource AfterTriggerType_6434_2,\n" +
+             "    publicSelectColumn int\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table foreignTable_6434_2\n" +
+             "(\n" +
+             "    key1 int references deleteTable_6434_2( privatePrimaryColumn )\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create trigger beforeDeleteTrigger_6434_2\n" +
+             "no cascade before delete on deleteTable_6434_2\n" +
+             "referencing old as old\n" +
+             "for each row\n" +
+             "call addHistoryRow_6434_2( 'before', beforeTriggerFunction_6434_2( old.privateBeforeTriggerSource,
'foo' ) )\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create trigger afterDeleteTrigger_6434_2\n" +
+             "after delete on deleteTable_6434_2\n" +
+             "referencing old as old\n" +
+             "for each row\n" +
+             "call addHistoryRow_6434_2( 'after', afterTriggerFunction_6434_2( old.privateAfterTriggerSource,
'foo' ) )\n"
+             );
+
+        //
+        // Privileges
+        //
+        Permission[]    permissions = new Permission[]
+        {
+            new Permission( "delete on deleteTable_6434_2", NO_TABLE_PERMISSION ),
+            new Permission( "execute on function selectFunction_6434_2", NO_GENERIC_PERMISSION
),
+            new Permission( "usage on derby aggregate selectAggregate_6434_2", NO_GENERIC_PERMISSION
),
+            new Permission( "select on selectTable_6434_2", NO_SELECT_OR_UPDATE_PERMISSION
),
+            new Permission( "select ( publicSelectColumn ) on deleteTable_6434_2", NO_SELECT_OR_UPDATE_PERMISSION
),
+        };
+        for ( Permission permission : permissions )
+        {
+            grant_6429( dboConnection, permission.text );
+        }
+
+        //
+        // Try adding and dropping privileges.
+        //
+        String  delete =
+            "delete from test_dbo.deleteTable_6434_2\n" +
+            "where publicSelectColumn =\n" +
+            "(\n" +
+            "    select test_dbo.selectAggregate_6434_2( selectColumn )\n" +
+            "    from test_dbo.selectTable_6434_2\n" +
+            "    where test_dbo.selectFunction_6434_2( selectColumn2, 'foo' ) < 100\n"
+
+            ")\n";
+
+        // fails because ruth doesn't have USAGE permission on type SelectType_6434_2
+        expectExecutionError( ruthConnection, NO_GENERIC_PERMISSION, delete );
+
+        // succeeds after granting that permission
+        grant_6429( dboConnection, "usage on type SelectType_6434_2" );
+        goodStatement( ruthConnection, delete );
+        
+        //
+        // Verify that revoking each permission in isolation raises
+        // the correct error.
+        //
+        for ( Permission permission : permissions )
+        {
+            vetPermission_6429( permission, dboConnection, ruthConnection, delete );
+        }
+
+        //
+        // Drop schema
+        //
+        goodStatement
+            (
+             dboConnection,
+             "drop table foreignTable_6434_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table deleteTable_6434_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table selectTable_6434_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table primaryTable_6434_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop procedure addHistoryRow_6434_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop derby aggregate selectAggregate_6434_2 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function afterTriggerFunction_6434_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function beforeTriggerFunction_6434_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function selectFunction_6434_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type AfterTriggerType_6434_2 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type BeforeTriggerType_6434_2 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type SelectType_6434_2 restrict"
+             );
+    }
+    
 }



Mime
View raw message