]> granicus.if.org Git - postgresql/blobdiff - src/bin/pg_basebackup/streamutil.c
Empty search_path in Autovacuum and non-psql/pgbench clients.
[postgresql] / src / bin / pg_basebackup / streamutil.c
index df17f60596a4b74d98810fdd876beec9050cb234..296b1888aad729993f77d12778748e82c4b8d268 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Author: Magnus Hagander <magnus@hagander.net>
  *
- * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
  *               src/bin/pg_basebackup/streamutil.c
 #include <sys/time.h>
 #include <unistd.h>
 
-/* for ntohl/htonl */
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
 /* local includes */
 #include "receivelog.h"
 #include "streamutil.h"
 
 #include "access/xlog_internal.h"
-#include "pqexpbuffer.h"
 #include "common/fe_memutils.h"
 #include "datatype/timestamp.h"
+#include "fe_utils/connect.h"
+#include "port/pg_bswap.h"
+#include "pqexpbuffer.h"
 
 #define ERRCODE_DUPLICATE_OBJECT  "42710"
 
@@ -211,6 +209,23 @@ GetConnection(void)
        if (conn_opts)
                PQconninfoFree(conn_opts);
 
+       /* Set always-secure search path, so malicious users can't get control. */
+       if (dbname != NULL)
+       {
+               PGresult   *res;
+
+               res = PQexec(tmpconn, ALWAYS_SECURE_SEARCH_PATH_SQL);
+               if (PQresultStatus(res) != PGRES_TUPLES_OK)
+               {
+                       fprintf(stderr, _("%s: could not clear search_path: %s\n"),
+                                       progname, PQerrorMessage(tmpconn));
+                       PQclear(res);
+                       PQfinish(tmpconn);
+                       exit(1);
+               }
+               PQclear(res);
+       }
+
        /*
         * Ensure we have the same value of integer_datetimes (now always "on") as
         * the server we are connecting to.
@@ -398,7 +413,8 @@ RunIdentifySystem(PGconn *conn, char **sysid, TimeLineID *starttli,
  */
 bool
 CreateReplicationSlot(PGconn *conn, const char *slot_name, const char *plugin,
-                                         bool is_physical, bool slot_exists_ok)
+                                         bool is_temporary, bool is_physical, bool reserve_wal,
+                                         bool slot_exists_ok)
 {
        PQExpBuffer query;
        PGresult   *res;
@@ -410,13 +426,18 @@ CreateReplicationSlot(PGconn *conn, const char *slot_name, const char *plugin,
        Assert(slot_name != NULL);
 
        /* Build query */
+       appendPQExpBuffer(query, "CREATE_REPLICATION_SLOT \"%s\"", slot_name);
+       if (is_temporary)
+               appendPQExpBuffer(query, " TEMPORARY");
        if (is_physical)
-               appendPQExpBuffer(query, "CREATE_REPLICATION_SLOT \"%s\" PHYSICAL",
-                                                 slot_name);
+       {
+               appendPQExpBuffer(query, " PHYSICAL");
+               if (reserve_wal)
+                       appendPQExpBuffer(query, " RESERVE_WAL");
+       }
        else
        {
-               appendPQExpBuffer(query, "CREATE_REPLICATION_SLOT \"%s\" LOGICAL \"%s\"",
-                                                 slot_name, plugin);
+               appendPQExpBuffer(query, " LOGICAL \"%s\"", plugin);
                if (PQserverVersion(conn) >= 100000)
                        /* pg_recvlogical doesn't use an exported snapshot, so suppress */
                        appendPQExpBuffer(query, " NOEXPORT_SNAPSHOT");
@@ -570,17 +591,9 @@ feTimestampDifferenceExceeds(TimestampTz start_time,
 void
 fe_sendint64(int64 i, char *buf)
 {
-       uint32          n32;
-
-       /* High order half first, since we're doing MSB-first */
-       n32 = (uint32) (i >> 32);
-       n32 = htonl(n32);
-       memcpy(&buf[0], &n32, 4);
+       uint64          n64 = pg_hton64(i);
 
-       /* Now the low order half */
-       n32 = (uint32) i;
-       n32 = htonl(n32);
-       memcpy(&buf[4], &n32, 4);
+       memcpy(buf, &n64, sizeof(n64));
 }
 
 /*
@@ -589,18 +602,9 @@ fe_sendint64(int64 i, char *buf)
 int64
 fe_recvint64(char *buf)
 {
-       int64           result;
-       uint32          h32;
-       uint32          l32;
+       uint64          n64;
 
-       memcpy(&h32, buf, 4);
-       memcpy(&l32, buf + 4, 4);
-       h32 = ntohl(h32);
-       l32 = ntohl(l32);
+       memcpy(&n64, buf, sizeof(n64));
 
-       result = h32;
-       result <<= 32;
-       result |= l32;
-
-       return result;
+       return pg_ntoh64(n64);
 }