Created
July 3, 2024 14:00
-
-
Save tie/9fd9c75fb1fdf87d48352bb2bd1d2cb0 to your computer and use it in GitHub Desktop.
PostgreSQL patch to allow running as root user (e.g. in containers).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/backend/main/main.c b/src/backend/main/main.c | |
index 51ffb8e773..c92d25c77b 100644 | |
--- a/src/backend/main/main.c | |
+++ b/src/backend/main/main.c | |
@@ -49,7 +49,6 @@ static bool reached_main = false; | |
static void startup_hacks(const char *progname); | |
static void init_locale(const char *categoryname, int category, const char *locale); | |
static void help(const char *progname); | |
-static void check_root(const char *progname); | |
/* | |
@@ -58,8 +57,6 @@ static void check_root(const char *progname); | |
int | |
main(int argc, char *argv[]) | |
{ | |
- bool do_check_root = true; | |
- | |
reached_main = true; | |
/* | |
@@ -153,30 +150,8 @@ main(int argc, char *argv[]) | |
fputs(PG_BACKEND_VERSIONSTR, stdout); | |
exit(0); | |
} | |
- | |
- /* | |
- * In addition to the above, we allow "--describe-config" and "-C var" | |
- * to be called by root. This is reasonably safe since these are | |
- * read-only activities. The -C case is important because pg_ctl may | |
- * try to invoke it while still holding administrator privileges on | |
- * Windows. Note that while -C can normally be in any argv position, | |
- * if you want to bypass the root check you must put it first. This | |
- * reduces the risk that we might misinterpret some other mode's -C | |
- * switch as being the postmaster/postgres one. | |
- */ | |
- if (strcmp(argv[1], "--describe-config") == 0) | |
- do_check_root = false; | |
- else if (argc > 2 && strcmp(argv[1], "-C") == 0) | |
- do_check_root = false; | |
} | |
- /* | |
- * Make sure we are not running as root, unless it's safe for the selected | |
- * option. | |
- */ | |
- if (do_check_root) | |
- check_root(progname); | |
- | |
/* | |
* Dispatch to one of various subprograms depending on first argument. | |
*/ | |
@@ -376,46 +351,6 @@ help(const char *progname) | |
-static void | |
-check_root(const char *progname) | |
-{ | |
-#ifndef WIN32 | |
- if (geteuid() == 0) | |
- { | |
- write_stderr("\"root\" execution of the PostgreSQL server is not permitted.\n" | |
- "The server must be started under an unprivileged user ID to prevent\n" | |
- "possible system security compromise. See the documentation for\n" | |
- "more information on how to properly start the server.\n"); | |
- exit(1); | |
- } | |
- | |
- /* | |
- * Also make sure that real and effective uids are the same. Executing as | |
- * a setuid program from a root shell is a security hole, since on many | |
- * platforms a nefarious subroutine could setuid back to root if real uid | |
- * is root. (Since nobody actually uses postgres as a setuid program, | |
- * trying to actively fix this situation seems more trouble than it's | |
- * worth; we'll just expend the effort to check for it.) | |
- */ | |
- if (getuid() != geteuid()) | |
- { | |
- write_stderr("%s: real and effective user IDs must match\n", | |
- progname); | |
- exit(1); | |
- } | |
-#else /* WIN32 */ | |
- if (pgwin32_is_admin()) | |
- { | |
- write_stderr("Execution of PostgreSQL by a user with administrative permissions is not\n" | |
- "permitted.\n" | |
- "The server must be started under an unprivileged user ID to prevent\n" | |
- "possible system security compromises. See the documentation for\n" | |
- "more information on how to properly start the server.\n"); | |
- exit(1); | |
- } | |
-#endif /* WIN32 */ | |
-} | |
- | |
/* | |
* At least on linux, set_ps_display() breaks /proc/$pid/environ. The | |
* sanitizer library uses /proc/$pid/environ to implement getenv() as it wants | |
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c | |
index ac409b0006..e2d79bc922 100644 | |
--- a/src/bin/initdb/initdb.c | |
+++ b/src/bin/initdb/initdb.c | |
@@ -751,15 +751,6 @@ get_id(void) | |
{ | |
const char *username; | |
-#ifndef WIN32 | |
- if (geteuid() == 0) /* 0 is root's uid */ | |
- { | |
- pg_log_error("cannot be run as root"); | |
- pg_log_error_hint("Please log in (using, e.g., \"su\") as the (unprivileged) user that will own the server process."); | |
- exit(1); | |
- } | |
-#endif | |
- | |
username = get_user_name_or_exit(progname); | |
return pg_strdup(username); | |
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c | |
index 6900b27675..cdea841733 100644 | |
--- a/src/bin/pg_ctl/pg_ctl.c | |
+++ b/src/bin/pg_ctl/pg_ctl.c | |
@@ -2240,21 +2240,6 @@ main(int argc, char **argv) | |
} | |
} | |
- /* | |
- * Disallow running as root, to forestall any possible security holes. | |
- */ | |
-#ifndef WIN32 | |
- 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); | |
- } | |
-#endif | |
- | |
env_wait = getenv("PGCTLTIMEOUT"); | |
if (env_wait != NULL) | |
wait_seconds = atoi(env_wait); | |
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c | |
index e9dcb5a6d8..1772cee522 100644 | |
--- a/src/bin/pg_resetwal/pg_resetwal.c | |
+++ b/src/bin/pg_resetwal/pg_resetwal.c | |
@@ -328,22 +328,6 @@ main(int argc, char *argv[]) | |
exit(1); | |
} | |
- /* | |
- * Don't allow pg_resetwal to be run as root, to avoid overwriting the | |
- * ownership of files in the data directory. We need only check for root | |
- * -- any other user won't have sufficient permissions to modify files in | |
- * the data directory. | |
- */ | |
-#ifndef WIN32 | |
- if (geteuid() == 0) | |
- { | |
- pg_log_error("cannot be executed by \"root\""); | |
- pg_log_error_hint("You must run %s as the PostgreSQL superuser.", | |
- progname); | |
- exit(1); | |
- } | |
-#endif | |
- | |
get_restricted_token(); | |
/* Set mask based on PGDATA permissions */ | |
diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c | |
index 57a168fea2..aa84020e78 100644 | |
--- a/src/bin/pg_rewind/pg_rewind.c | |
+++ b/src/bin/pg_rewind/pg_rewind.c | |
@@ -270,22 +270,6 @@ main(int argc, char **argv) | |
exit(1); | |
} | |
- /* | |
- * Don't allow pg_rewind to be run as root, to avoid overwriting the | |
- * ownership of files in the data directory. We need only check for root | |
- * -- any other user won't have sufficient permissions to modify files in | |
- * the data directory. | |
- */ | |
-#ifndef WIN32 | |
- if (geteuid() == 0) | |
- { | |
- pg_log_error("cannot be executed by \"root\""); | |
- pg_log_error_hint("You must run %s as the PostgreSQL superuser.", | |
- progname); | |
- exit(1); | |
- } | |
-#endif | |
- | |
get_restricted_token(); | |
/* Set mask based on PGDATA permissions */ | |
diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c | |
index 2917ec2329..64f5f17339 100644 | |
--- a/src/bin/pg_upgrade/option.c | |
+++ b/src/bin/pg_upgrade/option.c | |
@@ -76,8 +76,8 @@ parseCommandLine(int argc, char *argv[]) | |
old_cluster.port = getenv("PGPORTOLD") ? atoi(getenv("PGPORTOLD")) : DEF_PGUPORT; | |
new_cluster.port = getenv("PGPORTNEW") ? atoi(getenv("PGPORTNEW")) : DEF_PGUPORT; | |
- os_user_effective_id = get_user_info(&os_info.user); | |
- /* we override just the database user name; we got the OS id above */ | |
+ get_user_info(&os_info.user); | |
+ /* we override just the database user name */ | |
if (getenv("PGUSER")) | |
{ | |
pg_free(os_info.user); | |
@@ -99,10 +99,6 @@ parseCommandLine(int argc, char *argv[]) | |
} | |
} | |
- /* Allow help and version to be run as root, so do the test here. */ | |
- if (os_user_effective_id == 0) | |
- pg_fatal("%s: cannot be run as root", os_info.progname); | |
- | |
while ((option = getopt_long(argc, argv, "b:B:cd:D:j:kNo:O:p:P:rs:U:v", | |
long_options, &optindex)) != -1) | |
{ | |
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h | |
index d9a848cbfd..829581b19a 100644 | |
--- a/src/bin/pg_upgrade/pg_upgrade.h | |
+++ b/src/bin/pg_upgrade/pg_upgrade.h | |
@@ -461,7 +461,7 @@ void check_pghost_envvar(void); | |
/* util.c */ | |
char *quote_identifier(const char *s); | |
-int get_user_info(char **user_name_p); | |
+void get_user_info(char **user_name_p); | |
void check_ok(void); | |
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2, 3); | |
void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2, 3); | |
diff --git a/src/bin/pg_upgrade/util.c b/src/bin/pg_upgrade/util.c | |
index 2478372992..ef3ec57b0e 100644 | |
--- a/src/bin/pg_upgrade/util.c | |
+++ b/src/bin/pg_upgrade/util.c | |
@@ -319,27 +319,18 @@ quote_identifier(const char *s) | |
/* | |
* get_user_info() | |
*/ | |
-int | |
+void | |
get_user_info(char **user_name_p) | |
{ | |
- int user_id; | |
const char *user_name; | |
char *errstr; | |
-#ifndef WIN32 | |
- user_id = geteuid(); | |
-#else | |
- user_id = 1; | |
-#endif | |
- | |
user_name = get_user_name(&errstr); | |
if (!user_name) | |
pg_fatal("%s", errstr); | |
/* make a copy */ | |
*user_name_p = pg_strdup(user_name); | |
- | |
- return user_id; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment