Commit 8bc225e7 authored by Tom Lane's avatar Tom Lane

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).
parent 3b5f5d98
......@@ -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));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment