Skip to content

Commit e4f06dc

Browse files
committed
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.
1 parent 4c25a06 commit e4f06dc

File tree

5 files changed

+86
-26
lines changed

5 files changed

+86
-26
lines changed

doc/src/sgml/ref/grant.sgml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.24 2002/04/29 22:28:19 tgl Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.25 2002/04/30 01:26:25 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -161,6 +161,8 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
161161
</para>
162162
<para>
163163
For schemas, allows new objects to be created within the schema.
164+
To rename an existing object, you must own the object <emphasis>and</>
165+
have this privilege for the containing schema.
164166
</para>
165167
</listitem>
166168
</varlistentry>

src/backend/catalog/namespace.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.15 2002/04/29 22:15:07 tgl Exp $
16+
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.16 2002/04/30 01:26:25 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -1161,7 +1161,12 @@ GetTempTableNamespace(void)
11611161
{
11621162
/*
11631163
* First use of this temp namespace in this database; create it.
1164-
* The temp namespaces are always owned by the superuser.
1164+
* The temp namespaces are always owned by the superuser. We
1165+
* leave their permissions at default --- i.e., no access except to
1166+
* superuser --- to ensure that unprivileged users can't peek
1167+
* at other backends' temp tables. This works because the places
1168+
* that access the temp namespace for my own backend skip permissions
1169+
* checks on it.
11651170
*/
11661171
namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID);
11671172
/* Advance command counter to make namespace visible */

