mirror of
https://github.com/postgres/postgres.git
synced 2025-11-09 06:21:09 +03:00
Change the aclchk.c routines to uniformly use OIDs to identify the
objects to be privilege-checked. Some change in their APIs would be necessary no matter what in the schema environment, and simply getting rid of the name-based interface entirely seems like the best way.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.28 2002/03/06 06:09:28 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.29 2002/03/21 23:27:20 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -200,8 +200,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
|
||||
*/
|
||||
onerel = heap_open(relid, AccessShareLock);
|
||||
|
||||
if (!(pg_ownercheck(GetUserId(), RelationGetRelationName(onerel),
|
||||
RELNAME) ||
|
||||
if (!(pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) ||
|
||||
(is_dbadmin(MyDatabaseId) && !onerel->rd_rel->relisshared)))
|
||||
{
|
||||
/* No need for a WARNING if we already complained during VACUUM */
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.162 2002/03/21 16:00:31 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.163 2002/03/21 23:27:20 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The PerformAddAttribute() code, like most of the relation
|
||||
@@ -327,6 +327,17 @@ AlterTableAddColumn(const char *relationName,
|
||||
char *typename;
|
||||
int attndims;
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
|
||||
/*
|
||||
* permissions checking. this would normally be done in utility.c,
|
||||
* but this particular routine is recursive.
|
||||
@@ -336,20 +347,9 @@ AlterTableAddColumn(const char *relationName,
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
|
||||
myrelid = RelationGetRelid(rel);
|
||||
heap_close(rel, NoLock); /* close rel but keep lock! */
|
||||
|
||||
/*
|
||||
@@ -556,21 +556,19 @@ AlterTableAlterColumnDefault(const char *relationName,
|
||||
int16 attnum;
|
||||
Oid myrelid;
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
#ifndef NO_SECURITY
|
||||
if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
#endif
|
||||
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
|
||||
myrelid = RelationGetRelid(rel);
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
|
||||
heap_close(rel, NoLock);
|
||||
|
||||
/*
|
||||
@@ -730,24 +728,21 @@ AlterTableAlterColumnFlags(const char *relationName,
|
||||
Relation attrelation;
|
||||
HeapTuple tuple;
|
||||
|
||||
/* we allow statistics case for system tables */
|
||||
|
||||
if (*flagType =='M' && !allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
|
||||
#ifndef NO_SECURITY
|
||||
if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
#endif
|
||||
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
|
||||
myrelid = RelationGetRelid(rel);
|
||||
/* we allow statistics case for system tables */
|
||||
if (*flagType == 'M' &&
|
||||
!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
|
||||
heap_close(rel, NoLock); /* close rel, but keep lock! */
|
||||
|
||||
|
||||
@@ -1034,6 +1029,17 @@ AlterTableDropColumn(const char *relationName,
|
||||
if (inh)
|
||||
elog(ERROR, "ALTER TABLE / DROP COLUMN with inherit option is not supported yet");
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
|
||||
/*
|
||||
* permissions checking. this would normally be done in utility.c,
|
||||
* but this particular routine is recursive.
|
||||
@@ -1043,22 +1049,9 @@ AlterTableDropColumn(const char *relationName,
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
#ifndef NO_SECURITY
|
||||
if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
|
||||
myrelid = RelationGetRelid(rel);
|
||||
heap_close(rel, NoLock); /* close rel but keep lock! */
|
||||
|
||||
/*
|
||||
@@ -1180,25 +1173,22 @@ AlterTableAddConstraint(char *relationName,
|
||||
Oid myrelid;
|
||||
List *listptr;
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
#ifndef NO_SECURITY
|
||||
if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
|
||||
myrelid = RelationGetRelid(rel);
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
|
||||
if (inh)
|
||||
{
|
||||
@@ -1496,16 +1486,9 @@ AlterTableDropConstraint(const char *relationName,
|
||||
int behavior)
|
||||
{
|
||||
Relation rel;
|
||||
Oid myrelid;
|
||||
int deleted;
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
#ifndef NO_SECURITY
|
||||
if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We don't support CASCADE yet - in fact, RESTRICT doesn't work to
|
||||
* the spec either!
|
||||
@@ -1517,14 +1500,20 @@ AlterTableDropConstraint(const char *relationName,
|
||||
* Acquire an exclusive lock on the target relation for the duration
|
||||
* of the operation.
|
||||
*/
|
||||
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
|
||||
/* Disallow DROP CONSTRAINT on views, indexes, sequences, etc */
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
|
||||
/*
|
||||
* Since all we have is the name of the constraint, we have to look
|
||||
* through all catalogs that could possibly contain a constraint for
|
||||
@@ -1692,25 +1681,19 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
|
||||
IndexInfo *indexInfo;
|
||||
Oid classObjectId[2];
|
||||
|
||||
/*
|
||||
* permissions checking. XXX exactly what is appropriate here?
|
||||
*/
|
||||
#ifndef NO_SECURITY
|
||||
if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
||||
relationName);
|
||||
|
||||
myrelid = RelationGetRelid(rel);
|
||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
|
||||
/*
|
||||
* lock the pg_class tuple for update (is that really needed?)
|
||||
@@ -1940,20 +1923,32 @@ LockTableCommand(LockStmt *lockstmt)
|
||||
{
|
||||
RangeVar *relation = lfirst(p);
|
||||
char *relname = relation->relname;
|
||||
Oid reloid;
|
||||
int aclresult;
|
||||
Relation rel;
|
||||
|
||||
/*
|
||||
* We don't want to open the relation until we've checked privilege.
|
||||
* So, manually get the relation OID.
|
||||
*/
|
||||
reloid = GetSysCacheOid(RELNAME,
|
||||
PointerGetDatum(relname),
|
||||
0, 0, 0);
|
||||
if (!OidIsValid(reloid))
|
||||
elog(ERROR, "LOCK TABLE: relation \"%s\" does not exist",
|
||||
relname);
|
||||
|
||||
if (lockstmt->mode == AccessShareLock)
|
||||
aclresult = pg_aclcheck(relname, GetUserId(),
|
||||
ACL_SELECT);
|
||||
aclresult = pg_class_aclcheck(reloid, GetUserId(),
|
||||
ACL_SELECT);
|
||||
else
|
||||
aclresult = pg_aclcheck(relname, GetUserId(),
|
||||
ACL_UPDATE | ACL_DELETE);
|
||||
aclresult = pg_class_aclcheck(reloid, GetUserId(),
|
||||
ACL_UPDATE | ACL_DELETE);
|
||||
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
elog(ERROR, "LOCK TABLE: permission denied");
|
||||
|
||||
rel = relation_openr(relname, lockstmt->mode);
|
||||
rel = relation_open(reloid, lockstmt->mode);
|
||||
|
||||
/* Currently, we only allow plain tables to be locked */
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Copyright (c) 1999-2001, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.35 2001/11/02 16:30:29 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.36 2002/03/21 23:27:20 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "catalog/pg_database.h"
|
||||
#include "catalog/pg_description.h"
|
||||
#include "catalog/pg_operator.h"
|
||||
#include "catalog/pg_rewrite.h"
|
||||
#include "catalog/pg_trigger.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/comment.h"
|
||||
@@ -326,11 +327,6 @@ CommentRelation(int reltype, char *relname, char *comment)
|
||||
{
|
||||
Relation relation;
|
||||
|
||||
/* First, check object security */
|
||||
|
||||
if (!pg_ownercheck(GetUserId(), relname, RELNAME))
|
||||
elog(ERROR, "you are not permitted to comment on class '%s'", relname);
|
||||
|
||||
/*
|
||||
* Open the relation. We do this mainly to acquire a lock that
|
||||
* ensures no one else drops the relation before we commit. (If they
|
||||
@@ -339,6 +335,10 @@ CommentRelation(int reltype, char *relname, char *comment)
|
||||
*/
|
||||
relation = relation_openr(relname, AccessShareLock);
|
||||
|
||||
/* Check object security */
|
||||
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
||||
elog(ERROR, "you are not permitted to comment on class '%s'", relname);
|
||||
|
||||
/* Next, verify that the relation type matches the intent */
|
||||
|
||||
switch (reltype)
|
||||
@@ -387,15 +387,15 @@ CommentAttribute(char *relname, char *attrname, char *comment)
|
||||
Relation relation;
|
||||
AttrNumber attnum;
|
||||
|
||||
/* First, check object security */
|
||||
|
||||
if (!pg_ownercheck(GetUserId(), relname, RELNAME))
|
||||
elog(ERROR, "you are not permitted to comment on class '%s'", relname);
|
||||
|
||||
/* Open the containing relation to ensure it won't go away meanwhile */
|
||||
|
||||
relation = heap_openr(relname, AccessShareLock);
|
||||
|
||||
/* Check object security */
|
||||
|
||||
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
||||
elog(ERROR, "you are not permitted to comment on class '%s'", relname);
|
||||
|
||||
/* Now, fetch the attribute number from the system cache */
|
||||
|
||||
attnum = get_attnum(RelationGetRelid(relation), attrname);
|
||||
@@ -476,27 +476,32 @@ CommentDatabase(char *database, char *comment)
|
||||
static void
|
||||
CommentRewrite(char *rule, char *comment)
|
||||
{
|
||||
Oid oid;
|
||||
HeapTuple tuple;
|
||||
Oid reloid;
|
||||
Oid ruleoid;
|
||||
Oid classoid;
|
||||
char *relation;
|
||||
int aclcheck;
|
||||
int32 aclcheck;
|
||||
|
||||
/* First, validate user */
|
||||
/* Find the rule's pg_rewrite tuple, get its OID and its table's OID */
|
||||
|
||||
relation = RewriteGetRuleEventRel(rule);
|
||||
aclcheck = pg_aclcheck(relation, GetUserId(), ACL_RULE);
|
||||
tuple = SearchSysCache(RULENAME,
|
||||
PointerGetDatum(rule),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "rule '%s' does not exist", rule);
|
||||
|
||||
reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
|
||||
ruleoid = tuple->t_data->t_oid;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
/* Check object security */
|
||||
|
||||
aclcheck = pg_class_aclcheck(reloid, GetUserId(), ACL_RULE);
|
||||
if (aclcheck != ACLCHECK_OK)
|
||||
elog(ERROR, "you are not permitted to comment on rule '%s'",
|
||||
rule);
|
||||
|
||||
/* Next, find the rule's oid */
|
||||
|
||||
oid = GetSysCacheOid(RULENAME,
|
||||
PointerGetDatum(rule),
|
||||
0, 0, 0);
|
||||
if (!OidIsValid(oid))
|
||||
elog(ERROR, "rule '%s' does not exist", rule);
|
||||
|
||||
/* pg_rewrite doesn't have a hard-coded OID, so must look it up */
|
||||
|
||||
classoid = GetSysCacheOid(RELNAME,
|
||||
@@ -506,7 +511,7 @@ CommentRewrite(char *rule, char *comment)
|
||||
|
||||
/* Call CreateComments() to create/drop the comments */
|
||||
|
||||
CreateComments(oid, classoid, 0, comment);
|
||||
CreateComments(ruleoid, classoid, 0, comment);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
@@ -525,13 +530,7 @@ CommentType(char *type, char *comment)
|
||||
{
|
||||
Oid oid;
|
||||
|
||||
/* First, validate user */
|
||||
|
||||
if (!pg_ownercheck(GetUserId(), type, TYPENAME))
|
||||
elog(ERROR, "you are not permitted to comment on type '%s'",
|
||||
type);
|
||||
|
||||
/* Next, find the type's oid */
|
||||
/* Find the type's oid */
|
||||
|
||||
oid = GetSysCacheOid(TYPENAME,
|
||||
PointerGetDatum(type),
|
||||
@@ -539,6 +538,12 @@ CommentType(char *type, char *comment)
|
||||
if (!OidIsValid(oid))
|
||||
elog(ERROR, "type '%s' does not exist", type);
|
||||
|
||||
/* Check object security */
|
||||
|
||||
if (!pg_type_ownercheck(oid, GetUserId()))
|
||||
elog(ERROR, "you are not permitted to comment on type '%s'",
|
||||
type);
|
||||
|
||||
/* Call CreateComments() to create/drop the comments */
|
||||
|
||||
CreateComments(oid, RelOid_pg_type, 0, comment);
|
||||
@@ -576,18 +581,6 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
|
||||
else
|
||||
baseoid = InvalidOid;
|
||||
|
||||
/* Next, validate the user's attempt to comment */
|
||||
|
||||
if (!pg_aggr_ownercheck(GetUserId(), aggregate, baseoid))
|
||||
{
|
||||
if (baseoid == InvalidOid)
|
||||
elog(ERROR, "you are not permitted to comment on aggregate '%s' for all types",
|
||||
aggregate);
|
||||
else
|
||||
elog(ERROR, "you are not permitted to comment on aggregate '%s' for type %s",
|
||||
aggregate, format_type_be(baseoid));
|
||||
}
|
||||
|
||||
/* Now, attempt to find the actual tuple in pg_aggregate */
|
||||
|
||||
oid = GetSysCacheOid(AGGNAME,
|
||||
@@ -597,6 +590,18 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
|
||||
if (!OidIsValid(oid))
|
||||
agg_error("CommentAggregate", aggregate, baseoid);
|
||||
|
||||
/* Next, validate the user's attempt to comment */
|
||||
|
||||
if (!pg_aggr_ownercheck(oid, GetUserId()))
|
||||
{
|
||||
if (baseoid == InvalidOid)
|
||||
elog(ERROR, "you are not permitted to comment on aggregate '%s' for all types",
|
||||
aggregate);
|
||||
else
|
||||
elog(ERROR, "you are not permitted to comment on aggregate '%s' for type %s",
|
||||
aggregate, format_type_be(baseoid));
|
||||
}
|
||||
|
||||
/* pg_aggregate doesn't have a hard-coded OID, so must look it up */
|
||||
|
||||
classoid = GetSysCacheOid(RELNAME,
|
||||
@@ -654,12 +659,6 @@ CommentProc(char *function, List *arguments, char *comment)
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, validate the user's ability to comment on this function */
|
||||
|
||||
if (!pg_func_ownercheck(GetUserId(), function, argcount, argoids))
|
||||
elog(ERROR, "you are not permitted to comment on function '%s'",
|
||||
function);
|
||||
|
||||
/* Now, find the corresponding oid for this procedure */
|
||||
|
||||
oid = GetSysCacheOid(PROCNAME,
|
||||
@@ -670,6 +669,12 @@ CommentProc(char *function, List *arguments, char *comment)
|
||||
if (!OidIsValid(oid))
|
||||
func_error("CommentProc", function, argcount, argoids, NULL);
|
||||
|
||||
/* Now, validate the user's ability to comment on this function */
|
||||
|
||||
if (!pg_proc_ownercheck(oid, GetUserId()))
|
||||
elog(ERROR, "you are not permitted to comment on function '%s'",
|
||||
function);
|
||||
|
||||
/* Call CreateComments() to create/drop the comments */
|
||||
|
||||
CreateComments(oid, RelOid_pg_proc, 0, comment);
|
||||
@@ -757,7 +762,7 @@ CommentOperator(char *opername, List *arguments, char *comment)
|
||||
|
||||
/* Valid user's ability to comment on this operator */
|
||||
|
||||
if (!pg_oper_ownercheck(GetUserId(), oid))
|
||||
if (!pg_oper_ownercheck(oid, GetUserId()))
|
||||
elog(ERROR, "you are not permitted to comment on operator '%s'",
|
||||
opername);
|
||||
|
||||
@@ -798,13 +803,14 @@ CommentTrigger(char *trigger, char *relname, char *comment)
|
||||
|
||||
/* First, validate the user's action */
|
||||
|
||||
if (!pg_ownercheck(GetUserId(), relname, RELNAME))
|
||||
relation = heap_openr(relname, AccessShareLock);
|
||||
|
||||
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
||||
elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'",
|
||||
trigger, "defined for relation", relname);
|
||||
|
||||
/* Now, fetch the trigger oid from pg_trigger */
|
||||
/* Fetch the trigger oid from pg_trigger */
|
||||
|
||||
relation = heap_openr(relname, AccessShareLock);
|
||||
pg_trigger = heap_openr(TriggerRelationName, AccessShareLock);
|
||||
ScanKeyEntryInitialize(&entry[0], 0x0, Anum_pg_trigger_tgrelid,
|
||||
F_OIDEQ,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.150 2002/03/06 06:09:30 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.151 2002/03/21 23:27:20 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -266,16 +266,20 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
|
||||
FILE *fp;
|
||||
Relation rel;
|
||||
const AclMode required_access = (from ? ACL_INSERT : ACL_SELECT);
|
||||
int result;
|
||||
int32 aclresult;
|
||||
|
||||
/*
|
||||
* Open and lock the relation, using the appropriate lock type.
|
||||
*/
|
||||
rel = heap_openr(relname, (from ? RowExclusiveLock : AccessShareLock));
|
||||
|
||||
result = pg_aclcheck(relname, GetUserId(), required_access);
|
||||
if (result != ACLCHECK_OK)
|
||||
elog(ERROR, "%s: %s", relname, aclcheck_error_strings[result]);
|
||||
/* Check permissions. */
|
||||
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
|
||||
required_access);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
elog(ERROR, "%s: %s",
|
||||
RelationGetRelationName(rel),
|
||||
aclcheck_error_strings[aclresult]);
|
||||
if (!pipe && !superuser())
|
||||
elog(ERROR, "You must have Postgres superuser privilege to do a COPY "
|
||||
"directly to or from a file. Anyone can COPY to stdout or "
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.89 2002/03/21 16:00:31 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.90 2002/03/21 23:27:20 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -247,13 +247,6 @@ TruncateRelation(const char *relname)
|
||||
|
||||
AssertArg(relname);
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relname))
|
||||
elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
|
||||
relname);
|
||||
|
||||
if (!pg_ownercheck(GetUserId(), relname, RELNAME))
|
||||
elog(ERROR, "you do not own relation \"%s\"", relname);
|
||||
|
||||
/* Grab exclusive lock in preparation for truncate */
|
||||
rel = heap_openr(relname, AccessExclusiveLock);
|
||||
|
||||
@@ -265,6 +258,13 @@ TruncateRelation(const char *relname)
|
||||
elog(ERROR, "TRUNCATE cannot be used on views. '%s' is a view",
|
||||
relname);
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relname))
|
||||
elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
|
||||
relname);
|
||||
|
||||
if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
|
||||
elog(ERROR, "you do not own relation \"%s\"", relname);
|
||||
|
||||
/* Keep the lock until transaction commit */
|
||||
heap_close(rel, NoLock);
|
||||
|
||||
@@ -458,7 +458,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
|
||||
* We should have an UNDER permission flag for this, but for now,
|
||||
* demand that creator of a child table own the parent.
|
||||
*/
|
||||
if (!pg_ownercheck(GetUserId(), name, RELNAME))
|
||||
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
||||
elog(ERROR, "you do not own table \"%s\"", name);
|
||||
|
||||
parentOids = lappendi(parentOids, relation->rd_id);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.70 2002/03/20 19:43:49 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.71 2002/03/21 23:27:21 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -84,7 +84,7 @@ RemoveOperator(char *operatorName, /* operator name */
|
||||
|
||||
if (HeapTupleIsValid(tup))
|
||||
{
|
||||
if (!pg_oper_ownercheck(GetUserId(), tup->t_data->t_oid))
|
||||
if (!pg_oper_ownercheck(tup->t_data->t_oid, GetUserId()))
|
||||
elog(ERROR, "RemoveOperator: operator '%s': permission denied",
|
||||
operatorName);
|
||||
|
||||
@@ -92,7 +92,6 @@ RemoveOperator(char *operatorName, /* operator name */
|
||||
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
|
||||
|
||||
simple_heap_delete(relation, &tup->t_self);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -242,10 +241,6 @@ RemoveType(char *typeName) /* type name to be removed */
|
||||
HeapTuple tup;
|
||||
char *shadow_type;
|
||||
|
||||
if (!pg_ownercheck(GetUserId(), typeName, TYPENAME))
|
||||
elog(ERROR, "RemoveType: type '%s': permission denied",
|
||||
typeName);
|
||||
|
||||
relation = heap_openr(TypeRelationName, RowExclusiveLock);
|
||||
|
||||
tup = SearchSysCache(TYPENAME,
|
||||
@@ -254,6 +249,10 @@ RemoveType(char *typeName) /* type name to be removed */
|
||||
if (!HeapTupleIsValid(tup))
|
||||
elog(ERROR, "RemoveType: type '%s' does not exist", typeName);
|
||||
|
||||
if (!pg_type_ownercheck(tup->t_data->t_oid, GetUserId()))
|
||||
elog(ERROR, "RemoveType: type '%s': permission denied",
|
||||
typeName);
|
||||
|
||||
/* Delete any comments associated with this type */
|
||||
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
|
||||
|
||||
@@ -288,10 +287,9 @@ RemoveDomain(char *domainName, int behavior)
|
||||
HeapTuple tup;
|
||||
char typtype;
|
||||
|
||||
/* Domains are stored as types. Check for permissions on the type */
|
||||
if (!pg_ownercheck(GetUserId(), domainName, TYPENAME))
|
||||
elog(ERROR, "RemoveDomain: type '%s': permission denied",
|
||||
domainName);
|
||||
/* CASCADE unsupported */
|
||||
if (behavior == CASCADE)
|
||||
elog(ERROR, "DROP DOMAIN does not support the CASCADE keyword");
|
||||
|
||||
relation = heap_openr(TypeRelationName, RowExclusiveLock);
|
||||
|
||||
@@ -301,17 +299,16 @@ RemoveDomain(char *domainName, int behavior)
|
||||
if (!HeapTupleIsValid(tup))
|
||||
elog(ERROR, "RemoveType: type '%s' does not exist", domainName);
|
||||
|
||||
if (!pg_type_ownercheck(tup->t_data->t_oid, GetUserId()))
|
||||
elog(ERROR, "RemoveDomain: type '%s': permission denied",
|
||||
domainName);
|
||||
|
||||
/* Check that this is actually a domain */
|
||||
typtype = ((Form_pg_type) GETSTRUCT(tup))->typtype;
|
||||
|
||||
if (typtype != 'd')
|
||||
elog(ERROR, "%s is not a domain", domainName);
|
||||
|
||||
/* CASCADE unsupported */
|
||||
if (behavior == CASCADE) {
|
||||
elog(ERROR, "DROP DOMAIN does not support the CASCADE keyword");
|
||||
}
|
||||
|
||||
/* Delete any comments associated with this type */
|
||||
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
|
||||
|
||||
@@ -364,12 +361,6 @@ RemoveFunction(char *functionName, /* function name to be removed */
|
||||
}
|
||||
}
|
||||
|
||||
if (!pg_func_ownercheck(GetUserId(), functionName, nargs, argList))
|
||||
{
|
||||
elog(ERROR, "RemoveFunction: function '%s': permission denied",
|
||||
functionName);
|
||||
}
|
||||
|
||||
relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
|
||||
|
||||
tup = SearchSysCache(PROCNAME,
|
||||
@@ -381,6 +372,10 @@ RemoveFunction(char *functionName, /* function name to be removed */
|
||||
if (!HeapTupleIsValid(tup))
|
||||
func_error("RemoveFunction", functionName, nargs, argList, NULL);
|
||||
|
||||
if (!pg_proc_ownercheck(tup->t_data->t_oid, GetUserId()))
|
||||
elog(ERROR, "RemoveFunction: function '%s': permission denied",
|
||||
functionName);
|
||||
|
||||
if (((Form_pg_proc) GETSTRUCT(tup))->prolang == INTERNALlanguageId)
|
||||
{
|
||||
/* "Helpful" WARNING when removing a builtin function ... */
|
||||
@@ -423,16 +418,6 @@ RemoveAggregate(char *aggName, char *aggType)
|
||||
else
|
||||
basetypeID = InvalidOid;
|
||||
|
||||
if (!pg_aggr_ownercheck(GetUserId(), aggName, basetypeID))
|
||||
{
|
||||
if (basetypeID == InvalidOid)
|
||||
elog(ERROR, "RemoveAggregate: aggregate '%s' for all types: permission denied",
|
||||
aggName);
|
||||
else
|
||||
elog(ERROR, "RemoveAggregate: aggregate '%s' for type %s: permission denied",
|
||||
aggName, format_type_be(basetypeID));
|
||||
}
|
||||
|
||||
relation = heap_openr(AggregateRelationName, RowExclusiveLock);
|
||||
|
||||
tup = SearchSysCache(AGGNAME,
|
||||
@@ -443,6 +428,16 @@ RemoveAggregate(char *aggName, char *aggType)
|
||||
if (!HeapTupleIsValid(tup))
|
||||
agg_error("RemoveAggregate", aggName, basetypeID);
|
||||
|
||||
if (!pg_aggr_ownercheck(tup->t_data->t_oid, GetUserId()))
|
||||
{
|
||||
if (basetypeID == InvalidOid)
|
||||
elog(ERROR, "RemoveAggregate: aggregate '%s' for all types: permission denied",
|
||||
aggName);
|
||||
else
|
||||
elog(ERROR, "RemoveAggregate: aggregate '%s' for type %s: permission denied",
|
||||
aggName, format_type_be(basetypeID));
|
||||
}
|
||||
|
||||
/* Remove any comments related to this aggregate */
|
||||
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.63 2001/11/12 01:34:50 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.64 2002/03/21 23:27:21 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -81,6 +81,13 @@ renameatt(char *relname,
|
||||
List *indexoidlist;
|
||||
List *indexoidscan;
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
targetrelation = heap_openr(relname, AccessExclusiveLock);
|
||||
relid = RelationGetRelid(targetrelation);
|
||||
|
||||
/*
|
||||
* permissions checking. this would normally be done in utility.c,
|
||||
* but this particular routine is recursive.
|
||||
@@ -90,18 +97,10 @@ renameatt(char *relname,
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relname))
|
||||
elog(ERROR, "renameatt: class \"%s\" is a system catalog",
|
||||
relname);
|
||||
if (!IsBootstrapProcessingMode() &&
|
||||
!pg_ownercheck(GetUserId(), relname, RELNAME))
|
||||
if (!pg_class_ownercheck(relid, GetUserId()))
|
||||
elog(ERROR, "renameatt: you do not own class \"%s\"",
|
||||
relname);
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
targetrelation = heap_openr(relname, AccessExclusiveLock);
|
||||
relid = RelationGetRelid(targetrelation);
|
||||
|
||||
/*
|
||||
* if the 'recurse' flag is set then we are supposed to rename this
|
||||
* attribute in all classes that inherit from 'relname' (as well as in
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.72 2002/03/21 16:00:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.73 2002/03/21 23:27:21 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -299,13 +299,13 @@ nextval(PG_FUNCTION_ARGS)
|
||||
rescnt = 0;
|
||||
bool logit = false;
|
||||
|
||||
if (pg_aclcheck(seqname, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
|
||||
elog(ERROR, "%s.nextval: you don't have permissions to set sequence %s",
|
||||
seqname, seqname);
|
||||
|
||||
/* open and AccessShareLock sequence */
|
||||
elm = init_sequence("nextval", seqname);
|
||||
|
||||
if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
|
||||
elog(ERROR, "%s.nextval: you don't have permissions to set sequence %s",
|
||||
seqname, seqname);
|
||||
|
||||
pfree(seqname);
|
||||
|
||||
if (elm->last != elm->cached) /* some numbers were cached */
|
||||
@@ -466,13 +466,13 @@ currval(PG_FUNCTION_ARGS)
|
||||
SeqTable elm;
|
||||
int64 result;
|
||||
|
||||
if (pg_aclcheck(seqname, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
|
||||
elog(ERROR, "%s.currval: you don't have permissions to read sequence %s",
|
||||
seqname, seqname);
|
||||
|
||||
/* open and AccessShareLock sequence */
|
||||
elm = init_sequence("currval", seqname);
|
||||
|
||||
if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
|
||||
elog(ERROR, "%s.currval: you don't have permissions to read sequence %s",
|
||||
seqname, seqname);
|
||||
|
||||
if (elm->increment == 0) /* nextval/read_info were not called */
|
||||
elog(ERROR, "%s.currval is not yet defined in this session",
|
||||
seqname);
|
||||
@@ -504,14 +504,15 @@ do_setval(char *seqname, int64 next, bool iscalled)
|
||||
Buffer buf;
|
||||
Form_pg_sequence seq;
|
||||
|
||||
if (pg_aclcheck(seqname, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
|
||||
/* open and AccessShareLock sequence */
|
||||
elm = init_sequence("setval", seqname);
|
||||
|
||||
if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
|
||||
elog(ERROR, "%s.setval: you don't have permissions to set sequence %s",
|
||||
seqname, seqname);
|
||||
|
||||
/* open and AccessShareLock sequence */
|
||||
elm = init_sequence("setval", seqname);
|
||||
seq = read_info("setval", elm, &buf); /* lock page' buffer and
|
||||
* read tuple */
|
||||
/* lock page' buffer and read tuple */
|
||||
seq = read_info("setval", elm, &buf);
|
||||
|
||||
if ((next < seq->min_value) || (next > seq->max_value))
|
||||
elog(ERROR, "%s.setval: value " INT64_FORMAT " is out of bounds (" INT64_FORMAT "," INT64_FORMAT ")",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.106 2002/03/21 16:00:34 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.107 2002/03/21 23:27:22 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -71,12 +71,18 @@ CreateTrigger(CreateTrigStmt *stmt)
|
||||
char *constrname = "";
|
||||
Oid constrrelid = InvalidOid;
|
||||
|
||||
rel = heap_openr(stmt->relation->relname, AccessExclusiveLock);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "CreateTrigger: relation \"%s\" is not a table",
|
||||
stmt->relation->relname);
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(stmt->relation->relname))
|
||||
elog(ERROR, "CreateTrigger: can't create trigger for system relation %s",
|
||||
stmt->relation->relname);
|
||||
|
||||
if (pg_aclcheck(stmt->relation->relname, GetUserId(),
|
||||
stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER)
|
||||
if (pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
|
||||
stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER)
|
||||
!= ACLCHECK_OK)
|
||||
elog(ERROR, "permission denied");
|
||||
|
||||
@@ -98,18 +104,14 @@ CreateTrigger(CreateTrigStmt *stmt)
|
||||
* NoLock is probably sufficient here, since we're only
|
||||
* interested in getting the relation's OID...
|
||||
*/
|
||||
rel = heap_openr(stmt->constrrel->relname, NoLock);
|
||||
constrrelid = rel->rd_id;
|
||||
heap_close(rel, NoLock);
|
||||
Relation conrel;
|
||||
|
||||
conrel = heap_openr(stmt->constrrel->relname, NoLock);
|
||||
constrrelid = conrel->rd_id;
|
||||
heap_close(conrel, NoLock);
|
||||
}
|
||||
}
|
||||
|
||||
rel = heap_openr(stmt->relation->relname, AccessExclusiveLock);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "CreateTrigger: relation \"%s\" is not a table",
|
||||
stmt->relation->relname);
|
||||
|
||||
TRIGGER_CLEAR_TYPE(tgtype);
|
||||
if (stmt->before)
|
||||
TRIGGER_SETT_BEFORE(tgtype);
|
||||
@@ -321,20 +323,20 @@ DropTrigger(DropTrigStmt *stmt)
|
||||
int found = 0;
|
||||
int tgfound = 0;
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(stmt->relation->relname))
|
||||
elog(ERROR, "DropTrigger: can't drop trigger for system relation %s",
|
||||
stmt->relation->relname);
|
||||
|
||||
if (!pg_ownercheck(GetUserId(), stmt->relation->relname, RELNAME))
|
||||
elog(ERROR, "%s: %s", stmt->relation->relname,
|
||||
aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
|
||||
|
||||
rel = heap_openr(stmt->relation->relname, AccessExclusiveLock);
|
||||
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
elog(ERROR, "DropTrigger: relation \"%s\" is not a table",
|
||||
stmt->relation->relname);
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(stmt->relation->relname))
|
||||
elog(ERROR, "DropTrigger: can't drop trigger for system relation %s",
|
||||
stmt->relation->relname);
|
||||
|
||||
if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
|
||||
elog(ERROR, "%s: %s", stmt->relation->relname,
|
||||
aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
|
||||
|
||||
/*
|
||||
* Search pg_trigger, delete target trigger, count remaining triggers
|
||||
* for relation. Note this is OK only because we have
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.218 2002/03/21 16:00:35 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.219 2002/03/21 23:27:22 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -714,15 +714,14 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt)
|
||||
*
|
||||
* We allow the user to vacuum a table if he is superuser, the table
|
||||
* owner, or the database owner (but in the latter case, only if it's
|
||||
* not a shared relation). pg_ownercheck includes the superuser case.
|
||||
* not a shared relation). pg_class_ownercheck includes the superuser case.
|
||||
*
|
||||
* Note we choose to treat permissions failure as a WARNING and keep
|
||||
* trying to vacuum the rest of the DB --- is this appropriate?
|
||||
*/
|
||||
onerel = heap_open(relid, lmode);
|
||||
|
||||
if (!(pg_ownercheck(GetUserId(), RelationGetRelationName(onerel),
|
||||
RELNAME) ||
|
||||
if (!(pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) ||
|
||||
(is_dbadmin(MyDatabaseId) && !onerel->rd_rel->relisshared)))
|
||||
{
|
||||
elog(WARNING, "Skipping \"%s\" --- only table or database owner can VACUUM it",
|
||||
|
||||
Reference in New Issue
Block a user