Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 150841f

Browse files
committed
Protect dblink from invalid options when using postgres_fdw server
When dblink uses a postgres_fdw server name for its connection, it is possible for the connection to have options that are invalid with dblink (e.g. "updatable"). The recommended way to avoid this problem is to use dblink_fdw servers instead. However there are use cases for using postgres_fdw, and possibly other FDWs, for dblink connection options, therefore protect against trying to use any options that do not apply by using is_valid_dblink_option() when building the connection string from the options. Back-patch to 9.3. Although 9.2 supports FDWs for connection info, is_valid_dblink_option() did not yet exist, and neither did postgres_fdw, at least in the postgres source tree. Given the lack of previous complaints, fixing that seems too invasive/not worth it. Author: Corey Huinker Reviewed-By: Joe Conway Discussion: https://postgr.es/m/CADkLM%3DfWyXVEyYcqbcRnxcHutkP45UHU9WD7XpdZaMfe7S%3DRwA%40mail.gmail.com
1 parent 60ad2ff commit 150841f

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

contrib/dblink/dblink.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "access/reloptions.h"
4141
#include "catalog/indexing.h"
4242
#include "catalog/namespace.h"
43+
#include "catalog/pg_foreign_data_wrapper.h"
4344
#include "catalog/pg_foreign_server.h"
4445
#include "catalog/pg_type.h"
4546
#include "catalog/pg_user_mapping.h"
@@ -2727,6 +2728,25 @@ get_connect_string(const char *servername)
27272728
AclResult aclresult;
27282729
char *srvname;
27292730

2731+
static const PQconninfoOption *options = NULL;
2732+
2733+
/*
2734+
* Get list of valid libpq options.
2735+
*
2736+
* To avoid unnecessary work, we get the list once and use it throughout
2737+
* the lifetime of this backend process. We don't need to care about
2738+
* memory context issues, because PQconndefaults allocates with malloc.
2739+
*/
2740+
if (!options)
2741+
{
2742+
options = PQconndefaults();
2743+
if (!options) /* assume reason for failure is OOM */
2744+
ereport(ERROR,
2745+
(errcode(ERRCODE_FDW_OUT_OF_MEMORY),
2746+
errmsg("out of memory"),
2747+
errdetail("could not get libpq's default connection options")));
2748+
}
2749+
27302750
/* first gather the server connstr options */
27312751
srvname = pstrdup(servername);
27322752
truncate_identifier(srvname, strlen(srvname), false);
@@ -2750,25 +2770,28 @@ get_connect_string(const char *servername)
27502770
{
27512771
DefElem *def = lfirst(cell);
27522772

2753-
appendStringInfo(buf, "%s='%s' ", def->defname,
2754-
escape_param_str(strVal(def->arg)));
2773+
if (is_valid_dblink_option(options, def->defname, ForeignDataWrapperRelationId))
2774+
appendStringInfo(buf, "%s='%s' ", def->defname,
2775+
escape_param_str(strVal(def->arg)));
27552776
}
27562777

27572778
foreach(cell, foreign_server->options)
27582779
{
27592780
DefElem *def = lfirst(cell);
27602781

2761-
appendStringInfo(buf, "%s='%s' ", def->defname,
2762-
escape_param_str(strVal(def->arg)));
2782+
if (is_valid_dblink_option(options, def->defname, ForeignServerRelationId))
2783+
appendStringInfo(buf, "%s='%s' ", def->defname,
2784+
escape_param_str(strVal(def->arg)));
27632785
}
27642786

27652787
foreach(cell, user_mapping->options)
27662788
{
27672789

27682790
DefElem *def = lfirst(cell);
27692791

2770-
appendStringInfo(buf, "%s='%s' ", def->defname,
2771-
escape_param_str(strVal(def->arg)));
2792+
if (is_valid_dblink_option(options, def->defname, UserMappingRelationId))
2793+
appendStringInfo(buf, "%s='%s' ", def->defname,
2794+
escape_param_str(strVal(def->arg)));
27722795
}
27732796

27742797
return buf->data;

0 commit comments

Comments
 (0)