From 8bc225e7990a791dadf5f472c01fd9477a80d5db Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 29 Aug 2007 17:24:29 +0000 Subject: [PATCH] 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). --- src/backend/utils/adt/dbsize.c | 57 +++++++++++++--------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index 0681876b3d..3848e8111f 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -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)); } -- 2.40.0