99 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
1010 * Portions Copyright (c) 1994, Regents of the University of California
1111 *
12- * $Header: /cvsroot/pgsql/src/backend/libpq/crypt.c,v 1.49 2002/09/04 20:31:19 momjian Exp $
12+ * $Header: /cvsroot/pgsql/src/backend/libpq/crypt.c,v 1.50 2002/12/05 18:39:43 momjian Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
2929
3030
3131int
32- md5_crypt_verify (const Port * port ,const char * user ,const char * pgpass )
32+ md5_crypt_verify (const Port * port ,const char * user ,char * pgpass )
3333{
3434char * passwd = NULL ,
3535* valuntil = NULL ,
3636* crypt_pwd ;
3737int retval = STATUS_ERROR ;
3838List * * line ;
3939List * token ;
40+ char * crypt_pgpass = pgpass ;
4041
4142if ((line = get_user_line (user ))== NULL )
4243return STATUS_ERROR ;
@@ -54,11 +55,11 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass)
5455if (passwd == NULL || * passwd == '\0' )
5556return STATUS_ERROR ;
5657
57- /*If they encrypt their password, force MD5 */
58- if (isMD5 (passwd )&& port -> auth_method != uaMD5 )
58+ /*We can't do crypt with pg_shadow MD5 passwords */
59+ if (isMD5 (passwd )&& port -> auth_method == uaCrypt )
5960{
6061elog (LOG ,"Password is stored MD5 encrypted. "
61- "'password' and ' crypt' authmethods cannot be used." );
62+ "'crypt' authmethod cannot be used." );
6263return STATUS_ERROR ;
6364}
6465
@@ -72,6 +73,7 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass)
7273crypt_pwd = palloc (MD5_PASSWD_LEN + 1 );
7374if (isMD5 (passwd ))
7475{
76+ /* pg_shadow already encrypted, only do salt */
7577if (!EncryptMD5 (passwd + strlen ("md5" ),
7678(char * )port -> md5Salt ,
7779sizeof (port -> md5Salt ),crypt_pwd ))
@@ -82,6 +84,7 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass)
8284}
8385else
8486{
87+ /* pg_shadow plain, double-encrypt */
8588char * crypt_pwd2 = palloc (MD5_PASSWD_LEN + 1 );
8689
8790if (!EncryptMD5 (passwd ,port -> user ,strlen (port -> user ),
@@ -110,11 +113,22 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass)
110113break ;
111114}
112115default :
116+ if (isMD5 (passwd ))
117+ {
118+ /* Encrypt user-supplied password to match MD5 in pg_shadow */
119+ crypt_pgpass = palloc (MD5_PASSWD_LEN + 1 );
120+ if (!EncryptMD5 (pgpass ,port -> user ,strlen (port -> user ),
121+ crypt_pgpass ))
122+ {
123+ pfree (crypt_pgpass );
124+ return STATUS_ERROR ;
125+ }
126+ }
113127crypt_pwd = passwd ;
114128break ;
115129}
116130
117- if (strcmp (pgpass ,crypt_pwd )== 0 )
131+ if (strcmp (crypt_pgpass ,crypt_pwd )== 0 )
118132{
119133/*
120134 * 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)
136150
137151if (port -> auth_method == uaMD5 )
138152pfree (crypt_pwd );
153+ if (crypt_pgpass != pgpass )
154+ pfree (crypt_pgpass );
139155
140156return retval ;
141157}