From: Bruce Momjian Date: Thu, 5 Dec 2002 18:40:08 +0000 (+0000) Subject: Allow 'password' encryption even when pg_shadow has MD5 passwords, per X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=d8483795844007476f69a2aedf3ec0aa41801861;p=users%2Fbernd%2Fpostgres.git Allow 'password' encryption even when pg_shadow has MD5 passwords, per report from Terry Yapt and Hiroshi. Backpatch to 7.3. --- diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index 86c78cc7e7..d7d156347b 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -29,7 +29,7 @@ int -md5_crypt_verify(const Port *port, const char *user, const char *pgpass) +md5_crypt_verify(const Port *port, const char *user, char *pgpass) { char *passwd = NULL, *valuntil = NULL, @@ -37,6 +37,7 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass) int retval = STATUS_ERROR; List **line; List *token; + char *crypt_pgpass = pgpass; if ((line = get_user_line(user)) == NULL) return STATUS_ERROR; @@ -54,11 +55,11 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass) if (passwd == NULL || *passwd == '\0') return STATUS_ERROR; - /* If they encrypt their password, force MD5 */ - if (isMD5(passwd) && port->auth_method != uaMD5) + /* We can't do crypt with pg_shadow MD5 passwords */ + if (isMD5(passwd) && port->auth_method == uaCrypt) { elog(LOG, "Password is stored MD5 encrypted. " - "'password' and 'crypt' auth methods cannot be used."); + "'crypt' auth method cannot be used."); return STATUS_ERROR; } @@ -72,6 +73,7 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass) crypt_pwd = palloc(MD5_PASSWD_LEN + 1); if (isMD5(passwd)) { + /* pg_shadow already encrypted, only do salt */ if (!EncryptMD5(passwd + strlen("md5"), (char *) port->md5Salt, sizeof(port->md5Salt), crypt_pwd)) @@ -82,6 +84,7 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass) } else { + /* pg_shadow plain, double-encrypt */ char *crypt_pwd2 = palloc(MD5_PASSWD_LEN + 1); if (!EncryptMD5(passwd, port->user, strlen(port->user), @@ -110,11 +113,22 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass) break; } default: + if (isMD5(passwd)) + { + /* Encrypt user-supplied password to match MD5 in pg_shadow */ + crypt_pgpass = palloc(MD5_PASSWD_LEN + 1); + if (!EncryptMD5(pgpass, port->user, strlen(port->user), + crypt_pgpass)) + { + pfree(crypt_pgpass); + return STATUS_ERROR; + } + } crypt_pwd = passwd; break; } - if (strcmp(pgpass, crypt_pwd) == 0) + if (strcmp(crypt_pgpass, crypt_pwd) == 0) { /* * Password OK, now check to be sure we are not past valuntil @@ -136,6 +150,8 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass) if (port->auth_method == uaMD5) pfree(crypt_pwd); + if (crypt_pgpass != pgpass) + pfree(crypt_pgpass); return retval; } diff --git a/src/include/libpq/crypt.h b/src/include/libpq/crypt.h index e4c6585586..a8f01a366c 100644 --- a/src/include/libpq/crypt.h +++ b/src/include/libpq/crypt.h @@ -23,7 +23,7 @@ extern int md5_crypt_verify(const Port *port, const char *user, - const char *pgpass); + char *pgpass); extern bool md5_hash(const void *buff, size_t len, char *hexsum); extern bool CheckMD5Pwd(char *passwd, char *storedpwd, char *seed);