Re: Logging of PAM Authentication Failure - Mailing list pgsql-hackers

From Amit Langote
Subject Re: Logging of PAM Authentication Failure
Date
Msg-id CA+HiwqFZ6sThhy9nogWSBec_VEPxOCJhwbd59bvrmxxrqAZYrg@mail.gmail.com
Whole thread Raw
In response to Re: Logging of PAM Authentication Failure  (Amit Langote <amitlangote09@gmail.com>)
Responses Re: Logging of PAM Authentication Failure
List 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
constantsbe 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
feedbackor 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?



pgsql-hackers by date:

Previous
From: Christoph Berg
Date:
Subject: Re: plperl segfault in plperl_trusted_init() on kfreebsd
Next
From: Daniel Farina
Date:
Subject: Re: Better LWLocks with compare-and-swap (9.4)