Clean up loose ends remaining from schema privileges discussion.
authorTom Lane <[email protected]>
Tue, 30 Apr 2002 01:26:26 +0000 (01:26 +0000)
committerTom Lane <[email protected]>
Tue, 30 Apr 2002 01:26:26 +0000 (01:26 +0000)
I concluded that RENAME should require CREATE privilege on the namespace
as well as ownership of the table.

doc/src/sgml/ref/grant.sgml
src/backend/catalog/namespace.c
src/backend/tcop/utility.c
src/backend/utils/cache/lsyscache.c
src/include/utils/lsyscache.h

index 0ef5caa89a3450390f526d528241476e28ec7ba8..78435db7d8be6514bdf2b7fcd7c46e172be26d43 100644 (file)
@@ -161,6 +161,8 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
       </para>
       <para>
        For schemas, allows new objects to be created within the schema.
+       To rename an existing object, you must own the object <emphasis>and</>
+       have this privilege for the containing schema.
       </para>
      </listitem>
     </varlistentry>
index b06b23257fe10aa9e6b3a1b036304011c7cef44c..6f0cc453b5521d520af74e641ac86fad9e1a6b72 100644 (file)
@@ -1161,7 +1161,12 @@ GetTempTableNamespace(void)
        {
                /*
                 * First use of this temp namespace in this database; create it.
-                * The temp namespaces are always owned by the superuser.
+                * The temp namespaces are always owned by the superuser.  We
+                * leave their permissions at default --- i.e., no access except to
+                * superuser --- to ensure that unprivileged users can't peek
+                * at other backends' temp tables.  This works because the places
+                * that access the temp namespace for my own backend skip permissions
+                * checks on it.
                 */
                namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID);
                /* Advance command counter to make namespace visible */
index 04bbfc1e371c6139cd61f3df74380e90661ca859..4133bba54ceb6bcd37f5e5d3c4545330795cffea 100644 (file)
@@ -374,25 +374,49 @@ ProcessUtility(Node *parsetree,
                case T_RenameStmt:
                        {
                                RenameStmt *stmt = (RenameStmt *) parsetree;
+                               Oid             relid;
 
                                CheckOwnership(stmt->relation, true);
 
+                               relid = RangeVarGetRelid(stmt->relation, false);
+
                                switch (stmt->renameType)
                                {
                                        case RENAME_TABLE:
-                                               renamerel(RangeVarGetRelid(stmt->relation, false),
-                                                                 stmt->newname);
+                                       {
+                                               /*
+                                                * RENAME TABLE requires that we (still) hold CREATE
+                                                * rights on the containing namespace, as well as
+                                                * ownership of the table.  But skip check for
+                                                * temp tables.
+                                                */
+                                               Oid                     namespaceId = get_rel_namespace(relid);
+
+                                               if (!isTempNamespace(namespaceId))
+                                               {
+                                                       AclResult       aclresult;
+
+                                                       aclresult = pg_namespace_aclcheck(namespaceId,
+                                                                                                                         GetUserId(),
+                                                                                                                         ACL_CREATE);
+                                                       if (aclresult != ACLCHECK_OK)
+                                                               aclcheck_error(aclresult,
+                                                                                       get_namespace_name(namespaceId));
+                                               }
+
+                                               renamerel(relid, stmt->newname);
                                                break;
+                                       }
                                        case RENAME_COLUMN:
-                                               renameatt(RangeVarGetRelid(stmt->relation, false),
-                                                         stmt->oldname,        /* old att name */
-                                                         stmt->newname,        /* new att name */
-                                                         interpretInhOption(stmt->relation->inhOpt));  /* recursive? */
+                                               renameatt(relid,
+                                                                 stmt->oldname,        /* old att name */
+                                                                 stmt->newname,        /* new att name */
+                                                                 interpretInhOption(stmt->relation->inhOpt));  /* recursive? */
                                                break;
                                        case RENAME_TRIGGER:
-                                               renametrig(RangeVarGetRelid(stmt->relation, false),
-                                                         stmt->oldname,        /* old att name */
-                                                         stmt->newname);       /* new att name */
+                                               renametrig(relid,
+                                                                  stmt->oldname,       /* old att name */
+                                                                  stmt->newname);      /* new att name */
                                                break;
                                        case RENAME_RULE:
                                                elog(ERROR, "ProcessUtility: Invalid target for RENAME: %d",
@@ -410,6 +434,9 @@ ProcessUtility(Node *parsetree,
                case T_AlterTableStmt:
                        {
                                AlterTableStmt *stmt = (AlterTableStmt *) parsetree;
+                               Oid             relid;
+
+                               relid = RangeVarGetRelid(stmt->relation, false);
 
                                /*
                                 * Some or all of these functions are recursive to cover
@@ -422,7 +449,7 @@ ProcessUtility(Node *parsetree,
                                                 * Recursively add column to table and,
                                                 * if requested, to descendants
                                                 */
-                                               AlterTableAddColumn(RangeVarGetRelid(stmt->relation, false),
+                                               AlterTableAddColumn(relid,
                                                                                        interpretInhOption(stmt->relation->inhOpt),
                                                                                        (ColumnDef *) stmt->def);
                                                break;
@@ -431,18 +458,18 @@ ProcessUtility(Node *parsetree,
                                                 * Recursively alter column default for table and,
                                                 * if requested, for descendants
                                                 */
-                                               AlterTableAlterColumnDefault(RangeVarGetRelid(stmt->relation, false),
+                                               AlterTableAlterColumnDefault(relid,
                                                                                                         interpretInhOption(stmt->relation->inhOpt),
                                                                                                         stmt->name,
                                                                                                         stmt->def);
                                                break;
                                        case 'N':       /* ALTER COLUMN DROP NOT NULL */
-                                               AlterTableAlterColumnDropNotNull(RangeVarGetRelid(stmt->relation, false),
+                                               AlterTableAlterColumnDropNotNull(relid,
                                                                                interpretInhOption(stmt->relation->inhOpt),
                                                                                                        stmt->name);
                                                break;
                                        case 'O':       /* ALTER COLUMN SET NOT NULL */
-                                               AlterTableAlterColumnSetNotNull(RangeVarGetRelid(stmt->relation, false),
+                                               AlterTableAlterColumnSetNotNull(relid,
                                                                                interpretInhOption(stmt->relation->inhOpt),
                                                                                                        stmt->name);
                                                break;
@@ -452,7 +479,7 @@ ProcessUtility(Node *parsetree,
                                                 * Recursively alter column statistics for table and,
                                                 * if requested, for descendants
                                                 */
-                                               AlterTableAlterColumnFlags(RangeVarGetRelid(stmt->relation, false),
+                                               AlterTableAlterColumnFlags(relid,
                                                                                                   interpretInhOption(stmt->relation->inhOpt),
                                                                                                   stmt->name,
                                                                                                   stmt->def,
@@ -464,7 +491,7 @@ ProcessUtility(Node *parsetree,
                                                 * Recursively drop column from table and,
                                                 * if requested, from descendants
                                                 */
-                                               AlterTableDropColumn(RangeVarGetRelid(stmt->relation, false),
+                                               AlterTableDropColumn(relid,
                                                                                         interpretInhOption(stmt->relation->inhOpt),
                                                                                         stmt->name,
                                                                                         stmt->behavior);
@@ -474,7 +501,7 @@ ProcessUtility(Node *parsetree,
                                                 * Recursively add constraint to table and,
                                                 * if requested, to descendants
                                                 */
-                                               AlterTableAddConstraint(RangeVarGetRelid(stmt->relation, false),
+                                               AlterTableAddConstraint(relid,
                                                                                                interpretInhOption(stmt->relation->inhOpt),
                                                                                                (List *) stmt->def);
                                                break;
@@ -483,21 +510,20 @@ ProcessUtility(Node *parsetree,
                                                 * Recursively drop constraint from table and,
                                                 * if requested, from descendants
                                                 */
-                                               AlterTableDropConstraint(RangeVarGetRelid(stmt->relation, false),
+                                               AlterTableDropConstraint(relid,
                                                                                                 interpretInhOption(stmt->relation->inhOpt),
                                                                                                 stmt->name,
                                                                                                 stmt->behavior);
                                                break;
                                        case 'E':       /* CREATE TOAST TABLE */
-                                               AlterTableCreateToastTable(RangeVarGetRelid(stmt->relation, false),
-                                                                                                  false);
+                                               AlterTableCreateToastTable(relid, false);
                                                break;
                                        case 'U':       /* ALTER OWNER */
                                                /* check that we are the superuser */
                                                if (!superuser())
                                                        elog(ERROR, "ALTER TABLE: permission denied");
                                                /* get_usesysid raises an error if no such user */
-                                               AlterTableOwner(RangeVarGetRelid(stmt->relation, false),
+                                               AlterTableOwner(relid,
                                                                                get_usesysid(stmt->name));
                                                break;
                                        default:        /* oops */
index b416337b07d63e5d0bcba6dbfc1a81b313eafab5..a7b9ab40ce1454bccf492838c08907fe74f0a8d6 100644 (file)
@@ -708,6 +708,32 @@ get_rel_name(Oid relid)
                return NULL;
 }
 
+/*
+ * get_rel_namespace
+ *
+ *             Returns the pg_namespace OID associated with a given relation.
+ */
+Oid
+get_rel_namespace(Oid relid)
+{
+       HeapTuple       tp;
+
+       tp = SearchSysCache(RELOID,
+                                               ObjectIdGetDatum(relid),
+                                               0, 0, 0);
+       if (HeapTupleIsValid(tp))
+       {
+               Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+               Oid             result;
+
+               result = reltup->relnamespace;
+               ReleaseSysCache(tp);
+               return result;
+       }
+       else
+               return InvalidOid;
+}
+
 /*
  * get_rel_type_id
  *
index 81e53dbdaf132214125b2a9a7217e3244acdecab..bfc3a6575e35e745f37eb12b80c1ded7d2bbc762 100644 (file)
@@ -42,6 +42,7 @@ extern Oid    get_func_rettype(Oid funcid);
 extern char func_volatile(Oid funcid);
 extern Oid     get_relname_relid(const char *relname, Oid relnamespace);
 extern char *get_rel_name(Oid relid);
+extern Oid     get_rel_namespace(Oid relid);
 extern Oid     get_rel_type_id(Oid relid);
 extern bool get_typisdefined(Oid typid);
 extern int16 get_typlen(Oid typid);