mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
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:
parent
4c25a0655b
commit
e4f06dc12e
@ -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>
|
||||||
|
@ -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 */
|
||||||
|
@ -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,
|
|||||||
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,
|
|||||||
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 */
|
||||||
|
28
src/backend/utils/cache/lsyscache.c
vendored
28
src/backend/utils/cache/lsyscache.c
vendored
@ -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
|
||||||
*
|
*
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user