v1-0002-dblink-Allow-user-mapping-to-override-use_scram_p.patch
text/plain
Filename: v1-0002-dblink-Allow-user-mapping-to-override-use_scram_p.patch
Type: text/plain
Part: 1
From 7bbb36ef312f1d5de780268b3ccb16e50e98d2ce Mon Sep 17 00:00:00 2001
From: Matheus Alcantara <mths.dev@pm.me>
Date: Thu, 14 May 2026 17:08:24 -0300
Subject: [PATCH v1 2/2] dblink: Allow user mapping to override
use_scram_passthrough
Previously, use_scram_passthrough was checked on the foreign server
options first, which meant that if set on the server, the user mapping
option would be ignored. This changes the precedence to check the user
mapping option first, allowing users to override the server-level
setting on a per-user basis.
This is consistent with how postgres_fdw handles this option and how
other connection options like sslcert and sslkey work, where user
mapping settings take precedence over server settings.
Also add a test case to verify that setting use_scram_passthrough=false
on a user mapping correctly disables SCRAM passthrough even when the
server has it enabled.
Discussion: https://www.postgresql.org/message-id/CAHGQGwEJ8rZjmbOvCicyr4vbuLio082bNTde0WNoSWaWr9wVcg%40mail.gmail.com
---
contrib/dblink/dblink.c | 4 ++--
contrib/dblink/t/001_auth_scram.pl | 24 ++++++++++++++++++++++++
doc/src/sgml/dblink.sgml | 10 ++++++----
3 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index d843eee7e97..01894e7a556 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -3235,7 +3235,7 @@ UseScramPassthrough(ForeignServer *foreign_server, UserMapping *user)
{
ListCell *cell;
- foreach(cell, foreign_server->options)
+ foreach(cell, user->options)
{
DefElem *def = lfirst(cell);
@@ -3243,7 +3243,7 @@ UseScramPassthrough(ForeignServer *foreign_server, UserMapping *user)
return defGetBoolean(def);
}
- foreach(cell, user->options)
+ foreach(cell, foreign_server->options)
{
DefElem *def = (DefElem *) lfirst(cell);
diff --git a/contrib/dblink/t/001_auth_scram.pl b/contrib/dblink/t/001_auth_scram.pl
index 9558ca83b7c..b087b38e5a5 100644
--- a/contrib/dblink/t/001_auth_scram.pl
+++ b/contrib/dblink/t/001_auth_scram.pl
@@ -24,6 +24,7 @@ my $db1 = "db1"; # For node1
my $db2 = "db2"; # For node2
my $fdw_server = "db1_fdw";
my $fdw_server2 = "db2_fdw";
+my $fdw_server3 = "db1_fdw_override";
my $fdw_invalid_server = "db2_fdw_invalid"; # For invalid fdw options
my $fdw_invalid_server2 =
"db2_fdw_invalid2"; # For invalid scram keys fdw options
@@ -55,10 +56,12 @@ setup_fdw_server($node1, $db0, $fdw_server, $node1, $db1);
setup_fdw_server($node1, $db0, $fdw_server2, $node2, $db2);
setup_invalid_fdw_server($node1, $db0, $fdw_invalid_server, $node2, $db2);
setup_fdw_server($node1, $db0, $fdw_invalid_server2, $node2, $db2);
+setup_fdw_server($node1, $db0, $fdw_server3, $node1, $db1);
setup_user_mapping($node1, $db0, $fdw_server);
setup_user_mapping($node1, $db0, $fdw_server2);
setup_user_mapping($node1, $db0, $fdw_invalid_server);
+setup_user_mapping($node1, $db0, $fdw_server3);
# Make the user have the same SCRAM key on both servers. Forcing to have the
# same iteration and salt.
@@ -96,6 +99,27 @@ test_fdw_auth($node1, $db0, "t2", $fdw_server2,
test_fdw_auth_with_invalid_overwritten_require_auth($fdw_invalid_server);
+# Test that use_scram_passthrough=false on user mapping overrides server setting
+{
+ my $connstr = $node1->connstr($db0) . qq' user=$user';
+
+ $node1->safe_psql($db0,
+ qq'ALTER USER MAPPING FOR $user SERVER $fdw_server3 OPTIONS(add use_scram_passthrough \'false\')',
+ connstr => $connstr
+ );
+
+ my ($ret, $stdout, $stderr) = $node1->psql(
+ $db0,
+ "select * from dblink('$fdw_server3', 'select * from t') as t(a int, b int)",
+ connstr => $connstr);
+
+ is($ret, 3, 'SCRAM passthrough disabled on user mapping should fail');
+ like(
+ $stderr,
+ qr/password/i,
+ 'expected password-related error when scram passthrough disabled on user mapping');
+}
+
# Ensure that trust connections fail without superuser opt-in.
unlink($node1->data_dir . '/pg_hba.conf');
unlink($node2->data_dir . '/pg_hba.conf');
diff --git a/doc/src/sgml/dblink.sgml b/doc/src/sgml/dblink.sgml
index dd6778d22a8..fc496b74288 100644
--- a/doc/src/sgml/dblink.sgml
+++ b/doc/src/sgml/dblink.sgml
@@ -154,10 +154,12 @@ dblink_connect(text connname, text connstr) returns text
The foreign-data wrapper <filename>dblink_fdw</filename> has an additional
Boolean option <literal>use_scram_passthrough</literal> that controls
whether <filename>dblink</filename> will use the SCRAM pass-through
- authentication to connect to the remote database. With SCRAM pass-through
- authentication, <filename>dblink</filename> uses SCRAM-hashed secrets
- instead of plain-text user passwords to connect to the remote server. This
- avoids storing plain-text user passwords in PostgreSQL system catalogs.
+ authentication to connect to the remote database. It can be specified
+ for a foreign server or a user mapping. A user mapping setting overrides
+ the foreign server setting. With SCRAM pass-through authentication,
+ <filename>dblink</filename> uses SCRAM-hashed secrets instead of plain-text
+ user passwords to connect to the remote server. This avoids storing
+ plain-text user passwords in PostgreSQL system catalogs.
See the documentation of the equivalent <link
linkend="postgres-fdw-option-use-scram-passthrough"><literal>use_scram_passthrough</literal></link>
option of postgres_fdw for further details and restrictions.
--
2.53.0