1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-19 13:42:17 +03:00
Subject: [HACKERS] password authentication

This patch adds support for plaintext password authentication.  To use
it, you add a line like

host         all         0.0.0.0       0.0.0.0           password  pg_pwd.conf


to your pg_hba.conf, where 'pg_pwd.conf' is the name of a file containing
the usernames and password hashes in the format of the first two fields
of a Unix /etc/passwd file.  (Of course, you can use a specific database
name or IP instead.)

Then, to connect with a password through libpq, you use the PQconnectdb()
function, specifying the "password=" tag in the connect string and also
adding the tag "authtype=password".

I also added a command-line switch '-u' to psql that tells it to prompt
for a username and password and use password authentication.
This commit is contained in:
Marc G. Fournier
1997-03-12 21:23:16 +00:00
parent 5dde558ce6
commit 3a7c93e7f3
13 changed files with 345 additions and 85 deletions

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.6 1996/11/03 07:14:30 scrappy Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.7 1997/03/12 21:23:02 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -40,6 +40,7 @@
#include "libpq-fe.h"
#include "fe-auth.h"
#include "fe-connect.h"
/*----------------------------------------------------------------
* common definitions for generic fe/be routines
@@ -79,7 +80,8 @@ static struct authsvc authsvcs[] = {
#else /* !(KRB4 || KRB5) */
1
#endif /* !(KRB4 || KRB5) */
}
},
{ "password", STARTUP_PASSWORD_MSG, 0 }
};
static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
@@ -431,12 +433,30 @@ pg_krb5_sendauth(const char* PQerrormsg,int sock,
#endif /* KRB5 */
static int
pg_password_sendauth(Port *port, const char *user, const char *password)
{
PacketBuf buf;
char *tmp;
buf.len = htonl(sizeof(PacketBuf));
buf.msgtype = STARTUP_PASSWORD_MSG;
buf.data[0] = '\0';
tmp = buf.data;
strncpy(tmp, user, strlen(user)+1);
tmp += strlen(user)+1;
strncpy(tmp, password, strlen(password)+1);
return packetSend(port, &buf, sizeof(PacketBuf), BLOCKING);
}
/*
* fe_sendauth -- client demux routine for outgoing authentication information
*/
int
fe_sendauth(MsgType msgtype, Port *port, const char *hostname, const char* PQerrormsg)
fe_sendauth(MsgType msgtype, Port *port, const char *hostname,
const char *user, const char *password, const char* PQerrormsg)
{
switch (msgtype) {
#ifdef KRB4
@@ -464,6 +484,8 @@ fe_sendauth(MsgType msgtype, Port *port, const char *hostname, const char* PQerr
#endif
case STARTUP_MSG:
break;
case STARTUP_PASSWORD_MSG:
pg_password_sendauth(port, user, password);
default:
break;
}

View File

@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: fe-auth.h,v 1.2 1996/08/06 16:16:44 scrappy Exp $
* $Id: fe-auth.h,v 1.3 1997/03/12 21:23:04 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,7 +28,9 @@
#define DEFAULT_CLIENT_AUTHSVC "kerberos"
#endif /* KRB4 || KRB5 */
extern int fe_sendauth(MsgType msgtype, Port *port, const char *hostname, const char* PQerromsg);
extern int fe_sendauth(MsgType msgtype, Port *port, const char *hostname,
const char *user, const char *password,
const char* PQerromsg);
extern void fe_setauthsvc(const char *name, char* PQerrormsg);
#define PG_KRB4_VERSION "PGVER4.1" /* at most KRB_SENDAUTH_VLEN chars */

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.23 1997/02/13 08:32:08 scrappy Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.24 1997/03/12 21:23:09 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,6 +28,7 @@
#include "postgres.h"
#include "libpq/pqcomm.h" /* for decls of MsgType, PacketBuf, StartupInfo */
#include "fe-auth.h"
#include "fe-connect.h"
#include "libpq-fe.h"
#ifndef HAVE_STRDUP
@@ -38,8 +39,6 @@
/* use a local version instead of the one found in pqpacket.c */
static ConnStatusType connectDB(PGconn *conn);
static int packetSend(Port *port, PacketBuf *buf, PacketLen len,
bool nonBlocking);
static void startup2PacketBuf(StartupInfo* s, PacketBuf* res);
static void freePGconn(PGconn *conn);
static void closePGconn(PGconn *conn);
@@ -73,9 +72,15 @@ static PQconninfoOption PQconninfoOptions[] = {
/* Option-name Environment-Var Compiled-in Current value */
/* Label Disp-Char */
/* ----------------- --------------- --------------- --------------- */
{ "authtype", "PGAUTHTYPE", NULL, NULL,
"Database-Authtype", "", 20 },
{ "user", "PGUSER", NULL, NULL,
"Database-User", "", 20 },
{ "password", "PGPASSWORD", NULL, NULL,
"Database-Password", "", 20 },
{ "dbname", "PGDATABASE", NULL, NULL,
"Database-Name", "", 20 },
@@ -187,6 +192,8 @@ PQconnectdb(const char *conninfo)
conn->pgtty = strdup(conninfo_getval("tty"));
conn->pgoptions = strdup(conninfo_getval("options"));
conn->pguser = strdup(conninfo_getval("user"));
conn->pgpass = strdup(conninfo_getval("password"));
conn->pgauth = strdup(conninfo_getval("authtype"));
conn->dbName = strdup(conninfo_getval("dbname"));
/* ----------
@@ -195,6 +202,13 @@ PQconnectdb(const char *conninfo)
*/
conninfo_free();
/*
* try to set the auth service if one was specified
*/
if(conn->pgauth) {
fe_setauthsvc(conn->pgauth, conn->errorMessage);
}
/* ----------
* Connect to the database
* ----------
@@ -260,6 +274,8 @@ PQconndefaults(void)
*
* PGUSER Postgres username to associate with the connection.
*
* PGPASSWORD The user's password.
*
* PGDATABASE name of database to which to connect if <pgdatabase>
* argument is NULL or a null string
*
@@ -336,6 +352,12 @@ PQsetdb(const char *pghost, const char* pgport, const char* pgoptions, const cha
}
}
if((tmp = getenv("PGPASSWORD"))) {
conn->pgpass = strdup(tmp);
} else {
conn->pgpass = 0;
}
if (!error) {
if (((tmp = (char *)dbName) && (dbName[0] != '\0')) ||
((tmp = getenv("PGDATABASE")))) {
@@ -467,6 +489,7 @@ connectDB(PGconn *conn)
/* authenticate as required*/
if (fe_sendauth(msgtype, port, conn->pghost,
conn->pguser, conn->pgpass,
conn->errorMessage) != STATUS_OK) {
(void) sprintf(conn->errorMessage,
"connectDB() -- authentication failed with %s\n",
@@ -474,6 +497,11 @@ connectDB(PGconn *conn)
goto connect_errReturn;
}
/* free the password so it's not hanging out in memory forever */
if(conn->pgpass) {
free(conn->pgpass);
}
/* set up the socket file descriptors */
conn->Pfout = fdopen(port->sock, "w");
conn->Pfin = fdopen(dup(port->sock), "r");
@@ -595,7 +623,7 @@ PQreset(PGconn *conn)
* buffer management. For now, we're not going to do it.
*
*/
static int
int
packetSend(Port *port,
PacketBuf *buf,
PacketLen len,

View File

@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: libpq-fe.h,v 1.17 1997/01/06 10:11:11 bryanh Exp $
* $Id: libpq-fe.h,v 1.18 1997/03/12 21:23:16 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -125,6 +125,8 @@ typedef struct pg_conn{
int asyncNotifyWaiting;
Dllist* notifyList;
char *pguser; /* Postgres username of user who is connected */
char *pgpass;
char *pgauth;
PGlobjfuncs *lobjfuncs; /* Backend function OID's for large object access */
} PGconn;