diff --git a/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java b/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java index cf0aa0a11d..9614f969e7 100644 --- a/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java +++ b/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java @@ -540,9 +540,9 @@ public StoreCostController getStoreCostController(long conglomerateNumber) * * @param schema Schema name of the object that is being accessed * @param aid Requested authorizationId for new schema - * @param privType Either CREATE_SCHEMA_PRIV or MODIFY_SCHEMA_PRIV + * @param privType CREATE_SCHEMA_PRIV, MODIFY_SCHEMA_PRIV or DROP_SCHEMA_PRIV */ - public void addRequiredSchemaPriv(String schema, String aid, boolean privType); + public void addRequiredSchemaPriv(String schema, String aid, int privType); /** * Add a routine execute privilege to the list of used routine privileges. diff --git a/java/engine/org/apache/derby/iapi/sql/conn/Authorizer.java b/java/engine/org/apache/derby/iapi/sql/conn/Authorizer.java index ef8c1ac640..40194e7055 100644 --- a/java/engine/org/apache/derby/iapi/sql/conn/Authorizer.java +++ b/java/engine/org/apache/derby/iapi/sql/conn/Authorizer.java @@ -60,9 +60,10 @@ public interface Authorizer public static final int PRIV_TYPE_COUNT = 7; /* Used to check who can create schemas or who can modify objects in schema */ - public static final boolean CREATE_SCHEMA_PRIV = false; - public static final boolean MODIFY_SCHEMA_PRIV = true; - + public static final int CREATE_SCHEMA_PRIV = 16; + public static final int MODIFY_SCHEMA_PRIV = 17; + public static final int DROP_SCHEMA_PRIV = 18; + /** * The system authorization ID is defined by the SQL2003 spec as the grantor * of privileges to object owners. diff --git a/java/engine/org/apache/derby/iapi/sql/dictionary/StatementSchemaPermission.java b/java/engine/org/apache/derby/iapi/sql/dictionary/StatementSchemaPermission.java index 3b7ec15586..04d8491b9c 100644 --- a/java/engine/org/apache/derby/iapi/sql/dictionary/StatementSchemaPermission.java +++ b/java/engine/org/apache/derby/iapi/sql/dictionary/StatementSchemaPermission.java @@ -27,6 +27,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; import org.apache.derby.iapi.store.access.TransactionController; +import org.apache.derby.iapi.services.sanity.SanityManager; /** * This class describes a schema permission required by a statement. @@ -34,11 +35,21 @@ Licensed to the Apache Software Foundation (ASF) under one or more public class StatementSchemaPermission extends StatementPermission { + /** + * The schema name + */ private String schemaName; - private String aid; - private boolean privType; + /** + * Authorization id + */ + private String aid; + /** + * One of Authorizer.CREATE_SCHEMA_PRIV, MODIFY_SCHEMA_PRIV, + * DROP_SCHEMA_PRIV, etc. + */ + private int privType; - public StatementSchemaPermission(String schemaName, String aid, boolean privType) + public StatementSchemaPermission(String schemaName, String aid, int privType) { this.schemaName = schemaName; this.aid = aid; @@ -55,26 +66,39 @@ public void check( LanguageConnectionContext lcc, DataDictionary dd = lcc.getDataDictionary(); TransactionController tc = lcc.getTransactionExecute(); - if (privType == Authorizer.MODIFY_SCHEMA_PRIV) + switch ( privType ) { - SchemaDescriptor sd = dd.getSchemaDescriptor(schemaName, tc, false); - // If schema hasn't been created already, no need to check - if (sd == null) - return; + case Authorizer.MODIFY_SCHEMA_PRIV: + case Authorizer.DROP_SCHEMA_PRIV: + SchemaDescriptor sd = dd.getSchemaDescriptor(schemaName, tc, false); + // If schema hasn't been created already, no need to check + // for drop schema, an exception will be thrown if the schema + // does not exists. + if (sd == null) + return; - if (!authid.equals(sd.getAuthorizationId())) - throw StandardException.newException( - SQLState.AUTH_NO_ACCESS_NOT_OWNER, authid, schemaName); - } - else - { - // Non-Database Owner Users can only create schemas that match - // their authid. Also allow only Database Owner to set authid to - // another user. Note that for Database Owner, check interface - // wouldn't be called at all - if (!schemaName.equals(authid) || (aid != null && !aid.equals(authid))) - throw StandardException.newException( - SQLState.AUTH_NOT_DATABASE_OWNER, authid, schemaName); + if (!authid.equals(sd.getAuthorizationId())) + throw StandardException.newException( + SQLState.AUTH_NO_ACCESS_NOT_OWNER, authid, schemaName); + break; + + case Authorizer.CREATE_SCHEMA_PRIV: + // Non-DBA Users can only create schemas that match their authid + // Also allow only DBA to set authid to another user + // Note that for DBA, check interface wouldn't be called at all + if ( !schemaName.equals(authid) || + (aid != null && !aid.equals(authid)) ) + throw StandardException.newException( + SQLState.AUTH_NOT_DATABASE_OWNER, authid, schemaName); + break; + + default: + if (SanityManager.DEBUG) + { + SanityManager.THROWASSERT( + "Unexpected value (" + privType + ") for privType"); + } + break; } } diff --git a/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java b/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java index 58de781d91..16b642335b 100644 --- a/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java +++ b/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java @@ -807,7 +807,7 @@ public void addRequiredRoutinePriv( AliasDescriptor routine) * * @see CompilerContext#addRequiredSchemaPriv */ - public void addRequiredSchemaPriv(String schemaName, String aid, boolean privType) + public void addRequiredSchemaPriv(String schemaName, String aid, int privType) { if( requiredSchemaPrivileges == null || schemaName == null) return; diff --git a/java/engine/org/apache/derby/impl/sql/compile/DropSchemaNode.java b/java/engine/org/apache/derby/impl/sql/compile/DropSchemaNode.java index 0084f91914..6aab35f532 100644 --- a/java/engine/org/apache/derby/impl/sql/compile/DropSchemaNode.java +++ b/java/engine/org/apache/derby/impl/sql/compile/DropSchemaNode.java @@ -21,6 +21,8 @@ Licensed to the Apache Software Foundation (ASF) under one or more package org.apache.derby.impl.sql.compile; +import org.apache.derby.iapi.sql.compile.CompilerContext; +import org.apache.derby.iapi.sql.conn.Authorizer; import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; import org.apache.derby.iapi.sql.execute.ConstantAction; @@ -71,6 +73,18 @@ public QueryTreeNode bind() throws StandardException SQLState.LANG_CANNOT_DROP_SYSTEM_SCHEMAS, this.schemaName)); } + /* + ** In SQL authorization mode, the current authorization identifier + ** must be either the owner of the schema or the database owner + ** in order for the schema object to be dropped. + */ + if (isPrivilegeCollectionRequired()) + { + getCompilerContext().addRequiredSchemaPriv(schemaName, + lcc.getAuthorizationId(), + Authorizer.DROP_SCHEMA_PRIV); + } + return this; } diff --git a/java/testing/org/apache/derbyTesting/functionTests/master/grantRevokeDDL2.out b/java/testing/org/apache/derbyTesting/functionTests/master/grantRevokeDDL2.out index db7436f080..e6ede6be04 100644 --- a/java/testing/org/apache/derbyTesting/functionTests/master/grantRevokeDDL2.out +++ b/java/testing/org/apache/derbyTesting/functionTests/master/grantRevokeDDL2.out @@ -663,7 +663,12 @@ ij(USER1)> CREATE SCHEMA AUTHORIZATION user6; 0 rows inserted/updated/deleted ij(USER1)> CREATE SCHEMA myschema; 0 rows inserted/updated/deleted -ij(USER1)> -- ------------------------------------------------------------------- +ij(USER1)> -- DERBY-1858 +set connection user5; +ij(USER5)> -- expect error +DROP SCHEMA w3 RESTRICT; +ERROR: Failed with SQLSTATE 2850D +ij(USER5)> -- ------------------------------------------------------------------- -- views -- ------------------------------------------------------------------- set connection user1; @@ -1497,11 +1502,12 @@ ij(USER4)> create table ttt1 (i int); ij(USER4)> set connection user1; ij(USER1)> drop table user4.ttt1; 0 rows inserted/updated/deleted -ij(USER1)> -- set connection user2; --- DERBY-1858 +ij(USER1)> set connection user2; +ij(USER2)> -- DERBY-1858 -- expect error --- drop schema user4 restrict; -set connection user1; +drop schema user4 restrict; +ERROR: Failed with SQLSTATE 2850D +ij(USER2)> set connection user1; ij(USER1)> -- ok drop schema user4 restrict; 0 rows inserted/updated/deleted diff --git a/java/testing/org/apache/derbyTesting/functionTests/master/jdk16/grantRevokeDDL2.out b/java/testing/org/apache/derbyTesting/functionTests/master/jdk16/grantRevokeDDL2.out index 62961a112d..3199fa9378 100644 --- a/java/testing/org/apache/derbyTesting/functionTests/master/jdk16/grantRevokeDDL2.out +++ b/java/testing/org/apache/derbyTesting/functionTests/master/jdk16/grantRevokeDDL2.out @@ -657,7 +657,12 @@ ij(USER1)> CREATE SCHEMA AUTHORIZATION user6; 0 rows inserted/updated/deleted ij(USER1)> CREATE SCHEMA myschema; 0 rows inserted/updated/deleted -ij(USER1)> -- ------------------------------------------------------------------- +ij(USER1)> -- DERBY-1858 +set connection user5; +ij(USER5)> -- expect error +DROP SCHEMA w3 RESTRICT; +ERROR: Failed with SQLSTATE 2850D +ij(USER5)> -- ------------------------------------------------------------------- -- views -- ------------------------------------------------------------------- set connection user1; @@ -1491,11 +1496,12 @@ ij(USER4)> create table ttt1 (i int); ij(USER4)> set connection user1; ij(USER1)> drop table user4.ttt1; 0 rows inserted/updated/deleted -ij(USER1)> -- set connection user2; --- DERBY-1858 +ij(USER1)> set connection user2; +ij(USER2)> -- DERBY-1858 -- expect error --- drop schema user4 restrict; -set connection user1; +drop schema user4 restrict; +ERROR: Failed with SQLSTATE 2850D +ij(USER2)> set connection user1; ij(USER1)> -- ok drop schema user4 restrict; 0 rows inserted/updated/deleted diff --git a/java/testing/org/apache/derbyTesting/functionTests/tests/lang/grantRevokeDDL2.sql b/java/testing/org/apache/derbyTesting/functionTests/tests/lang/grantRevokeDDL2.sql index df7518b12d..76d62d8774 100644 --- a/java/testing/org/apache/derbyTesting/functionTests/tests/lang/grantRevokeDDL2.sql +++ b/java/testing/org/apache/derbyTesting/functionTests/tests/lang/grantRevokeDDL2.sql @@ -423,6 +423,11 @@ CREATE SCHEMA w3 AUTHORIZATION user2; CREATE SCHEMA AUTHORIZATION user6; CREATE SCHEMA myschema; +-- DERBY-1858 +set connection user5; +-- expect error +DROP SCHEMA w3 RESTRICT; + -- ------------------------------------------------------------------- -- views -- ------------------------------------------------------------------- @@ -979,10 +984,10 @@ create table ttt1 (i int); set connection user1; drop table user4.ttt1; --- set connection user2; +set connection user2; -- DERBY-1858 -- expect error --- drop schema user4 restrict; +drop schema user4 restrict; set connection user1; -- ok