I am not sure, but it is possible you are seeing a problem with the new
storage of passwords as MD5 encrypted on pg_shadow. The attached patch
fixes this.
---------------------------------------------------------------------------
Tim Frank wrote:
> I was testing this on a 7.3 beta the other week to try to make it work
> with LDAP authentication, and I think I only got it working if I bypased
> the system-auth PAM file that everything was normally funneled through.
> I don't know exactly why it wasn't working, but whenever I put a line
> that used pam_unix.so it would fail with the same error you are
> encountering.
>
> I didn't invest a huge amount of time figuring out why pam_unix.so was
> causing a problem because I wanted to use pam_ldap.so anyways.
>
> There doesn't seem to be many examples out there that I could find that
> I got to work. FYI I am testing on RedHat 7.x and 8.0 machines.
>
> Tim
>
> EMOTO Masahiko wrote:
> > Does anyone show me a sample of PAM authenticate file?
> >
> > I want to use pam for client authentication, and I create pg_hba.cnf as,
> >
> >
> >>host all all 127.0.0.1 255.255.255.255 trust
> >>host all all 192.168.0.0 255.255.0.0 pam postgresql
> >
> >
> > and /etc/pam.d/postgresql as
> >
> >>auth required /lib/security/pam_stack.so service=system-auth
> >>account required /lib/security/pam_stack.so service=system-auth
> >
> >
> > I tried to connect to the server, but failed. The messages I received were follows;
> >
> >
> >>[CLIENT]
> >>% psql -h dgpc1 db1 -U emo
> >>Password:
> >>psql: FATAL: PAM authentication failed for user "emo"
> >>
> >>[SERVER]
> >>DEBUG: reaping dead processes
> >>DEBUG: child process (pid 15642) exited with exit code 0
> >>DEBUG: BackendStartup: forked pid=15643 socket=8
> >>DEBUG: received PAM packet
> >>LOG: CheckPAMAuth: pam_authenticate failed: 'Authentication failure'
> >>FATAL: PAM authentication failed for user "emo"
> >>DEBUG: proc_exit(0)
> >>DEBUG: shmem_exit(0)
> >>DEBUG: exit(0)
> >>DEBUG: reaping dead processes
> >
> >
> > The user account exists in the database, and I typed the system password.
> >
> >
> > Environment:
> > OS : Linux Kernel 2.4.19
> > PostgreSQL 7.3
> >
> >
> > By the way, what really I want to do is to configure the server behave like FTP servers;
> > All the users except the guest (anonymous) requires the password authentication.
> > The guest user can only read the data, and cannot alter the data.
> > Are there any solutions to do this?
> >
> >
> > --- EMOTO Masahiko ---
> >
> > ---------------------------(end of broadcast)---------------------------
> > TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo@postgresql.org so that your
> message can get through to the mailing list cleanly
>
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Index: src/backend/libpq/crypt.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/libpq/crypt.c,v
retrieving revision 1.49
diff -c -c -r1.49 crypt.c
*** src/backend/libpq/crypt.c 4 Sep 2002 20:31:19 -0000 1.49
--- src/backend/libpq/crypt.c 5 Dec 2002 18:03:53 -0000
***************
*** 29,35 ****
int
! md5_crypt_verify(const Port *port, const char *user, const char *pgpass)
{
char *passwd = NULL,
*valuntil = NULL,
--- 29,35 ----
int
! md5_crypt_verify(const Port *port, const char *user, char *pgpass)
{
char *passwd = NULL,
*valuntil = NULL,
***************
*** 37,42 ****
--- 37,43 ----
int retval = STATUS_ERROR;
List **line;
List *token;
+ char *crypt_pgpass = pgpass;
if ((line = get_user_line(user)) == NULL)
return STATUS_ERROR;
***************
*** 54,64 ****
if (passwd == NULL || *passwd == '\0')
return STATUS_ERROR;
! /* If they encrypt their password, force MD5 */
! if (isMD5(passwd) && port->auth_method != uaMD5)
{
elog(LOG, "Password is stored MD5 encrypted. "
! "'password' and 'crypt' auth methods cannot be used.");
return STATUS_ERROR;
}
--- 55,65 ----
if (passwd == NULL || *passwd == '\0')
return STATUS_ERROR;
! /* We can't do crypt with pg_shadow MD5 passwords */
! if (isMD5(passwd) && port->auth_method == uaCrypt)
{
elog(LOG, "Password is stored MD5 encrypted. "
! "'crypt' auth method cannot be used.");
return STATUS_ERROR;
}
***************
*** 72,77 ****
--- 73,79 ----
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,87 ****
--- 84,90 ----
}
else
{
+ /* pg_shadow plain, double-encrypt */
char *crypt_pwd2 = palloc(MD5_PASSWD_LEN + 1);
if (!EncryptMD5(passwd, port->user, strlen(port->user),
***************
*** 110,120 ****
break;
}
default:
crypt_pwd = passwd;
break;
}
! if (strcmp(pgpass, crypt_pwd) == 0)
{
/*
* Password OK, now check to be sure we are not past valuntil
--- 113,134 ----
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(crypt_pgpass, crypt_pwd) == 0)
{
/*
* Password OK, now check to be sure we are not past valuntil
***************
*** 136,141 ****
--- 150,157 ----
if (port->auth_method == uaMD5)
pfree(crypt_pwd);
+ if (crypt_pgpass != pgpass)
+ pfree(crypt_pgpass);
return retval;
}
Index: src/include/libpq/crypt.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/libpq/crypt.h,v
retrieving revision 1.22
diff -c -c -r1.22 crypt.h
*** src/include/libpq/crypt.h 4 Sep 2002 20:31:42 -0000 1.22
--- src/include/libpq/crypt.h 5 Dec 2002 18:03:54 -0000
***************
*** 23,29 ****
extern int md5_crypt_verify(const Port *port, const char *user,
! const char *pgpass);
extern bool md5_hash(const void *buff, size_t len, char *hexsum);
extern bool CheckMD5Pwd(char *passwd, char *storedpwd, char *seed);
--- 23,29 ----
extern int md5_crypt_verify(const Port *port, const char *user,
! char *pgpass);
extern bool md5_hash(const void *buff, size_t len, char *hexsum);
extern bool CheckMD5Pwd(char *passwd, char *storedpwd, char *seed);