diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 3ac47ce3e0e..c631c1aefcc 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -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);
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 dblink_fdw has an additional
Boolean option use_scram_passthrough that controls
whether dblink will use the SCRAM pass-through
- authentication to connect to the remote database. With SCRAM pass-through
- authentication, dblink 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,
+ dblink 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 use_scram_passthrough
option of postgres_fdw for further details and restrictions.