2020年1月30日(木) 14:57 Michael Paquier <[email protected]>:
>
> On Thu, Jan 30, 2020 at 02:29:06PM +0900, Ian Barwick wrote:
> > I can't think of any practical reason why pg_basebackup would ever need to
> > be run as root; we disallow that for initdb, pg_ctl and pg_upgrade, so it
> > seems reasonable to do the same for pg_basebackup. Trivial patch attached,
> > which as with the other cases will allow only the --help/--version options
> > to be executed as root, otherwise nothing else.
>
> My take on the matter is that we should prevent anything creating or
> modifying the data directory to run as root if we finish with
> permissions incompatible with what a postmaster expects. So +1.
>
> > The patch doesn't update the pg_basebackup documentation page; we don't
> > mention it in the pg_ctl and pg_upgrade pages either and it doesn't seem
> > particularly important to mention it explicitly.
>
> We don't mention that in the docs of pg_rewind either. Note also that
> before 5d5aedd pg_rewind printed an error without exiting :)
Ouch.
> > + /*
> > + * Disallow running as root, as PostgreSQL will be unable to start
> > + * with root-owned files.
> > + */
>
> Here is a suggestion:
> /*
> * Don't allow pg_basebackup to be run as root, to avoid creating
> * files in the data directory with ownership rights incompatible
> * with the postmaster. We need only check for root -- any other user
> * won't have sufficient permissions to modify files in the data
> * directory.
> */
I think we can skip the second sentence altogether. It'd be theoretically
easy enough to up with some combination of group permissions,
sticky bits, umask, ACL settings etc/ which would allow one user to
modify the files owned by another user,
> > + #ifndef WIN32
>
> Indentation here.
Whoops, that's what comes from typing on the train ;)
> > + if (geteuid() == 0) /* 0 is root's uid */
> > + {
> > + pg_log_error("cannot be run as root");
> > + fprintf(stderr,
> > + _("Please log in (using, e.g., \"su\") as the
> > (unprivileged) user that will\n"
> > + "own the server process.\n"));
> > + exit(1);
> > + }
> > +#endif
>
> I would recommend to map with the existing message of pg_rewind for
> consistency:
> pg_log_error("cannot be executed by \"root\"");
> fprintf(stderr, _("You must run %s as the PostgreSQL superuser.\n"),
> progname);
Hmm, I was using the existing message from initdb and pg_ctl for consistency:
src/bin/initdb/initdb.c:
if (geteuid() == 0) /* 0 is root's uid */
{
pg_log_error("cannot be run as root");
fprintf(stderr,
_("Please log in (using, e.g., \"su\") as the
(unprivileged) user that will\n"
"own the server process.\n"));
exit(1);
}
src/bin/pg_ctl/pg_ctl.c:
if (geteuid() == 0)
{
write_stderr(_("%s: cannot be run as root\n"
"Please log in (using, e.g., \"su\") as the "
"(unprivileged) user that will\n"
"own the server process.\n"),
progname);
exit(1);
}
src/bin/pg_upgrade/option.c:
if (os_user_effective_id == 0)
pg_fatal("%s: cannot be run as root\n", os_info.progname);
I wonder if it would be worth settling on a common message and way of emitting
it, each utility does it slightly differently.
> A backpatch could be surprising for some users as that's a behavior
> change, so I would recommend not to do a backpatch.
Agreed.
Regards
Ian Barwick
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index 238b671f7a..dfa816cbae 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -2077,6 +2077,22 @@ main(int argc, char **argv)
}
}
+ /*
+ * Don't allow pg_basebackup to be run as root, to avoid creating
+ * files in the data directory with ownership rights incompatible
+ * with the postmaster.
+ */
+#ifndef WIN32
+ if (geteuid() == 0) /* 0 is root's uid */
+ {
+ pg_log_error("cannot be run as root");
+ fprintf(stderr,
+ _("Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n"
+ "own the server process.\n"));
+ exit(1);
+ }
+#endif
+
atexit(cleanup_directories_atexit);
while ((c = getopt_long(argc, argv, "CD:F:r:RS:T:X:l:nNzZ:d:c:h:p:U:s:wWkvP",