From c9b299f6df983ff3b196677a625393c31598d86f Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Tue, 14 Oct 2025 12:20:48 -0500 Subject: [PATCH] dblink: Avoid locking relation before privilege check. The present coding of dblink's get_rel_from_relname() predates the introduction of RangeVarGetRelidExtended(), which provides a way to check permissions before locking the relation. This commit adjusts get_rel_from_relname() to use that function. Reviewed-by: Jeff Davis Discussion: https://postgr.es/m/aOgmi6avE6qMw_6t%40nathan --- contrib/dblink/dblink.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c index 0cf4c27f2e9..1e7696beb50 100644 --- a/contrib/dblink/dblink.c +++ b/contrib/dblink/dblink.c @@ -2460,6 +2460,21 @@ get_tuple_of_interest(Relation rel, int *pkattnums, int pknumatts, char **src_pk return NULL; } +static void +RangeVarCallbackForDblink(const RangeVar *relation, + Oid relId, Oid oldRelId, void *arg) +{ + AclResult aclresult; + + if (!OidIsValid(relId)) + return; + + aclresult = pg_class_aclcheck(relId, GetUserId(), *((AclMode *) arg)); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, get_relkind_objtype(get_rel_relkind(relId)), + relation->relname); +} + /* * Open the relation named by relname_text, acquire specified type of lock, * verify we have specified permissions. @@ -2469,19 +2484,13 @@ static Relation get_rel_from_relname(text *relname_text, LOCKMODE lockmode, AclMode aclmode) { RangeVar *relvar; - Relation rel; - AclResult aclresult; + Oid relid; relvar = makeRangeVarFromNameList(textToQualifiedNameList(relname_text)); - rel = table_openrv(relvar, lockmode); + relid = RangeVarGetRelidExtended(relvar, lockmode, 0, + RangeVarCallbackForDblink, &aclmode); - aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), - aclmode); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind), - RelationGetRelationName(rel)); - - return rel; + return table_open(relid, NoLock); } /*