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.
This commit is contained in:
parent
5dde558ce6
commit
3a7c93e7f3
@ -4,7 +4,7 @@
|
|||||||
# Makefile for libpq subsystem (backend half of libpq interface)
|
# Makefile for libpq subsystem (backend half of libpq interface)
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# 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
|
endif
|
||||||
|
|
||||||
OBJS = be-dumpdata.o be-fsstubs.o be-pqexec.o \
|
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
|
all: SUBSYS.o
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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.h>
|
||||||
#include <libpq/libpq-be.h>
|
#include <libpq/libpq-be.h>
|
||||||
#include <libpq/hba.h>
|
#include <libpq/hba.h>
|
||||||
|
#include <libpq/password.h>
|
||||||
|
|
||||||
/*----------------------------------------------------------------
|
/*----------------------------------------------------------------
|
||||||
* common definitions for generic fe/be routines
|
* common definitions for generic fe/be routines
|
||||||
@ -113,10 +114,11 @@ static struct authsvc authsvcs[] = {
|
|||||||
{ "krb4", STARTUP_KRB4_MSG, 1 },
|
{ "krb4", STARTUP_KRB4_MSG, 1 },
|
||||||
{ "krb5", STARTUP_KRB5_MSG, 1 },
|
{ "krb5", STARTUP_KRB5_MSG, 1 },
|
||||||
#if defined(KRB5)
|
#if defined(KRB5)
|
||||||
{ "kerberos", STARTUP_KRB5_MSG, 1 }
|
{ "kerberos", STARTUP_KRB5_MSG, 1 },
|
||||||
#else
|
#else
|
||||||
{ "kerberos", STARTUP_KRB4_MSG, 1 }
|
{ "kerberos", STARTUP_KRB4_MSG, 1 },
|
||||||
#endif
|
#endif
|
||||||
|
{ "password", STARTUP_PASSWORD_MSG, 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
|
static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
|
||||||
@ -403,6 +405,26 @@ return(STATUS_ERROR);
|
|||||||
}
|
}
|
||||||
#endif /* KRB5 */
|
#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
|
* 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)
|
if (msgtype_arg == STARTUP_MSG && useHostBasedAuth)
|
||||||
msgtype = STARTUP_HBA_MSG;
|
msgtype = STARTUP_HBA_MSG;
|
||||||
else
|
else
|
||||||
msgtype = STARTUP_UNAUTH_MSG;
|
msgtype = msgtype_arg;
|
||||||
|
|
||||||
if (!username) {
|
if (!username) {
|
||||||
(void) sprintf(PQerrormsg,
|
(void) sprintf(PQerrormsg,
|
||||||
@ -490,6 +512,21 @@ be_recvauth(MsgType msgtype_arg, Port *port, char *username, StartupInfo* sp)
|
|||||||
return(STATUS_ERROR);
|
return(STATUS_ERROR);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
(void) sprintf(PQerrormsg,
|
(void) sprintf(PQerrormsg,
|
||||||
"be_recvauth: unrecognized message type: %d\n",
|
"be_recvauth: unrecognized message type: %d\n",
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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() */
|
#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.
|
/* Some standard C libraries, including GNU, have an isblank() function.
|
||||||
Others, including Solaris, do not. So we have our own.
|
Others, including Solaris, do not. So we have our own.
|
||||||
*/
|
*/
|
||||||
@ -108,7 +83,7 @@ read_through_eol(FILE *file) {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
read_hba_entry2(FILE *file, enum Userauth *userauth_p, char usermap_name[],
|
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,
|
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
|
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. */
|
/* Get authentication type token. */
|
||||||
next_token(file, buf, sizeof(buf));
|
next_token(file, buf, sizeof(buf));
|
||||||
|
userauth_valid = false;
|
||||||
if (buf[0] == '\0') {
|
if (buf[0] == '\0') {
|
||||||
*error_p = true;
|
*error_p = true;
|
||||||
read_through_eol(file);
|
|
||||||
} else {
|
} else {
|
||||||
if (strcmp(buf, "trust") == 0) {
|
userauth_valid = true;
|
||||||
userauth_valid = true;
|
if(strcmp(buf, "trust") == 0) {
|
||||||
*userauth_p = Trust;
|
*userauth_p = Trust;
|
||||||
} else if (strcmp(buf, "ident") == 0) {
|
} else if(strcmp(buf, "ident") == 0) {
|
||||||
userauth_valid = true;
|
|
||||||
*userauth_p = Ident;
|
*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) {
|
if (!userauth_valid) {
|
||||||
*error_p = true;
|
*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 {
|
} else {
|
||||||
/* Get the map name token, if any */
|
strncpy(usermap_name, buf, USERMAP_NAME_SIZE);
|
||||||
next_token(file, buf, sizeof(buf));
|
next_token(file, buf, sizeof(buf));
|
||||||
if (buf[0] == '\0') {
|
if (buf[0] != '\0') {
|
||||||
*error_p = false;
|
*error_p = true;
|
||||||
usermap_name[0] = '\0';
|
read_through_eol(file);
|
||||||
} else {
|
} else *error_p = false;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,7 +146,8 @@ static void
|
|||||||
process_hba_record(FILE *file,
|
process_hba_record(FILE *file,
|
||||||
const struct in_addr ip_addr, const char database[],
|
const struct in_addr ip_addr, const char database[],
|
||||||
bool *matches_p, bool *error_p,
|
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.
|
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"
|
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.
|
the rest of the info from it.
|
||||||
*/
|
*/
|
||||||
read_hba_entry2(file, userauth_p, usermap_name,
|
read_hba_entry2(file, userauth_p, usermap_name,
|
||||||
error_p);
|
error_p, matches_p, find_password_entries);
|
||||||
*matches_p = true;
|
|
||||||
if (*error_p) {
|
if (*error_p) {
|
||||||
sprintf(PQerrormsg,
|
sprintf(PQerrormsg,
|
||||||
"process_hba_record: invalid syntax in "
|
"process_hba_record: invalid syntax in "
|
||||||
@ -249,7 +237,7 @@ static void
|
|||||||
process_open_config_file(FILE *file,
|
process_open_config_file(FILE *file,
|
||||||
const struct in_addr ip_addr, const char database[],
|
const struct in_addr ip_addr, const char database[],
|
||||||
bool *host_ok_p, enum Userauth *userauth_p,
|
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
|
This function does the same thing as find_hba_entry, only with
|
||||||
the config file already open on stream descriptor "file".
|
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);
|
if (c == '#') read_through_eol(file);
|
||||||
else {
|
else {
|
||||||
process_hba_record(file, ip_addr, database,
|
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,
|
find_hba_entry(const char DataDir[], const struct in_addr ip_addr,
|
||||||
const char database[],
|
const char database[],
|
||||||
bool *host_ok_p, enum Userauth *userauth_p,
|
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
|
Read the config file and find an entry that allows connection from
|
||||||
host "ip_addr" to database "database". If not found, return
|
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);
|
pqdebug("%s", PQerrormsg);
|
||||||
} else {
|
} else {
|
||||||
process_open_config_file(file, ip_addr, database, host_ok_p, userauth_p,
|
process_open_config_file(file, ip_addr, database, host_ok_p, userauth_p,
|
||||||
usermap_name);
|
usermap_name, find_password_entries);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
free(conf_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,
|
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;
|
if (!host_ok) retvalue = STATUS_ERROR;
|
||||||
else {
|
else {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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);
|
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;
|
||||||
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -660,8 +660,8 @@ ConnStartup(Port *port, int *status,
|
|||||||
char buffer[200 + sizeof(namebuf)];
|
char buffer[200 + sizeof(namebuf)];
|
||||||
sprintf(buffer,
|
sprintf(buffer,
|
||||||
"Failed to authenticate client as Postgres user '%s' "
|
"Failed to authenticate client as Postgres user '%s' "
|
||||||
"using authentication scheme %d.",
|
"using %s: %s",
|
||||||
namebuf, msgType);
|
namebuf, name_of_authentication_type(msgType), PQerrormsg);
|
||||||
strncpy(errormsg, buffer, errormsg_len);
|
strncpy(errormsg, buffer, errormsg_len);
|
||||||
*status = STATUS_ERROR;
|
*status = STATUS_ERROR;
|
||||||
} else {
|
} else {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.57 1997/02/13 08:31:48 scrappy Exp $
|
* $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.58 1997/03/12 21:19:14 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -29,6 +29,9 @@
|
|||||||
#ifndef HAVE_STRDUP
|
#ifndef HAVE_STRDUP
|
||||||
#include "strdup.h"
|
#include "strdup.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_TERMIOS_H
|
||||||
|
#include <termios.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBREADLINE
|
#ifdef HAVE_LIBREADLINE
|
||||||
# ifdef HAVE_READLINE_H
|
# ifdef HAVE_READLINE_H
|
||||||
@ -67,6 +70,7 @@ typedef struct _psqlSettings {
|
|||||||
bool singleStep; /* prompt before for each query */
|
bool singleStep; /* prompt before for each query */
|
||||||
bool singleLineMode; /* query terminated by newline */
|
bool singleLineMode; /* query terminated by newline */
|
||||||
bool useReadline;/* use libreadline routines */
|
bool useReadline;/* use libreadline routines */
|
||||||
|
bool getPassword;/* prompt the user for a username and password */
|
||||||
} PsqlSettings;
|
} PsqlSettings;
|
||||||
|
|
||||||
/* declarations for functions in this file */
|
/* declarations for functions in this file */
|
||||||
@ -78,6 +82,9 @@ handleCopyIn(PGresult * res, const bool mustprompt,
|
|||||||
FILE * copystream);
|
FILE * copystream);
|
||||||
static int tableList(PsqlSettings * ps, bool deep_tablelist);
|
static int tableList(PsqlSettings * ps, bool deep_tablelist);
|
||||||
static int tableDesc(PsqlSettings * ps, char *table);
|
static int tableDesc(PsqlSettings * ps, char *table);
|
||||||
|
static void prompt_for_password(char *username, char *password);
|
||||||
|
static char * make_connect_string(char *host, char *port, char *dbname,
|
||||||
|
char *username, char *password);
|
||||||
|
|
||||||
char *gets_noreadline(char *prompt, FILE * source);
|
char *gets_noreadline(char *prompt, FILE * source);
|
||||||
char *gets_readline(char *prompt, FILE * source);
|
char *gets_readline(char *prompt, FILE * source);
|
||||||
@ -125,6 +132,7 @@ usage(char *progname)
|
|||||||
fprintf(stderr, "\t -s single step mode (prompts for each query)\n");
|
fprintf(stderr, "\t -s single step mode (prompts for each query)\n");
|
||||||
fprintf(stderr, "\t -S single line mode (i.e. query terminated by newline)\n");
|
fprintf(stderr, "\t -S single line mode (i.e. query terminated by newline)\n");
|
||||||
fprintf(stderr, "\t -t turn off printing of headings and row count\n");
|
fprintf(stderr, "\t -t turn off printing of headings and row count\n");
|
||||||
|
fprintf(stderr, "\t -u ask for a username and password for authentication\n");
|
||||||
fprintf(stderr, "\t -T html set html3.0 table command options (cf. -H)\n");
|
fprintf(stderr, "\t -T html set html3.0 table command options (cf. -H)\n");
|
||||||
fprintf(stderr, "\t -x turn on expanded output (field names on left)\n");
|
fprintf(stderr, "\t -x turn on expanded output (field names on left)\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -1463,8 +1471,13 @@ main(int argc, char **argv)
|
|||||||
else
|
else
|
||||||
settings.useReadline = 1;
|
settings.useReadline = 1;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef PSQL_ALWAYS_GET_PASSWORDS
|
||||||
|
settings.getPassword = 1;
|
||||||
|
#else
|
||||||
|
settings.getPassword = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "Aa:c:d:ef:F:lh:Hnso:p:qStT:x")) != EOF) {
|
while ((c = getopt(argc, argv, "Aa:c:d:ef:F:lh:Hnso:p:qStT:ux")) != EOF) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'A':
|
case 'A':
|
||||||
settings.opt.align = 0;
|
settings.opt.align = 0;
|
||||||
@ -1523,6 +1536,9 @@ main(int argc, char **argv)
|
|||||||
case 'T':
|
case 'T':
|
||||||
settings.opt.tableOpt = optarg;
|
settings.opt.tableOpt = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'u':
|
||||||
|
settings.getPassword = 1;
|
||||||
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
settings.opt.expanded = 1;
|
settings.opt.expanded = 1;
|
||||||
break;
|
break;
|
||||||
@ -1538,7 +1554,21 @@ main(int argc, char **argv)
|
|||||||
if (listDatabases)
|
if (listDatabases)
|
||||||
dbname = "template1";
|
dbname = "template1";
|
||||||
|
|
||||||
settings.db = PQsetdb(host, port, NULL, NULL, dbname);
|
if(settings.getPassword) {
|
||||||
|
char username[9];
|
||||||
|
char password[9];
|
||||||
|
char *connect_string;
|
||||||
|
|
||||||
|
prompt_for_password(username, password);
|
||||||
|
|
||||||
|
/* now use PQconnectdb so we can pass these options */
|
||||||
|
connect_string = make_connect_string(host, port, dbname, username, password);
|
||||||
|
settings.db = PQconnectdb(connect_string);
|
||||||
|
free(connect_string);
|
||||||
|
} else {
|
||||||
|
settings.db = PQsetdb(host, port, NULL, NULL, dbname);
|
||||||
|
}
|
||||||
|
|
||||||
dbname = PQdb(settings.db);
|
dbname = PQdb(settings.db);
|
||||||
|
|
||||||
if (PQstatus(settings.db) == CONNECTION_BAD) {
|
if (PQstatus(settings.db) == CONNECTION_BAD) {
|
||||||
@ -1711,3 +1741,87 @@ setFout(PsqlSettings * ps, char *fname)
|
|||||||
}
|
}
|
||||||
return ps->queryFout;
|
return ps->queryFout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void prompt_for_password(char *username, char *password)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
#ifdef HAVE_TERMIOS_H
|
||||||
|
struct termios t_orig, t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("Username: ");
|
||||||
|
fgets(username, 9, stdin);
|
||||||
|
length = strlen(username);
|
||||||
|
if(length > 0 && username[length-1] == '\n') username[length-1] = '\0';
|
||||||
|
|
||||||
|
printf("Password: ");
|
||||||
|
#ifdef HAVE_TERMIOS_H
|
||||||
|
tcgetattr(0, &t);
|
||||||
|
t_orig = t;
|
||||||
|
t.c_lflag &= ~ECHO;
|
||||||
|
tcsetattr(0, TCSADRAIN, &t);
|
||||||
|
#endif
|
||||||
|
fgets(password, 9, stdin);
|
||||||
|
#ifdef HAVE_TERMIOS_H
|
||||||
|
tcsetattr(0, TCSADRAIN, &t_orig);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
length = strlen(password);
|
||||||
|
if(length > 0 && password[length-1] == '\n') password[length-1] = '\0';
|
||||||
|
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *make_connect_string(char *host, char *port, char *dbname,
|
||||||
|
char *username, char *password)
|
||||||
|
{
|
||||||
|
int connect_string_len = 0;
|
||||||
|
char *connect_string;
|
||||||
|
|
||||||
|
if(host)
|
||||||
|
connect_string_len += 6 + strlen(host); /* 6 == "host=" + " " */
|
||||||
|
if(username)
|
||||||
|
connect_string_len += 6 + strlen(username); /* 6 == "user=" + " " */
|
||||||
|
if(password)
|
||||||
|
connect_string_len += 10 + strlen(password); /* 10 == "password=" + " " */
|
||||||
|
if(port)
|
||||||
|
connect_string_len += 6 + strlen(port); /* 6 == "port=" + " " */
|
||||||
|
if(dbname)
|
||||||
|
connect_string_len += 8 + strlen(dbname); /* 8 == "dbname=" + " " */
|
||||||
|
connect_string_len += 18; /* "authtype=password" + null */
|
||||||
|
|
||||||
|
connect_string = (char *)malloc(connect_string_len);
|
||||||
|
if(!connect_string) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
connect_string[0] = '\0';
|
||||||
|
if(host) {
|
||||||
|
strcat(connect_string, "host=");
|
||||||
|
strcat(connect_string, host);
|
||||||
|
strcat(connect_string, " ");
|
||||||
|
}
|
||||||
|
if(username) {
|
||||||
|
strcat(connect_string, "user=");
|
||||||
|
strcat(connect_string, username);
|
||||||
|
strcat(connect_string, " ");
|
||||||
|
}
|
||||||
|
if(password) {
|
||||||
|
strcat(connect_string, "password=");
|
||||||
|
strcat(connect_string, password);
|
||||||
|
strcat(connect_string, " ");
|
||||||
|
}
|
||||||
|
if(port) {
|
||||||
|
strcat(connect_string, "port=");
|
||||||
|
strcat(connect_string, port);
|
||||||
|
strcat(connect_string, " ");
|
||||||
|
}
|
||||||
|
if(dbname) {
|
||||||
|
strcat(connect_string, "dbname=");
|
||||||
|
strcat(connect_string, dbname);
|
||||||
|
strcat(connect_string, " ");
|
||||||
|
}
|
||||||
|
strcat(connect_string, "authtype=password");
|
||||||
|
|
||||||
|
return connect_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -266,8 +266,11 @@
|
|||||||
*/
|
*/
|
||||||
/*#define GEQO */ /* backend/optimizer/path/allpaths.c */
|
/*#define GEQO */ /* backend/optimizer/path/allpaths.c */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define this if you want psql to _always_ ask for a username and a password
|
||||||
|
* for password authentication.
|
||||||
|
*/
|
||||||
|
/* #define PSQL_ALWAYS_GET_PASSWORDS */
|
||||||
|
|
||||||
/* Undocumented "features"? */
|
/* Undocumented "features"? */
|
||||||
#define FASTBUILD /* access/nbtree/nbtsort.c */
|
#define FASTBUILD /* access/nbtree/nbtsort.c */
|
||||||
|
@ -4,16 +4,46 @@
|
|||||||
* Interface to hba.c
|
* Interface to hba.c
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* $Id: hba.h,v 1.2 1996/11/06 10:29:58 scrappy Exp $
|
* $Id: hba.h,v 1.3 1997/03/12 21:22:16 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#ifndef HBA_H
|
#ifndef HBA_H
|
||||||
#define HBA_H
|
#define HBA_H
|
||||||
|
|
||||||
|
#include <libpq/pqcomm.h>
|
||||||
|
|
||||||
|
#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, Password};
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
hba_recvauth(const Port *port, const char database[], const char user[],
|
hba_recvauth(const Port *port, const char database[], const char user[],
|
||||||
const char DataDir[]);
|
const char DataDir[]);
|
||||||
|
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[], bool find_password_entries);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pqcomm.h,v 1.7 1997/02/11 15:37:18 momjian Exp $
|
* $Id: pqcomm.h,v 1.8 1997/03/12 21:22:19 scrappy Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Some of this should move to libpq.h
|
* Some of this should move to libpq.h
|
||||||
@ -52,10 +52,15 @@ typedef enum _MsgType {
|
|||||||
STARTUP_KRB4_MSG=10, /* krb4 session follows startup packet */
|
STARTUP_KRB4_MSG=10, /* krb4 session follows startup packet */
|
||||||
STARTUP_KRB5_MSG=11, /* krb5 session follows startup packet */
|
STARTUP_KRB5_MSG=11, /* krb5 session follows startup packet */
|
||||||
STARTUP_HBA_MSG=12, /* use host-based authentication */
|
STARTUP_HBA_MSG=12, /* use host-based authentication */
|
||||||
STARTUP_UNAUTH_MSG=13 /* use unauthenticated connection */
|
STARTUP_UNAUTH_MSG=13, /* use unauthenticated connection */
|
||||||
|
STARTUP_PASSWORD_MSG=14 /* use plaintext password authentication */
|
||||||
/* insert new values here -- DO NOT REORDER OR DELETE ENTRIES */
|
/* insert new values here -- DO NOT REORDER OR DELETE ENTRIES */
|
||||||
|
/* also change LAST_AUTHENTICATION_TYPE below and add to the */
|
||||||
|
/* authentication_type_name[] array in pqcomm.c */
|
||||||
} MsgType;
|
} MsgType;
|
||||||
|
|
||||||
|
#define LAST_AUTHENTICATION_TYPE 14
|
||||||
|
|
||||||
typedef char *Addr;
|
typedef char *Addr;
|
||||||
typedef int PacketLen; /* packet length */
|
typedef int PacketLen; /* packet length */
|
||||||
|
|
||||||
@ -126,6 +131,6 @@ extern int PacketSend(Port *port, PacketBuf *buf,
|
|||||||
PacketLen len, char nonBlocking);
|
PacketLen len, char nonBlocking);
|
||||||
/* extern PacketBuf* StartupInfo2PacketBuf(StartupInfo*); */
|
/* extern PacketBuf* StartupInfo2PacketBuf(StartupInfo*); */
|
||||||
/* extern StartupInfo* PacketBuf2StartupInfo(PacketBuf*); */
|
/* extern StartupInfo* PacketBuf2StartupInfo(PacketBuf*); */
|
||||||
|
extern char *name_of_authentication_type(int type);
|
||||||
|
|
||||||
#endif /* PQCOMM_H */
|
#endif /* PQCOMM_H */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 "libpq-fe.h"
|
||||||
#include "fe-auth.h"
|
#include "fe-auth.h"
|
||||||
|
#include "fe-connect.h"
|
||||||
|
|
||||||
/*----------------------------------------------------------------
|
/*----------------------------------------------------------------
|
||||||
* common definitions for generic fe/be routines
|
* common definitions for generic fe/be routines
|
||||||
@ -79,7 +80,8 @@ static struct authsvc authsvcs[] = {
|
|||||||
#else /* !(KRB4 || KRB5) */
|
#else /* !(KRB4 || KRB5) */
|
||||||
1
|
1
|
||||||
#endif /* !(KRB4 || KRB5) */
|
#endif /* !(KRB4 || KRB5) */
|
||||||
}
|
},
|
||||||
|
{ "password", STARTUP_PASSWORD_MSG, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
|
static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
|
||||||
@ -431,12 +433,30 @@ pg_krb5_sendauth(const char* PQerrormsg,int sock,
|
|||||||
|
|
||||||
#endif /* KRB5 */
|
#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
|
* fe_sendauth -- client demux routine for outgoing authentication information
|
||||||
*/
|
*/
|
||||||
int
|
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) {
|
switch (msgtype) {
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
@ -464,6 +484,8 @@ fe_sendauth(MsgType msgtype, Port *port, const char *hostname, const char* PQerr
|
|||||||
#endif
|
#endif
|
||||||
case STARTUP_MSG:
|
case STARTUP_MSG:
|
||||||
break;
|
break;
|
||||||
|
case STARTUP_PASSWORD_MSG:
|
||||||
|
pg_password_sendauth(port, user, password);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* 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"
|
#define DEFAULT_CLIENT_AUTHSVC "kerberos"
|
||||||
#endif /* KRB4 || KRB5 */
|
#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);
|
extern void fe_setauthsvc(const char *name, char* PQerrormsg);
|
||||||
|
|
||||||
#define PG_KRB4_VERSION "PGVER4.1" /* at most KRB_SENDAUTH_VLEN chars */
|
#define PG_KRB4_VERSION "PGVER4.1" /* at most KRB_SENDAUTH_VLEN chars */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 "postgres.h"
|
||||||
#include "libpq/pqcomm.h" /* for decls of MsgType, PacketBuf, StartupInfo */
|
#include "libpq/pqcomm.h" /* for decls of MsgType, PacketBuf, StartupInfo */
|
||||||
#include "fe-auth.h"
|
#include "fe-auth.h"
|
||||||
|
#include "fe-connect.h"
|
||||||
#include "libpq-fe.h"
|
#include "libpq-fe.h"
|
||||||
|
|
||||||
#ifndef HAVE_STRDUP
|
#ifndef HAVE_STRDUP
|
||||||
@ -38,8 +39,6 @@
|
|||||||
/* use a local version instead of the one found in pqpacket.c */
|
/* use a local version instead of the one found in pqpacket.c */
|
||||||
static ConnStatusType connectDB(PGconn *conn);
|
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 startup2PacketBuf(StartupInfo* s, PacketBuf* res);
|
||||||
static void freePGconn(PGconn *conn);
|
static void freePGconn(PGconn *conn);
|
||||||
static void closePGconn(PGconn *conn);
|
static void closePGconn(PGconn *conn);
|
||||||
@ -73,9 +72,15 @@ static PQconninfoOption PQconninfoOptions[] = {
|
|||||||
/* Option-name Environment-Var Compiled-in Current value */
|
/* Option-name Environment-Var Compiled-in Current value */
|
||||||
/* Label Disp-Char */
|
/* Label Disp-Char */
|
||||||
/* ----------------- --------------- --------------- --------------- */
|
/* ----------------- --------------- --------------- --------------- */
|
||||||
|
{ "authtype", "PGAUTHTYPE", NULL, NULL,
|
||||||
|
"Database-Authtype", "", 20 },
|
||||||
|
|
||||||
{ "user", "PGUSER", NULL, NULL,
|
{ "user", "PGUSER", NULL, NULL,
|
||||||
"Database-User", "", 20 },
|
"Database-User", "", 20 },
|
||||||
|
|
||||||
|
{ "password", "PGPASSWORD", NULL, NULL,
|
||||||
|
"Database-Password", "", 20 },
|
||||||
|
|
||||||
{ "dbname", "PGDATABASE", NULL, NULL,
|
{ "dbname", "PGDATABASE", NULL, NULL,
|
||||||
"Database-Name", "", 20 },
|
"Database-Name", "", 20 },
|
||||||
|
|
||||||
@ -187,6 +192,8 @@ PQconnectdb(const char *conninfo)
|
|||||||
conn->pgtty = strdup(conninfo_getval("tty"));
|
conn->pgtty = strdup(conninfo_getval("tty"));
|
||||||
conn->pgoptions = strdup(conninfo_getval("options"));
|
conn->pgoptions = strdup(conninfo_getval("options"));
|
||||||
conn->pguser = strdup(conninfo_getval("user"));
|
conn->pguser = strdup(conninfo_getval("user"));
|
||||||
|
conn->pgpass = strdup(conninfo_getval("password"));
|
||||||
|
conn->pgauth = strdup(conninfo_getval("authtype"));
|
||||||
conn->dbName = strdup(conninfo_getval("dbname"));
|
conn->dbName = strdup(conninfo_getval("dbname"));
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
@ -195,6 +202,13 @@ PQconnectdb(const char *conninfo)
|
|||||||
*/
|
*/
|
||||||
conninfo_free();
|
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
|
* Connect to the database
|
||||||
* ----------
|
* ----------
|
||||||
@ -260,6 +274,8 @@ PQconndefaults(void)
|
|||||||
*
|
*
|
||||||
* PGUSER Postgres username to associate with the connection.
|
* PGUSER Postgres username to associate with the connection.
|
||||||
*
|
*
|
||||||
|
* PGPASSWORD The user's password.
|
||||||
|
*
|
||||||
* PGDATABASE name of database to which to connect if <pgdatabase>
|
* PGDATABASE name of database to which to connect if <pgdatabase>
|
||||||
* argument is NULL or a null string
|
* 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 (!error) {
|
||||||
if (((tmp = (char *)dbName) && (dbName[0] != '\0')) ||
|
if (((tmp = (char *)dbName) && (dbName[0] != '\0')) ||
|
||||||
((tmp = getenv("PGDATABASE")))) {
|
((tmp = getenv("PGDATABASE")))) {
|
||||||
@ -467,6 +489,7 @@ connectDB(PGconn *conn)
|
|||||||
|
|
||||||
/* authenticate as required*/
|
/* authenticate as required*/
|
||||||
if (fe_sendauth(msgtype, port, conn->pghost,
|
if (fe_sendauth(msgtype, port, conn->pghost,
|
||||||
|
conn->pguser, conn->pgpass,
|
||||||
conn->errorMessage) != STATUS_OK) {
|
conn->errorMessage) != STATUS_OK) {
|
||||||
(void) sprintf(conn->errorMessage,
|
(void) sprintf(conn->errorMessage,
|
||||||
"connectDB() -- authentication failed with %s\n",
|
"connectDB() -- authentication failed with %s\n",
|
||||||
@ -474,6 +497,11 @@ connectDB(PGconn *conn)
|
|||||||
goto connect_errReturn;
|
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 */
|
/* set up the socket file descriptors */
|
||||||
conn->Pfout = fdopen(port->sock, "w");
|
conn->Pfout = fdopen(port->sock, "w");
|
||||||
conn->Pfin = fdopen(dup(port->sock), "r");
|
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.
|
* buffer management. For now, we're not going to do it.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
packetSend(Port *port,
|
packetSend(Port *port,
|
||||||
PacketBuf *buf,
|
PacketBuf *buf,
|
||||||
PacketLen len,
|
PacketLen len,
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* 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;
|
int asyncNotifyWaiting;
|
||||||
Dllist* notifyList;
|
Dllist* notifyList;
|
||||||
char *pguser; /* Postgres username of user who is connected */
|
char *pguser; /* Postgres username of user who is connected */
|
||||||
|
char *pgpass;
|
||||||
|
char *pgauth;
|
||||||
PGlobjfuncs *lobjfuncs; /* Backend function OID's for large object access */
|
PGlobjfuncs *lobjfuncs; /* Backend function OID's for large object access */
|
||||||
} PGconn;
|
} PGconn;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user