Ignore tablespace ACLs when ignoring schema ACLs.
authorNoah Misch
Sun, 12 Feb 2017 21:03:41 +0000 (16:03 -0500)
committerNoah Misch
Sun, 12 Feb 2017 21:04:09 +0000 (16:04 -0500)
The ALTER TABLE ALTER TYPE implementation can issue DROP INDEX and
CREATE INDEX to refit existing indexes for the new column type.  Since
this CREATE INDEX is an implementation detail of an index alteration,
the ensuing DefineIndex() should skip ACL checks specific to index
creation.  It already skips the namespace ACL check.  Make it skip the
tablespace ACL check, too.  Back-patch to 9.2 (all supported versions).

Reviewed by Tom Lane.

src/backend/commands/indexcmds.c
src/test/regress/input/tablespace.source
src/test/regress/output/tablespace.source

index a90cfc55cedc7da4e1724725fb4fd71e0c36b600..f46bdbbb58ff2ac8ce13a174780575efc98b8f3d 100644 (file)
@@ -285,8 +285,8 @@ CheckIndexCompatible(Oid oldId,
  * 'indexRelationId': normally InvalidOid, but during bootstrap can be
  *     nonzero to specify a preselected OID for the index.
  * 'is_alter_table': this is due to an ALTER rather than a CREATE operation.
- * 'check_rights': check for CREATE rights in the namespace.  (This should
- *     be true except when ALTER is deleting/recreating an index.)
+ * 'check_rights': check for CREATE rights in namespace and tablespace.  (This
+ *     should be true except when ALTER is deleting/recreating an index.)
  * 'skip_build': make the catalog entries but leave the index file empty;
  *     it will be filled later.
  * 'quiet': suppress the NOTICE chatter ordinarily provided for constraints.
@@ -420,8 +420,9 @@ DefineIndex(Oid relationId,
        /* note InvalidOid is OK in this case */
    }
 
-   /* Check permissions except when using database's default */
-   if (OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace)
+   /* Check tablespace permissions */
+   if (check_rights &&
+       OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace)
    {
        AclResult   aclresult;
 
index d50ee371dbefb4dd0700d910ef735b1e3616b5f4..59690cd695bc6008cf18ea161ebb93d5a20f14f8 100644 (file)
@@ -97,11 +97,18 @@ DROP TABLESPACE testspace;
 
 CREATE ROLE tablespace_testuser1 login;
 CREATE ROLE tablespace_testuser2 login;
+GRANT USAGE ON SCHEMA testschema TO tablespace_testuser2;
 
 ALTER TABLESPACE testspace OWNER TO tablespace_testuser1;
 
+CREATE TABLE testschema.tablespace_acl (c int);
+-- new owner lacks permission to create this index from scratch
+CREATE INDEX k ON testschema.tablespace_acl (c) TABLESPACE testspace;
+ALTER TABLE testschema.tablespace_acl OWNER TO tablespace_testuser2;
+
 SET SESSION ROLE tablespace_testuser2;
 CREATE TABLE tablespace_table (i int) TABLESPACE testspace; -- fail
+ALTER TABLE testschema.tablespace_acl ALTER c TYPE bigint;
 RESET ROLE;
 
 ALTER TABLESPACE testspace RENAME TO testspace_renamed;
index 5cf183e3729bfa23841c0166a7db9cd2098ba0d6..f7a03af85d083ec349dcbdea58dba3ac2053dd55 100644 (file)
@@ -192,10 +192,16 @@ DROP TABLESPACE testspace;
 ERROR:  tablespace "testspace" is not empty
 CREATE ROLE tablespace_testuser1 login;
 CREATE ROLE tablespace_testuser2 login;
+GRANT USAGE ON SCHEMA testschema TO tablespace_testuser2;
 ALTER TABLESPACE testspace OWNER TO tablespace_testuser1;
+CREATE TABLE testschema.tablespace_acl (c int);
+-- new owner lacks permission to create this index from scratch
+CREATE INDEX k ON testschema.tablespace_acl (c) TABLESPACE testspace;
+ALTER TABLE testschema.tablespace_acl OWNER TO tablespace_testuser2;
 SET SESSION ROLE tablespace_testuser2;
 CREATE TABLE tablespace_table (i int) TABLESPACE testspace; -- fail
 ERROR:  permission denied for tablespace testspace
+ALTER TABLE testschema.tablespace_acl ALTER c TYPE bigint;
 RESET ROLE;
 ALTER TABLESPACE testspace RENAME TO testspace_renamed;
 ALTER TABLE ALL IN TABLESPACE testspace_renamed SET TABLESPACE pg_default;
@@ -206,10 +212,11 @@ NOTICE:  no matching relations in tablespace "testspace_renamed" found
 -- Should succeed
 DROP TABLESPACE testspace_renamed;
 DROP SCHEMA testschema CASCADE;
-NOTICE:  drop cascades to 4 other objects
+NOTICE:  drop cascades to 5 other objects
 DETAIL:  drop cascades to table testschema.foo
 drop cascades to table testschema.asselect
 drop cascades to table testschema.asexecute
 drop cascades to table testschema.atable
+drop cascades to table testschema.tablespace_acl
 DROP ROLE tablespace_testuser1;
 DROP ROLE tablespace_testuser2;