diff options
author | Stephen Frost <sfrost@snowman.net> | 2018-04-07 17:45:39 -0400 |
---|---|---|
committer | Stephen Frost <sfrost@snowman.net> | 2018-04-07 17:45:39 -0400 |
commit | c37b3d08ca6873f9d4eaf24c72a90a550970cbb8 (patch) | |
tree | a92cd4f79d20c4d002bd1f41af8bfe9507d92636 /src/bin/initdb/initdb.c | |
parent | da9b580d89903fee871cf54845ffa2b26bda2e11 (diff) |
Allow group access on PGDATA
Allow the cluster to be optionally init'd with read access for the
group.
This means a relatively non-privileged user can perform a backup of the
cluster without requiring write privileges, which enhances security.
The mode of PGDATA is used to determine whether group permissions are
enabled for directory and file creates. This method was chosen as it's
simple and works well for the various utilities that write into PGDATA.
Changing the mode of PGDATA manually will not automatically change the
mode of all the files contained therein. If the user would like to
enable group access on an existing cluster then changing the mode of all
the existing files will be required. Note that pg_upgrade will
automatically change the mode of all migrated files if the new cluster
is init'd with the -g option.
Tests are included for the backend and all the utilities which operate
on the PG data directory to ensure that the correct mode is set based on
the data directory permissions.
Author: David Steele <david@pgmasters.net>
Reviewed-By: Michael Paquier, with discussion amongst many others.
Discussion: https://postgr.es/m/ad346fe6-b23e-59f1-ecb7-0e08390ad629%40pgmasters.net
Diffstat (limited to 'src/bin/initdb/initdb.c')
-rw-r--r-- | src/bin/initdb/initdb.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 3765548a249..ec1f0c4bff1 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -1168,6 +1168,19 @@ setup_config(void) "password_encryption = scram-sha-256"); } + /* + * If group access has been enabled for the cluster then it makes sense to + * ensure that the log files also allow group access. Otherwise a backup + * from a user in the group would fail if the log files were not + * relocated. + */ + if (pg_dir_create_mode == PG_DIR_MODE_GROUP) + { + conflines = replace_token(conflines, + "#log_file_mode = 0600", + "log_file_mode = 0640"); + } + snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data); writefile(path, conflines); @@ -2312,6 +2325,7 @@ usage(const char *progname) printf(_(" --auth-local=METHOD default authentication method for local-socket connections\n")); printf(_(" [-D, --pgdata=]DATADIR location for this database cluster\n")); printf(_(" -E, --encoding=ENCODING set default encoding for new databases\n")); + printf(_(" -g, --allow-group-access allow group read/execute on data directory\n")); printf(_(" --locale=LOCALE set default locale for new databases\n")); printf(_(" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" " --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" @@ -2883,8 +2897,13 @@ initialize_data_directory(void) setup_signals(); - /* Set dir/file mode mask */ - umask(PG_MODE_MASK_OWNER); + /* + * Set mask based on requested PGDATA permissions. pg_mode_mask, and + * friends like pg_dir_create_mode, are set to owner-only by default and + * then updated if -g is passed in by calling SetDataDirectoryCreatePerm() + * when parsing our options (see above). + */ + umask(pg_mode_mask); create_data_directory(); @@ -3018,6 +3037,7 @@ main(int argc, char *argv[]) {"waldir", required_argument, NULL, 'X'}, {"wal-segsize", required_argument, NULL, 12}, {"data-checksums", no_argument, NULL, 'k'}, + {"allow-group-access", no_argument, NULL, 'g'}, {NULL, 0, NULL, 0} }; @@ -3059,7 +3079,7 @@ main(int argc, char *argv[]) /* process command-line options */ - while ((c = getopt_long(argc, argv, "dD:E:kL:nNU:WA:sST:X:", long_options, &option_index)) != -1) + while ((c = getopt_long(argc, argv, "dD:E:kL:nNU:WA:sST:X:g", long_options, &option_index)) != -1) { switch (c) { @@ -3153,6 +3173,9 @@ main(int argc, char *argv[]) case 12: str_wal_segment_size_mb = pg_strdup(optarg); break; + case 'g': + SetDataDirectoryCreatePerm(PG_DIR_MODE_GROUP); + break; default: /* getopt_long already emitted a complaint */ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), |