pgpool2.git / summary / log / commit / refs

commit    c78cb93e5337c825e463c3c6cfd418bcf0eccb31
Author:   Muhammad Usama <m.usama@gmail.com>
Date:     Tue Oct 30 13:08:52 2018 +0000

    Fix for 0000419: pg_md5: -m removes users
    
    The problem was in pool_create_passwdent() which was expecting the password
    string will always have the same length. This is not true anymore after the
    support for AES and TEXT type passwords, So inlace updating of pool_passwd is
    not an option anymore.
    The fix is to use the memory buffer to compile the pool_passwd file and rewrite
    it completely.
    The patch was provided by Takuma Hoshiai <hoshiai@sraoss.co.jp>
    and modified by me.


src/auth/pool_passwd.c | 92 ++++++++++++++++++++++-------------------- src/include/auth/pool_passwd.h | 1 + 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/src/auth/pool_passwd.c b/src/auth/pool_passwd.c index bbc33b9a0..b31de5e51 100644 --- a/src/auth/pool_passwd.c +++ b/src/auth/pool_passwd.c @@ -40,6 +40,7 @@ static FILE *passwd_fd = NULL; /* File descriptor for pool_passwd */ static char saved_passwd_filename[POOLMAXPATHLEN + 1]; +static char *userMatchesString(char *buf, char *user); static POOL_PASSWD_MODE pool_passwd_mode; /* @@ -93,11 +94,12 @@ pool_init_pool_passwd(char *pool_passwd_filename, POOL_PASSWD_MODE mode) int pool_create_passwdent(char *username, char *passwd) { - int len; - int c; - char name[MAX_USER_NAME_LEN]; - char *p; - int readlen; +#define LINE_LEN \ + MAX_USER_NAME_LEN + 1 + MAX_POOL_PASSWD_LEN + 2 + char linebuf[LINE_LEN]; + char *writebuf = NULL; + int len; + bool updated = false; if (!passwd_fd) ereport(ERROR, @@ -113,62 +115,64 @@ pool_create_passwdent(char *username, char *passwd) (errmsg("error updating password, invalid password length:%d", len))); rewind(passwd_fd); - name[0] = '\0'; - while (!feof(passwd_fd)) + while (!feof(passwd_fd) && !ferror(passwd_fd)) { - p = name; - readlen = 0; + char *t = linebuf; + int len; - while (readlen < sizeof(name)) - { - c = fgetc(passwd_fd); - if (c == EOF) - break; - else if (c == ':') - break; + if (fgets(linebuf, sizeof(linebuf), passwd_fd) == NULL) + break; - readlen++; - *p++ = c; - } - *p = '\0'; + len = strlen(linebuf); + if (len == 0) + continue; - if (!strcmp(username, name)) + if (!updated && userMatchesString(t, username)) { - /* User name found. Update password. */ - while ((c = *passwd++)) - { - fputc(c, passwd_fd); - } - fputc('\n', passwd_fd); - return 0; + len = snprintf(linebuf, sizeof(linebuf), "%s:%s\n", username, passwd); + updated = true; } + + if (writebuf == NULL) + writebuf = palloc0(len + 1); else { - /* Skip password */ - while ((c = fgetc(passwd_fd)) != EOF && - c != '\n') - ; + writebuf = repalloc(writebuf, (len + strlen(writebuf) + 1)); } + strcat(writebuf, linebuf); } - fseek(passwd_fd, 0, SEEK_END); - - /* - * Not found the user name. Create a new entry. - */ - while ((c = *username++)) + if (!updated) { - fputc(c, passwd_fd); + /* password was not update, append this at the end */ + len = snprintf(linebuf, sizeof(linebuf), "%s:%s\n", username, passwd); + if (writebuf == NULL) + writebuf = palloc0(len + 1); + else + { + writebuf = repalloc(writebuf, (len + strlen(writebuf) + 1)); + } + strcat(writebuf, linebuf); } - fputc(':', passwd_fd); - while ((c = *passwd++)) + + if(!writebuf) + return 0; + + fclose(passwd_fd); + passwd_fd = fopen(saved_passwd_filename, "w+"); + if (!passwd_fd) { - fputc(c, passwd_fd); + ereport(ERROR, + (errmsg("pool_passwd reopen failed"))); } - fputc('\n', passwd_fd); + /* write pool_passwd file. */ + fwrite(writebuf, 1, strlen(writebuf), passwd_fd); + pfree(writebuf); return 0; + +#undef LINE_LEN } /* @@ -181,7 +185,7 @@ pool_get_passwd(char *username) { int c; char name[MAX_USER_NAME_LEN + 1]; - static char passwd[POOL_PASSWD_LEN + 1]; + static char passwd[MAX_POOL_PASSWD_LEN + 1]; char *p; int readlen; diff --git a/src/include/auth/pool_passwd.h b/src/include/auth/pool_passwd.h index c00cb960a..bbcaaa810 100644 --- a/src/include/auth/pool_passwd.h +++ b/src/include/auth/pool_passwd.h @@ -29,6 +29,7 @@ #define POOL_PASSWD_FILENAME "pool_passwd" #define POOL_PASSWD_LEN 35 +#define MAX_POOL_PASSWD_LEN 132 /* In case of TEXT prefix(4byte) and plain text password(128byte)*/ #define MAX_USER_NAME_LEN 128 #define MAX_PGPASS_LEN 128 [parent: ffd6bfa8c212]