summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorMarc G. Fournier1997-03-12 21:23:16 +0000
committerMarc G. Fournier1997-03-12 21:23:16 +0000
commit3a7c93e7f32b555defdc2ea0b0554f6dd0a34c41 (patch)
tree39e3c59630f15d44aaa3ad7ad0ae4fac7723f68b /src/backend
parent5dde558ce60db1f8747bbf745d56bd9cd5f4c7b7 (diff)
From: Dan McGuirk <mcguirk@indirect.com>
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.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/libpq/Makefile5
-rw-r--r--src/backend/libpq/auth.c47
-rw-r--r--src/backend/libpq/hba.c100
-rw-r--r--src/backend/libpq/pqcomm.c28
-rw-r--r--src/backend/postmaster/postmaster.c6
5 files changed, 120 insertions, 66 deletions
diff --git a/src/backend/libpq/Makefile b/src/backend/libpq/Makefile
index c8a0533a2b9..a7c7f13704e 100644
--- a/src/backend/libpq/Makefile
+++ b/src/backend/libpq/Makefile
@@ -4,7 +4,7 @@
# Makefile for libpq subsystem (backend half of libpq interface)
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.4 1996/11/14 10:23:51 bryanh Exp $
+# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.5 1997/03/12 21:17:45 scrappy Exp $
#
#-------------------------------------------------------------------------
@@ -24,7 +24,8 @@ LDADD+= $(KRBLIBS)
endif
OBJS = be-dumpdata.o be-fsstubs.o be-pqexec.o \
- auth.o hba.o pqcomm.o portal.o util.o portalbuf.o pqpacket.o pqsignal.o
+ auth.o hba.o pqcomm.o portal.o util.o portalbuf.o pqpacket.o pqsignal.o \
+ password.o
all: SUBSYS.o
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index d1cb560f192..333fb6ce7d1 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.8 1996/11/16 08:09:15 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.9 1997/03/12 21:17:48 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -70,6 +70,7 @@
#include <libpq/libpq.h>
#include <libpq/libpq-be.h>
#include <libpq/hba.h>
+#include <libpq/password.h>
/*----------------------------------------------------------------
* common definitions for generic fe/be routines
@@ -113,10 +114,11 @@ static struct authsvc authsvcs[] = {
{ "krb4", STARTUP_KRB4_MSG, 1 },
{ "krb5", STARTUP_KRB5_MSG, 1 },
#if defined(KRB5)
- { "kerberos", STARTUP_KRB5_MSG, 1 }
+ { "kerberos", STARTUP_KRB5_MSG, 1 },
#else
- { "kerberos", STARTUP_KRB4_MSG, 1 }
+ { "kerberos", STARTUP_KRB4_MSG, 1 },
#endif
+ { "password", STARTUP_PASSWORD_MSG, 1 }
};
static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
@@ -403,6 +405,26 @@ return(STATUS_ERROR);
}
#endif /* KRB5 */
+static int
+pg_password_recvauth(Port *port, char *database, char *DataDir)
+{
+ PacketBuf buf;
+ char *user, *password;
+
+ if(PacketReceive(port, &buf, BLOCKING) != STATUS_OK) {
+ sprintf(PQerrormsg,
+ "pg_password_recvauth: failed to receive authentication packet.\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return STATUS_ERROR;
+ }
+
+ user = buf.data;
+ password = buf.data + strlen(user) + 1;
+
+ return verify_password(user, password, port, database, DataDir);
+}
+
/*
* be_recvauth -- server demux routine for incoming authentication information
*/
@@ -418,8 +440,8 @@ be_recvauth(MsgType msgtype_arg, Port *port, char *username, StartupInfo* sp)
*/
if (msgtype_arg == STARTUP_MSG && useHostBasedAuth)
msgtype = STARTUP_HBA_MSG;
- else
- msgtype = STARTUP_UNAUTH_MSG;
+ else
+ msgtype = msgtype_arg;
if (!username) {
(void) sprintf(PQerrormsg,
@@ -490,6 +512,21 @@ be_recvauth(MsgType msgtype_arg, Port *port, char *username, StartupInfo* sp)
return(STATUS_ERROR);
}
break;
+ case STARTUP_PASSWORD_MSG:
+ if(!be_getauthsvc(msgtype)) {
+ sprintf(PQerrormsg,
+ "be_recvauth: "
+ "plaintext password authentication disallowed\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return(STATUS_ERROR);
+ }
+ if(pg_password_recvauth(port, sp->database, DataDir) != STATUS_OK) {
+ /* pg_password_recvauth or lower-level routines have already set */
+ /* the error message */
+ return(STATUS_ERROR);
+ }
+ break;
default:
(void) sprintf(PQerrormsg,
"be_recvauth: unrecognized message type: %d\n",
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 4bdf497a759..22d532bf537 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.15 1997/01/14 01:56:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.16 1997/03/12 21:17:53 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,31 +30,6 @@
#include <port/inet_aton.h> /* For inet_aton() */
-#define CONF_FILE "pg_hba.conf"
- /* Name of the config file */
-
-#define MAP_FILE "pg_ident.conf"
- /* Name of the usermap file */
-
-#define OLD_CONF_FILE "pg_hba"
- /* Name of the config file in prior releases of Postgres. */
-
-#define MAX_LINES 255
- /* Maximum number of config lines that can apply to one database */
-
-#define MAX_TOKEN 80
-/* Maximum size of one token in the configuration file */
-
-#define USERMAP_NAME_SIZE 16 /* Max size of a usermap name */
-
-#define IDENT_PORT 113
- /* Standard TCP port number for Ident service. Assigned by IANA */
-
-#define IDENT_USERNAME_MAX 512
- /* Max size of username ident server can return */
-
-enum Userauth {Trust, Ident};
-
/* Some standard C libraries, including GNU, have an isblank() function.
Others, including Solaris, do not. So we have our own.
*/
@@ -108,7 +83,7 @@ read_through_eol(FILE *file) {
static void
read_hba_entry2(FILE *file, enum Userauth *userauth_p, char usermap_name[],
- bool *error_p) {
+ bool *error_p, bool *matches_p, bool find_password_entries) {
/*--------------------------------------------------------------------------
Read from file FILE the rest of a host record, after the mask field,
and return the interpretation of it as *userauth_p, usermap_name, and
@@ -120,34 +95,47 @@ read_hba_entry2(FILE *file, enum Userauth *userauth_p, char usermap_name[],
/* Get authentication type token. */
next_token(file, buf, sizeof(buf));
+ userauth_valid = false;
if (buf[0] == '\0') {
*error_p = true;
- read_through_eol(file);
} else {
- if (strcmp(buf, "trust") == 0) {
- userauth_valid = true;
+ userauth_valid = true;
+ if(strcmp(buf, "trust") == 0) {
*userauth_p = Trust;
- } else if (strcmp(buf, "ident") == 0) {
- userauth_valid = true;
+ } else if(strcmp(buf, "ident") == 0) {
*userauth_p = Ident;
- } else userauth_valid = false;
+ } else if(strcmp(buf, "password") == 0) {
+ *userauth_p = Password;
+ } else {
+ userauth_valid = false;
+ }
+
+ if((find_password_entries && strcmp(buf, "password") == 0) ||
+ (!find_password_entries && strcmp(buf, "password") != 0)) {
+ *matches_p = true;
+ } else {
+ *matches_p = false;
+ }
+ }
+
+ if(!userauth_valid || !*matches_p || *error_p) {
if (!userauth_valid) {
*error_p = true;
- read_through_eol(file);
+ }
+ read_through_eol(file);
+ } else {
+ /* Get the map name token, if any */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] == '\0') {
+ *error_p = false;
+ usermap_name[0] = '\0';
} else {
- /* Get the map name token, if any */
+ strncpy(usermap_name, buf, USERMAP_NAME_SIZE);
next_token(file, buf, sizeof(buf));
- if (buf[0] == '\0') {
- *error_p = false;
- usermap_name[0] = '\0';
- } else {
- strncpy(usermap_name, buf, USERMAP_NAME_SIZE);
- next_token(file, buf, sizeof(buf));
- if (buf[0] != '\0') {
- *error_p = true;
- read_through_eol(file);
- } else *error_p = false;
- }
+ if (buf[0] != '\0') {
+ *error_p = true;
+ read_through_eol(file);
+ } else *error_p = false;
}
}
}
@@ -158,7 +146,8 @@ static void
process_hba_record(FILE *file,
const struct in_addr ip_addr, const char database[],
bool *matches_p, bool *error_p,
- enum Userauth *userauth_p, char usermap_name[] ) {
+ enum Userauth *userauth_p, char usermap_name[],
+ bool find_password_entries) {
/*---------------------------------------------------------------------------
Process the non-comment record in the config file that is next on the file.
See if it applies to a connection to a host with IP address "ip_addr"
@@ -221,8 +210,7 @@ process_hba_record(FILE *file,
the rest of the info from it.
*/
read_hba_entry2(file, userauth_p, usermap_name,
- error_p);
- *matches_p = true;
+ error_p, matches_p, find_password_entries);
if (*error_p) {
sprintf(PQerrormsg,
"process_hba_record: invalid syntax in "
@@ -249,7 +237,7 @@ static void
process_open_config_file(FILE *file,
const struct in_addr ip_addr, const char database[],
bool *host_ok_p, enum Userauth *userauth_p,
- char usermap_name[] ) {
+ char usermap_name[], bool find_password_entries) {
/*---------------------------------------------------------------------------
This function does the same thing as find_hba_entry, only with
the config file already open on stream descriptor "file".
@@ -274,7 +262,8 @@ process_open_config_file(FILE *file,
if (c == '#') read_through_eol(file);
else {
process_hba_record(file, ip_addr, database,
- &found_entry, &error, userauth_p, usermap_name);
+ &found_entry, &error, userauth_p, usermap_name,
+ find_password_entries);
}
}
}
@@ -286,11 +275,11 @@ process_open_config_file(FILE *file,
-static void
+void
find_hba_entry(const char DataDir[], const struct in_addr ip_addr,
const char database[],
bool *host_ok_p, enum Userauth *userauth_p,
- char usermap_name[] ) {
+ char usermap_name[], bool find_password_entries) {
/*--------------------------------------------------------------------------
Read the config file and find an entry that allows connection from
host "ip_addr" to database "database". If not found, return
@@ -360,7 +349,7 @@ find_hba_entry(const char DataDir[], const struct in_addr ip_addr,
pqdebug("%s", PQerrormsg);
} else {
process_open_config_file(file, ip_addr, database, host_ok_p, userauth_p,
- usermap_name);
+ usermap_name, find_password_entries);
fclose(file);
}
free(conf_file);
@@ -731,7 +720,8 @@ hba_recvauth(const Port *port, const char database[], const char user[],
find_hba_entry(DataDir, port->raddr.sin_addr, database,
- &host_ok, &userauth, usermap_name);
+ &host_ok, &userauth, usermap_name,
+ false /* don't find password entries of type 'password' */);
if (!host_ok) retvalue = STATUS_ERROR;
else {
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 928bc281b8d..6b8ecdac28b 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.11 1997/02/14 04:15:29 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.12 1997/03/12 21:17:58 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -703,3 +703,29 @@ StreamOpen(char *hostName, short portName, Port *port)
return(STATUS_OK);
}
+
+static char *authentication_type_name[] = {
+ 0, 0, 0, 0, 0, 0, 0,
+ "the default authentication type",
+ 0, 0,
+ "Kerberos v4",
+ "Kerberos v5",
+ "host-based authentication",
+ "unauthenication",
+ "plaintext password authentication"
+};
+
+char *name_of_authentication_type(int type)
+{
+ char *result = 0;
+
+ if(type >= 1 && type <= LAST_AUTHENTICATION_TYPE) {
+ result = authentication_type_name[type];
+ }
+
+ if(result == 0) {
+ result = "<unknown authentication type>";
+ }
+
+ return result;
+}
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 628d44d7d97..5c749c5f353 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.43 1997/03/02 02:17:32 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.44 1997/03/12 21:18:38 scrappy Exp $
*
* NOTES
*
@@ -660,8 +660,8 @@ ConnStartup(Port *port, int *status,
char buffer[200 + sizeof(namebuf)];
sprintf(buffer,
"Failed to authenticate client as Postgres user '%s' "
- "using authentication scheme %d.",
- namebuf, msgType);
+ "using %s: %s",
+ namebuf, name_of_authentication_type(msgType), PQerrormsg);
strncpy(errormsg, buffer, errormsg_len);
*status = STATUS_ERROR;
} else {