On Tue, Mar 18, 2025 at 12:32 PM Peter Eisentraut <[email protected]> wrote:
> Yeah, I think option (2) is enough for now. If someone wants to enable
> the kinds of things you describe, they can always come back and
> implement option (1) later.
Sounds good to me.
--
Notes on v8:
- The following documentation pieces need to be adjusted, now that
we've decided that `use_scram_passthrough` will enforce
`require_auth=scram-sha-256`:
> + The remote server must request SCRAM authentication. (If desired,
> + enforce this on the client side (FDW side) with the option
> + <literal>require_auth</literal>.) If another authentication method is
> + requested by the server, then that one will be used normally.
and
> + The user mapping password is not used. (It could be set to support
> other
> + authentication methods, but that would arguably violate the point of
> this
> + feature, which is to avoid storing plain-text passwords.)
I think they should just be reduced to "The remote server must request
SCRAM authentication." and "The user mapping password is not used."
- In get_connect_string():
> + /* first gather the server connstr options */
> + Oid serverid = foreign_server->serverid;
I think this comment belongs elsewhere (connect_pg_server) and should
be deleted from this block.
- Sorry for not realizing this before now, but I couldn't figure out
why connect_pg_server() took the rconn pointer, and it turns out it
just passes it along to dblink_security_check(), which pfree's it
before throwing an error. So that will double-free with the current
refactoring patch (and I'm not sure why assertions aren't catching
that?).
I thought for sure this inconsistency would be a problem on HEAD, but
it turns out that rconn is set to NULL in the code path where it would
be a bug... How confusing.
Now that we handle the pfree() in PG_CATCH instead, that lower-level
pfree should be removed, and then connect_pg_server() doesn't need to
take an rconn pointer at all. For extra credit you could maybe move
the allocation of rconn down below the call to connect_pg_server(),
and get rid of the try/catch?
> + /* Verify the set of connection parameters. */
> dblink_connstr_check(connstr);
> ...
> + /* Perform post-connection security checks. */
> dblink_security_check(conn, rconn, connstr);
- These comment additions probably belong in 0001 rather than 0002.
- As discussed offlist, 0002 needs pgperltidy'd rather than perltidy'd.
- I have attached some additional nitpicky comment edits and
whitespace changes as a diff; pick and choose as desired.
Thanks!
--Jacob
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 50959c4f5bb..d333f1c5429 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -2567,14 +2567,14 @@ deleteConnection(const char *name)
}
/*
- * Ensure that require_auth and scram keys are correctly set on connstr.
- * SCRAM keys used to pass-through is coming from the initial connection from
- * the client with the server.
+ * Ensure that require_auth and SCRAM keys are correctly set on connstr.
+ * SCRAM keys used to pass-through are coming from the initial connection
+ * from the client with the server.
*
- * All required scram options is set by ourself, so we just need to ensure
+ * All required SCRAM options are set by dblink, so we just need to ensure
* that these options are not overwritten by the user.
*
- * See appendSCRAMKeysInfo and it's usage for more.
+ * See appendSCRAMKeysInfo and its usage for more.
*/
bool
dblink_connstr_has_required_scram_options(const char *connstr)
@@ -2645,13 +2645,13 @@ dblink_security_check(PGconn *conn, remoteConn *rconn,
const char *connstr)
return;
/*
- * Password was not used to connect, check if scram pass-through is in
+ * Password was not used to connect, check if SCRAM pass-through is in
* use.
*
* If dblink_connstr_has_required_scram_options is true we assume that
- * UseScramPassthrough is also true because the required scram keys is
+ * UseScramPassthrough is also true because the required SCRAM keys are
* only added if UseScramPassthrough is set, and the user is not allowed
- * to add the scram keys on fdw and user mapping options.
+ * to add the SCRAM keys on fdw and user mapping options.
*/
if (MyProcPort->has_scram_keys &&
dblink_connstr_has_required_scram_options(connstr))
return;
@@ -2710,12 +2710,12 @@ dblink_connstr_has_pw(const char *connstr)
/*
* For non-superusers, insist that the connstr specify a password, except if
* GSSAPI credentials have been delegated (and we check that they are used for
- * the connection in dblink_security_check later) or if scram pass-through is
+ * the connection in dblink_security_check later) or if SCRAM pass-through is
* being used. This prevents a password or GSSAPI credentials from being
* picked up from .pgpass, a service file, the environment, etc. We don't want
* the postgres user's passwords or Kerberos credentials to be accessible to
- * non-superusers. In case of scram pass-through insist that the connstr
- * has the required scram pass-through options.
+ * non-superusers. In case of SCRAM pass-through insist that the connstr
+ * has the required SCRAM pass-through options.
*/
static void
dblink_connstr_check(const char *connstr)
@@ -2729,7 +2729,6 @@ dblink_connstr_check(const char *connstr)
if (MyProcPort->has_scram_keys &&
dblink_connstr_has_required_scram_options(connstr))
return;
-
#ifdef ENABLE_GSS
if (be_gssapi_get_delegation(MyProcPort))
return;
@@ -2876,8 +2875,8 @@ get_connect_string(ForeignServer *foreign_server)
/*
* First append hardcoded options needed for SCRAM pass-through, so if
the
- * user overwrite these options we can ereport on dblink_connstr_check
and
- * dblink_security_check.
+ * user overwrites these options we can ereport on dblink_connstr_check
+ * and dblink_security_check.
*/
if (MyProcPort->has_scram_keys && UseScramPassthrough(foreign_server,
user_mapping))
appendSCRAMKeysInfo(&buf);
@@ -3063,7 +3062,6 @@ is_valid_dblink_option(const PQconninfoOption *options,
const char *option,
return true;
}
-
/*
* Same as is_valid_dblink_option but also check for only dblink_fdw specific
* options.
@@ -3078,7 +3076,6 @@ is_valid_dblink_fdw_option(const PQconninfoOption
*options, const char *option,
return is_valid_dblink_option(options, option, context);
}
-
/*
* Copy the remote session's values of GUCs that affect datatype I/O
* and apply them locally in a new GUC nesting level. Returns the new
@@ -3161,7 +3158,6 @@ appendSCRAMKeysInfo(StringInfo buf)
char *client_key;
char *server_key;
-
len = pg_b64_enc_len(sizeof(MyProcPort->scram_ClientKey));
/* don't forget the zero-terminator */
client_key = palloc0(len + 1);
diff --git a/doc/src/sgml/dblink.sgml b/doc/src/sgml/dblink.sgml
index e3b4129ae26..9cbcf645e78 100644
--- a/doc/src/sgml/dblink.sgml
+++ b/doc/src/sgml/dblink.sgml
@@ -136,7 +136,7 @@ dblink_connect(text connname, text connstr) returns text
</para>
</refsect1>
-<refsect1>
+ <refsect1>
<title>Foreign Data Wrapper</title>
<para>
@@ -208,8 +208,6 @@ dblink_connect(text connname, text connstr) returns text
</listitem>
</itemizedlist>
</para>
-
-
</refsect1>
<refsect1>
@@ -257,7 +255,7 @@ SELECT dblink_connect('myconn', 'dbname=postgres
options=-csearch_path=');
(1 row)
-- FOREIGN DATA WRAPPER functionality
--- Note: local connection that don't use SCRAM pass-through require password
+-- Note: local connections that don't use SCRAM pass-through require password
-- authentication for this to work properly. Otherwise, you will receive
-- the following error from dblink_connect():
-- ERROR: password is required