diff options
Diffstat (limited to 'src/bin/pg_basebackup/streamutil.c')
-rw-r--r-- | src/bin/pg_basebackup/streamutil.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c index 1438f368edc..4fd536931b1 100644 --- a/src/bin/pg_basebackup/streamutil.c +++ b/src/bin/pg_basebackup/streamutil.c @@ -23,6 +23,7 @@ #include "access/xlog_internal.h" #include "common/fe_memutils.h" +#include "common/file_perm.h" #include "datatype/timestamp.h" #include "fe_utils/connect.h" #include "port/pg_bswap.h" @@ -32,9 +33,16 @@ uint32 WalSegSz; +static bool RetrieveDataDirCreatePerm(PGconn *conn); + /* SHOW command for replication connection was introduced in version 10 */ #define MINIMUM_VERSION_FOR_SHOW_CMD 100000 +/* + * Group access is supported from version 11. + */ +#define MINIMUM_VERSION_FOR_GROUP_ACCESS 110000 + const char *progname; char *connection_string = NULL; char *dbhost = NULL; @@ -254,6 +262,16 @@ GetConnection(void) exit(1); } + /* + * Retrieve the source data directory mode and use it to construct a umask + * for creating directories and files. + */ + if (!RetrieveDataDirCreatePerm(tmpconn)) + { + PQfinish(tmpconn); + exit(1); + } + return tmpconn; } @@ -328,6 +346,64 @@ RetrieveWalSegSize(PGconn *conn) } /* + * RetrieveDataDirCreatePerm + * + * This function is used to determine the privileges on the server's PG data + * directory and, based on that, set what the permissions will be for + * directories and files we create. + * + * PG11 added support for (optionally) group read/execute rights to be set on + * the data directory. Prior to PG11, only the owner was allowed to have rights + * on the data directory. + */ +static bool +RetrieveDataDirCreatePerm(PGconn *conn) +{ + PGresult *res; + int data_directory_mode; + + /* check connection existence */ + Assert(conn != NULL); + + /* for previous versions leave the default group access */ + if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_GROUP_ACCESS) + return true; + + res = PQexec(conn, "SHOW data_directory_mode"); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, _("%s: could not send replication command \"%s\": %s\n"), + progname, "SHOW data_directory_mode", PQerrorMessage(conn)); + + PQclear(res); + return false; + } + if (PQntuples(res) != 1 || PQnfields(res) < 1) + { + fprintf(stderr, + _("%s: could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields\n"), + progname, PQntuples(res), PQnfields(res), 1, 1); + + PQclear(res); + return false; + } + + if (sscanf(PQgetvalue(res, 0, 0), "%o", &data_directory_mode) != 1) + { + fprintf(stderr, _("%s: group access flag could not be parsed: %s\n"), + progname, PQgetvalue(res, 0, 0)); + + PQclear(res); + return false; + } + + SetDataDirectoryCreatePerm(data_directory_mode); + + PQclear(res); + return true; +} + +/* * Run IDENTIFY_SYSTEM through a given connection and give back to caller * some result information if requested: * - System identifier |