src/backend/tcop/utility.c

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.152 2002/04/27 03:45:03 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.153 2002/04/30 01:26:26 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -374,25 +374,49 @@ ProcessUtility(Node *parsetree,
374374
case T_RenameStmt:
375375
{
376376
RenameStmt *stmt = (RenameStmt *) parsetree;
377+
Oid relid;
377378

378379
CheckOwnership(stmt->relation, true);
379380

381+
relid = RangeVarGetRelid(stmt->relation, false);
382+
380383
switch (stmt->renameType)
381384
{
382385
case RENAME_TABLE:
383-
renamerel(RangeVarGetRelid(stmt->relation, false),
384-
stmt->newname);
386+
{
387+
/*
388+
* RENAME TABLE requires that we (still) hold CREATE
389+
* rights on the containing namespace, as well as
390+
* ownership of the table. But skip check for
391+
* temp tables.
392+
*/
393+
Oid namespaceId = get_rel_namespace(relid);
394+
395+
if (!isTempNamespace(namespaceId))
396+
{
397+
AclResult aclresult;
398+
399+
aclresult = pg_namespace_aclcheck(namespaceId,
400+
GetUserId(),
401+
ACL_CREATE);
402+
if (aclresult != ACLCHECK_OK)
403+
aclcheck_error(aclresult,
404+
get_namespace_name(namespaceId));
405+
}
406+
407+
renamerel(relid, stmt->newname);
385408
break;
409+
}
386410
case RENAME_COLUMN:
387-
renameatt(RangeVarGetRelid(stmt->relation, false),
388-
stmt->oldname, /* old att name */
389-
stmt->newname, /* new att name */
390-
interpretInhOption(stmt->relation->inhOpt)); /* recursive? */
411+
renameatt(relid,
412+
stmt->oldname, /* old att name */
413+
stmt->newname, /* new att name */
414+
interpretInhOption(stmt->relation->inhOpt)); /* recursive? */
391415
break;
392416
case RENAME_TRIGGER:
393-
renametrig(RangeVarGetRelid(stmt->relation, false),
394-
stmt->oldname, /* old att name */
395-
stmt->newname); /* new att name */
417+
renametrig(relid,
418+
stmt->oldname, /* old att name */
419+
stmt->newname); /* new att name */
396420
break;
397421
case RENAME_RULE:
398422
elog(ERROR, "ProcessUtility: Invalid target for RENAME: %d",
@@ -410,6 +434,9 @@ ProcessUtility(Node *parsetree,
410434
case T_AlterTableStmt:
411435
{
412436
AlterTableStmt *stmt = (AlterTableStmt *) parsetree;
437+
Oid relid;
438+
439+
relid = RangeVarGetRelid(stmt->relation, false);
413440

414441
/*
415442
* Some or all of these functions are recursive to cover
@@ -422,7 +449,7 @@ ProcessUtility(Node *parsetree,
422449
* Recursively add column to table and,
423450
* if requested, to descendants
424451
*/
425-
AlterTableAddColumn(RangeVarGetRelid(stmt->relation, false),
452+
AlterTableAddColumn(relid,
426453
interpretInhOption(stmt->relation->inhOpt),
427454
(ColumnDef *) stmt->def);
428455
break;
@@ -431,18 +458,18 @@ ProcessUtility(Node *parsetree,
431458
* Recursively alter column default for table and,
432459
* if requested, for descendants
433460
*/
434-
AlterTableAlterColumnDefault(RangeVarGetRelid(stmt->relation, false),
461+
AlterTableAlterColumnDefault(relid,
435462
interpretInhOption(stmt->relation->inhOpt),
436463
stmt->name,
437464
stmt->def);
438465
break;
439466
case 'N': /* ALTER COLUMN DROP NOT NULL */
440-
AlterTableAlterColumnDropNotNull(RangeVarGetRelid(stmt->relation, false),
467+
AlterTableAlterColumnDropNotNull(relid,
441468
interpretInhOption(stmt->relation->inhOpt),
442469
stmt->name);
443470
break;
444471
case 'O': /* ALTER COLUMN SET NOT NULL */
445-
AlterTableAlterColumnSetNotNull(RangeVarGetRelid(stmt->relation, false),
472+
AlterTableAlterColumnSetNotNull(relid,
446473
interpretInhOption(stmt->relation->inhOpt),
447474
stmt->name);
448475
break;
@@ -452,7 +479,7 @@ ProcessUtility(Node *parsetree,
452479
* Recursively alter column statistics for table and,
453480
* if requested, for descendants
454481
*/
455-
AlterTableAlterColumnFlags(RangeVarGetRelid(stmt->relation, false),
482+
AlterTableAlterColumnFlags(relid,
456483
interpretInhOption(stmt->relation->inhOpt),
457484
stmt->name,
458485
stmt->def,
@@ -464,7 +491,7 @@ ProcessUtility(Node *parsetree,
464491
* Recursively drop column from table and,
465492
* if requested, from descendants
466493
*/
467-
AlterTableDropColumn(RangeVarGetRelid(stmt->relation, false),
494+
AlterTableDropColumn(relid,
468495
interpretInhOption(stmt->relation->inhOpt),
469496
stmt->name,
470497
stmt->behavior);
@@ -474,7 +501,7 @@ ProcessUtility(Node *parsetree,
474501
* Recursively add constraint to table and,
475502
* if requested, to descendants
476503
*/
477-
AlterTableAddConstraint(RangeVarGetRelid(stmt->relation, false),
504+
AlterTableAddConstraint(relid,
478505
interpretInhOption(stmt->relation->inhOpt),
479506
(List *) stmt->def);
480507
break;
@@ -483,21 +510,20 @@ ProcessUtility(Node *parsetree,
483510
* Recursively drop constraint from table and,
484511
* if requested, from descendants
485512
*/
486-
AlterTableDropConstraint(RangeVarGetRelid(stmt->relation, false),
513+
AlterTableDropConstraint(relid,
487514
interpretInhOption(stmt->relation->inhOpt),
488515
stmt->name,
489516
stmt->behavior);
490517
break;
491518
case 'E': /* CREATE TOAST TABLE */
492-
AlterTableCreateToastTable(RangeVarGetRelid(stmt->relation, false),
493-
false);
519+
AlterTableCreateToastTable(relid, false);
494520
break;
495521
case 'U': /* ALTER OWNER */
496522
/* check that we are the superuser */
497523
if (!superuser())
498524
elog(ERROR, "ALTER TABLE: permission denied");
499525
/* get_usesysid raises an error if no such user */
500-
AlterTableOwner(RangeVarGetRelid(stmt->relation, false),
526+
AlterTableOwner(relid,
501527
get_usesysid(stmt->name));
502528
break;
503529
default: /* oops */

src/backend/utils/cache/lsyscache.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.71 2002/04/27 03:45:03 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.72 2002/04/30 01:26:26 tgl Exp $
1111
*
1212
* NOTES
1313
* Eventually, the index information should go through here, too.
@@ -708,6 +708,32 @@ get_rel_name(Oid relid)
708708
return NULL;
709709
}
710710

711+
/*
712+
* get_rel_namespace
713+
*
714+
* Returns the pg_namespace OID associated with a given relation.
715+
*/
716+
Oid
717+
get_rel_namespace(Oid relid)
718+
{
719+
HeapTuple tp;
720+
721+
tp = SearchSysCache(RELOID,
722+
ObjectIdGetDatum(relid),
723+
0, 0, 0);
724+
if (HeapTupleIsValid(tp))
725+
{
726+
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
727+
Oid result;
728+
729+
result = reltup->relnamespace;
730+
ReleaseSysCache(tp);
731+
return result;
732+
}
733+
else
734+
return InvalidOid;
735+
}
736+
711737
/*
712738
* get_rel_type_id
713739
*

src/include/utils/lsyscache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: lsyscache.h,v 1.50 2002/04/27 03:45:03 tgl Exp $
9+
* $Id: lsyscache.h,v 1.51 2002/04/30 01:26:26 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -42,6 +42,7 @@ extern Oid get_func_rettype(Oid funcid);
4242
extern char func_volatile(Oid funcid);
4343
extern Oid get_relname_relid(const char *relname, Oid relnamespace);
4444
extern char *get_rel_name(Oid relid);
45+
extern Oid get_rel_namespace(Oid relid);
4546
extern Oid get_rel_type_id(Oid relid);
4647
extern bool get_typisdefined(Oid typid);
4748
extern int16 get_typlen(Oid typid);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy