Clean up loose ends remaining from schema privileges discussion.
authorTom Lane
Tue, 30 Apr 2002 01:26:26 +0000 (01:26 +0000)
committerTom Lane
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 1697f91929a5ee4332cb928c2efe43f75b58147f..226db71d6838c99747760bc80254cca291a61353 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -161,6 +161,8 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
       
       
        For schemas, allows new objects to be created within the schema.
+       To rename an existing object, you must own the object and
+       have this privilege for the containing schema.
       
      
     
index 51ef7c3f8d9c54fdd50a3e691767f3e7de0cb76a..80ce60f8ab24643641d88fe71c03e3c8f5f4e99b 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.15 2002/04/29 22:15:07 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.16 2002/04/30 01:26:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 771f3d30cc8d2b5340184644c0440b619f76a554..9a9c062559e7a696eea76af281031cc2105cb297 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.152 2002/04/27 03:45:03 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.153 2002/04/30 01:26:26 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 f6b98c5bee621132442e4b65f1c097907e035360..ca3bd80e8a7e58366a5ab4a0e4c1295984ebd73e 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.71 2002/04/27 03:45:03 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.72 2002/04/30 01:26:26 tgl Exp $
  *
  * NOTES
  *   Eventually, the index information should go through here, too.
@@ -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 f57219df119b5c6e495ddf7ef6b0c017be662b2e..9f8122567375f22ecfebc5e2b2ab94c957ab81c6 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: lsyscache.h,v 1.50 2002/04/27 03:45:03 tgl Exp $
+ * $Id: lsyscache.h,v 1.51 2002/04/30 01:26:26 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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);