Relax permissions checks on dbsize functions, per discussion. Revert out all

checks for individual-table-size functions, since anyone in the database could
get approximate values from pg_class.relpages anyway.  Allow database-size to
users with CONNECT privilege for the target database (note that this is
granted by default).  Allow tablespace-size if the user has CREATE privilege
on the tablespace (which is *not* granted by default), or if the tablespace is
the default tablespace for the current database (since we treat that as
implicitly allowing use of the tablespace).
This commit is contained in:
Tom Lane 2007-08-29 17:24:29 +00:00
parent 3b5f5d9873
commit 8bc225e799
1 changed files with 21 additions and 36 deletions

View File

@ -5,7 +5,7 @@
* Copyright (c) 2002-2007, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.13 2007/08/27 01:19:14 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.14 2007/08/29 17:24:29 tgl Exp $
*
*/
@ -79,6 +79,13 @@ calculate_database_size(Oid dbOid)
struct dirent *direntry;
char dirpath[MAXPGPATH];
char pathname[MAXPGPATH];
AclResult aclresult;
/* User must have connect privilege for target database */
aclresult = pg_database_aclcheck(dbOid, GetUserId(), ACL_CONNECT);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_DATABASE,
get_database_name(dbOid));
/* Shared storage in pg_global is not counted */
@ -122,10 +129,6 @@ pg_database_size_oid(PG_FUNCTION_ARGS)
{
Oid dbOid = PG_GETARG_OID(0);
if (!pg_database_ownercheck(dbOid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
get_database_name(dbOid));
PG_RETURN_INT64(calculate_database_size(dbOid));
}
@ -141,10 +144,6 @@ pg_database_size_name(PG_FUNCTION_ARGS)
errmsg("database \"%s\" does not exist",
NameStr(*dbName))));
if (!pg_database_ownercheck(dbOid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
NameStr(*dbName));
PG_RETURN_INT64(calculate_database_size(dbOid));
}
@ -160,6 +159,19 @@ calculate_tablespace_size(Oid tblspcOid)
int64 totalsize = 0;
DIR *dirdesc;
struct dirent *direntry;
AclResult aclresult;
/*
* User must have CREATE privilege for target tablespace, either explicitly
* granted or implicitly because it is default for current database.
*/
if (tblspcOid != MyDatabaseTableSpace)
{
aclresult = pg_tablespace_aclcheck(tblspcOid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
get_tablespace_name(tblspcOid));
}
if (tblspcOid == DEFAULTTABLESPACE_OID)
snprintf(tblspcPath, MAXPGPATH, "base");
@ -212,11 +224,6 @@ pg_tablespace_size_oid(PG_FUNCTION_ARGS)
{
Oid tblspcOid = PG_GETARG_OID(0);
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use pg_tablespace_size"))));
PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));
}
@ -226,11 +233,6 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS)
Name tblspcName = PG_GETARG_NAME(0);
Oid tblspcOid = get_tablespace_oid(NameStr(*tblspcName));
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use pg_tablespace_size"))));
if (!OidIsValid(tblspcOid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@ -289,10 +291,6 @@ pg_relation_size_oid(PG_FUNCTION_ARGS)
rel = relation_open(relOid, AccessShareLock);
if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
RelationGetRelationName(rel));
size = calculate_relation_size(&(rel->rd_node));
relation_close(rel, AccessShareLock);
@ -311,10 +309,6 @@ pg_relation_size_name(PG_FUNCTION_ARGS)
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);
if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
RelationGetRelationName(rel));
size = calculate_relation_size(&(rel->rd_node));
relation_close(rel, AccessShareLock);
@ -336,11 +330,6 @@ calculate_total_relation_size(Oid Relid)
ListCell *cell;
heapRel = relation_open(Relid, AccessShareLock);
if (!pg_class_ownercheck(RelationGetRelid(heapRel), GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
RelationGetRelationName(heapRel));
toastOid = heapRel->rd_rel->reltoastrelid;
/* Get the heap size */
@ -380,8 +369,6 @@ pg_total_relation_size_oid(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
/* permission check is inside calculate_total_relation_size */
PG_RETURN_INT64(calculate_total_relation_size(relid));
}
@ -395,8 +382,6 @@ pg_total_relation_size_name(PG_FUNCTION_ARGS)
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
relid = RangeVarGetRelid(relrv, false);
/* permission check is inside calculate_total_relation_size */
PG_RETURN_INT64(calculate_total_relation_size(relid));
}