aboutsummaryrefslogtreecommitdiff
path: root/contrib/dblink/dblink.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/dblink/dblink.c')
-rw-r--r--contrib/dblink/dblink.c127
1 files changed, 45 insertions, 82 deletions
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 55f75eff361..78a8bcee6e3 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -48,7 +48,6 @@
#include "funcapi.h"
#include "lib/stringinfo.h"
#include "libpq-fe.h"
-#include "libpq/libpq-be.h"
#include "libpq/libpq-be-fe-helpers.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
@@ -112,8 +111,7 @@ static HeapTuple get_tuple_of_interest(Relation rel, int *pkattnums, int pknumat
static Relation get_rel_from_relname(text *relname_text, LOCKMODE lockmode, AclMode aclmode);
static char *generate_relation_name(Relation rel);
static void dblink_connstr_check(const char *connstr);
-static bool dblink_connstr_has_pw(const char *connstr);
-static void dblink_security_check(PGconn *conn, remoteConn *rconn, const char *connstr);
+static void dblink_security_check(PGconn *conn, remoteConn *rconn);
static void dblink_res_error(PGconn *conn, const char *conname, PGresult *res,
bool fail, const char *fmt,...) pg_attribute_printf(5, 6);
static char *get_connect_string(const char *servername);
@@ -215,7 +213,7 @@ dblink_get_conn(char *conname_or_str,
errmsg("could not establish connection"),
errdetail_internal("%s", msg)));
}
- dblink_security_check(conn, rconn, connstr);
+ dblink_security_check(conn, rconn);
if (PQclientEncoding(conn) != GetDatabaseEncoding())
PQsetClientEncoding(conn, GetDatabaseEncodingName());
freeconn = true;
@@ -309,7 +307,7 @@ dblink_connect(PG_FUNCTION_ARGS)
}
/* check password actually used if not superuser */
- dblink_security_check(conn, rconn, connstr);
+ dblink_security_check(conn, rconn);
/* attempt to set client encoding to match server encoding, if needed */
if (PQclientEncoding(conn) != GetDatabaseEncoding())
@@ -2586,99 +2584,64 @@ deleteConnection(const char *name)
errmsg("undefined connection name")));
}
-/*
- * We need to make sure that the connection made used credentials
- * which were provided by the user, so check what credentials were
- * used to connect and then make sure that they came from the user.
- */
static void
-dblink_security_check(PGconn *conn, remoteConn *rconn, const char *connstr)
+dblink_security_check(PGconn *conn, remoteConn *rconn)
{
- /* Superuser bypasses security check */
- if (superuser())
- return;
-
- /* If password was used to connect, make sure it was one provided */
- if (PQconnectionUsedPassword(conn) && dblink_connstr_has_pw(connstr))
- return;
-
-#ifdef ENABLE_GSS
- /* If GSSAPI creds used to connect, make sure it was one delegated */
- if (PQconnectionUsedGSSAPI(conn) && be_gssapi_get_deleg(MyProcPort))
- return;
-#endif
-
- /* Otherwise, fail out */
- libpqsrv_disconnect(conn);
- if (rconn)
- pfree(rconn);
+ if (!superuser())
+ {
+ if (!PQconnectionUsedPassword(conn))
+ {
+ libpqsrv_disconnect(conn);
+ if (rconn)
+ pfree(rconn);
- ereport(ERROR,
- (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
- errmsg("password or GSSAPI delegated credentials required"),
- errdetail("Non-superusers may only connect using credentials they provide, eg: password in connection string or delegated GSSAPI credentials"),
- errhint("Ensure provided credentials match target server's authentication method.")));
+ ereport(ERROR,
+ (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
+ errmsg("password is required"),
+ errdetail("Non-superuser cannot connect if the server does not request a password."),
+ errhint("Target server's authentication method must be changed.")));
+ }
+ }
}
/*
- * Function to check if the connection string includes an explicit
- * password, needed to ensure that non-superuser password-based auth
- * is using a provided password and not one picked up from the
- * environment.
+ * For non-superusers, insist that the connstr specify a password. This
+ * prevents a password from being picked up from .pgpass, a service file,
+ * the environment, etc. We don't want the postgres user's passwords
+ * to be accessible to non-superusers.
*/
-static bool
-dblink_connstr_has_pw(const char *connstr)
+static void
+dblink_connstr_check(const char *connstr)
{
- PQconninfoOption *options;
- PQconninfoOption *option;
- bool connstr_gives_password = false;
-
- options = PQconninfoParse(connstr, NULL);
- if (options)
+ if (!superuser())
{
- for (option = options; option->keyword != NULL; option++)
+ PQconninfoOption *options;
+ PQconninfoOption *option;
+ bool connstr_gives_password = false;
+
+ options = PQconninfoParse(connstr, NULL);
+ if (options)
{
- if (strcmp(option->keyword, "password") == 0)
+ for (option = options; option->keyword != NULL; option++)
{
- if (option->val != NULL && option->val[0] != '\0')
+ if (strcmp(option->keyword, "password") == 0)
{
- connstr_gives_password = true;
- break;
+ if (option->val != NULL && option->val[0] != '\0')
+ {
+ connstr_gives_password = true;
+ break;
+ }
}
}
+ PQconninfoFree(options);
}
- PQconninfoFree(options);
- }
-
- return connstr_gives_password;
-}
-/*
- * 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). 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.
- */
-static void
-dblink_connstr_check(const char *connstr)
-{
- if (superuser())
- return;
-
- if (dblink_connstr_has_pw(connstr))
- return;
-
-#ifdef ENABLE_GSS
- if (be_gssapi_get_deleg(MyProcPort))
- return;
-#endif
-
- ereport(ERROR,
- (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
- errmsg("password or GSSAPI delegated credentials required"),
- errdetail("Non-superusers must provide a password in the connection string or send delegated GSSAPI credentials.")));
+ if (!connstr_gives_password)
+ ereport(ERROR,
+ (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
+ errmsg("password is required"),
+ errdetail("Non-superusers must provide a password in the connection string.")));
+ }
}
/*