Re: Logging of PAM Authentication Failure

From: Amit Langote <amitlangote09(at)gmail(dot)com>
To: Kyotaro HORIGUCHI <kyota(dot)horiguchi(at)gmail(dot)com>
Cc: Kyotaro HORIGUCHI <horiguchi(dot)kyotaro(at)lab(dot)ntt(dot)co(dot)jp>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Robert Haas <robertmhaas(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Logging of PAM Authentication Failure
Date: 2013-05-16 05:20:48
Message-ID: CA+HiwqFZ6sThhy9nogWSBec_VEPxOCJhwbd59bvrmxxrqAZYrg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Sorry that I am writing separate emails on the same topic.
I seem to have a solution that allows us to accomplish what we are
trying to without much change to the existing libpq interface
(especially what to expect about return values and connection state
that we are in when we return from connectDBComplete() and
PQconnectPoll() ).

Following are required changes roughly:

1] in src/bin/psql/startup.c, main()

if (PQstatus(pset.db) == CONNECTION_BAD &&
PQconnectionNeedsPassword(pset.db) &&
password == NULL &&
pset.getPassword != TRI_NO)
{
password = simple_prompt(password_prompt, 100, false);
/* How would this detect authentication_timeoue and exit
accordingly ?*/
PQsendPassword(pset.db, password);
}

And there is no do{...}while(new_pass); unlike current code.

2] in src/interfaces/libpq/fe-connect.c, new function: void
PQsendPassword(PGconn *conn, char *password) /*suggest better name?
*/

void PQsendPassword(PGconn *conn, char *password)
{
conn->pgpass = password;
conn->status = CONNECTION_SENDING_PASSWORD; /*suggest better
name for the status? */

(void) connectDBComplete(conn);

}

3] in src/interfaces/libpq/fe-connect.c, connectDBComplete(PGconn
*conn), No change required. :-)

4] in in src/interfaces/libpq/fe-connect.c, PQconnectPoll(PGconn *conn)

a) add a new case for both switch's (one before and after keep_going: )

/* These are writing states, so we just proceed. */
case CONNECTION_STARTED:
case CONNECTION_MADE:
case CONNECTION_SENDING_PASSWORD:
break;
...
...
keep_going:
...
...
case CONNECTION_SENDING_PASSWORD:
{
/*
** Note that conn->pghost must be
non-NULL if we are going to
** avoid the Kerberos code doing a
hostname look-up.
**/
if (pg_fe_sendauth(areq, conn) != STATUS_OK)
{
conn->errorMessage.len =
strlen(conn->errorMessage.data);
goto error_return;
}
conn->errorMessage.len =
strlen(conn->errorMessage.data);

/*
** Just make sure that any data sent
by pg_fe_sendauth is
** flushed out. Although this
theoretically could block, it
** really shouldn't since we don't
send large auth responses.
**/
if (pqFlush(conn))
goto error_return;

/*
* Now go to read the server's
response to password just sent
* */
conn->status = CONNECTION_AWAITING_RESPONSE;
return PGRES_POLLING_READING;
}

5] in src/interfaces/libpq/libpq-fe.h, add a new intermediate connection state

/*
* Although it is okay to add to these lists, values which become unused
* should never be removed, nor should constants be redefined - that would
* break compatibility with existing code.
*/

typedef enum
{
CONNECTION_OK,
CONNECTION_BAD,
/* Non-blocking mode only below here */

/*
* The existence of these should never be relied upon - they should only
* be used for user feedback or similar purposes.
*/
CONNECTION_STARTED, /* Waiting for
connection to be made. */
CONNECTION_MADE, /* Connection OK;
waiting to send. */
CONNECTION_AWAITING_RESPONSE, /* Waiting for a
response from the

* postmaster. */
CONNECTION_AUTH_OK, /* Received
authentication; waiting for
*
backend startup. */
CONNECTION_SETENV, /* Negotiating environment. */
CONNECTION_SSL_STARTUP, /* Negotiating SSL. */
CONNECTION_NEEDED, /* Internal state:
connect() needed */
CONNECTION_SENDING_PASSWORD
} ConnStatusType;

As you can probably see this requires minimum libpq changes:

1] Add one more connection state: CONNECTION_SENDING_PASSWORD
2] Add one more function: PQsendPassword(PGconn*, char*)
3] Modify PQconnectPoll() to allow to handle an intermediate
CONNECTION_SENDING_PASSWORD state for the clients which use
PQsendPassword() to send a password that user entered in between a
connection sequence over an existing connection.

Comments?

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Daniel Farina 2013-05-16 05:53:17 Re: Better LWLocks with compare-and-swap (9.4)
Previous Message Christoph Berg 2013-05-16 05:15:16 Re: plperl segfault in plperl_trusted_init() on kfreebsd