diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 99cf5b43e9e0e..047b25ea6a61c 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -1303,8 +1303,8 @@ get_set_pwd(void) /* * Read password from terminal */ - pwd1 = simple_prompt("Enter new superuser password: ", 100, false); - pwd2 = simple_prompt("Enter it again: ", 100, false); + pwd1 = simple_prompt("Enter new superuser password: ", MAX_PASSWD, false); + pwd2 = simple_prompt("Enter it again: ", MAX_PASSWD, false); if (strcmp(pwd1, pwd2) != 0) { fprintf(stderr, _("Passwords didn't match.\n")); @@ -1323,7 +1323,7 @@ get_set_pwd(void) * for now. */ FILE *pwf = fopen(pwfilename, "r"); - char pwdbuf[MAXPGPATH]; + char *pwdbuf = calloc(1,1), buf[1024]; int i; if (!pwf) @@ -1332,7 +1332,27 @@ get_set_pwd(void) progname, pwfilename, strerror(errno)); exit_nicely(); } - if (!fgets(pwdbuf, sizeof(pwdbuf), pwf)) + + do + { + if (fgets(buf, sizeof(buf), pwf) == NULL) + break; + pwdbuf = realloc( pwdbuf, strlen(pwdbuf)+1+strlen(buf) ); + if (!pwdbuf) + { + // Out of memory ? + fprintf(stderr, _("%s: could not read password from file \"%s\": %s\n"), + progname, pwfilename, strerror(errno)); + exit_nicely(); + } + strcat( pwdbuf, buf); + i = strlen(pwdbuf); + } while (strlen(buf) > 0 && pwdbuf[i-1] != '\n'); + + while (i > 0 && (pwdbuf[i - 1] == '\r' || pwdbuf[i - 1] == '\n')) + pwdbuf[--i] = '\0'; + + if (!i) { fprintf(stderr, _("%s: could not read password from file \"%s\": %s\n"), progname, pwfilename, strerror(errno)); @@ -1340,10 +1360,6 @@ get_set_pwd(void) } fclose(pwf); - i = strlen(pwdbuf); - while (i > 0 && (pwdbuf[i - 1] == '\r' || pwdbuf[i - 1] == '\n')) - pwdbuf[--i] = '\0'; - pwd1 = xstrdup(pwdbuf); } diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c index a843eacc0c842..4626c1f3f04df 100644 --- a/src/bin/pg_dump/pg_backup_db.c +++ b/src/bin/pg_dump/pg_backup_db.c @@ -143,7 +143,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) if (AH->promptPassword == TRI_YES && password == NULL) { - password = simple_prompt("Password: ", 100, false); + password = simple_prompt("Password: ", MAX_PASSWD, false); if (password == NULL) die_horribly(AH, modulename, "out of memory\n"); } @@ -195,7 +195,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) free(password); if (AH->promptPassword != TRI_NO) - password = simple_prompt("Password: ", 100, false); + password = simple_prompt("Password: ", MAX_PASSWD, false); else die_horribly(AH, modulename, "connection needs password\n"); @@ -242,7 +242,7 @@ ConnectDatabase(Archive *AHX, if (prompt_password == TRI_YES && password == NULL) { - password = simple_prompt("Password: ", 100, false); + password = simple_prompt("Password: ", MAX_PASSWD, false); if (password == NULL) die_horribly(AH, modulename, "out of memory\n"); } @@ -288,7 +288,7 @@ ConnectDatabase(Archive *AHX, prompt_password != TRI_NO) { PQfinish(AH->connection); - password = simple_prompt("Password: ", 100, false); + password = simple_prompt("Password: ", MAX_PASSWD, false); if (password == NULL) die_horribly(AH, modulename, "out of memory\n"); new_pass = true; diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 4f8dd600686d9..8216eb81b0af5 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -1687,7 +1687,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, static char *password = NULL; if (prompt_password == TRI_YES && !password) - password = simple_prompt("Password: ", 100, false); + password = simple_prompt("Password: ", MAX_PASSWD, false); /* * Start the connection. Loop until we have a password if requested by @@ -1733,7 +1733,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, prompt_password != TRI_NO) { PQfinish(conn); - password = simple_prompt("Password: ", 100, false); + password = simple_prompt("Password: ", MAX_PASSWD, false); new_pass = true; } } while (new_pass); diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 8421ad008602d..4f347a4d0f8c5 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -895,8 +895,8 @@ exec_command(const char *cmd, char *pw1; char *pw2; - pw1 = simple_prompt("Enter new password: ", 100, false); - pw2 = simple_prompt("Enter it again: ", 100, false); + pw1 = simple_prompt("Enter new password: ", MAX_PASSWD, false); + pw2 = simple_prompt("Enter it again: ", MAX_PASSWD, false); if (strcmp(pw1, pw2) != 0) { @@ -1462,7 +1462,7 @@ prompt_for_password(const char *username) char *result; if (username == NULL) - result = simple_prompt("Password: ", 100, false); + result = simple_prompt("Password: ", MAX_PASSWD, false); else { char *prompt_text; @@ -1470,7 +1470,7 @@ prompt_for_password(const char *username) prompt_text = malloc(strlen(username) + 100); snprintf(prompt_text, strlen(username) + 100, _("Password for user %s: "), username); - result = simple_prompt(prompt_text, 100, false); + result = simple_prompt(prompt_text, MAX_PASSWD, false); free(prompt_text); } diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index aff57728a2a67..eebbddc171d65 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -174,7 +174,7 @@ main(int argc, char *argv[]) } if (pset.getPassword == TRI_YES) - password = simple_prompt(password_prompt, 100, false); + password = simple_prompt(password_prompt, MAX_PASSWD, false); /* loop until we have a password if requested by backend */ do @@ -213,7 +213,7 @@ main(int argc, char *argv[]) pset.getPassword != TRI_NO) { PQfinish(pset.db); - password = simple_prompt(password_prompt, 100, false); + password = simple_prompt(password_prompt, MAX_PASSWD, false); new_pass = true; } } while (new_pass); diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c index 1a5284e5264e3..ebf4af2f5b2f9 100644 --- a/src/bin/scripts/common.c +++ b/src/bin/scripts/common.c @@ -100,7 +100,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, bool new_pass; if (prompt_password == TRI_YES) - password = simple_prompt("Password: ", 100, false); + password = simple_prompt("Password: ", MAX_PASSWD, false); /* * Start the connection. Loop until we have a password if requested by @@ -152,7 +152,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, prompt_password != TRI_NO) { PQfinish(conn); - password = simple_prompt("Password: ", 100, false); + password = simple_prompt("Password: ", MAX_PASSWD, false); new_pass = true; } } while (new_pass); diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c index 20a1a52a3ae0a..d9c3edb7d689d 100644 --- a/src/bin/scripts/createuser.c +++ b/src/bin/scripts/createuser.c @@ -197,8 +197,8 @@ main(int argc, char *argv[]) char *pw1, *pw2; - pw1 = simple_prompt("Enter password for new role: ", 100, false); - pw2 = simple_prompt("Enter it again: ", 100, false); + pw1 = simple_prompt("Enter password for new role: ", MAX_PASSWD, false); + pw2 = simple_prompt("Enter it again: ", MAX_PASSWD, false); if (strcmp(pw1, pw2) != 0) { fprintf(stderr, _("Passwords didn't match.\n")); diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index ac45ee6426eb3..4cef51f6d4f28 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -22,6 +22,20 @@ */ #define NAMEDATALEN 64 +/* + * Maximum password length via command line tools + * + * If 0, no maximum password length is enforced. + * If greater than 0, this defines the maximum number of characters + * which will be read as input for a password prompt. Input in + * excess of this maximum will be silently ignored. + * + * The database itself does not have a password length limit, + * regardless of this setting. + * + */ +#define MAX_PASSWD 0 + /* * Maximum number of arguments to a function. * diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 27a9805625bf9..a0f5ec9708320 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -4905,22 +4905,31 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username) while (!feof(fp) && !ferror(fp)) { - char *t = buf, + char *t = calloc(1,sizeof(char)), *ret, *p1, *p2; int len; - if (fgets(buf, sizeof(buf), fp) == NULL) - break; - len = strlen(buf); + do + { + if ( fgets(buf, LINELEN, fp) == NULL) + break; + t = realloc(t, strlen(t)+1+strlen(buf)); + /* Out of memory? */ + if( !t ) + return NULL; + strcat(t, buf); + len = strlen(t); + } while (strlen(buf) > 0 && t[len-1] != '\n'); + if (len == 0) continue; /* Remove trailing newline */ - if (buf[len - 1] == '\n') - buf[len - 1] = 0; + while ( len > 0 && (t[len-1] == '\n' || t[len-1] == '\r')) + t[--len] = 0; if ((t = pwdfMatchesString(t, hostname)) == NULL || (t = pwdfMatchesString(t, port)) == NULL || diff --git a/src/port/sprompt.c b/src/port/sprompt.c index 7baa26edbc46b..aafec28a2f7a8 100644 --- a/src/port/sprompt.c +++ b/src/port/sprompt.c @@ -38,7 +38,10 @@ char * simple_prompt(const char *prompt, int maxlen, bool echo) { int length; + int buflen; + int bufsize = 1024; char *destination; + char buf[bufsize]; FILE *termin, *termout; @@ -52,7 +55,11 @@ simple_prompt(const char *prompt, int maxlen, bool echo) #endif #endif - destination = (char *) malloc(maxlen + 1); + if (maxlen > 0) { + destination = (char *) calloc(1, sizeof(char)); + } else { + destination = (char *) malloc((maxlen + 1) * sizeof(char)); + } if (!destination) return NULL; @@ -108,21 +115,34 @@ simple_prompt(const char *prompt, int maxlen, bool echo) fflush(termout); } - if (fgets(destination, maxlen + 1, termin) == NULL) - destination[0] = '\0'; - - length = strlen(destination); - if (length > 0 && destination[length - 1] != '\n') - { - /* eat rest of the line */ - char buf[128]; - int buflen; + if (maxlen > 0) { + if (fgets(destination, maxlen + 1, termin) == NULL) + destination[0] = '\0'; + length = strlen(destination); + if (length > 0 && destination[length - 1] != '\n') + { + /* eat rest of the line */ + do + { + if (fgets(buf, bufsize, termin) == NULL) + break; + buflen = strlen(buf); + } while (buflen > 0 && buf[buflen - 1] != '\n'); + } + + } else { do { - if (fgets(buf, sizeof(buf), termin) == NULL) + if (fgets(buf, bufsize, termin) == NULL) break; buflen = strlen(buf); + destination = realloc( destination, strlen(destination)+1+buflen ); + /* Out of memory ? */ + if( !destination ) + return NULL; + strcat( destination, buf ); + length = strlen(destination); } while (buflen > 0 && buf[buflen - 1] != '\n'); }