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.