Allow 'password' encryption even when pg_shadow has MD5 passwords, per
authorBruce Momjian
Thu, 5 Dec 2002 18:39:43 +0000 (18:39 +0000)
committerBruce Momjian
Thu, 5 Dec 2002 18:39:43 +0000 (18:39 +0000)
report from Terry Yapt and Hiroshi.

Backpatch to 7.3.

src/backend/libpq/crypt.c
src/include/libpq/crypt.h

index 9cc6b483ed1ace320b7935afe046e5bcaae9b8a1..7270dfc82ceb5943511552186ee475c1c4e38d52 100644 (file)
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/backend/libpq/crypt.c,v 1.49 2002/09/04 20:31:19 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/crypt.c,v 1.50 2002/12/05 18:39:43 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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;
 }
index 246ab0bd66b935bfe37cbaa587dd782c45e3d091..b3b050a8365c25a60041a43828a6f4aceb787362 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: crypt.h,v 1.22 2002/09/04 20:31:42 momjian Exp $
+ * $Id: crypt.h,v 1.23 2002/12/05 18:39:43 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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);