dblink: Give user mapping precedence for use_scram_passthrough

Commit 97f6fc10ff changed postgres_fdw so that user-mapping settings
override foreign server settings for use_scram_passthrough. This commit
applies the same behavior to dblink.

Backpatch to v18, where use_scram_passthrough was introduced.

Author: Matheus Alcantara <matheusssilv97@gmail.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/CAHGQGwEJ8rZjmbOvCicyr4vbuLio082bNTde0WNoSWaWr9wVcg@mail.gmail.com
Backpatch-through: 18
This commit is contained in:
Fujii Masao 2026-05-26 00:51:18 +09:00
parent 97f6fc10ff
commit 5f5165e2fe
3 changed files with 38 additions and 6 deletions

View file

@ -3231,12 +3231,18 @@ appendSCRAMKeysInfo(StringInfo buf)
}
/*
* Return whether SCRAM pass-through is enabled.
*
* If use_scram_passthrough is specified in both the foreign server
* and the user mapping, the user mapping setting takes precedence.
*/
static bool
UseScramPassthrough(ForeignServer *foreign_server, UserMapping *user)
{
ListCell *cell;
foreach(cell, foreign_server->options)
foreach(cell, user->options)
{
DefElem *def = lfirst(cell);
@ -3244,7 +3250,7 @@ UseScramPassthrough(ForeignServer *foreign_server, UserMapping *user)
return defGetBoolean(def);
}
foreach(cell, user->options)
foreach(cell, foreign_server->options)
{
DefElem *def = (DefElem *) lfirst(cell);

View file

@ -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');

View file

@ -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.