--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.sql.catalog.PermissionsCacheable\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.sql.catalog;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.services.cache.Cacheable;\r
+import org.apache.derby.iapi.services.cache.CacheManager;\r
+import org.apache.derby.iapi.services.io.FormatableBitSet;\r
+\r
+import org.apache.derby.iapi.sql.conn.Authorizer;\r
+import org.apache.derby.iapi.sql.conn.ConnectionUtil;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.TablePermsDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.ColPermsDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.RoutinePermsDescriptor;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+/**\r
+ * This class implements a Cacheable for a DataDictionary cache of\r
+ * permissions.\r
+ */\r
+class PermissionsCacheable implements Cacheable\r
+{\r
+ protected final DataDictionaryImpl dd;\r
+ private PermissionsDescriptor permissions;\r
+ \r
+ PermissionsCacheable(DataDictionaryImpl dd)\r
+ {\r
+ this.dd = dd;\r
+ }\r
+\r
+ /* Cacheable interface */\r
+ public Cacheable setIdentity(Object key) throws StandardException\r
+ {\r
+ // If the user does not have permission then cache an empty (no permission) descriptor in\r
+ // case the same user asks again. That is particularly important for table permission because\r
+ // we ask about table permission before column permissions. If a user has permission to use a\r
+ // proper subset of the columns we will still ask about table permission every time he tries\r
+ // to access that column subset.\r
+ if( key instanceof TablePermsDescriptor)\r
+ {\r
+ TablePermsDescriptor tablePermsKey = (TablePermsDescriptor) key;\r
+ permissions = dd.getUncachedTablePermsDescriptor( tablePermsKey);\r
+ if( permissions == null)\r
+ {\r
+ // The owner has all privileges unless they have been revoked.\r
+ TableDescriptor td = dd.getTableDescriptor( tablePermsKey.getTableUUID());\r
+ SchemaDescriptor sd = td.getSchemaDescriptor();\r
+ if( sd.isSystemSchema())\r
+ // RESOLVE The access to system tables is hard coded to SELECT only to everyone.\r
+ // Is this the way we want Derby to work? Should we allow revocation of read access\r
+ // to system tables? If so we must explicitly add a row to the SYS.SYSTABLEPERMISSIONS\r
+ // table for each system table when a database is created.\r
+ permissions = new TablePermsDescriptor( dd,\r
+ tablePermsKey.getGrantee(),\r
+ (String) null,\r
+ tablePermsKey.getTableUUID(),\r
+ "Y", "N", "N", "N", "N", "N");\r
+ else if( tablePermsKey.getGrantee().equals( sd.getAuthorizationId()))\r
+ permissions = new TablePermsDescriptor( dd,\r
+ tablePermsKey.getGrantee(),\r
+ Authorizer.SYSTEM_AUTHORIZATION_ID,\r
+ tablePermsKey.getTableUUID(),\r
+ "Y", "Y", "Y", "Y", "Y", "Y");\r
+ else\r
+ permissions = new TablePermsDescriptor( dd,\r
+ tablePermsKey.getGrantee(),\r
+ (String) null,\r
+ tablePermsKey.getTableUUID(),\r
+ "N", "N", "N", "N", "N", "N");\r
+ }\r
+ }\r
+ else if( key instanceof ColPermsDescriptor)\r
+ {\r
+ ColPermsDescriptor colPermsKey = (ColPermsDescriptor) key;\r
+ permissions = dd.getUncachedColPermsDescriptor(colPermsKey );\r
+ if( permissions == null)\r
+ permissions = new ColPermsDescriptor( dd,\r
+ colPermsKey.getGrantee(),\r
+ (String) null,\r
+ colPermsKey.getTableUUID(),\r
+ colPermsKey.getType(),\r
+ (FormatableBitSet) null);\r
+ }\r
+ else if( key instanceof RoutinePermsDescriptor)\r
+ {\r
+ RoutinePermsDescriptor routinePermsKey = (RoutinePermsDescriptor) key;\r
+ permissions = dd.getUncachedRoutinePermsDescriptor( routinePermsKey);\r
+ if( permissions == null)\r
+ {\r
+ // The owner has all privileges unless they have been revoked.\r
+ try\r
+ {\r
+ AliasDescriptor ad = dd.getAliasDescriptor( routinePermsKey.getRoutineUUID());\r
+ SchemaDescriptor sd = dd.getSchemaDescriptor( ad.getSchemaUUID(),\r
+ ConnectionUtil.getCurrentLCC().getTransactionExecute());\r
+ if (sd.isSystemSchema() && !sd.isSchemaWithGrantableRoutines())\r
+ permissions = new RoutinePermsDescriptor( dd,\r
+ routinePermsKey.getGrantee(),\r
+ (String) null,\r
+ routinePermsKey.getRoutineUUID(),\r
+ true);\r
+ else if( routinePermsKey.getGrantee().equals( sd.getAuthorizationId()))\r
+ permissions = new RoutinePermsDescriptor( dd,\r
+ routinePermsKey.getGrantee(),\r
+ Authorizer.SYSTEM_AUTHORIZATION_ID,\r
+ routinePermsKey.getRoutineUUID(),\r
+ true);\r
+ }\r
+ catch( java.sql.SQLException sqle)\r
+ {\r
+ throw StandardException.plainWrapException( sqle);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if( SanityManager.DEBUG)\r
+ SanityManager.NOTREACHED();\r
+ return null;\r
+ }\r
+ if( permissions != null)\r
+ return this;\r
+ return null;\r
+ } // end of setIdentity\r
+\r
+ public Cacheable createIdentity(Object key, Object createParameter) throws StandardException\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.ASSERT( (key instanceof TablePermsDescriptor) ||\r
+ (key instanceof ColPermsDescriptor) ||\r
+ (key instanceof RoutinePermsDescriptor),\r
+ "Invalid class, " + key.getClass().getName()\r
+ + ", passed as key to PermissionsCacheable.createIdentity");\r
+ }\r
+ if( key == null)\r
+ return null;\r
+ permissions = (PermissionsDescriptor) ((PermissionsDescriptor)key).clone();\r
+ return this;\r
+ } // end of createIdentity\r
+\r
+ public void clearIdentity()\r
+ {\r
+ permissions = null;\r
+ }\r
+\r
+ public Object getIdentity()\r
+ {\r
+ return permissions;\r
+ }\r
+\r
+ public boolean isDirty()\r
+ {\r
+ return false;\r
+ }\r
+\r
+ public void clean(boolean forRemove) throws StandardException\r
+ {\r
+ }\r
+}\r