Commit e4f06dc1 authored by Tom Lane's avatar Tom Lane

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.
parent 4c25a065
<!-- <!--
$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 ] } ...@@ -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>
......
...@@ -13,7 +13,7 @@ ...@@ -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) ...@@ -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 */
......
...@@ -10,7 +10,7 @@ ...@@ -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,25 +374,49 @@ ProcessUtility(Node *parsetree, ...@@ -374,25 +374,49 @@ 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;
case RENAME_RULE: case RENAME_RULE:
elog(ERROR, "ProcessUtility: Invalid target for RENAME: %d", elog(ERROR, "ProcessUtility: Invalid target for RENAME: %d",
...@@ -410,6 +434,9 @@ ProcessUtility(Node *parsetree, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 */
......
...@@ -7,7 +7,7 @@ ...@@ -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) ...@@ -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
* *
......
...@@ -6,7 +6,7 @@ ...@@ -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); ...@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment