Commit 37f6fd1e authored by Tom Lane's avatar Tom Lane

Fix initdb misbehavior when user mis-enters superuser password.

While testing simple_prompt() revisions, I happened to notice that
current initdb behaves rather badly when --pwprompt is specified and
the user miskeys the second password.  It complains about the mismatch,
does "rm -rf" on the data directory, and exits.  The problem is that
since commit c4a8812c, there's a standalone backend sitting waiting
for commands at that point.  It gets unhappy about its datadir having
gone away, and spews a PANIC message at the user, which is not nice.
(And the shell then adds to the mess with meaningless bleating about a
core dump...)  We don't really want that sort of thing to happen unless
there's an internal failure in initdb, which this surely is not.

The best fix seems to be to move the collection of the password
earlier, so that it's done essentially as part of argument collection,
rather than at the rather ad-hoc time it was done before.

Back-patch to 9.6 where the problem was introduced.
parent 8e1e3f95
...@@ -135,6 +135,7 @@ static const char *default_text_search_config = ""; ...@@ -135,6 +135,7 @@ static const char *default_text_search_config = "";
static char *username = ""; static char *username = "";
static bool pwprompt = false; static bool pwprompt = false;
static char *pwfilename = NULL; static char *pwfilename = NULL;
static char *superuser_password = NULL;
static const char *authmethodhost = ""; static const char *authmethodhost = "";
static const char *authmethodlocal = ""; static const char *authmethodlocal = "";
static bool debug = false; static bool debug = false;
...@@ -255,7 +256,7 @@ static void test_config_settings(void); ...@@ -255,7 +256,7 @@ static void test_config_settings(void);
static void setup_config(void); static void setup_config(void);
static void bootstrap_template1(void); static void bootstrap_template1(void);
static void setup_auth(FILE *cmdfd); static void setup_auth(FILE *cmdfd);
static void get_set_pwd(FILE *cmdfd); static void get_su_pwd(void);
static void setup_depend(FILE *cmdfd); static void setup_depend(FILE *cmdfd);
static void setup_sysviews(FILE *cmdfd); static void setup_sysviews(FILE *cmdfd);
static void setup_description(FILE *cmdfd); static void setup_description(FILE *cmdfd);
...@@ -1544,13 +1545,17 @@ setup_auth(FILE *cmdfd) ...@@ -1544,13 +1545,17 @@ setup_auth(FILE *cmdfd)
for (line = pg_authid_setup; *line != NULL; line++) for (line = pg_authid_setup; *line != NULL; line++)
PG_CMD_PUTS(*line); PG_CMD_PUTS(*line);
if (superuser_password)
PG_CMD_PRINTF2("ALTER USER \"%s\" WITH PASSWORD E'%s';\n\n",
username, escape_quotes(superuser_password));
} }
/* /*
* get the superuser password if required, and call postgres to set it * get the superuser password if required
*/ */
static void static void
get_set_pwd(FILE *cmdfd) get_su_pwd(void)
{ {
char *pwd1, char *pwd1,
*pwd2; *pwd2;
...@@ -1560,6 +1565,8 @@ get_set_pwd(FILE *cmdfd) ...@@ -1560,6 +1565,8 @@ get_set_pwd(FILE *cmdfd)
/* /*
* Read password from terminal * Read password from terminal
*/ */
printf("\n");
fflush(stdout);
pwd1 = simple_prompt("Enter new superuser password: ", 100, false); pwd1 = simple_prompt("Enter new superuser password: ", 100, false);
pwd2 = simple_prompt("Enter it again: ", 100, false); pwd2 = simple_prompt("Enter it again: ", 100, false);
if (strcmp(pwd1, pwd2) != 0) if (strcmp(pwd1, pwd2) != 0)
...@@ -1609,10 +1616,7 @@ get_set_pwd(FILE *cmdfd) ...@@ -1609,10 +1616,7 @@ get_set_pwd(FILE *cmdfd)
} }
PG_CMD_PRINTF2("ALTER USER \"%s\" WITH PASSWORD E'%s';\n\n", superuser_password = pwd1;
username, escape_quotes(pwd1));
free(pwd1);
} }
/* /*
...@@ -3279,8 +3283,6 @@ initialize_data_directory(void) ...@@ -3279,8 +3283,6 @@ initialize_data_directory(void)
PG_CMD_OPEN; PG_CMD_OPEN;
setup_auth(cmdfd); setup_auth(cmdfd);
if (pwprompt || pwfilename)
get_set_pwd(cmdfd);
setup_depend(cmdfd); setup_depend(cmdfd);
...@@ -3569,6 +3571,9 @@ main(int argc, char *argv[]) ...@@ -3569,6 +3571,9 @@ main(int argc, char *argv[])
else else
printf(_("Data page checksums are disabled.\n")); printf(_("Data page checksums are disabled.\n"));
if (pwprompt || pwfilename)
get_su_pwd();
printf("\n"); printf("\n");
initialize_data_directory(); initialize_data_directory();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment