mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +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
|
||||
-->
|
||||
|
||||
@ -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>
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
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
|
||||
*
|
||||
* 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
|
||||
*
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user