Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 63783 invoked from network); 18 Dec 2009 15:16:39 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 18 Dec 2009 15:16:39 -0000 Received: (qmail 8555 invoked by uid 500); 18 Dec 2009 15:16:39 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 8519 invoked by uid 500); 18 Dec 2009 15:16:39 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 8509 invoked by uid 99); 18 Dec 2009 15:16:39 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 18 Dec 2009 15:16:39 +0000 X-ASF-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 18 Dec 2009 15:16:32 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id C7AAB23889D7; Fri, 18 Dec 2009 15:16:11 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r892272 [1/2] - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/sql/compile/ engine/org/apache/derby/iapi/sql/dictionary/ engine/org/apache/derby/impl/sql/catalog/ engine/org/apache/derby/impl/sql/compile/ engine/org/apache/derby... Date: Fri, 18 Dec 2009 15:15:36 -0000 To: derby-commits@db.apache.org From: rhillegas@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091218151611.C7AAB23889D7@eris.apache.org> Author: rhillegas Date: Fri Dec 18 15:15:02 2009 New Revision: 892272 URL: http://svn.apache.org/viewvc?rev=892272&view=rev Log: DERBY-651: Add support for USAGE privilege on UDTs and the beginning of support for USAGE privilege on SEQUENCES. Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/PrivilegedSQLObject.java (with props) db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementGenericPermission.java (with props) db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericPrivilegeInfo.java (with props) db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTPermsTest.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/iapi/sql/dictionary/AliasDescriptor.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/PermDescriptor.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SequenceDescriptor.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementPermission.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementRoutinePermission.java db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/CoreDDFinderClassInfo.java db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DDdependableFinder.java db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/PermissionsCacheable.java db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SYSPERMSRowFactory.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/PrivilegeNode.java db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj 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/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.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=892272&r1=892271&r2=892272&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 Fri Dec 18 15:15:02 2009 @@ -34,6 +34,7 @@ import org.apache.derby.iapi.sql.dictionary.AliasDescriptor; import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor; import org.apache.derby.iapi.sql.dictionary.TableDescriptor; +import org.apache.derby.iapi.sql.dictionary.PrivilegedSQLObject; import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; import org.apache.derby.iapi.sql.depend.Dependent; @@ -565,6 +566,13 @@ public void addRequiredRoutinePriv( AliasDescriptor routine); /** + * Add a usage privilege to the list of required privileges. + * + * @param usableObject + */ + public void addRequiredUsagePriv( PrivilegedSQLObject usableObject ); + + /** * Add a required role privilege to the list of privileges. * * @see CompilerContext#addRequiredRolePriv Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java Fri Dec 18 15:15:02 2009 @@ -32,6 +32,7 @@ import org.apache.derby.catalog.AliasInfo; import org.apache.derby.catalog.types.RoutineAliasInfo; +import org.apache.derby.catalog.types.UDTAliasInfo; import org.apache.derby.catalog.UUID; @@ -59,7 +60,7 @@ public final class AliasDescriptor extends TupleDescriptor - implements UniqueTupleDescriptor, Provider, Dependent + implements PrivilegedSQLObject, Provider, Dependent { private final UUID aliasID; private final String aliasName; @@ -70,6 +71,7 @@ private final boolean systemAlias; private final AliasInfo aliasInfo; private final String specificName; + private final SchemaDescriptor schemaDescriptor; /** * Constructor for a AliasDescriptor @@ -89,12 +91,14 @@ String aliasName, UUID schemaID, String javaClassName, char aliasType, char nameSpace, boolean systemAlias, AliasInfo aliasInfo, String specificName) + throws StandardException { super( dataDictionary ); this.aliasID = aliasID; this.aliasName = aliasName; this.schemaID = schemaID; + this.schemaDescriptor = dataDictionary.getSchemaDescriptor(schemaID, null); this.javaClassName = javaClassName; this.aliasType = aliasType; this.nameSpace = nameSpace; @@ -117,6 +121,26 @@ return aliasID; } + /** + * @see PrivilegedSQLObject#getObjectTypeName + */ + public String getObjectTypeName() + { + if ( aliasInfo instanceof UDTAliasInfo ) + { + return PermDescriptor.UDT_TYPE; + } + else + { + if( SanityManager.DEBUG) + { + SanityManager.THROWASSERT( "Unsupported alias type: " + aliasInfo.getClass().getName() ); + } + + return null; // should never get here + } + } + /** * Gets the UUID of the schema for this method alias. * @@ -128,6 +152,26 @@ } /** + * Gets the SchemaDescriptor for this alias. + * + * @return SchemaDescriptor The SchemaDescriptor. + */ + public final SchemaDescriptor getSchemaDescriptor() + { + return schemaDescriptor; + } + + /** + * Gets the name of the alias. + * + * @return A String containing the name of the statement. + */ + public final String getName() + { + return aliasName; + } + + /** * Gets the name of the schema that the alias lives in. * * @return A String containing the name of the schema that the alias @@ -135,7 +179,7 @@ */ public String getSchemaName() throws StandardException { - return getDataDictionary().getSchemaDescriptor( schemaID, null ).getSchemaName(); + return schemaDescriptor.getSchemaName(); } /** Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java Fri Dec 18 15:15:02 2009 @@ -2023,13 +2023,16 @@ * Get permissions granted to one user for an object using the object's Id * and the user's authorization Id. * - * @param objectUUID + * @param objectUUID ID of the object being protected + * @param objectType Type of the object (e.g., PermDescriptor.SEQUENCE_TYPE) + * @param privilege The kind of privilege needed (e.g., PermDescriptor.USAGE_PRIV) + * @param granteeAuthid The user who needs the permission * * @return The descriptor of the permissions for the object * * @exception StandardException */ - public PermDescriptor getPermissions(UUID objectUUID, String granteeAuthId) + public PermDescriptor getGenericPermissions(UUID objectUUID, String objectType, String privilege, String granteeAuthId) throws StandardException; /** @@ -2041,7 +2044,7 @@ * * @exception StandardException */ - public PermDescriptor getPermissions(UUID permUUID) + public PermDescriptor getGenericPermissions(UUID permUUID) throws StandardException; /** Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/PermDescriptor.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/PermDescriptor.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/PermDescriptor.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/PermDescriptor.java Fri Dec 18 15:15:02 2009 @@ -1,6 +1,6 @@ /* - Derby - Class org.apache.derby.iapi.sql.dictionary.SequenceDescriptor + Derby - Class org.apache.derby.iapi.sql.dictionary.PermDescriptor Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -25,17 +25,29 @@ import org.apache.derby.catalog.DependableFinder; import org.apache.derby.catalog.Dependable; import org.apache.derby.iapi.error.StandardException; +import org.apache.derby.iapi.reference.SQLState; import org.apache.derby.iapi.services.sanity.SanityManager; import org.apache.derby.iapi.services.io.StoredFormatIds; import org.apache.derby.iapi.sql.depend.Provider; import org.apache.derby.impl.sql.catalog.DDdependableFinder; +import org.apache.derby.iapi.sql.dictionary.PrivilegedSQLObject; /** * This class describes rows in the SYS.SYSPERMS system table, which keeps track of the * permissions that have been granted but not revoked. */ public class PermDescriptor extends PermissionsDescriptor - implements Provider { + implements Provider +{ + // object types + public static final String SEQUENCE_TYPE = "SEQUENCE"; + public static final String UDT_TYPE = "TYPE"; + + // permissions + public static final String USAGE_PRIV = "USAGE"; + + // state + private String objectType; private UUID permObjectId; private String permission; @@ -45,8 +57,13 @@ * Constructor * * @param dataDictionary data dictionary - * @param permUUID unique identification in time and space of this perm - * descriptor + * @param permUUID unique identification in time and space of this perm descriptor + * @param objectType E.g., SEQUENCE_TYPE + * @param permObjectId Unique id of the object being protected + * @param permission E.g., USAGE_PRIV + * @param grantor Authorization id which confers the privilege + * @param grantee Authorization id which receives the privilege + * @param isGrantable True if the privilege can be granted onwards */ public PermDescriptor(DataDictionary dataDictionary, UUID permUUID, String objectType, @@ -110,26 +127,50 @@ return false; PermDescriptor otherPerm = (PermDescriptor) other; return super.keyEquals(otherPerm) && - oid.equals(otherPerm.oid); + permObjectId.equals(otherPerm.permObjectId); } /** * @return the hashCode for the key part of this permissions descriptor */ public int hashCode() { - return super.keyHashCode() + oid.hashCode(); + return super.keyHashCode() + permObjectId.hashCode(); } /** * @see PermissionsDescriptor#checkOwner */ - public boolean checkOwner(String authorizationId) throws StandardException { - UUID sd = getDataDictionary().getAliasDescriptor(oid).getSchemaUUID(); - if (getDataDictionary().getSchemaDescriptor(sd, null).getAuthorizationId() - .equals(authorizationId)) { - return true; - } else { - return false; + public boolean checkOwner( String authorizationId ) throws StandardException + { + DataDictionary dd = getDataDictionary(); + PrivilegedSQLObject pso = getProtectedObject( dd, permObjectId, objectType ); + + return pso.getSchemaDescriptor().getAuthorizationId().equals(authorizationId); + } + + /** + * Get the protected object. + * + * @param dd Metadata + * @param objectID Unique handle on the protected object + * @param objectType Type of the object + */ + public static PrivilegedSQLObject getProtectedObject + ( DataDictionary dd, UUID objectID, String objectType ) throws StandardException + { + if ( PermDescriptor.SEQUENCE_TYPE.equals( objectType ) ) + { + return dd.getSequenceDescriptor( objectID ); + } + else if ( PermDescriptor.UDT_TYPE.equals( objectType ) ) + { + return dd.getAliasDescriptor( objectID ); + } + else + { + // oops, still need to implement support for this kind + // of privileged object + throw StandardException.newException( SQLState.BTREE_UNIMPLEMENTED_FEATURE ); } } @@ -144,8 +185,14 @@ * * @return String The name of this provider. */ - public String getObjectName() { - return permission + "privilege on " + objectType; + public String getObjectName() + { + try { + DataDictionary dd = getDataDictionary(); + PrivilegedSQLObject pso = getProtectedObject( dd, permObjectId, objectType ); + + return pso.getName(); + } catch (StandardException se) { return objectType; } } /** Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/PrivilegedSQLObject.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/PrivilegedSQLObject.java?rev=892272&view=auto ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/PrivilegedSQLObject.java (added) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/PrivilegedSQLObject.java Fri Dec 18 15:15:02 2009 @@ -0,0 +1,34 @@ +/* + + Derby - Class org.apache.derby.iapi.sql.dictionary.PrivilegedSQLObject + + 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.dictionary; + +import org.apache.derby.iapi.sql.depend.Provider; + +/** + * This is a descriptor for schema object which can have privileges granted on it. + */ +public interface PrivilegedSQLObject extends UniqueSQLObjectDescriptor, Provider +{ + /** Get the type of the object for storage in SYS.SYSPERMS */ + public String getObjectTypeName(); + +} Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/PrivilegedSQLObject.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SequenceDescriptor.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SequenceDescriptor.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SequenceDescriptor.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SequenceDescriptor.java Fri Dec 18 15:15:02 2009 @@ -39,7 +39,8 @@ * This class is used by rows in the SYS.SYSSEQUENCES system table. */ public class SequenceDescriptor extends TupleDescriptor - implements Provider, Dependent, UniqueSQLObjectDescriptor { + implements Provider, Dependent, PrivilegedSQLObject +{ private UUID sequenceUUID; private String sequenceName; @@ -93,6 +94,14 @@ return sequenceUUID; } + /** + * @see PrivilegedSQLObject#getObjectTypeName + */ + public String getObjectTypeName() + { + return PermDescriptor.SEQUENCE_TYPE; + } + public String toString() { if (SanityManager.DEBUG) { return "sequenceUUID: " + sequenceUUID + "\n" + @@ -267,10 +276,6 @@ return sequenceName; } - public UUID getSequenceUUID() { - return sequenceUUID; - } - public UUID getSchemaId() { return schemaId; } Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementGenericPermission.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementGenericPermission.java?rev=892272&view=auto ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementGenericPermission.java (added) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementGenericPermission.java Fri Dec 18 15:15:02 2009 @@ -0,0 +1,118 @@ +/* + + Derby - Class org.apache.derby.iapi.sql.dictionary.StatementGenericPermission + + 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.dictionary; + +import org.apache.derby.iapi.error.StandardException; +import org.apache.derby.catalog.UUID; +import org.apache.derby.iapi.sql.conn.Authorizer; +import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; +import org.apache.derby.iapi.reference.SQLState; +import org.apache.derby.iapi.sql.dictionary.PermDescriptor; +import org.apache.derby.iapi.store.access.TransactionController; +import org.apache.derby.iapi.sql.Activation; +import org.apache.derby.iapi.sql.execute.ExecPreparedStatement; +import org.apache.derby.iapi.sql.depend.DependencyManager; +import org.apache.derby.iapi.services.context.ContextManager; + +/** + * This class describes a generic permission (such as USAGE) + * required by a statement. + */ + +public final class StatementGenericPermission extends StatementPermission +{ + private UUID _objectID; + private String _objectType; // e.g., PermDescriptor.SEQUENCE_TYPE + private String _privilege; // e.g., PermDescriptor.USAGE_PRIV + + public StatementGenericPermission( UUID objectID, String objectType, String privilege ) + { + _objectID = objectID; + _objectType = objectType; + _privilege = privilege; + } + + // accessors + public UUID getObjectID() { return _objectID; } + public String getPrivilege() { return _privilege; } + + /** + * @see StatementPermission#getObjectType + */ + public String getObjectType() { return _objectType; } + + /** + * @see StatementPermission#check + */ + public void check( LanguageConnectionContext lcc, + String authorizationId, + boolean forGrant, + Activation activation) throws StandardException + { + genericCheck( lcc, authorizationId, forGrant, activation, _privilege ); + } + + + /** + * @see StatementPermission#isCorrectPermission + */ + public boolean isCorrectPermission( PermissionsDescriptor raw ) + { + if ( (raw == null) || !( raw instanceof PermDescriptor) ) { return false; } + + PermDescriptor pd = (PermDescriptor) raw; + + return + pd.getPermObjectId().equals( _objectID ) && + pd.getObjectType().equals( _objectType ) && + pd.getPermission().equals( _privilege ) + ; + } + + /** + * @see StatementPermission#getPrivilegedObject + */ + public PrivilegedSQLObject getPrivilegedObject( DataDictionary dd ) throws StandardException + { + if ( PermDescriptor.UDT_TYPE.equals( _objectType ) ) { return dd.getAliasDescriptor( _objectID ); } + else if ( PermDescriptor.SEQUENCE_TYPE.equals( _objectType ) ) { return dd.getSequenceDescriptor( _objectID ); } + else + { + throw StandardException.newException( SQLState.BTREE_UNIMPLEMENTED_FEATURE ); + } + } + + /** + * @see StatementPermission#getPermissionDescriptor + */ + public PermissionsDescriptor getPermissionDescriptor(String authid, DataDictionary dd) + throws StandardException + { + return dd.getGenericPermissions( _objectID, _objectType, _privilege, authid ); + } + + + public String toString() + { + return "StatementGenericPermission( " + _objectID + ", " + _objectType + ", " + _privilege + " )"; + } +} Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementGenericPermission.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementPermission.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementPermission.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementPermission.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementPermission.java Fri Dec 18 15:15:02 2009 @@ -21,9 +21,15 @@ package org.apache.derby.iapi.sql.dictionary; +import org.apache.derby.iapi.reference.SQLState; +import org.apache.derby.iapi.sql.conn.Authorizer; import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; import org.apache.derby.iapi.error.StandardException; import org.apache.derby.iapi.sql.Activation; +import org.apache.derby.iapi.store.access.TransactionController; +import org.apache.derby.iapi.sql.execute.ExecPreparedStatement; +import org.apache.derby.iapi.sql.depend.DependencyManager; +import org.apache.derby.iapi.services.context.ContextManager; /** * This class describes a permission require by a statement. @@ -55,7 +61,7 @@ /** * - * Get the PermissionDescriptor for the passed authorization id for this + * Get the PermissionsDescriptor for the passed authorization id for this * object. This method gets called during the execution phase of create * view/constraint/trigger. The return value of this method is saved in * dependency system to keep track of views/constraints/triggers @@ -68,11 +74,150 @@ * @param authid AuthorizationId * @param dd DataDictionary * - * @return PermissionsDescriptor The PermissionDescriptor for the passed + * @return PermissionsDescriptor The PermissionsDescriptor for the passed * authorization id on this object * * @exception StandardException */ public abstract PermissionsDescriptor getPermissionDescriptor(String authid, DataDictionary dd) throws StandardException; + + /** + * Return true if the passed in permission matches the one required by this + * StatementPermission. + */ + public boolean isCorrectPermission( PermissionsDescriptor pd ) throws StandardException + { return false; } + + /** + * Get the privileged object associated with this permission. + */ + public PrivilegedSQLObject getPrivilegedObject( DataDictionary dd ) throws StandardException + { return null; } + + /** + * Get the type of the privileged object. + */ + public String getObjectType() + { return null; } + + /** + * Generic logic called by check() for USAGE and EXECUTE privileges. Throws + * an exception if the correct permission cannot be found. + */ + public void genericCheck + ( + LanguageConnectionContext lcc, + String authorizationId, + boolean forGrant, + Activation activation, + String privilegeType ) + throws StandardException + { + DataDictionary dd = lcc.getDataDictionary(); + TransactionController tc = lcc.getTransactionExecute(); + ExecPreparedStatement ps = activation.getPreparedStatement(); + + PermissionsDescriptor perm = getPermissionDescriptor( authorizationId, dd ); + if( !isCorrectPermission( perm ) ) { perm = getPermissionDescriptor(Authorizer.PUBLIC_AUTHORIZATION_ID, dd ); } + + // if the user has the correct permission, we're done + if ( isCorrectPermission( perm ) ) { return; } + + boolean resolved = false; + + // Since no permission exists for the current user or PUBLIC, + // check if a permission exists for the current role (if set). + String role = lcc.getCurrentRoleId(activation); + + if (role != null) { + + // Check that role is still granted to current user or + // to PUBLIC: A revoked role which is current for this + // session, is lazily set to none when it is attemped + // used. + String dbo = dd.getAuthorizationDatabaseOwner(); + RoleGrantDescriptor rd = dd.getRoleGrantDescriptor + (role, authorizationId, dbo); + + if (rd == null) { + rd = dd.getRoleGrantDescriptor( + role, + Authorizer.PUBLIC_AUTHORIZATION_ID, + dbo); + } + + if (rd == null) { + // We have lost the right to set this role, so we can't + // make use of any permission granted to it or its + // ancestors. + lcc.setCurrentRole(activation, null); + } else { + // The current role is OK, so we can make use of + // any permission granted to it. + // + // Look at the current role and, if necessary, the + // transitive closure of roles granted to current role to + // see if permission has been granted to any of the + // applicable roles. + + RoleClosureIterator rci = + dd.createRoleClosureIterator + (activation.getTransactionController(), + role, true ); + + String r; + while (!resolved && (r = rci.next()) != null) + { + perm = getPermissionDescriptor( r, dd ); + + if ( isCorrectPermission( perm ) ) { resolved = true; } + } + } + + if (resolved ) { + // Also add a dependency on the role (qua provider), so that if + // role is no longer available to the current user (e.g. grant + // is revoked, role is dropped, another role has been set), we + // are able to invalidate the ps or activation (the latter is + // used if the current role changes). + DependencyManager dm = dd.getDependencyManager(); + RoleGrantDescriptor rgd = dd.getRoleDefinitionDescriptor(role); + ContextManager cm = lcc.getContextManager(); + dm.addDependency(ps, rgd, cm); + dm.addDependency(activation, rgd, cm); + } + } + + if (!resolved) + { + PrivilegedSQLObject pso = getPrivilegedObject( dd ); + + if( pso == null ) + { + throw StandardException.newException + ( SQLState.AUTH_INTERNAL_BAD_UUID, getObjectType() ); + } + + SchemaDescriptor sd = pso.getSchemaDescriptor(); + + if( sd == null) + { + throw StandardException.newException( + SQLState.AUTH_INTERNAL_BAD_UUID, "SCHEMA"); + } + + throw StandardException.newException( + (forGrant + ? SQLState.AUTH_NO_GENERIC_PERMISSION_FOR_GRANT + : SQLState.AUTH_NO_GENERIC_PERMISSION), + authorizationId, + privilegeType, + getObjectType(), + sd.getSchemaName(), + pso.getName()); + } + + } // end of genericCheck + } Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementRoutinePermission.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementRoutinePermission.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementRoutinePermission.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/StatementRoutinePermission.java Fri Dec 18 15:15:02 2009 @@ -64,111 +64,26 @@ boolean forGrant, Activation activation) throws StandardException { - DataDictionary dd = lcc.getDataDictionary(); - TransactionController tc = lcc.getTransactionExecute(); - ExecPreparedStatement ps = activation.getPreparedStatement(); - - RoutinePermsDescriptor perms = dd.getRoutinePermissions( routineUUID, authorizationId); - if( perms == null || ! perms.getHasExecutePermission()) - perms = dd.getRoutinePermissions(routineUUID, Authorizer.PUBLIC_AUTHORIZATION_ID); - - if (perms != null && perms.getHasExecutePermission()) { - // The user or PUBLIC has execute permission, all is well. - return; - } - - boolean resolved = false; - - // Since no permission exists for the current user or PUBLIC, - // check if a permission exists for the current role (if set). - String role = lcc.getCurrentRoleId(activation); - - if (role != null) { - - // Check that role is still granted to current user or - // to PUBLIC: A revoked role which is current for this - // session, is lazily set to none when it is attemped - // used. - String dbo = dd.getAuthorizationDatabaseOwner(); - RoleGrantDescriptor rd = dd.getRoleGrantDescriptor - (role, authorizationId, dbo); - - if (rd == null) { - rd = dd.getRoleGrantDescriptor( - role, - Authorizer.PUBLIC_AUTHORIZATION_ID, - dbo); - } - - if (rd == null) { - // We have lost the right to set this role, so we can't - // make use of any permission granted to it or its - // ancestors. - lcc.setCurrentRole(activation, null); - } else { - // The current role is OK, so we can make use of - // any permission granted to it. - // - // Look at the current role and, if necessary, the - // transitive closure of roles granted to current role to - // see if permission has been granted to any of the - // applicable roles. - - RoleClosureIterator rci = - dd.createRoleClosureIterator - (activation.getTransactionController(), - role, true /* inverse relation*/); - - String r; - while (!resolved && (r = rci.next()) != null) { - perms = dd. - getRoutinePermissions(routineUUID, r); - - if (perms != null && - perms.getHasExecutePermission()) { - resolved = true; - } - } - } - - if (resolved /* using a role*/) { - // Also add a dependency on the role (qua provider), so that if - // role is no longer available to the current user (e.g. grant - // is revoked, role is dropped, another role has been set), we - // are able to invalidate the ps or activation (the latter is - // used if the current role changes). - DependencyManager dm = dd.getDependencyManager(); - RoleGrantDescriptor rgd = dd.getRoleDefinitionDescriptor(role); - ContextManager cm = lcc.getContextManager(); - dm.addDependency(ps, rgd, cm); - dm.addDependency(activation, rgd, cm); - } - } - - if (!resolved) { - AliasDescriptor ad = dd.getAliasDescriptor( routineUUID); - - if( ad == null) - throw StandardException.newException( - SQLState.AUTH_INTERNAL_BAD_UUID, "routine"); - - SchemaDescriptor sd = dd.getSchemaDescriptor( - ad.getSchemaUUID(), tc); - - if( sd == null) - throw StandardException.newException( - SQLState.AUTH_INTERNAL_BAD_UUID, "schema"); - - throw StandardException.newException( - (forGrant - ? SQLState.AUTH_NO_EXECUTE_PERMISSION_FOR_GRANT - : SQLState.AUTH_NO_EXECUTE_PERMISSION), - authorizationId, - ad.getDescriptorType(), - sd.getSchemaName(), - ad.getDescriptorName()); - } - } // end of check + genericCheck( lcc, authorizationId, forGrant, activation, "EXECUTE" ); + } + + /** + * @see StatementPermission#isCorrectPermission + */ + public boolean isCorrectPermission( PermissionsDescriptor raw ) + { + if ( (raw == null) || !( raw instanceof RoutinePermsDescriptor) ) { return false; } + + RoutinePermsDescriptor pd = (RoutinePermsDescriptor) raw; + + return pd.getHasExecutePermission(); + } + + /** + * @see StatementPermission#getPrivilegedObject + */ + public PrivilegedSQLObject getPrivilegedObject( DataDictionary dd ) throws StandardException + { return dd.getAliasDescriptor( routineUUID); } /** * @see StatementPermission#getPermissionDescriptor @@ -179,6 +94,10 @@ return dd.getRoutinePermissions(routineUUID,authid); } + /** + * @see StatementPermission#getObjectType + */ + public String getObjectType() { return "ROUTINE"; } public String toString() { Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/CoreDDFinderClassInfo.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/CoreDDFinderClassInfo.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/CoreDDFinderClassInfo.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/CoreDDFinderClassInfo.java Fri Dec 18 15:15:02 2009 @@ -52,6 +52,8 @@ case StoredFormatIds.TABLE_PERMISSION_FINDER_V01_ID: case StoredFormatIds.ROUTINE_PERMISSION_FINDER_V01_ID: case StoredFormatIds.COLUMNS_PERMISSION_FINDER_V01_ID: + case StoredFormatIds.SEQUENCE_DESCRIPTOR_FINDER_V01_ID: + case StoredFormatIds.PERM_DESCRIPTOR_FINDER_V01_ID: case StoredFormatIds.ROLE_GRANT_FINDER_V01_ID: return new DDdependableFinder(fmtId); case StoredFormatIds.COLUMN_DESCRIPTOR_FINDER_V01_ID: Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DDdependableFinder.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DDdependableFinder.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DDdependableFinder.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DDdependableFinder.java Fri Dec 18 15:15:02 2009 @@ -178,6 +178,12 @@ case StoredFormatIds.ROLE_GRANT_FINDER_V01_ID: return Dependable.ROLE_GRANT; + case StoredFormatIds.SEQUENCE_DESCRIPTOR_FINDER_V01_ID: + return Dependable.SEQUENCE; + + case StoredFormatIds.PERM_DESCRIPTOR_FINDER_V01_ID: + return Dependable.PERM; + default: if (SanityManager.DEBUG) { @@ -261,6 +267,12 @@ case StoredFormatIds.ROLE_GRANT_FINDER_V01_ID: return dd.getRoleGrantDescriptor(dependableObjectID); + case StoredFormatIds.SEQUENCE_DESCRIPTOR_FINDER_V01_ID: + return dd.getSequenceDescriptor(dependableObjectID); + + case StoredFormatIds.PERM_DESCRIPTOR_FINDER_V01_ID: + return dd.getGenericPermissions(dependableObjectID); + default: if (SanityManager.DEBUG) { Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java Fri Dec 18 15:15:02 2009 @@ -12230,20 +12230,27 @@ if( existingRow == null) { if( ! add) + { //we didn't find an entry in system catalog and this is revoke //so that means there is nothing to revoke. Simply return. //No need to reset permission descriptor's uuid because //no row was ever found in system catalog for the given //permission and hence uuid can't be non-null return false; - //We didn't find an entry in system catalog and this is grant so - //so that means we have to enter a new row in system catalog for - //this grant. - ExecRow row = ti.getCatalogRowFactory().makeRow( perm, (TupleDescriptor) null); - int insertRetCode = ti.insertRow(row, tc); - if( SanityManager.DEBUG) - SanityManager.ASSERT( insertRetCode == TabInfoImpl.ROWNOTDUPLICATE, - "Race condition in inserting table privilege."); + } + else + { + //We didn't find an entry in system catalog and this is grant so + //so that means we have to enter a new row in system catalog for + //this grant. + ExecRow row = ti.getCatalogRowFactory().makeRow( perm, (TupleDescriptor) null); + int insertRetCode = ti.insertRow(row, tc); + if( SanityManager.DEBUG) + { + SanityManager.ASSERT( insertRetCode == TabInfoImpl.ROWNOTDUPLICATE, + "Race condition in inserting table privilege."); + } + } } else { @@ -12252,9 +12259,14 @@ boolean[] indicesToUpdate = new boolean[ rf.getNumIndexes()]; int changedColCount = 0; if( add) + { changedColCount = rf.orPermissions( existingRow, perm, colsChanged); + } else + { changedColCount = rf.removePermissions( existingRow, perm, colsChanged); + } + if( changedColCount == 0) { //grant/revoke privilege didn't change anything and hence @@ -12285,10 +12297,12 @@ colsToUpdate[ changedColCount++] = i + 1; } if( SanityManager.DEBUG) + { SanityManager.ASSERT( changedColCount == colsToUpdate.length, "return value of " + rf.getClass().getName() + ".orPermissions does not match the number of booleans it set in colsChanged."); + } ti.updateRow(key, existingRow, primaryIndexNumber, indicesToUpdate, colsToUpdate, tc); } @@ -12301,8 +12315,13 @@ //If we are dealing with grant, then the caller does not need to send //any invalidation actions to anyone and hence return false if (add) + { return false; - return true; + } + else + { + return true; + } } // end of addPermissionsDescriptor /** @@ -12786,30 +12805,47 @@ * , null if no table-level permissions have been granted to him on the table. * @throws StandardException */ - PermDescriptor getUncachedPermDescriptor(PermDescriptor key) - throws StandardException { - - return (PermDescriptor) + PermDescriptor getUncachedGenericPermDescriptor(PermDescriptor key) + throws StandardException + { + if (key.getObjectID() == null) + { + //the PERMISSSIONID for SYSRPERMS is not known, so use the id of the + //protected object plus the + //grantor and granteee to find a PermDescriptor + return (PermDescriptor) getUncachedPermissionsDescriptor(SYSPERMS_CATALOG_NUM, - SYSPERMSRowFactory.PERMS_UUID_IDX_NUM, key); - + SYSPERMSRowFactory.GRANTEE_OBJECTID_GRANTOR_INDEX_NUM, key); + } else + { + //we know the PERMISSIONID for SYSPERMS, so use that to + //find a PermDescriptor from the sytem table + return (PermDescriptor) + getUncachedPermissionsDescriptor(SYSPERMS_CATALOG_NUM, + SYSPERMSRowFactory.PERMS_UUID_IDX_NUM,key); + } - } // end of getUncachedPermDescriptor + } // end of getUncachedGenericPermDescriptor /** * Get permissions granted to one user for an object using the object's Id * and the user's authorization Id. * - * @param objectUUID + * @param objectUUID The id of the protected object + * @param objectType Type of the object (e.g., SEQUENCE) + * @param privilege The kind of privilege needed (e.g., PermDescriptor.USAGE_PRIV) + * @param granteeAuthid The user or role who wants to have permission on this object * * @return The descriptor of the permissions for the object * * @exception StandardException */ - public PermDescriptor getPermissions(UUID objectUUID, String granteeAuthId) - throws StandardException { - PermDescriptor key = new PermDescriptor(this, null, null, objectUUID, null, null, granteeAuthId, false); - return getUncachedPermDescriptor(key); + public PermDescriptor getGenericPermissions(UUID objectUUID, String objectType, String privilege, String granteeAuthId) + throws StandardException + { + PermDescriptor key = new PermDescriptor( this, null, objectType, objectUUID, privilege, null, granteeAuthId, false ); + + return (PermDescriptor) getPermissions( key); } /** @@ -12819,10 +12855,10 @@ * @return The descriptor of the user's permissions for the object. * @throws StandardException */ - public PermDescriptor getPermissions(UUID permUUID) + public PermDescriptor getGenericPermissions(UUID permUUID) throws StandardException { PermDescriptor key = new PermDescriptor(this, permUUID); - return getUncachedPermDescriptor(key); + return getUncachedGenericPermDescriptor(key); } /** Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/PermissionsCacheable.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/PermissionsCacheable.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/PermissionsCacheable.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/PermissionsCacheable.java Fri Dec 18 15:15:02 2009 @@ -21,6 +21,8 @@ package org.apache.derby.impl.sql.catalog; +import org.apache.derby.catalog.UUID; + import org.apache.derby.iapi.error.StandardException; import org.apache.derby.iapi.services.cache.Cacheable; @@ -29,13 +31,14 @@ import org.apache.derby.iapi.sql.conn.Authorizer; import org.apache.derby.iapi.sql.conn.ConnectionUtil; - import org.apache.derby.iapi.sql.dictionary.TableDescriptor; import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; import org.apache.derby.iapi.sql.dictionary.AliasDescriptor; import org.apache.derby.iapi.sql.dictionary.TablePermsDescriptor; +import org.apache.derby.iapi.sql.dictionary.PermDescriptor; import org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor; import org.apache.derby.iapi.sql.dictionary.ColPermsDescriptor; +import org.apache.derby.iapi.sql.dictionary.PrivilegedSQLObject; import org.apache.derby.iapi.sql.dictionary.RoutinePermsDescriptor; import org.apache.derby.iapi.services.sanity.SanityManager; @@ -138,14 +141,44 @@ } } } + else if( key instanceof PermDescriptor) + { + PermDescriptor permKey = (PermDescriptor) key; + permissions = dd.getUncachedGenericPermDescriptor( permKey); + if( permissions == null) + { + // The owner has all privileges unless they have been revoked. + String objectType = permKey.getObjectType(); + String privilege = permKey.getPermission(); + UUID protectedObjectsID = permKey.getPermObjectId(); + + + PrivilegedSQLObject pso = PermDescriptor.getProtectedObject( dd, protectedObjectsID, objectType ); + SchemaDescriptor sd = pso.getSchemaDescriptor(); + if( permKey.getGrantee().equals( sd.getAuthorizationId())) + { + permissions = new PermDescriptor + ( + dd, + null, + objectType, + pso.getUUID(), + privilege, + Authorizer.SYSTEM_AUTHORIZATION_ID, + permKey.getGrantee(), + true + ); + } + } + } else { if( SanityManager.DEBUG) SanityManager.NOTREACHED(); return null; } - if( permissions != null) - return this; + if( permissions != null) { return this; } + return null; } // end of setIdentity Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SYSPERMSRowFactory.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SYSPERMSRowFactory.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SYSPERMSRowFactory.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SYSPERMSRowFactory.java Fri Dec 18 15:15:02 2009 @@ -61,22 +61,23 @@ private static final int[][] indexColumnPositions = { {SYSPERMS_PERMISSIONID}, - {SYSPERMS_OBJECTID} + {SYSPERMS_OBJECTID}, + {SYSPERMS_GRANTEE, SYSPERMS_OBJECTID, SYSPERMS_GRANTOR}, }; - // UUID - static final int PERMS_UUID_IDX_NUM = 0; - - // object Id + // index numbers + public static final int PERMS_UUID_IDX_NUM = 0; public static final int PERMS_OBJECTID_IDX_NUM = 1; + public static final int GRANTEE_OBJECTID_GRANTOR_INDEX_NUM = 2; - private static final boolean[] uniqueness = { true, false }; + private static final boolean[] uniqueness = { true, false, true }; private static final String[] uuids = { "9810800c-0121-c5e1-a2f5-00000043e718", // catalog UUID "6ea6ffac-0121-c5e3-f286-00000043e718", // heap UUID - "5cc556fc-0121-c5e6-4e43-00000043e718", // uuid index - "7a92cf84-0122-51e6-2c5e-00000047b548" // object id index + "5cc556fc-0121-c5e6-4e43-00000043e718", // PERMS_UUID_IDX_NUM + "7a92cf84-0122-51e6-2c5e-00000047b548", // PERMS_OBJECTID_IDX_NUM + "9810800c-0125-8de5-3aa0-0000001999e8", // GRANTEE_OBJECTID_GRANTOR_INDEX_NUM }; @@ -105,7 +106,18 @@ ExecIndexRow row = null; switch (indexNumber) { - case PERMS_UUID_IDX_NUM: + case GRANTEE_OBJECTID_GRANTOR_INDEX_NUM: + // RESOLVE We do not support the FOR GRANT OPTION, so generic permission rows are unique on the + // grantee and object UUID columns. The grantor column will always have the name of the owner of the + // object. So the index key, used for searching the index, only has grantee and object UUID columns. + // It does not have a grantor column. + row = getExecutionFactory().getIndexableRow( 2 ); + row.setColumn(1, getAuthorizationID( perm.getGrantee())); + String protectedObjectsIDStr = ((PermDescriptor) perm).getPermObjectId().toString(); + row.setColumn(2, new SQLChar(protectedObjectsIDStr)); + break; + + case PERMS_UUID_IDX_NUM: row = getExecutionFactory().getIndexableRow(1); String permUUIDStr = ((PermDescriptor) perm).getUUID().toString(); row.setColumn(1, new SQLChar(permUUIDStr)); @@ -114,6 +126,11 @@ return row; } // end of buildIndexKeyRow + public int getPrimaryKeyIndexNumber() + { + return GRANTEE_OBJECTID_GRANTOR_INDEX_NUM; + } + /** * Or a set of permissions in with a row from this catalog table * @@ -141,11 +158,16 @@ */ public int removePermissions(ExecRow row, PermissionsDescriptor perm, boolean[] colsChanged) throws StandardException { - return -1; // There is only one kind of routine privilege so delete the whole row. + return -1; // There is only one kind of privilege per row so delete the whole row. } // end of removePermissions - void setUUIDOfThePassedDescriptor(ExecRow row, PermissionsDescriptor perm) throws StandardException { - //To change body of implemented methods use File | Settings | File Templates. + /** + * @see PermissionsCatalogRowFactory#setUUIDOfThePassedDescriptor + */ + void setUUIDOfThePassedDescriptor(ExecRow row, PermissionsDescriptor perm) throws StandardException + { + DataValueDescriptor existingPermDVD = row.getColumn(SYSPERMS_PERMISSIONID); + perm.setUUID(getUUIDFactory().recreateUUID(existingPermDVD.getString())); } /** @@ -172,6 +194,11 @@ if (td != null) { PermDescriptor sd = (PermDescriptor) td; UUID pid = sd.getUUID(); + if ( pid == null ) + { + pid = getUUIDFactory().createUUID(); + sd.setUUID(pid); + } permIdString = pid.toString(); objectType = sd.getObjectType(); 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=892272&r1=892271&r2=892272&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 Fri Dec 18 15:15:02 2009 @@ -38,6 +38,9 @@ import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor; import org.apache.derby.iapi.sql.dictionary.TableDescriptor; import org.apache.derby.iapi.sql.dictionary.AliasDescriptor; +import org.apache.derby.iapi.sql.dictionary.PermDescriptor; +import org.apache.derby.iapi.sql.dictionary.PrivilegedSQLObject; +import org.apache.derby.iapi.sql.dictionary.StatementGenericPermission; import org.apache.derby.iapi.sql.dictionary.StatementTablePermission; import org.apache.derby.iapi.sql.dictionary.StatementSchemaPermission; import org.apache.derby.iapi.sql.dictionary.StatementColumnPermission; @@ -705,6 +708,7 @@ requiredTablePrivileges = null; requiredSchemaPrivileges = null; requiredRoutinePrivileges = null; + requiredUsagePrivileges = null; requiredRolePrivileges = null; LanguageConnectionContext lcc = (LanguageConnectionContext) getContextManager().getContext(LanguageConnectionContext.CONTEXT_ID); @@ -714,6 +718,7 @@ requiredTablePrivileges = new HashMap(); requiredSchemaPrivileges = new HashMap(); requiredRoutinePrivileges = new HashMap(); + requiredUsagePrivileges = new HashMap(); requiredRolePrivileges = new HashMap(); } } // end of initRequiredPriv @@ -828,6 +833,20 @@ } /** + * @see CompilerContext#addRequiredUsagePriv + */ + public void addRequiredUsagePriv( PrivilegedSQLObject usableObject ) + { + if( requiredUsagePrivileges == null || usableObject == null) { return; } + + UUID objectID = usableObject.getUUID(); + String objectType = usableObject.getObjectTypeName(); + + if (requiredUsagePrivileges.get( objectID ) == null) + { requiredUsagePrivileges.put( objectID, objectType ); } + } + + /** * Add a required schema privilege to the list privileges. * * @see CompilerContext#addRequiredSchemaPriv @@ -868,15 +887,17 @@ { int size = 0; if( requiredRoutinePrivileges != null) - size += requiredRoutinePrivileges.size(); + { size += requiredRoutinePrivileges.size(); } + if( requiredUsagePrivileges != null) + { size += requiredUsagePrivileges.size(); } if( requiredTablePrivileges != null) - size += requiredTablePrivileges.size(); + { size += requiredTablePrivileges.size(); } if( requiredSchemaPrivileges != null) - size += requiredSchemaPrivileges.size(); + { size += requiredSchemaPrivileges.size(); } if( requiredColumnPrivileges != null) - size += requiredColumnPrivileges.size(); + { size += requiredColumnPrivileges.size(); } if( requiredRolePrivileges != null) - size += requiredRolePrivileges.size(); + { size += requiredRolePrivileges.size(); } ArrayList list = new ArrayList( size); if( requiredRoutinePrivileges != null) @@ -888,6 +909,15 @@ list.add( new StatementRoutinePermission( routineUUID)); } } + if( requiredUsagePrivileges != null) + { + for( Iterator itr = requiredUsagePrivileges.keySet().iterator(); itr.hasNext();) + { + UUID objectID = (UUID) itr.next(); + + list.add( new StatementGenericPermission( objectID, (String) requiredUsagePrivileges.get( objectID ), PermDescriptor.USAGE_PRIV ) ); + } + } if( requiredTablePrivileges != null) { for( Iterator itr = requiredTablePrivileges.values().iterator(); itr.hasNext();) @@ -973,5 +1003,6 @@ private HashMap requiredTablePrivileges; private HashMap requiredSchemaPrivileges; private HashMap requiredRoutinePrivileges; + private HashMap requiredUsagePrivileges; private HashMap requiredRolePrivileges; } // end of class CompilerContextImpl Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/PrivilegeNode.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/PrivilegeNode.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/PrivilegeNode.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/PrivilegeNode.java Fri Dec 18 15:15:02 2009 @@ -28,9 +28,11 @@ import org.apache.derby.iapi.sql.dictionary.DataDictionary; import org.apache.derby.iapi.sql.dictionary.TableDescriptor; import org.apache.derby.iapi.sql.dictionary.AliasDescriptor; +import org.apache.derby.iapi.sql.dictionary.PrivilegedSQLObject; import org.apache.derby.catalog.types.RoutineAliasInfo; import org.apache.derby.catalog.AliasInfo; import org.apache.derby.iapi.reference.SQLState; +import org.apache.derby.impl.sql.execute.GenericPrivilegeInfo; import org.apache.derby.impl.sql.execute.PrivilegeInfo; import org.apache.derby.catalog.TypeDescriptor; @@ -45,20 +47,34 @@ // Privilege object type public static final int TABLE_PRIVILEGES = 0; public static final int ROUTINE_PRIVILEGES = 1; + public static final int SEQUENCE_PRIVILEGES = 2; + public static final int UDT_PRIVILEGES = 3; + // + // State initialized when the node is instantiated + // private int objectType; private TableName objectName; private TablePrivilegesNode specificPrivileges; // Null for routine and usage privs private RoutineDesignator routineDesignator; // null for table and usage privs + private String privilege; // E.g., PermDescriptor.USAGE_PRIV + private boolean restrict; + + // + // State which is filled in by the bind() logic. + // + private Provider dependencyProvider; + /** - * initialize a PrivilegesNode + * Initialize a PrivilegeNode for use against SYS.SYSTABLEPERMS and SYS.SYSROUTINEPERMS. * * @param objectType (an Integer) * @param objectOfPrivilege (a TableName or RoutineDesignator) - * @param specificPrivileges null for routines + * @param specificPrivileges null for routines and usage */ public void init( Object objectType, Object objectOfPrivilege, Object specificPrivileges) + throws StandardException { this.objectType = ((Integer) objectType).intValue(); if( SanityManager.DEBUG) @@ -89,14 +105,27 @@ break; default: - if( SanityManager.DEBUG) - { - SanityManager.THROWASSERT( "Invalid privilege objectType: " + this.objectType); - } + throw unimplementedFeature(); } } /** + * Initialize a PrivilegeNode for use against SYS.SYSPERMS. + * + * @param objectType E.g., SEQUENCE + * @param objectName A possibles schema-qualified name + * @param privilege A PermDescriptor privilege, e.g. PermDescriptor.USAGE_PRIV + * @param restrict True if this is a REVOKE...RESTRICT action + */ + public void init( Object objectType, Object objectName, Object privilege, Object restrict ) + { + this.objectType = ((Integer) objectType).intValue(); + this.objectName = (TableName) objectName; + this.privilege = (String) privilege; + this.restrict = ((Boolean) restrict).booleanValue(); + } + + /** * Bind this GrantNode. Resolve all table, column, and routine references. Register * a dependency on the object of the privilege if it has not already been done * @@ -111,7 +140,6 @@ */ public QueryTreeNode bind( HashMap dependencies, List grantees, boolean isGrant ) throws StandardException { - Provider dependencyProvider = null; SchemaDescriptor sd = getSchemaDescriptor( objectName.getSchemaName(), true); objectName.setSchemaName( sd.getSchemaName() ); @@ -229,11 +257,27 @@ dependencyProvider = proc; break; - default: - if( SanityManager.DEBUG) + case SEQUENCE_PRIVILEGES: + + dependencyProvider = getDataDictionary().getSequenceDescriptor( sd, objectName.getTableName() ); + if ( dependencyProvider == null ) + { + throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "SEQUENCE", objectName.getFullTableName()); + } + break; + + case UDT_PRIVILEGES: + + dependencyProvider = getDataDictionary().getAliasDescriptor + ( sd.getUUID().toString(), objectName.getTableName(), AliasInfo.ALIAS_NAME_SPACE_UDT_AS_CHAR ); + if ( dependencyProvider == null ) { - SanityManager.THROWASSERT( "Invalid privilege objectType: " + this.objectType); + throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "TYPE", objectName.getFullTableName()); } + break; + + default: + throw unimplementedFeature(); } if( dependencyProvider != null) @@ -247,10 +291,11 @@ return this; } // end of bind + /** * @return PrivilegeInfo for this node */ - PrivilegeInfo makePrivilegeInfo() + PrivilegeInfo makePrivilegeInfo() throws StandardException { switch( objectType) { @@ -259,7 +304,19 @@ case ROUTINE_PRIVILEGES: return routineDesignator.makePrivilegeInfo(); + + case SEQUENCE_PRIVILEGES: + case UDT_PRIVILEGES: + return new GenericPrivilegeInfo( (PrivilegedSQLObject) dependencyProvider, privilege, restrict ); + + default: + throw unimplementedFeature(); } - return null; + } + + /** Report an unimplemented feature */ + private StandardException unimplementedFeature() + { + return StandardException.newException( SQLState.BTREE_UNIMPLEMENTED_FEATURE ); } } Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java Fri Dec 18 15:15:02 2009 @@ -1652,6 +1652,8 @@ throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, ad.getAliasType(udtNameSpace), unqualifiedTypeName); } + createTypeDependency( ad ); + DataTypeDescriptor result = new DataTypeDescriptor ( TypeId.getUserDefinedTypeId( typeSchema.getSchemaName(), unqualifiedTypeName, ad.getJavaClassName() ), @@ -1662,7 +1664,8 @@ } /** - * Declare a dependency on a type. This is only used if the type is an ANSI UDT. + * Declare a dependency on a type and check that you have privilege to use + * it. This is only used if the type is an ANSI UDT. * * @param dtd Type which may have a dependency declared on it. */ @@ -1670,9 +1673,19 @@ { AliasDescriptor ad = getDataDictionary().getAliasDescriptorForUDT( null, dtd ); - if ( ad != null ) + if ( ad != null ) { createTypeDependency( ad ); } + } + /** + * Declare a dependency on an ANSI UDT, identified by its AliasDescriptor, + * and check that you have privilege to use it. + */ + private void createTypeDependency( AliasDescriptor ad ) throws StandardException + { + getCompilerContext().createDependency( ad ); + + if ( isPrivilegeCollectionRequired() ) { - getCompilerContext().createDependency( ad ); + getCompilerContext().addRequiredUsagePriv( ad ); } } Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj Fri Dec 18 15:15:02 2009 @@ -107,6 +107,7 @@ import org.apache.derby.impl.sql.compile.CharStream; import org.apache.derby.impl.sql.execute.TablePrivilegeInfo; import org.apache.derby.iapi.sql.dictionary.DataDictionary; +import org.apache.derby.iapi.sql.dictionary.PermDescriptor; import org.apache.derby.iapi.sql.dictionary.TableDescriptor; import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor; import org.apache.derby.iapi.sql.dictionary.ViewDescriptor; @@ -1713,6 +1714,7 @@ tokenKind == UPDATE || tokenKind == REFERENCES || tokenKind == EXECUTE || + tokenKind == USAGE || tokenKind == ALL); } @@ -13290,7 +13292,11 @@ checkVersion( DataDictionary.DD_VERSION_DERBY_10_2, "GRANT"); checkSqlStandardAccess( "GRANT"); } - ( node = tableGrantStatement() | node = routineGrantStatement() ) + ( + node = tableGrantStatement() | + node = routineGrantStatement() | + node = usageGrantStatement() + ) { return node; } @@ -13392,6 +13398,61 @@ }// end of routineGrantStatement /* + * usageGrantStatement + */ +StatementNode +usageGrantStatement() throws StandardException : +{ + List grantees; + TableName name; + Integer objectType; +} +{ + + objectType = usableObjects() + name = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) + grantees = granteeList() + { + checkVersion( DataDictionary.DD_VERSION_DERBY_10_6, "GRANT USAGE"); + PrivilegeNode privilegeNode = (PrivilegeNode) nodeFactory.getNode + ( + C_NodeTypes.PRIVILEGE_NODE, + objectType, + name, + PermDescriptor.USAGE_PRIV, + Boolean.FALSE, + getContextManager() + ); + return (StatementNode) nodeFactory.getNode + ( + C_NodeTypes.GRANT_NODE, + privilegeNode, + grantees, + getContextManager() + ); + } +}// end of usageGrantStatement + +/* + * usableObjects + */ +Integer +usableObjects() throws StandardException : +{ +} +{ + + { + return ReuseFactory.getInteger( PrivilegeNode.SEQUENCE_PRIVILEGES); + } +| + + { + return ReuseFactory.getInteger( PrivilegeNode.UDT_PRIVILEGES); + } +}// end of routineGrantStatement + +/* * routineAlias */ RoutineDesignator routineDesignator() throws StandardException : @@ -13617,7 +13678,11 @@ checkVersion( DataDictionary.DD_VERSION_DERBY_10_2, "REVOKE"); checkSqlStandardAccess( "REVOKE"); } - ( node = tableRevokeStatement() | node = routineRevokeStatement() ) + ( + node = tableRevokeStatement() | + node = routineRevokeStatement() | + node = usageRevokeStatement() + ) { return node; } @@ -13682,6 +13747,42 @@ } }// end of routineRevokeStatement +/* + * usageRevokeStatement + */ +StatementNode +usageRevokeStatement() throws StandardException : +{ + List grantees; + TableName name; + Integer objectType; +} +{ + + objectType = usableObjects() + name = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) + grantees = granteeList() + { + checkVersion( DataDictionary.DD_VERSION_DERBY_10_6, "REVOKE USAGE"); + PrivilegeNode privilegeNode = (PrivilegeNode) nodeFactory.getNode + ( + C_NodeTypes.PRIVILEGE_NODE, + objectType, + name, + PermDescriptor.USAGE_PRIV, + Boolean.TRUE, + getContextManager() + ); + return (StatementNode) nodeFactory.getNode + ( + C_NodeTypes.REVOKE_NODE, + privilegeNode, + grantees, + getContextManager() + ); + } +}// end of usageRevokeStatement + /* * roleRevokeStatement Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericPrivilegeInfo.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericPrivilegeInfo.java?rev=892272&view=auto ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericPrivilegeInfo.java (added) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericPrivilegeInfo.java Fri Dec 18 15:15:02 2009 @@ -0,0 +1,143 @@ +/* + + Derby - Class org.apache.derby.impl.sql.execute.GenericPrivilegeInfo + + 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.impl.sql.execute; + +import org.apache.derby.iapi.sql.Activation; +import org.apache.derby.iapi.services.sanity.SanityManager; +import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; +import org.apache.derby.iapi.store.access.TransactionController; +import org.apache.derby.iapi.sql.depend.DependencyManager; +import org.apache.derby.iapi.sql.dictionary.DataDictionary; +import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator; +import org.apache.derby.iapi.sql.dictionary.PermDescriptor; +import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor; +import org.apache.derby.iapi.sql.dictionary.PrivilegedSQLObject; +import org.apache.derby.iapi.sql.dictionary.TupleDescriptor; +import org.apache.derby.iapi.error.StandardException; +import org.apache.derby.catalog.UUID; + +import java.util.Iterator; +import java.util.List; + +public class GenericPrivilegeInfo extends PrivilegeInfo +{ + /////////////////////////////////////////////////////////////////////////////////// + // + // CONSTANTS + // + /////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////// + // + // STATE + // + /////////////////////////////////////////////////////////////////////////////////// + + private PrivilegedSQLObject _tupleDescriptor; + private String _privilege; + private boolean _restrict; + + /////////////////////////////////////////////////////////////////////////////////// + // + // CONSTRUCTOR + // + /////////////////////////////////////////////////////////////////////////////////// + + /** + * Construct from the object which is protected by privileges. + * + * @param tupleDescriptor The object which is being protected + * @param privilege Kind of privilege (e.g., PermDescriptor.USAGE_PRIV) + * @param restrict True if this is a REVOKE RESTRICT action + */ + public GenericPrivilegeInfo( PrivilegedSQLObject tupleDescriptor, String privilege, boolean restrict ) + { + _tupleDescriptor = tupleDescriptor; + _privilege = privilege; + _restrict = restrict; + } + + /////////////////////////////////////////////////////////////////////////////////// + // + // PrivilegeInfo BEHAVIOR + // + /////////////////////////////////////////////////////////////////////////////////// + + /** + * This is the guts of the Execution-time logic for GRANT/REVOKE generic privileges. + * + * @param activation + * @param grant true if grant, false if revoke + * @param grantees a list of authorization ids (strings) + * + * @exception StandardException Thrown on failure + */ + public void executeGrantRevoke( Activation activation, + boolean grant, + List grantees) + throws StandardException + { + // Check that the current user has permission to grant the privileges. + LanguageConnectionContext lcc = activation.getLanguageConnectionContext(); + DataDictionary dd = lcc.getDataDictionary(); + String currentUser = lcc.getAuthorizationId(); + TransactionController tc = lcc.getTransactionExecute(); + SchemaDescriptor sd = _tupleDescriptor.getSchemaDescriptor(); + UUID objectID = _tupleDescriptor.getUUID(); + String objectTypeName = _tupleDescriptor.getObjectTypeName(); + + // Check that the current user has permission to grant the privileges. + checkOwnership( currentUser, (TupleDescriptor) _tupleDescriptor, sd, dd ); + + DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator(); + + PermDescriptor permDesc = ddg.newPermDescriptor + ( null, objectTypeName, objectID, _privilege, currentUser, null, false ); + + dd.startWriting(lcc); + for( Iterator itr = grantees.iterator(); itr.hasNext();) + { + // Keep track to see if any privileges are revoked by a revoke + // statement. If a privilege is not revoked, we need to raise a + // warning. + boolean privileges_revoked = false; + String grantee = (String) itr.next(); + if (dd.addRemovePermissionsDescriptor( grant, permDesc, grantee, tc)) + { + // + // We fall in here if we are performing REVOKE. + // + privileges_revoked = true; + int invalidationType = _restrict ? DependencyManager.REVOKE_PRIVILEGE_RESTRICT : DependencyManager.REVOKE_PRIVILEGE; + + dd.getDependencyManager().invalidateFor( permDesc, invalidationType, lcc ); + + // Now invalidate all GPSs refering to the object. + dd.getDependencyManager().invalidateFor(_tupleDescriptor, invalidationType, lcc ); + } + + addWarningIfPrivilegeNotRevoked(activation, grant, privileges_revoked, grantee); + } + } // end of executeGrantRevoke + + +} Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericPrivilegeInfo.java ------------------------------------------------------------------------------ svn:eol-style = native 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=892272&r1=892271&r2=892272&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 Fri Dec 18 15:15:02 2009 @@ -1089,8 +1089,9 @@ 42504 - User '{0}' does not have execute permission on {1} '{2}'.'{3}'. + User '{0}' does not have {1} permission on {2} '{3}'.'{4}'. authorizationID + permissionType objectName schemaName tableName @@ -1098,8 +1099,9 @@ 42505 - User '{0}' does not have execute permission on {1} '{2}'.'{3}' for grant. + User '{0}' does not have {1} permission on {2} '{3}'.'{4}' for grant. authorizationID + permissionType objectName schemaName tableName 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=892272&r1=892271&r2=892272&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 Fri Dec 18 15:15:02 2009 @@ -753,8 +753,8 @@ String AUTH_NO_TABLE_PERMISSION_FOR_GRANT = "42501"; String AUTH_NO_COLUMN_PERMISSION = "42502"; String AUTH_NO_COLUMN_PERMISSION_FOR_GRANT = "42503"; - String AUTH_NO_EXECUTE_PERMISSION = "42504"; - String AUTH_NO_EXECUTE_PERMISSION_FOR_GRANT = "42505"; + String AUTH_NO_GENERIC_PERMISSION = "42504"; + String AUTH_NO_GENERIC_PERMISSION_FOR_GRANT = "42505"; String AUTH_NOT_OWNER = "42506"; String AUTH_NO_ACCESS_NOT_OWNER = "42507"; String AUTH_NOT_DATABASE_OWNER = "42508"; Modified: db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java (original) +++ db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java Fri Dec 18 15:15:02 2009 @@ -843,12 +843,12 @@ return null; } - public PermDescriptor getPermissions(UUID permUUID) throws StandardException { + public PermDescriptor getGenericPermissions(UUID permUUID) throws StandardException { // TODO Auto-generated method stub return null; } - public PermDescriptor getPermissions(UUID objectID, String granteeAuthId) + public PermDescriptor getGenericPermissions(UUID objectID, String objectType, String privilege, String granteeAuthId) throws StandardException { // TODO Auto-generated method stub return null; Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java Fri Dec 18 15:15:02 2009 @@ -81,6 +81,7 @@ protected static final String LACK_TABLE_PRIV = "42500"; protected static final String LACK_COLUMN_PRIV = "42502"; protected static final String LACK_EXECUTE_PRIV = "42504"; + protected static final String LACK_USAGE_PRIV = "42504"; protected static final String CANT_ADD_IDENTITY = "42601"; protected static final String CANT_MODIFY_IDENTITY = "42Z23"; @@ -88,6 +89,10 @@ protected static final String CONSTRAINT_DROPPED_WARNING = "01500"; protected static final String TRIGGER_DROPPED_WARNING = "01502"; protected static final String LANG_INVALID_USE_OF_DEFAULT = "42Y85"; + protected static final String GRANT_REVOKE_NOT_ALLOWED = "42509"; + protected static final String ROUTINE_DEPENDS_ON_TYPE = "X0Y30"; + protected static final String TABLE_DEPENDS_ON_TYPE = "X0Y29"; + protected static final String VIEW_DEPENDS_ON_PRIVILEGE = "X0Y23"; /////////////////////////////////////////////////////////////////////////////////// // @@ -159,6 +164,27 @@ } /** + * Assert that the statement text, when compiled, raises an exception + */ + protected void expectCompilationError( Connection conn, String sqlState, String query ) + { + println( "\nExpecting " + sqlState + " when preparing:\n\t" + query ); + + PreparedStatement ps = null; + + try { + ps = conn.prepareStatement( query ); + } catch (SQLException se ) + { + assertSQLState( sqlState, se ); + + return; + } + + fail( "Expected SQL state: " + sqlState ); + } + + /** * Assert that the statement text, when executed, raises an error. */ protected void expectExecutionError( Connection conn, String sqlState, String query ) @@ -351,6 +377,54 @@ } /** + * Test that a privilege can't be revoked if an object depends on it. + */ + protected void verifyRevokePrivilege + ( + Connection grantorConnection, + Connection granteeConnection, + String grantStatement, + String revokeStatement, + String createStatement, + String dropStatement, + String badRevokeSQLState + ) throws Exception + { + expectExecutionError + ( + granteeConnection, + LACK_USAGE_PRIV, + createStatement + ); + goodStatement + ( + grantorConnection, + grantStatement + ); + goodStatement + ( + granteeConnection, + createStatement + ); + expectExecutionError + ( + grantorConnection, + badRevokeSQLState, + revokeStatement + ); + goodStatement + ( + granteeConnection, + dropStatement + ); + goodStatement + ( + grantorConnection, + revokeStatement + ); + } + + /** *

* Fill an ArrayList from an array. *

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java?rev=892272&r1=892271&r2=892272&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java Fri Dec 18 15:15:02 2009 @@ -372,6 +372,7 @@ {"SYSKEYS", "SYSKEYS_HEAP", "false"}, {"SYSKEYS", "SYSKEYS_INDEX1", "true"}, {"SYSPERMS", "SYSPERMS_HEAP", "false"}, + {"SYSPERMS", "SYSPERMS_INDEX3", "true"}, {"SYSPERMS", "SYSPERMS_INDEX2", "true"}, {"SYSPERMS", "SYSPERMS_INDEX1", "true"}, {"SYSROLES", "SYSROLES_HEAP", "false"},