Clean up loose ends remaining from schema privileges discussion.

I concluded that RENAME should require CREATE privilege on the namespace
as well as ownership of the table.
This commit is contained in:
Tom Lane 2002-04-30 01:26:26 +00:00
parent 4c25a0655b
commit e4f06dc12e
5 changed files with 86 additions and 26 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.24 2002/04/29 22:28:19 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.25 2002/04/30 01:26:25 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
@ -161,6 +161,8 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
</para> </para>
<para> <para>
For schemas, allows new objects to be created within the schema. 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> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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. * 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); namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID);
/* Advance command counter to make namespace visible */ /* Advance command counter to make namespace visible */

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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,23 +374,47 @@ ProcessUtility(Node *parsetree,
case T_RenameStmt: case T_RenameStmt:
{ {
RenameStmt *stmt = (RenameStmt *) parsetree; RenameStmt *stmt = (RenameStmt *) parsetree;
Oid relid;
CheckOwnership(stmt->relation, true); CheckOwnership(stmt->relation, true);
relid = RangeVarGetRelid(stmt->relation, false);
switch (stmt->renameType) switch (stmt->renameType)
{ {
case RENAME_TABLE: 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; break;
}
case RENAME_COLUMN: case RENAME_COLUMN:
renameatt(RangeVarGetRelid(stmt->relation, false), renameatt(relid,
stmt->oldname, /* old att name */ stmt->oldname, /* old att name */
stmt->newname, /* new att name */ stmt->newname, /* new att name */
interpretInhOption(stmt->relation->inhOpt)); /* recursive? */ interpretInhOption(stmt->relation->inhOpt)); /* recursive? */
break; break;
case RENAME_TRIGGER: case RENAME_TRIGGER:
renametrig(RangeVarGetRelid(stmt->relation, false), renametrig(relid,
stmt->oldname, /* old att name */ stmt->oldname, /* old att name */
stmt->newname); /* new att name */ stmt->newname); /* new att name */
break; break;
@ -410,6 +434,9 @@ ProcessUtility(Node *parsetree,
case T_AlterTableStmt: case T_AlterTableStmt:
{ {
AlterTableStmt *stmt = (AlterTableStmt *) parsetree; AlterTableStmt *stmt = (AlterTableStmt *) parsetree;
Oid relid;
relid = RangeVarGetRelid(stmt->relation, false);
/* /*
* Some or all of these functions are recursive to cover * Some or all of these functions are recursive to cover
@ -422,7 +449,7 @@ ProcessUtility(Node *parsetree,
* Recursively add column to table and, * Recursively add column to table and,
* if requested, to descendants * if requested, to descendants
*/ */
AlterTableAddColumn(RangeVarGetRelid(stmt->relation, false), AlterTableAddColumn(relid,
interpretInhOption(stmt->relation->inhOpt), interpretInhOption(stmt->relation->inhOpt),
(ColumnDef *) stmt->def); (ColumnDef *) stmt->def);
break; break;
@ -431,18 +458,18 @@ ProcessUtility(Node *parsetree,
* Recursively alter column default for table and, * Recursively alter column default for table and,
* if requested, for descendants * if requested, for descendants
*/ */
AlterTableAlterColumnDefault(RangeVarGetRelid(stmt->relation, false), AlterTableAlterColumnDefault(relid,
interpretInhOption(stmt->relation->inhOpt), interpretInhOption(stmt->relation->inhOpt),
stmt->name, stmt->name,
stmt->def); stmt->def);
break; break;
case 'N': /* ALTER COLUMN DROP NOT NULL */ case 'N': /* ALTER COLUMN DROP NOT NULL */
AlterTableAlterColumnDropNotNull(RangeVarGetRelid(stmt->relation, false), AlterTableAlterColumnDropNotNull(relid,
interpretInhOption(stmt->relation->inhOpt), interpretInhOption(stmt->relation->inhOpt),
stmt->name); stmt->name);
break; break;
case 'O': /* ALTER COLUMN SET NOT NULL */ case 'O': /* ALTER COLUMN SET NOT NULL */
AlterTableAlterColumnSetNotNull(RangeVarGetRelid(stmt->relation, false), AlterTableAlterColumnSetNotNull(relid,
interpretInhOption(stmt->relation->inhOpt), interpretInhOption(stmt->relation->inhOpt),
stmt->name); stmt->name);
break; break;
@ -452,7 +479,7 @@ ProcessUtility(Node *parsetree,
* Recursively alter column statistics for table and, * Recursively alter column statistics for table and,
* if requested, for descendants * if requested, for descendants
*/ */
AlterTableAlterColumnFlags(RangeVarGetRelid(stmt->relation, false), AlterTableAlterColumnFlags(relid,
interpretInhOption(stmt->relation->inhOpt), interpretInhOption(stmt->relation->inhOpt),
stmt->name, stmt->name,
stmt->def, stmt->def,
@ -464,7 +491,7 @@ ProcessUtility(Node *parsetree,
* Recursively drop column from table and, * Recursively drop column from table and,
* if requested, from descendants * if requested, from descendants
*/ */
AlterTableDropColumn(RangeVarGetRelid(stmt->relation, false), AlterTableDropColumn(relid,
interpretInhOption(stmt->relation->inhOpt), interpretInhOption(stmt->relation->inhOpt),
stmt->name, stmt->name,
stmt->behavior); stmt->behavior);
@ -474,7 +501,7 @@ ProcessUtility(Node *parsetree,
* Recursively add constraint to table and, * Recursively add constraint to table and,
* if requested, to descendants * if requested, to descendants
*/ */
AlterTableAddConstraint(RangeVarGetRelid(stmt->relation, false), AlterTableAddConstraint(relid,
interpretInhOption(stmt->relation->inhOpt), interpretInhOption(stmt->relation->inhOpt),
(List *) stmt->def); (List *) stmt->def);
break; break;
@ -483,21 +510,20 @@ ProcessUtility(Node *parsetree,
* Recursively drop constraint from table and, * Recursively drop constraint from table and,
* if requested, from descendants * if requested, from descendants
*/ */
AlterTableDropConstraint(RangeVarGetRelid(stmt->relation, false), AlterTableDropConstraint(relid,
interpretInhOption(stmt->relation->inhOpt), interpretInhOption(stmt->relation->inhOpt),
stmt->name, stmt->name,
stmt->behavior); stmt->behavior);
break; break;
case 'E': /* CREATE TOAST TABLE */ case 'E': /* CREATE TOAST TABLE */
AlterTableCreateToastTable(RangeVarGetRelid(stmt->relation, false), AlterTableCreateToastTable(relid, false);
false);
break; break;
case 'U': /* ALTER OWNER */ case 'U': /* ALTER OWNER */
/* check that we are the superuser */ /* check that we are the superuser */
if (!superuser()) if (!superuser())
elog(ERROR, "ALTER TABLE: permission denied"); elog(ERROR, "ALTER TABLE: permission denied");
/* get_usesysid raises an error if no such user */ /* get_usesysid raises an error if no such user */
AlterTableOwner(RangeVarGetRelid(stmt->relation, false), AlterTableOwner(relid,
get_usesysid(stmt->name)); get_usesysid(stmt->name));
break; break;
default: /* oops */ default: /* oops */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 * NOTES
* Eventually, the index information should go through here, too. * Eventually, the index information should go through here, too.
@ -708,6 +708,32 @@ get_rel_name(Oid relid)
return NULL; 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 * get_rel_type_id
* *

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 char func_volatile(Oid funcid);
extern Oid get_relname_relid(const char *relname, Oid relnamespace); extern Oid get_relname_relid(const char *relname, Oid relnamespace);
extern char *get_rel_name(Oid relid); extern char *get_rel_name(Oid relid);
extern Oid get_rel_namespace(Oid relid);
extern Oid get_rel_type_id(Oid relid); extern Oid get_rel_type_id(Oid relid);
extern bool get_typisdefined(Oid typid); extern bool get_typisdefined(Oid typid);
extern int16 get_typlen(Oid typid); extern int16 get_typlen(Oid typid);