Commit d5bbe2ac authored by Marc G. Fournier's avatar Marc G. Fournier

From: Phil Thompson <phil@river-bank.demon.co.uk>

I've completed the patch to fix the protocol and authentication issues I
was discussing a couple of weeks ago.  The particular changes are:

- the protocol has a version number
- network byte order is used throughout
- the pg_hba.conf file is used to specify what method is used to
  authenticate a frontend (either password, ident, trust, reject, krb4
  or krb5)
- support for multiplexed backends is removed
- appropriate changes to man pages
- the -a switch to many programs to specify an authentication service
  no longer has any effect
- the libpq.so version number has changed to 1.1

The new backend still supports the old protocol so old interfaces won't
break.
parent 91d983aa
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-dumpdata.c,v 1.9 1997/09/12 04:07:50 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-dumpdata.c,v 1.10 1998/01/26 01:41:05 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include <postgres.h> #include <postgres.h>
#include <lib/dllist.h> #include <lib/dllist.h>
#include <libpq/libpq-be.h> #include <libpq/libpq.h>
#include <access/heapam.h> #include <access/heapam.h>
#include <access/htup.h> #include <access/htup.h>
#include <storage/buf.h> #include <storage/buf.h>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-pqexec.c,v 1.13 1998/01/07 21:03:16 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-pqexec.c,v 1.14 1998/01/26 01:41:06 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include <tcop/fastpath.h> #include <tcop/fastpath.h>
#include <tcop/tcopprot.h> #include <tcop/tcopprot.h>
#include <lib/dllist.h> #include <lib/dllist.h>
#include <libpq/libpq-be.h> #include <libpq/libpq.h>
#include <fmgr.h> #include <fmgr.h>
#include <utils/exc.h> #include <utils/exc.h>
#include <utils/builtins.h> #include <utils/builtins.h>
......
...@@ -17,9 +17,6 @@ ...@@ -17,9 +17,6 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
#include "postgres.h" #include "postgres.h"
#include "miscadmin.h" #include "miscadmin.h"
...@@ -27,6 +24,10 @@ ...@@ -27,6 +24,10 @@
#include "storage/fd.h" #include "storage/fd.h"
#include "libpq/crypt.h" #include "libpq/crypt.h"
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
char** pwd_cache = NULL; char** pwd_cache = NULL;
int pwd_cache_count = 0; int pwd_cache_count = 0;
...@@ -219,6 +220,7 @@ int crypt_getloginfo(const char* user, char** passwd, char** valuntil) { ...@@ -219,6 +220,7 @@ int crypt_getloginfo(const char* user, char** passwd, char** valuntil) {
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#ifdef 0
MsgType crypt_salt(const char* user) { MsgType crypt_salt(const char* user) {
char* passwd; char* passwd;
...@@ -237,6 +239,7 @@ MsgType crypt_salt(const char* user) { ...@@ -237,6 +239,7 @@ MsgType crypt_salt(const char* user) {
if (valuntil) free((void*)valuntil); if (valuntil) free((void*)valuntil);
return STARTUP_SALT_MSG; return STARTUP_SALT_MSG;
} }
#endif
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -258,7 +261,13 @@ int crypt_verify(Port* port, const char* user, const char* pgpass) { ...@@ -258,7 +261,13 @@ int crypt_verify(Port* port, const char* user, const char* pgpass) {
return STATUS_ERROR; return STATUS_ERROR;
} }
crypt_pwd = crypt(passwd, port->salt); /*
* Compare with the encrypted or plain password depending on the
* authentication method being used for this connection.
*/
crypt_pwd = (port->auth_method == uaCrypt ? crypt(passwd, port->salt) : passwd);
if (!strcmp(pgpass, crypt_pwd)) { if (!strcmp(pgpass, crypt_pwd)) {
/* check here to be sure we are not past valuntil /* check here to be sure we are not past valuntil
*/ */
......
This diff is collapsed.
#include <postgres.h> #include <postgres.h>
#include <miscadmin.h>
#include <libpq/password.h> #include <libpq/password.h>
#include <libpq/hba.h>
#include <libpq/libpq.h> #include <libpq/libpq.h>
#include <storage/fd.h> #include <storage/fd.h>
#include <string.h> #include <string.h>
...@@ -10,56 +10,15 @@ ...@@ -10,56 +10,15 @@
#endif #endif
int int
verify_password(char *user, char *password, Port *port, verify_password(char *auth_arg, char *user, char *password)
char *database, char *DataDir)
{ {
bool host_ok;
enum Userauth userauth;
char pw_file_name[PWFILE_NAME_SIZE + 1];
char *pw_file_fullname; char *pw_file_fullname;
FILE *pw_file; FILE *pw_file;
char pw_file_line[255]; pw_file_fullname = (char *) palloc(strlen(DataDir) + strlen(auth_arg) + 2);
char *p,
*test_user,
*test_pw;
find_hba_entry(DataDir, port->raddr.in.sin_addr, database,
&host_ok, &userauth, pw_file_name, true);
if (!host_ok)
{
sprintf(PQerrormsg,
"verify_password: couldn't find entry for connecting host\n");
fputs(PQerrormsg, stderr);
pqdebug("%s", PQerrormsg);
return STATUS_ERROR;
}
if (userauth != Password)
{
sprintf(PQerrormsg,
"verify_password: couldn't find entry of type 'password' "
"for this host\n");
fputs(PQerrormsg, stderr);
pqdebug("%s", PQerrormsg);
return STATUS_ERROR;
}
if (!pw_file_name || pw_file_name[0] == '\0')
{
sprintf(PQerrormsg,
"verify_password: no password file specified\n");
fputs(PQerrormsg, stderr);
pqdebug("%s", PQerrormsg);
return STATUS_ERROR;
}
pw_file_fullname = (char *) palloc(strlen(DataDir) + strlen(pw_file_name) + 2);
strcpy(pw_file_fullname, DataDir); strcpy(pw_file_fullname, DataDir);
strcat(pw_file_fullname, "/"); strcat(pw_file_fullname, "/");
strcat(pw_file_fullname, pw_file_name); strcat(pw_file_fullname, auth_arg);
pw_file = AllocateFile(pw_file_fullname, "r"); pw_file = AllocateFile(pw_file_fullname, "r");
if (!pw_file) if (!pw_file)
...@@ -69,12 +28,17 @@ verify_password(char *user, char *password, Port *port, ...@@ -69,12 +28,17 @@ verify_password(char *user, char *password, Port *port,
pw_file_fullname); pw_file_fullname);
fputs(PQerrormsg, stderr); fputs(PQerrormsg, stderr);
pqdebug("%s", PQerrormsg); pqdebug("%s", PQerrormsg);
pfree(pw_file_fullname);
return STATUS_ERROR; return STATUS_ERROR;
} }
while (!feof(pw_file)) while (!feof(pw_file))
{ {
fgets(pw_file_line, 255, pw_file); char pw_file_line[255], *p, *test_user, *test_pw;
fgets(pw_file_line, sizeof (pw_file_line), pw_file);
p = pw_file_line; p = pw_file_line;
test_user = strtok(p, ":"); test_user = strtok(p, ":");
...@@ -97,6 +61,9 @@ verify_password(char *user, char *password, Port *port, ...@@ -97,6 +61,9 @@ verify_password(char *user, char *password, Port *port,
if (strcmp(crypt(password, test_pw), test_pw) == 0) if (strcmp(crypt(password, test_pw), test_pw) == 0)
{ {
/* it matched. */ /* it matched. */
pfree(pw_file_fullname);
return STATUS_OK; return STATUS_OK;
} }
...@@ -105,6 +72,9 @@ verify_password(char *user, char *password, Port *port, ...@@ -105,6 +72,9 @@ verify_password(char *user, char *password, Port *port,
user); user);
fputs(PQerrormsg, stderr); fputs(PQerrormsg, stderr);
pqdebug("%s", PQerrormsg); pqdebug("%s", PQerrormsg);
pfree(pw_file_fullname);
return STATUS_ERROR; return STATUS_ERROR;
} }
} }
...@@ -114,5 +84,8 @@ verify_password(char *user, char *password, Port *port, ...@@ -114,5 +84,8 @@ verify_password(char *user, char *password, Port *port,
user); user);
fputs(PQerrormsg, stderr); fputs(PQerrormsg, stderr);
pqdebug("%s", PQerrormsg); pqdebug("%s", PQerrormsg);
pfree(pw_file_fullname);
return STATUS_ERROR; return STATUS_ERROR;
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
# #
# This file controls what hosts are allowed to connect to what databases # This file controls what hosts are allowed to connect to what databases
# and specifies some options on how users on a particular host are identified. # and specifies some options on how users on a particular host are identified.
# It is read each time a host tries to make a connection to a database.
# #
# Each line (terminated by a newline character) is a record. A record cannot # Each line (terminated by a newline character) is a record. A record cannot
# be continued across two lines. # be continued across two lines.
...@@ -29,13 +30,14 @@ ...@@ -29,13 +30,14 @@
# Record type "host" # Record type "host"
# ------------------ # ------------------
# #
# This record identifies a set of hosts that are permitted to connect to # This record identifies a set of network hosts that are permitted to connect
# databases. No hosts are permitted to connect except as specified by a # to databases. No network hosts are permitted to connect except as specified
# "host" record. # by a "host" record. See the record type "local" to specify permitted
# connections using UNIX sockets.
# #
# Format: # Format:
# #
# host DBNAME IP_ADDRESS ADDRESS_MASK USERAUTH [MAP] # host DBNAME IP_ADDRESS ADDRESS_MASK USERAUTH [AUTH_ARGUMENT]
# #
# DBNAME is the name of a Postgres database, or "all" to indicate all # DBNAME is the name of a Postgres database, or "all" to indicate all
# databases. # databases.
...@@ -49,33 +51,54 @@ ...@@ -49,33 +51,54 @@
# under the Postgres username he supplies in his connection parameters. # under the Postgres username he supplies in his connection parameters.
# #
# ident: Authentication is done by the ident server on the remote # ident: Authentication is done by the ident server on the remote
# host, via the ident (RFC 1413) protocol. # host, via the ident (RFC 1413) protocol. AUTH_ARGUMENT, if
# specified, is a map name to be found in the pg_ident.conf file.
# That table maps from ident usernames to Postgres usernames. The
# special map name "sameuser" indicates an implied map (not found
# in pg_ident.conf) that maps every ident username to the identical
# Postgres username.
# #
# trust: No authentication is done. Trust that the user has the # trust: No authentication is done. Trust that the user has the
# authority to user whatever username he says he does. # authority to user whatever username he says he does.
# Before Postgres Version 6, all authentication was this way. # Before Postgres Version 6, all authentication was this way.
# #
# MAP is the name of a map that matches an authenticated principal with # reject: Reject the connection.
# a Postgres username. If USERNAME is "trust", this value is ignored and
# may be absent.
# #
# In the case of USERAUTH=ident, this is a map name to be found in the # password: Authentication is done by matching a password supplied in clear
# pg_ident.conf file. That table maps from ident usernames to Postgres # by the host. If AUTH_ARGUMENT is specified then the password is
# usernames. The special map name "sameuser" indicates an implied map # compared with the user's entry in that file (in the $PGDATA
# (not found in pg_ident.conf) that maps every ident username to the identical # directory). See pg_passwd(1). If it is omitted then the
# Postgres username. # password is compared with the user's entry in the pg_user table.
#
# crypt: Authentication is done by matching an encrypted password supplied
# by the host with that held for the user in the pg_user table.
#
# krb4: Kerberos V4 authentication is used.
#
# krb5: Kerberos V5 authentication is used.
# Record type "local"
# ------------------
#
# This record identifies the authentication to use when connecting to a
# particular database via a local UNIX socket.
# #
# Format:
#
# local DBNAME USERAUTH [AUTH_ARGUMENT]
#
# The format is the same as that of the "host" record type except that the
# IP_ADDRESS and ADDRESS_MASK are omitted and the "ident", "krb4" and "krb5"
# values of USERAUTH are no allowed.
# For backwards compatibility, PostgreSQL also accepts pre-Version 6 records, # For backwards compatibility, PostgreSQL also accepts pre-Version 6 records,
# which look like: # which look like:
# #
# all 127.0.0.1 0.0.0.0 # all 127.0.0.1 0.0.0.0
#
#
# TYPE DATABASE IP_ADDRESS MASK USERAUTH MAP # TYPE DATABASE IP_ADDRESS MASK USERAUTH MAP
host all 127.0.0.1 255.255.255.255 trust #host all 127.0.0.1 255.255.255.255 trust
# The above allows any user on the local system to connect to any database # The above allows any user on the local system to connect to any database
# under any username. # under any username.
...@@ -86,10 +109,11 @@ host all 127.0.0.1 255.255.255.255 trust ...@@ -86,10 +109,11 @@ host all 127.0.0.1 255.255.255.255 trust
# connect to database template1 as the same username that ident on that host # connect to database template1 as the same username that ident on that host
# identifies him as (typically his Unix username). # identifies him as (typically his Unix username).
#host all 192.168.0.1 255.255.255.255 reject
#host all 0.0.0.0 0.0.0.0 trust #host all 0.0.0.0 0.0.0.0 trust
# The above would allow anyone anywhere to connect to any database under # The above would allow anyone anywhere except from 192.168.0.1 to connect to
# any username. # any database under any username.
#host all 192.168.0.0 255.255.255.0 ident omicron #host all 192.168.0.0 255.255.255.0 ident omicron
# #
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.34 1998/01/25 05:13:18 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.35 1998/01/26 01:41:11 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
...@@ -269,28 +270,6 @@ int ...@@ -269,28 +270,6 @@ int
pq_getnchar(char *s, int off, int maxlen) pq_getnchar(char *s, int off, int maxlen)
{ {
return pqGetNBytes(s + off, maxlen, Pfin); return pqGetNBytes(s + off, maxlen, Pfin);
#if 0
int c = '\0';
if (Pfin == (FILE *) NULL)
{
/* elog(DEBUG, "Input descriptor is null"); */
return (EOF);
}
s += off;
while (maxlen-- && (c = pq_getc(Pfin)) != EOF)
*s++ = c;
/* -----------------
* If EOF reached let caller know
* -----------------
*/
if (c == EOF)
return (EOF);
return (!EOF);
#endif
} }
/* -------------------------------- /* --------------------------------
...@@ -591,11 +570,7 @@ do_unlink() ...@@ -591,11 +570,7 @@ do_unlink()
int int
StreamServerPort(char *hostName, short portName, int *fdP) StreamServerPort(char *hostName, short portName, int *fdP)
{ {
union SockAddr saddr;
{
struct sockaddr_in in;
struct sockaddr_un un;
} saddr;
int fd, int fd,
err, err,
family; family;
...@@ -624,20 +599,19 @@ StreamServerPort(char *hostName, short portName, int *fdP) ...@@ -624,20 +599,19 @@ StreamServerPort(char *hostName, short portName, int *fdP)
return (STATUS_ERROR); return (STATUS_ERROR);
} }
bzero(&saddr, sizeof(saddr)); bzero(&saddr, sizeof(saddr));
saddr.sa.sa_family = family;
if (family == AF_UNIX) if (family == AF_UNIX)
{ {
saddr.un.sun_family = family;
len = UNIXSOCK_PATH(saddr.un, portName); len = UNIXSOCK_PATH(saddr.un, portName);
strcpy(sock_path, saddr.un.sun_path); strcpy(sock_path, saddr.un.sun_path);
} }
else else
{ {
saddr.in.sin_family = family;
saddr.in.sin_addr.s_addr = htonl(INADDR_ANY); saddr.in.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.in.sin_port = htons(portName); saddr.in.sin_port = htons(portName);
len = sizeof saddr.in; len = sizeof (struct sockaddr_in);
} }
err = bind(fd, (struct sockaddr *) & saddr, len); err = bind(fd, &saddr.sa, len);
if (err < 0) if (err < 0)
{ {
sprintf(PQerrormsg, sprintf(PQerrormsg,
...@@ -685,7 +659,7 @@ StreamConnection(int server_fd, Port *port) ...@@ -685,7 +659,7 @@ StreamConnection(int server_fd, Port *port)
{ {
int len, int len,
addrlen; addrlen;
int family = port->raddr.in.sin_family; int family = port->raddr.sa.sa_family;
/* accept connection (and fill in the client (remote) address) */ /* accept connection (and fill in the client (remote) address) */
len = family == AF_INET ? len = family == AF_INET ?
...@@ -726,8 +700,6 @@ StreamConnection(int server_fd, Port *port) ...@@ -726,8 +700,6 @@ StreamConnection(int server_fd, Port *port)
} }
} }
port->mask = 1 << port->sock;
/* reset to non-blocking */ /* reset to non-blocking */
fcntl(port->sock, F_SETFL, 1); fcntl(port->sock, F_SETFL, 1);
...@@ -788,7 +760,7 @@ StreamOpen(char *hostName, short portName, Port *port) ...@@ -788,7 +760,7 @@ StreamOpen(char *hostName, short portName, Port *port)
len = UNIXSOCK_PATH(port->raddr.un, portName); len = UNIXSOCK_PATH(port->raddr.un, portName);
} }
/* connect to the server */ /* connect to the server */
if ((port->sock = socket(port->raddr.in.sin_family, SOCK_STREAM, 0)) < 0) if ((port->sock = socket(port->raddr.sa.sa_family, SOCK_STREAM, 0)) < 0)
{ {
sprintf(PQerrormsg, sprintf(PQerrormsg,
"FATAL: StreamOpen: socket() failed: errno=%d\n", "FATAL: StreamOpen: socket() failed: errno=%d\n",
...@@ -797,7 +769,7 @@ StreamOpen(char *hostName, short portName, Port *port) ...@@ -797,7 +769,7 @@ StreamOpen(char *hostName, short portName, Port *port)
pqdebug("%s", PQerrormsg); pqdebug("%s", PQerrormsg);
return (STATUS_ERROR); return (STATUS_ERROR);
} }
err = connect(port->sock, (struct sockaddr *) & port->raddr, len); err = connect(port->sock, &port->raddr.sa, len);
if (err < 0) if (err < 0)
{ {
sprintf(PQerrormsg, sprintf(PQerrormsg,
...@@ -809,8 +781,7 @@ StreamOpen(char *hostName, short portName, Port *port) ...@@ -809,8 +781,7 @@ StreamOpen(char *hostName, short portName, Port *port)
} }
/* fill in the client address */ /* fill in the client address */
if (getsockname(port->sock, (struct sockaddr *) & port->laddr, if (getsockname(port->sock, &port->laddr.sa, &len) < 0)
&len) < 0)
{ {
sprintf(PQerrormsg, sprintf(PQerrormsg,
"FATAL: StreamOpen: getsockname() failed: errno=%d\n", "FATAL: StreamOpen: getsockname() failed: errno=%d\n",
...@@ -822,32 +793,3 @@ StreamOpen(char *hostName, short portName, Port *port) ...@@ -822,32 +793,3 @@ 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;
}
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <netinet/in.h>
#include "postgres.h" #include "postgres.h"
#include "libpq/pqcomm.h" #include "libpq/pqcomm.h"
/*
* The backend supports the old little endian byte order and the current
* network byte order.
*/
#ifndef FRONTEND
#include "libpq/libpq-be.h"
#ifdef HAVE_ENDIAN_H #ifdef HAVE_ENDIAN_H
#include <endian.h> #include <endian.h>
#endif #endif
/* --------------------------------------------------------------------- */
/* These definitions for ntoh/hton are the other way around from the
* default system definitions, so we roll our own here.
*/
#ifndef BYTE_ORDER #ifndef BYTE_ORDER
#error BYTE_ORDER must be defined as LITTLE_ENDIAN, BIG_ENDIAN or PDP_ENDIAN #error BYTE_ORDER must be defined as LITTLE_ENDIAN, BIG_ENDIAN or PDP_ENDIAN
#endif #endif
#if BYTE_ORDER == LITTLE_ENDIAN #if BYTE_ORDER == LITTLE_ENDIAN
#define ntoh_s(n) n #define ntoh_s(n) n
#define ntoh_l(n) n #define ntoh_l(n) n
#define hton_s(n) n #define hton_s(n) n
#define hton_l(n) n #define hton_l(n) n
#else /* BYTE_ORDER != LITTLE_ENDIAN */
#else
#if BYTE_ORDER == BIG_ENDIAN #if BYTE_ORDER == BIG_ENDIAN
#define ntoh_s(n) (u_short)(((u_char *)&n)[1] << 8 \
#define ntoh_s(n) (uint16)(((u_char *)&n)[1] << 8 \
| ((u_char *)&n)[0]) | ((u_char *)&n)[0])
#define ntoh_l(n) (uint32) (((u_char *)&n)[3] << 24 \ #define ntoh_l(n) (uint32)(((u_char *)&n)[3] << 24 \
| ((u_char *)&n)[2] << 16 \ | ((u_char *)&n)[2] << 16 \
| ((u_char *)&n)[1] << 8 \ | ((u_char *)&n)[1] << 8 \
| ((u_char *)&n)[0]) | ((u_char *)&n)[0])
#define hton_s(n) (ntoh_s(n)) #define hton_s(n) (ntoh_s(n))
#define hton_l(n) (ntoh_l(n)) #define hton_l(n) (ntoh_l(n))
#else #else
/* BYTE_ORDER != BIG_ENDIAN */
#if BYTE_ORDER == PDP_ENDIAN #if BYTE_ORDER == PDP_ENDIAN
#error PDP_ENDIAN macros not written yet #error PDP_ENDIAN macros not written yet
#else #else
/* BYTE_ORDER != anything known */
#error BYTE_ORDER not defined as anything understood #error BYTE_ORDER not defined as anything understood
#endif /* BYTE_ORDER == PDP_ENDIAN */
#endif /* BYTE_ORDER == BIG_ENDIAN */ #endif
#endif /* BYTE_ORDER == LITTLE_ENDIAN */ #endif
#endif
#endif
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
int int
pqPutShort(int integer, FILE *f) pqPutShort(int integer, FILE *f)
{ {
int retval = 0; uint16 n;
u_short n,
s;
s = integer; #ifdef FRONTEND
n = hton_s(s); n = htons((uint16)integer);
if (fwrite(&n, sizeof(u_short), 1, f) != 1) #else
retval = EOF; n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_s(integer) : htons((uint16)integer));
#endif
return retval; if (fwrite(&n, 2, 1, f) != 1)
return EOF;
return 0;
} }
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
int int
pqPutLong(int integer, FILE *f) pqPutLong(int integer, FILE *f)
{ {
int retval = 0;
uint32 n; uint32 n;
n = hton_l(integer); #ifdef FRONTEND
if (fwrite(&n, sizeof(uint32), 1, f) != 1) n = htonl((uint32)integer);
retval = EOF; #else
n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_l(integer) : htonl((uint32)integer));
#endif
return retval; if (fwrite(&n, 4, 1, f) != 1)
return EOF;
return 0;
} }
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
int int
pqGetShort(int *result, FILE *f) pqGetShort(int *result, FILE *f)
{ {
int retval = 0; uint16 n;
u_short n;
if (fread(&n, sizeof(u_short), 1, f) != 1) if (fread(&n, 2, 1, f) != 1)
retval = EOF; return EOF;
#ifdef FRONTEND
*result = (int)ntohs(n);
#else
*result = (int)((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_s(n) : ntohs(n));
#endif
*result = ntoh_s(n); return 0;
return retval;
} }
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
int int
pqGetLong(int *result, FILE *f) pqGetLong(int *result, FILE *f)
{ {
int retval = 0;
uint32 n; uint32 n;
if (fread(&n, sizeof(uint32), 1, f) != 1) if (fread(&n, 4, 1, f) != 1)
retval = EOF; return EOF;
#ifdef FRONTEND
*result = (int)ntohl(n);
#else
*result = (int)((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_l(n) : ntohl(n));
#endif
*result = ntoh_l(n); return 0;
return retval;
} }
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* pqGetNBytes: Read a chunk of exactly len bytes in buffer s. /* pqGetNBytes: Read a chunk of exactly len bytes in buffer s (which must be 1
byte longer) and terminate it with a '\0'.
Return 0 if ok. Return 0 if ok.
*/ */
int int
...@@ -116,7 +145,6 @@ pqGetNBytes(char *s, size_t len, FILE *f) ...@@ -116,7 +145,6 @@ pqGetNBytes(char *s, size_t len, FILE *f)
cnt = fread(s, 1, len, f); cnt = fread(s, 1, len, f);
s[cnt] = '\0'; s[cnt] = '\0';
/* mjl: actually needs up to len+1 bytes, is this okay? XXX */
return (cnt == len) ? 0 : EOF; return (cnt == len) ? 0 : EOF;
} }
...@@ -126,7 +154,7 @@ int ...@@ -126,7 +154,7 @@ int
pqPutNBytes(const char *s, size_t len, FILE *f) pqPutNBytes(const char *s, size_t len, FILE *f)
{ {
if (f == NULL) if (f == NULL)
return 0; return EOF;
if (fwrite(s, 1, len, f) != len) if (fwrite(s, 1, len, f) != len)
return EOF; return EOF;
...@@ -143,10 +171,22 @@ pqGetString(char *s, size_t len, FILE *f) ...@@ -143,10 +171,22 @@ pqGetString(char *s, size_t len, FILE *f)
if (f == NULL) if (f == NULL)
return EOF; return EOF;
while (len-- && (c = getc(f)) != EOF && c) /*
* Keep on reading until we get the terminating '\0' and discard those
* bytes we don't have room for.
*/
while ((c = getc(f)) != EOF && c != '\0')
if (len > 1)
{
*s++ = c; *s++ = c;
len--;
}
*s = '\0'; *s = '\0';
/* mjl: actually needs up to len+1 bytes, is this okay? XXX */
if (c == EOF)
return EOF;
return 0; return 0;
} }
...@@ -183,5 +223,3 @@ pqPutByte(int c, FILE *f) ...@@ -183,5 +223,3 @@ pqPutByte(int c, FILE *f)
return (putc(c, f) == c) ? 0 : EOF; return (putc(c, f) == c) ? 0 : EOF;
} }
/* --------------------------------------------------------------------- */
...@@ -8,36 +8,14 @@ ...@@ -8,36 +8,14 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.12 1997/12/09 03:10:51 scrappy Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.13 1998/01/26 01:41:12 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
/* NOTES
* This is the module that understands the lowest-level part
* of the communication protocol. All of the trickiness in
* this module is for making sure that non-blocking I/O in
* the Postmaster works correctly. Check the notes in PacketRecv
* on non-blocking I/O.
*
* Data Structures:
* Port has two important functions. (1) It records the
* sock/addr used in communication. (2) It holds partially
* read in messages. This is especially important when
* we haven't seen enough to construct a complete packet
* header.
*
* PacketBuf -- None of the clients of this module should know
* what goes into a packet hdr (although they know how big
* it is). This routine is in charge of host to net order
* conversion for headers. Data conversion is someone elses
* responsibility.
*
* IMPORTANT: these routines are called by backends, clients, and
* the Postmaster.
*
*/
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h> #include <netdb.h>
...@@ -50,260 +28,158 @@ ...@@ -50,260 +28,158 @@
#include <storage/ipc.h> #include <storage/ipc.h>
#include <libpq/libpq.h> #include <libpq/libpq.h>
/* /*
* PacketReceive -- receive a packet on a port. * Set up a packet read for the postmaster event loop.
*
* RETURNS: connection id of the packet sender, if one
* is available.
*
*/ */
int
PacketReceive(Port *port, /* receive port */ void PacketReceiveSetup(Packet *pkt, void (*iodone)(), char *arg)
PacketBuf *buf, /* MAX_PACKET_SIZE-worth of buffer space */
bool nonBlocking) /* NON_BLOCKING or BLOCKING i/o */
{ {
PacketLen max_size = sizeof(PacketBuf); pkt->nrtodo = sizeof (pkt->len);
PacketLen cc; /* character count -- bytes recvd */ pkt->ptr = (char *)&pkt->len;
PacketLen packetLen; /* remaining packet chars to read */ pkt->iodone = iodone;
Addr tmp; /* curr recv buf pointer */ pkt->arg = arg;
int hdrLen; pkt->state = ReadingPacketLength;
int flag; }
int decr;
hdrLen = sizeof(buf->len);
if (nonBlocking == NON_BLOCKING) /*
{ * Read a packet fragment. Return STATUS_OK if the connection should stay
flag = MSG_PEEK; * open.
decr = 0;
}
else
{
flag = 0;
decr = hdrLen;
}
/*
* Assume port->nBytes is zero unless we were interrupted during
* non-blocking I/O. This first recv() is to get the hdr information
* so we know how many bytes to read. Life would be very complicated
* if we read too much data (buffering).
*/ */
tmp = ((Addr) buf) + port->nBytes;
if (port->nBytes >= hdrLen) int PacketReceiveFragment(Packet *pkt, int sock)
{ {
packetLen = ntohl(buf->len) - port->nBytes; int got;
}
else
{
/* peeking into the incoming message */
cc = recv(port->sock, (char *) &(buf->len), hdrLen, flag);
if (cc < hdrLen)
{
/* if cc is negative, the system call failed */
if (cc < 0)
{
return (STATUS_ERROR);
}
/* if ((got = read(sock,pkt->ptr,pkt->nrtodo)) > 0)
* cc == 0 means the connection was broken at the other end.
*/
else if (!cc)
{ {
return (STATUS_INVALID); pkt->nrtodo -= got;
pkt->ptr += got;
} /* See if we have got what we need for the packet length. */
else
{
/* if (pkt->nrtodo == 0 && pkt->state == ReadingPacketLength)
* Worst case. We didn't even read in enough data to get
* the header length. since we are using a data stream,
* this happens only if the client is mallicious.
*
* Don't save the number of bytes we've read so far. Since we
* only peeked at the incoming message, the kernel is
* going to keep it for us.
*/
return (STATUS_NOT_DONE);
}
}
else
{ {
pkt->len = ntohl(pkt->len);
/* if (pkt->len < sizeof (pkt->len) ||
* This is an attempt to shield the Postmaster from mallicious pkt->len > sizeof (pkt->len) + sizeof (pkt->pkt))
* attacks by placing tighter restrictions on the reported
* packet length.
*
* Check for negative packet length
*/
if ((buf->len) <= 0)
{ {
return (STATUS_INVALID); PacketSendError(pkt,"Invalid packet length");
return STATUS_OK;
} }
/* /* Set up for the rest of the packet. */
* Check for oversize packet
*/ pkt->nrtodo = pkt->len - sizeof (pkt->len);
if ((ntohl(buf->len)) > max_size) pkt->ptr = (char *)&pkt->pkt;
{ pkt->state = ReadingPacket;
return (STATUS_INVALID);
} }
/* /* See if we have got what we need for the packet. */
* great. got the header. now get the true length (including
* header size).
*/
packetLen = ntohl(buf->len);
/* if (pkt->nrtodo == 0 && pkt->state == ReadingPacket)
* if someone is sending us junk, close the connection
*/
if (packetLen > max_size)
{ {
port->nBytes = packetLen; pkt->state = Idle;
return (STATUS_BAD_PACKET);
} /* Special case to close the connection. */
packetLen -= decr;
tmp += decr - port->nBytes; if (pkt->iodone == NULL)
return STATUS_ERROR;
(*pkt->iodone)(pkt->arg, pkt->len - sizeof (pkt->len),
(char *)&pkt->pkt);
} }
return STATUS_OK;
} }
/* if (got == 0)
* Now that we know how big it is, read the packet. We read the return STATUS_ERROR;
* entire packet, since the last call was just a peek.
*/ if (errno == EINTR)
while (packetLen) return STATUS_OK;
{
cc = read(port->sock, tmp, packetLen); fprintf(stderr, "read() system call failed\n");
if (cc < 0)
return (STATUS_ERROR); return STATUS_ERROR;
}
/*
* cc == 0 means the connection was broken at the other end.
*/
else if (!cc)
return (STATUS_INVALID);
/* /*
fprintf(stderr,"expected packet of %d bytes, got %d bytes\n", * Set up a packet write for the postmaster event loop.
packetLen, cc); */
*/
tmp += cc;
packetLen -= cc;
/* if non-blocking, we're done. */
if (nonBlocking && packetLen)
{
port->nBytes += cc;
return (STATUS_NOT_DONE);
}
}
port->nBytes = 0; void PacketSendSetup(Packet *pkt, int nbytes, void (*iodone)(), char *arg)
return (STATUS_OK); {
pkt->nrtodo = nbytes;
pkt->ptr = (char *)&pkt->pkt;
pkt->iodone = iodone;
pkt->arg = arg;
pkt->state = WritingPacket;
} }
/* /*
* PacketSend -- send a single-packet message. * Write a packet fragment. Return STATUS_OK if the connection should stay
* * open.
* RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
* SIDE_EFFECTS: may block.
* NOTES: Non-blocking writes would significantly complicate
* buffer management. For now, we're not going to do it.
*
*/ */
int
PacketSend(Port *port, int PacketSendFragment(Packet *pkt, int sock)
PacketBuf *buf,
PacketLen len,
bool nonBlocking)
{ {
PacketLen doneLen; int done;
if ((done = write(sock,pkt->ptr,pkt->nrtodo)) > 0)
{
pkt->nrtodo -= done;
pkt->ptr += done;
Assert(!nonBlocking); /* See if we have written the whole packet. */
Assert(buf);
doneLen = write(port->sock, buf, len); if (pkt->nrtodo == 0)
if (doneLen < len)
{ {
sprintf(PQerrormsg, pkt->state = Idle;
"FATAL: PacketSend: couldn't send complete packet: errno=%d\n",
errno); /* Special case to close the connection. */
fputs(PQerrormsg, stderr);
return (STATUS_ERROR); if (pkt->iodone == NULL)
return STATUS_ERROR;
(*pkt->iodone)(pkt->arg);
} }
return (STATUS_OK); return STATUS_OK;
}
if (done == 0)
return STATUS_ERROR;
if (errno == EINTR)
return STATUS_OK;
fprintf(stderr, "write() system call failed\n");
return STATUS_ERROR;
} }
/* /*
* StartupInfo2PacketBuf - * Send an error message from the postmaster to the frontend.
* convert the fields of the StartupInfo to a PacketBuf
*
*/ */
/* moved to src/libpq/fe-connect.c */
/* void PacketSendError(Packet *pkt, char *errormsg)
PacketBuf*
StartupInfo2PacketBuf(StartupInfo* s)
{ {
PacketBuf* res; fprintf(stderr, "%s\n", errormsg);
char* tmp;
res = (PacketBuf*)palloc(sizeof(PacketBuf));
res->len = htonl(sizeof(PacketBuf));
res->data[0] = '\0';
tmp= res->data;
strncpy(tmp, s->database, sizeof(s->database));
tmp += sizeof(s->database);
strncpy(tmp, s->user, sizeof(s->user));
tmp += sizeof(s->user);
strncpy(tmp, s->options, sizeof(s->options));
tmp += sizeof(s->options);
strncpy(tmp, s->execFile, sizeof(s->execFile));
tmp += sizeof(s->execFile);
strncpy(tmp, s->tty, sizeof(s->execFile));
return res;
}
*/
/* pkt->pkt.em.data[0] = 'E';
* PacketBuf2StartupInfo - StrNCpy(&pkt->pkt.em.data[1], errormsg, sizeof (pkt->pkt.em.data) - 2);
* convert the fields of the StartupInfo to a PacketBuf
* /*
* The NULL i/o callback will cause the connection to be broken when
* the error message has been sent.
*/ */
/* moved to postmaster.c
StartupInfo* PacketSendSetup(pkt, strlen(pkt->pkt.em.data) + 1, NULL, NULL);
PacketBuf2StartupInfo(PacketBuf* p)
{
StartupInfo* res;
char* tmp;
res = (StartupInfo*)palloc(sizeof(StartupInfo));
res->database[0]='\0';
res->user[0]='\0';
res->options[0]='\0';
res->execFile[0]='\0';
res->tty[0]='\0';
tmp= p->data;
strncpy(res->database,tmp,sizeof(res->database));
tmp += sizeof(res->database);
strncpy(res->user,tmp, sizeof(res->user));
tmp += sizeof(res->user);
strncpy(res->options,tmp, sizeof(res->options));
tmp += sizeof(res->options);
strncpy(res->execFile,tmp, sizeof(res->execFile));
tmp += sizeof(res->execFile);
strncpy(res->tty,tmp, sizeof(res->tty));
return res;
} }
*/
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.15 1997/12/06 22:57:02 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.16 1998/01/26 01:41:23 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "postgres.h" #include "postgres.h"
#include "access/htup.h" #include "access/htup.h"
#include "libpq/libpq-be.h" #include "libpq/libpq.h"
#include "access/printtup.h" #include "access/printtup.h"
#include "utils/portal.h" #include "utils/portal.h"
#include "utils/palloc.h" #include "utils/palloc.h"
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.11 1998/01/11 21:16:01 scrappy Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.12 1998/01/26 01:41:28 scrappy Exp $
* *
* NOTES * NOTES
* This cruft is the server side of PQfn. * This cruft is the server side of PQfn.
...@@ -336,7 +336,7 @@ HandleFunctionRequest() ...@@ -336,7 +336,7 @@ HandleFunctionRequest()
else else
{ /* ... fixed */ { /* ... fixed */
/* XXX cross our fingers and trust "argsize" */ /* XXX cross our fingers and trust "argsize" */
if (!(p = palloc(argsize))) if (!(p = palloc(argsize + 1)))
{ {
elog(ERROR, "HandleFunctionRequest: palloc failed"); elog(ERROR, "HandleFunctionRequest: palloc failed");
} }
......
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.18 1998/01/25 05:14:42 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.19 1998/01/26 01:41:42 scrappy Exp $
* *
* NOTES * NOTES
* Globals used all over the place should be declared here and not * Globals used all over the place should be declared here and not
...@@ -32,9 +32,10 @@ ...@@ -32,9 +32,10 @@
#include "storage/sinvaladt.h" #include "storage/sinvaladt.h"
#include "storage/lmgr.h" #include "storage/lmgr.h"
#include "utils/elog.h" #include "utils/elog.h"
#include "libpq/pqcomm.h"
#include "catalog/catname.h" #include "catalog/catname.h"
ProtocolVersion FrontendProtocol = PG_PROTOCOL_LATEST;
int Portfd = -1; int Portfd = -1;
int Noversion = 0; int Noversion = 0;
int Quiet = 1; int Quiet = 1;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: c.h,v 1.28 1998/01/24 22:47:43 momjian Exp $ * $Id: c.h,v 1.29 1998/01/26 01:41:49 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -204,21 +204,23 @@ typedef char *Pointer; ...@@ -204,21 +204,23 @@ typedef char *Pointer;
/* /*
* intN -- * intN --
* Signed integer, AT LEAST N BITS IN SIZE, * Signed integer, EXACTLY N BITS IN SIZE,
* used for numerical computations. * used for numerical computations and the
* frontend/backend protocol.
*/ */
typedef signed char int8; /* >= 8 bits */ typedef signed char int8; /* == 8 bits */
typedef signed short int16; /* >= 16 bits */ typedef signed short int16; /* == 16 bits */
typedef signed int int32; /* >= 32 bits */ typedef signed int int32; /* == 32 bits */
/* /*
* uintN -- * uintN --
* Unsigned integer, AT LEAST N BITS IN SIZE, * Unsigned integer, EXACTLY N BITS IN SIZE,
* used for numerical computations. * used for numerical computations and the
* frontend/backend protocol.
*/ */
typedef unsigned char uint8; /* >= 8 bits */ typedef unsigned char uint8; /* == 8 bits */
typedef unsigned short uint16; /* >= 16 bits */ typedef unsigned short uint16; /* == 16 bits */
typedef unsigned int uint32; /* >= 32 bits */ typedef unsigned int uint32; /* == 32 bits */
/* /*
* floatN -- * floatN --
......
...@@ -6,40 +6,22 @@ ...@@ -6,40 +6,22 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: auth.h,v 1.7 1997/09/08 21:52:28 momjian Exp $ * $Id: auth.h,v 1.8 1998/01/26 01:42:05 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef AUTH_H #ifndef AUTH_H
#define AUTH_H #define AUTH_H
#include <libpq/pqcomm.h> #include "libpq/libpq-be.h"
/*---------------------------------------------------------------- /*----------------------------------------------------------------
* Common routines and definitions * Common routines and definitions
*---------------------------------------------------------------- *----------------------------------------------------------------
*/ */
/* what we call "no authentication system" */ void be_recvauth(Port *port);
#define UNAUTHNAME "unauth" void auth_failed(Port *port);
/* what a frontend uses by default */
#if !defined(KRB4) && !defined(KRB5)
#define DEFAULT_CLIENT_AUTHSVC UNAUTHNAME
#else /* KRB4 || KRB5 */
#define DEFAULT_CLIENT_AUTHSVC "kerberos"
#endif /* KRB4 || KRB5 */
extern int fe_sendauth(MsgType msgtype, Port *port, char *hostname);
extern void fe_setauthsvc(char *name);
extern MsgType fe_getauthsvc();
extern char *fe_getauthname(void);
extern int be_recvauth(MsgType msgtype, Port *port, char *username, StartupInfo *sp);
extern void be_setauthsvc(char *name);
/* the value that matches any dbName value when doing
host based authentication*/
#define ALL_DBNAME "*"
#define PG_KRB4_VERSION "PGVER4.1" /* at most KRB_SENDAUTH_VLEN chars */ #define PG_KRB4_VERSION "PGVER4.1" /* at most KRB_SENDAUTH_VLEN chars */
#define PG_KRB5_VERSION "PGVER5.1" #define PG_KRB5_VERSION "PGVER5.1"
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#ifndef PG_CRYPT_H #ifndef PG_CRYPT_H
#define PG_CRYPT_H #define PG_CRYPT_H
#include <libpq/pqcomm.h> #include <libpq/libpq-be.h>
#define CRYPT_PWD_FILE "pg_pwd" #define CRYPT_PWD_FILE "pg_pwd"
#define CRYPT_PWD_FILE_SEPCHAR "'\\t'" #define CRYPT_PWD_FILE_SEPCHAR "'\\t'"
...@@ -21,7 +21,9 @@ extern int pwd_cache_count; ...@@ -21,7 +21,9 @@ extern int pwd_cache_count;
extern char* crypt_getpwdfilename(void); extern char* crypt_getpwdfilename(void);
extern char* crypt_getpwdreloadfilename(void); extern char* crypt_getpwdreloadfilename(void);
#ifdef 0
extern MsgType crypt_salt(const char* user); extern MsgType crypt_salt(const char* user);
#endif
extern int crypt_verify(Port* port, const char* user, const char* pgpass); extern int crypt_verify(Port* port, const char* user, const char* pgpass);
#endif #endif
...@@ -4,14 +4,17 @@ ...@@ -4,14 +4,17 @@
* Interface to hba.c * Interface to hba.c
* *
* *
* $Id: hba.h,v 1.6 1998/01/24 22:49:15 momjian Exp $ * $Id: hba.h,v 1.7 1998/01/26 01:42:15 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef HBA_H #ifndef HBA_H
#define HBA_H #define HBA_H
#include <libpq/pqcomm.h> #include <netinet/in.h>
#include "libpq/libpq-be.h"
#define CONF_FILE "pg_hba.conf" #define CONF_FILE "pg_hba.conf"
/* Name of the config file */ /* Name of the config file */
...@@ -28,7 +31,7 @@ ...@@ -28,7 +31,7 @@
#define MAX_TOKEN 80 #define MAX_TOKEN 80
/* Maximum size of one token in the configuration file */ /* Maximum size of one token in the configuration file */
#define USERMAP_NAME_SIZE 16 /* Max size of a usermap name */ #define MAX_AUTH_ARG 80 /* Max size of an authentication arg */
#define IDENT_PORT 113 #define IDENT_PORT 113
/* Standard TCP port number for Ident service. Assigned by IANA */ /* Standard TCP port number for Ident service. Assigned by IANA */
...@@ -36,18 +39,19 @@ ...@@ -36,18 +39,19 @@
#define IDENT_USERNAME_MAX 512 #define IDENT_USERNAME_MAX 512
/* Max size of username ident server can return */ /* Max size of username ident server can return */
enum Userauth typedef enum UserAuth {
{ uaReject,
Trust, Ident, uaKrb4,
Password uaKrb5,
}; uaTrust,
uaIdent,
extern int hba_recvauth(const Port *port, const char database[], const char user[], uaPassword,
const char DataDir[]); uaCrypt
void } UserAuth;
find_hba_entry(const char DataDir[], const struct in_addr ip_addr,
const char database[], int hba_getauthmethod(SockAddr *raddr, char *database, char *auth_arg,
bool *host_ok_p, enum Userauth * userauth_p, UserAuth *auth_method);
char usermap_name[], bool find_password_entries); int authident(struct sockaddr_in *raddr, struct sockaddr_in *laddr,
const char postgres_username[], const char auth_arg[]);
#endif #endif
...@@ -7,45 +7,126 @@ ...@@ -7,45 +7,126 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: libpq-be.h,v 1.8 1998/01/24 22:49:18 momjian Exp $ * $Id: libpq-be.h,v 1.9 1998/01/26 01:42:17 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef LIBPQ_BE_H #ifndef LIBPQ_BE_H
#define LIBPQ_BE_H #define LIBPQ_BE_H
#include <access/htup.h> #include <stdio.h>
#include <access/tupdesc.h> #include <sys/types.h>
#include <libpq/libpq.h>
/* ---------------- #include "libpq/pqcomm.h"
* include stuff common to fe and be #include "libpq/hba.h"
* ----------------
/* Protocol v0 password packet. */
typedef struct PasswordPacketV0 {
uint32 unused;
char data[288]; /* User and password as strings. */
} PasswordPacketV0;
/*
* Password packet. The length of the password can be changed without
* affecting anything.
*/ */
typedef struct PasswordPacket {
char passwd[100]; /* The password. */
} PasswordPacket;
/* Error message packet. */
typedef struct ErrorMessagePacket {
char data[1 + 100]; /* 'E' + the message. */
} ErrorMessagePacket;
/* Authentication request packet. */
typedef struct AuthRequestPacket {
char data[1 + sizeof (AuthRequest) + 2]; /* 'R' + the request + optional salt. */
} AuthRequestPacket;
/* These are used by the packet handling routines. */
typedef enum {
Idle,
ReadingPacketLength,
ReadingPacket,
WritingPacket
} PacketState;
typedef struct Packet {
PacketState state; /* What's in progress. */
PacketLen len; /* Actual length */
int nrtodo; /* Bytes still to transfer */
char *ptr; /* Buffer pointer */
void (*iodone)(); /* I/O complete callback */
char *arg; /* Argument to callback */
/* ---------------- /* A union of all the different packets. */
* declarations for backend libpq support routines
* ---------------- union {
/* These are outgoing so have no packet length prepended. */
ErrorMessagePacket em;
AuthRequestPacket ar;
/* These are incoming and have a packet length prepended. */
StartupPacket si;
PasswordPacketV0 pwv0;
PasswordPacket pw;
} pkt;
} Packet;
/*
* This is used by the postmaster in its communication with frontends. It is
* contains all state information needed during this communication before the
* backend is run.
*/
typedef struct Port {
int sock; /* File descriptor */
Packet pktInfo; /* For the packet handlers */
SockAddr laddr; /* local addr (us) */
SockAddr raddr; /* remote addr (them) */
char salt[2]; /* Password salt */
/*
* Information that needs to be held during the fe/be authentication
* handshake.
*/ */
/* in be-dumpdata.c */ ProtocolVersion proto;
extern void be_portalinit(void); char database[SM_DATABASE + 1];
extern void be_portalpush(PortalEntry *entry); char user[SM_USER + 1];
extern PortalEntry *be_portalpop(void); char options[SM_OPTIONS + 1];
extern PortalEntry *be_currentportal(void); char tty[SM_TTY + 1];
extern PortalEntry *be_newportal(void); char auth_arg[MAX_AUTH_ARG];
extern void be_typeinit(PortalEntry *entry, TupleDesc attrs, UserAuth auth_method;
int natts); } Port;
extern void be_printtup(HeapTuple tuple, TupleDesc typeinfo);
extern FILE *Pfout, *Pfin;
/* in be-pqexec.c */ extern int PQAsyncNotifyWaiting;
extern char * PQfn(int fnid, int *result_buf, int result_len, int result_is_int, extern ProtocolVersion FrontendProtocol;
PQArgBlock *args, int nargs);
extern char *PQexec(char *query);
extern int pqtest_PQexec(char *q); /*
extern int pqtest_PQfn(char *q); * prototypes for functions in pqpacket.c
extern int32 pqtest(struct varlena * vlena); */
void PacketReceiveSetup(Packet *pkt, void (*iodone)(), char *arg);
int PacketReceiveFragment(Packet *pkt, int sock);
void PacketSendSetup(Packet *pkt, int nbytes, void (*iodone)(), char *arg);
int PacketSendFragment(Packet *pkt, int sock);
void PacketSendError(Packet *pkt, char *errormsg);
#endif /* LIBPQ_BE_H */ #endif /* LIBPQ_BE_H */
...@@ -6,20 +6,19 @@ ...@@ -6,20 +6,19 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: libpq.h,v 1.9 1998/01/24 22:49:21 momjian Exp $ * $Id: libpq.h,v 1.10 1998/01/26 01:42:18 scrappy Exp $
*
* NOTES
* This file contains definitions for structures and
* externs for functions used by both frontend applications
* and the POSTGRES backend. See the files libpq-fe.h and
* libpq-be.h for frontend/backend specific information
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef LIBPQ_H #ifndef LIBPQ_H
#define LIBPQ_H #define LIBPQ_H
#include <libpq/pqcomm.h> #include <netinet/in.h>
#include "libpq/libpq-be.h"
#include "access/htup.h"
#include "access/tupdesc.h"
/* ---------------- /* ----------------
* PQArgBlock -- * PQArgBlock --
...@@ -228,6 +227,27 @@ extern int pbuf_findFnumber(GroupBuffer *group, char *field_name); ...@@ -228,6 +227,27 @@ extern int pbuf_findFnumber(GroupBuffer *group, char *field_name);
extern void pbuf_checkFnumber(GroupBuffer *group, int field_number); extern void pbuf_checkFnumber(GroupBuffer *group, int field_number);
extern char *pbuf_findFname(GroupBuffer *group, int field_number); extern char *pbuf_findFname(GroupBuffer *group, int field_number);
/* in be-dumpdata.c */
extern void be_portalinit(void);
extern void be_portalpush(PortalEntry *entry);
extern PortalEntry *be_portalpop(void);
extern PortalEntry *be_currentportal(void);
extern PortalEntry *be_newportal(void);
extern void
be_typeinit(PortalEntry *entry, TupleDesc attrs,
int natts);
extern void be_printtup(HeapTuple tuple, TupleDesc typeinfo);
/* in be-pqexec.c */
extern char *
PQfn(int fnid, int *result_buf, int result_len, int result_is_int,
PQArgBlock *args, int nargs);
extern char *PQexec(char *query);
extern int pqtest_PQexec(char *q);
extern int pqtest_PQfn(char *q);
extern int32 pqtest(struct varlena * vlena);
/* /*
* prototypes for functions in pqcomm.c * prototypes for functions in pqcomm.c
*/ */
......
#ifndef PASSWORD_H #ifndef PASSWORD_H
#define PASSWORD_H #define PASSWORD_H
#include <libpq/hba.h> int verify_password(char *auth_arg, char *user, char *password);
#include <libpq/pqcomm.h>
#define PWFILE_NAME_SIZE USERMAP_NAME_SIZE
int
verify_password(char *user, char *password, Port *port,
char *database, char *DataDir);
#endif #endif
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* pqcomm.h-- * pqcomm.h--
* Parameters for the communication module * Definitions common to frontends and backends.
* *
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: pqcomm.h,v 1.18 1998/01/24 22:49:23 momjian Exp $ * $Id: pqcomm.h,v 1.19 1998/01/26 01:42:21 scrappy Exp $
*
* NOTES
* Some of this should move to libpq.h
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -18,134 +15,105 @@ ...@@ -18,134 +15,105 @@
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <netinet/in.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <netinet/in.h>
#include "c.h"
/*
* startup msg parameters: path length, argument string length /* Define a generic socket address type. */
*/
#define PATH_SIZE 64 typedef union SockAddr {
#define ARGV_SIZE 64 struct sockaddr sa;
struct sockaddr_in in;
struct sockaddr_un un;
} SockAddr;
/* Configure the UNIX socket address for the well known port. */
#define UNIXSOCK_PATH(sun,port) \ #define UNIXSOCK_PATH(sun,port) \
sprintf(sun.sun_path,"/tmp/.s.PGSQL.%d",port) + sizeof(sun.sun_family) + 1; (sprintf((sun).sun_path, "/tmp/.s.PGSQL.%d", (port)) + \
sizeof ((sun).sun_family))
/* The various kinds of startup messages are for the various kinds of
user authentication systems. In the beginning, there was only /*
STARTUP_MSG and all connections were unauthenticated. Now, there are * These manipulate the frontend/backend protocol version number.
several choices of authentication method (the client picks one, but *
the server needn't necessarily accept it). So now, the STARTUP_MSG * The major number should be incremented for incompatible changes. The minor
message means to start either an unauthenticated or a host-based * number should be incremented for compatible changes (eg. additional
authenticated connection, depending on what the server prefers. This * functionality).
is possible because the protocol between server and client is the same *
in both cases (basically, no negotiation is required at all). * If a backend supports version m.n of the protocol it must actually support
* versions m.0..n]. Backend support for version m-1 can be dropped after a
* `reasonable' length of time.
*
* A frontend isn't required to support anything other than the current
* version.
*/ */
typedef enum _MsgType #define PG_PROTOCOL_MAJOR(v) ((v) >> 16)
{ #define PG_PROTOCOL_MINOR(v) ((v) & 0x0000ffff)
ACK_MSG = 0, /* acknowledge a message */ #define PG_PROTOCOL(m,n) (((m) << 16) | (n))
ERROR_MSG = 1, /* error response to client from server */
RESET_MSG = 2, /* client must reset connection */ /* The earliest and latest frontend/backend protocol version supported. */
PRINT_MSG = 3, /* tuples for client from server */
NET_ERROR = 4, /* error in net system call */ #define PG_PROTOCOL_EARLIEST PG_PROTOCOL(0,0)
FUNCTION_MSG = 5, /* fastpath call (unused) */ #define PG_PROTOCOL_LATEST PG_PROTOCOL(1,0)
QUERY_MSG = 6, /* client query to server */
STARTUP_MSG = 7, /* initialize a connection with a backend */ /*
DUPLICATE_MSG = 8, /* duplicate msg arrived (errors msg only) */ * All packets sent to the postmaster start with the length. This is omitted
INVALID_MSG = 9, /* for some control functions */ * from the different packet definitions specified below.
STARTUP_KRB4_MSG = 10, /* krb4 session follows startup packet */
STARTUP_KRB5_MSG = 11, /* krb5 session follows startup packet */
STARTUP_HBA_MSG = 12, /* use host-based authentication */
STARTUP_UNAUTH_MSG = 13, /* use unauthenticated connection */
STARTUP_PASSWORD_MSG = 14, /* use plaintext password authentication */
/* The following three are not really a named authentication method
* since the front end has no choice in choosing the method. The
* backend sends the SALT/UNSALT messages back to the frontend after
* the USER login has been given to the backend.
*/ */
STARTUP_CRYPT_MSG = 15, /* use crypt()'ed password authentication */
STARTUP_USER_MSG = 16, /* send user name to check pg_user for password */ typedef uint32 PacketLen;
STARTUP_SALT_MSG = 17, /* frontend should crypt the password it sends */
STARTUP_UNSALT_MSG = 18 /* frontend should NOT crypt the password it sends */
/* 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;
#define LAST_AUTHENTICATION_TYPE 14
typedef char *Addr;
typedef int PacketLen; /* packet length */
typedef struct StartupInfo
{
/* PacketHdr hdr; */
char database[PATH_SIZE]; /* database name */
char user[NAMEDATALEN]; /* user name */
char options[ARGV_SIZE]; /* possible additional args */
char execFile[ARGV_SIZE]; /* possible backend to use */
char tty[PATH_SIZE]; /* possible tty for debug output */
} StartupInfo;
/* amount of available data in a packet buffer */
#define MESSAGE_SIZE sizeof(StartupInfo)
/* I/O can be blocking or non-blocking */
#define BLOCKING (FALSE)
#define NON_BLOCKING (TRUE)
/* a PacketBuf gets shipped from client to server so be careful
of differences in representation.
Be sure to use htonl() and ntohl() on the len and msgtype fields! */
typedef struct PacketBuf
{
int len;
MsgType msgtype;
char data[MESSAGE_SIZE];
} PacketBuf;
/* update the conversion routines
StartupInfo2PacketBuf() and PacketBuf2StartupInfo() (decl. below)
if StartupInfo or PacketBuf structs ever change */
/* /*
* socket descriptor port * Startup message parameters sizes. These must not be changed without changing
* we need addresses of both sides to do authentication calls * the protcol version. These are all strings that are '\0' terminated only if
* there is room.
*/ */
typedef struct Port
{ #define SM_DATABASE 64
int sock; /* file descriptor */ #define SM_USER 32
int mask; /* select mask */ #define SM_OPTIONS 64
int nBytes; /* nBytes read in so far */ #define SM_UNUSED 64
/* local addr (us) */ #define SM_TTY 64
union { struct sockaddr_in in; struct sockaddr_un un; } laddr;
/* remote addr (them) */ typedef uint32 ProtocolVersion; /* Fe/Be protocol version nr. */
union { struct sockaddr_in in; struct sockaddr_un un; } raddr;
/* typedef struct StartupPacket {
* PacketBufId id; ProtocolVersion protoVersion; /* Protocol version */
*//* id of packet buf currently in use */ char database[SM_DATABASE]; /* Database name */
PacketBuf buf; /* stream implementation (curr pack buf) */ char user[SM_USER]; /* User name */
char salt[2]; char options[SM_OPTIONS]; /* Optional additional args */
} Port; char unused[SM_UNUSED]; /* Unused */
char tty[SM_TTY]; /* Tty for debug output */
/* invalid socket descriptor */ } StartupPacket;
#define INVALID_SOCK (-1)
#define INVALID_ID (-1) /* These are the authentication requests sent by the backend. */
#define MAX_CONNECTIONS 10
#define N_PACK_BUFS 20 #define AUTH_REQ_OK 0 /* User is authenticated */
#define AUTH_REQ_KRB4 1 /* Kerberos V4 */
/* no multi-packet messages yet */ #define AUTH_REQ_KRB5 2 /* Kerberos V5 */
#define MAX_PACKET_BACKLOG 1 #define AUTH_REQ_PASSWORD 3 /* Password */
#define AUTH_REQ_CRYPT 4 /* Encrypted password */
#define DEFAULT_STRING ""
typedef uint32 AuthRequest;
extern FILE *Pfout,
*Pfin;
extern int PQAsyncNotifyWaiting; /* This next section is to maintain compatibility with protocol v0.0. */
#define STARTUP_MSG 7 /* Initialise a connection */
#define STARTUP_KRB4_MSG 10 /* krb4 session follows */
#define STARTUP_KRB5_MSG 11 /* krb5 session follows */
#define STARTUP_PASSWORD_MSG 14 /* Password follows */
typedef ProtocolVersion MsgType;
/* in pqcompriv.c */ /* in pqcompriv.c */
int pqGetShort(int *, FILE *); int pqGetShort(int *, FILE *);
...@@ -160,15 +128,4 @@ int pqPutNBytes(const char *, size_t, FILE *); ...@@ -160,15 +128,4 @@ int pqPutNBytes(const char *, size_t, FILE *);
int pqPutString(const char *, FILE *); int pqPutString(const char *, FILE *);
int pqPutByte(int, FILE *); int pqPutByte(int, FILE *);
/*
* prototypes for functions in pqpacket.c
*/
extern int PacketReceive(Port *port, PacketBuf *buf, char nonBlocking);
extern int PacketSend(Port *port, PacketBuf *buf,
PacketLen len, char nonBlocking);
/* extern PacketBuf* StartupInfo2PacketBuf(StartupInfo*); */
/* extern StartupInfo* PacketBuf2StartupInfo(PacketBuf*); */
extern char *name_of_authentication_type(int type);
#endif /* PQCOMM_H */ #endif /* PQCOMM_H */
...@@ -7,10 +7,13 @@ ...@@ -7,10 +7,13 @@
# #
# #
# IDENTIFICATION # IDENTIFICATION
# $Header: /cvsroot/pgsql/src/interfaces/libpq/Attic/Makefile.in,v 1.4 1998/01/17 23:39:11 scrappy Exp $ # $Header: /cvsroot/pgsql/src/interfaces/libpq/Attic/Makefile.in,v 1.5 1998/01/26 01:42:24 scrappy Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
SO_MAJOR_VERSION=1
SO_MINOR_VERSION=1
SRCDIR= ../.. SRCDIR= ../..
include $(SRCDIR)/Makefile.global include $(SRCDIR)/Makefile.global
...@@ -19,7 +22,7 @@ INCLUDE_OPT= -I$(SRCDIR)/include -I$(SRCDIR)/backend ...@@ -19,7 +22,7 @@ INCLUDE_OPT= -I$(SRCDIR)/include -I$(SRCDIR)/backend
PORTNAME=@PORTNAME@ PORTNAME=@PORTNAME@
CFLAGS+= $(INCLUDE_OPT) CFLAGS+= $(INCLUDE_OPT) -DFRONTEND
ifdef KRBVERS ifdef KRBVERS
CFLAGS+= $(KRBFLAGS) CFLAGS+= $(KRBFLAGS)
...@@ -34,20 +37,20 @@ install-shlib-dep := ...@@ -34,20 +37,20 @@ install-shlib-dep :=
ifeq ($(PORTNAME), linux) ifeq ($(PORTNAME), linux)
ifdef LINUX_ELF ifdef LINUX_ELF
install-shlib-dep := install-shlib install-shlib-dep := install-shlib
shlib := libpq.so.1 shlib := libpq.so.$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)
LDFLAGS_SL = -shared LDFLAGS_SL = -shared
CFLAGS += $(CFLAGS_SL) CFLAGS += $(CFLAGS_SL)
endif endif
endif endif
ifeq ($(PORTNAME), bsd) ifeq ($(PORTNAME), bsd)
install-shlib-dep := install-shlib install-shlib-dep := install-shlib
shlib := libpq.so.1.0 shlib := libpq.so.$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)
LDFLAGS_SL = -x -Bshareable -Bforcearchive LDFLAGS_SL = -x -Bshareable -Bforcearchive
CFLAGS += $(CFLAGS_SL) CFLAGS += $(CFLAGS_SL)
endif endif
ifeq ($(PORTNAME), i386_solaris) ifeq ($(PORTNAME), i386_solaris)
install-shlib-dep := install-shlib install-shlib-dep := install-shlib
shlib := libpq.so.1 shlib := libpq.so.$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)
LDFLAGS_SL = -G -z text LDFLAGS_SL = -G -z text
CFLAGS += $(CFLAGS_SL) CFLAGS += $(CFLAGS_SL)
endif endif
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.12 1997/12/04 00:28:08 scrappy Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.13 1998/01/26 01:42:25 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -42,6 +42,11 @@ ...@@ -42,6 +42,11 @@
#include "fe-auth.h" #include "fe-auth.h"
#include "fe-connect.h" #include "fe-connect.h"
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
/*---------------------------------------------------------------- /*----------------------------------------------------------------
* common definitions for generic fe/be routines * common definitions for generic fe/be routines
*---------------------------------------------------------------- *----------------------------------------------------------------
...@@ -457,49 +462,49 @@ pg_krb5_sendauth(const char *PQerrormsg, int sock, ...@@ -457,49 +462,49 @@ pg_krb5_sendauth(const char *PQerrormsg, int sock,
#endif /* KRB5 */ #endif /* KRB5 */
static int static int
pg_password_sendauth(Port *port, const char *user, const char *password) pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
{ {
PacketBuf buf; /* Encrypt the password if needed. */
char *tmp;
buf.len = htonl(sizeof(PacketBuf)); if (areq == AUTH_REQ_CRYPT)
buf.msgtype = STARTUP_PASSWORD_MSG; password = crypt(password, conn->salt);
buf.data[0] = '\0';
tmp = buf.data; return packetSend(conn, password, strlen(password) + 1);
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, fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
const char *user, const char *password, const char *PQerrormsg) const char *password, const char *PQerrormsg)
{ {
switch (msgtype) switch (areq)
{ {
case AUTH_REQ_OK:
break;
case AUTH_REQ_KRB4:
#ifdef KRB4 #ifdef KRB4
case STARTUP_KRB4_MSG: if (pg_krb4_sendauth(PQerrormsg, conn->sock, &conn->laddr.in,
if (pg_krb4_sendauth(PQerrormsg, port->sock, &port->laddr, &conn->raddr.in,
&port->raddr,
hostname) != STATUS_OK) hostname) != STATUS_OK)
{ {
(void) sprintf(PQerrormsg, (void) sprintf(PQerrormsg,
"fe_sendauth: krb4 authentication failed\n"); "fe_sendauth: krb4 authentication failed\n");
/* fputs(PQerrormsg, stderr); */
return (STATUS_ERROR); return (STATUS_ERROR);
} }
break; break;
#else
(void)sprintf(PQerrormsg,
"fe_sendauth: krb4 authentication not supported\n");
return (STATUS_ERROR);
#endif #endif
case AUTH_REQ_KRB5:
#ifdef KRB5 #ifdef KRB5
case STARTUP_KRB5_MSG: if (pg_krb5_sendauth(PQerrormsg, conn->sock, &conn->laddr.in,
if (pg_krb5_sendauth(PQerrormsg, port->sock, &port->laddr, &conn->raddr.in,
&port->raddr,
hostname) != STATUS_OK) hostname) != STATUS_OK)
{ {
(void) sprintf(PQerrormsg, (void) sprintf(PQerrormsg,
...@@ -507,15 +512,29 @@ fe_sendauth(MsgType msgtype, Port *port, const char *hostname, ...@@ -507,15 +512,29 @@ fe_sendauth(MsgType msgtype, Port *port, const char *hostname,
return (STATUS_ERROR); return (STATUS_ERROR);
} }
break; break;
#else
(void)sprintf(PQerrormsg,
"fe_sendauth: krb5 authentication not supported\n");
return (STATUS_ERROR);
#endif #endif
case STARTUP_MSG:
case AUTH_REQ_PASSWORD:
case AUTH_REQ_CRYPT:
if (pg_password_sendauth(conn, password, areq) != STATUS_OK)
{
(void)sprintf(PQerrormsg,
"fe_sendauth: error sending password authentication\n");
return (STATUS_ERROR);
}
break; break;
case STARTUP_PASSWORD_MSG:
case STARTUP_CRYPT_MSG:
pg_password_sendauth(port, user, password);
default: default:
break; (void)sprintf(PQerrormsg,
"fe_sendauth: authentication type %u not supported\n",areq);
return (STATUS_ERROR);
} }
return (STATUS_OK); return (STATUS_OK);
} }
......
...@@ -6,13 +6,16 @@ ...@@ -6,13 +6,16 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: fe-auth.h,v 1.6 1997/09/08 21:55:35 momjian Exp $ * $Id: fe-auth.h,v 1.7 1998/01/26 01:42:26 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef FE_AUTH_H #ifndef FE_AUTH_H
#define FE_AUTH_H #define FE_AUTH_H
#include "libpq-fe.h"
/*---------------------------------------------------------------- /*----------------------------------------------------------------
* Common routines and definitions * Common routines and definitions
*---------------------------------------------------------------- *----------------------------------------------------------------
...@@ -29,9 +32,8 @@ ...@@ -29,9 +32,8 @@
#endif /* KRB4 || KRB5 */ #endif /* KRB4 || KRB5 */
extern int extern int
fe_sendauth(MsgType msgtype, Port *port, const char *hostname, fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
const char *user, const char *password, const char *password, const char *PQerromsg);
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 */
......
This diff is collapsed.
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.45 1997/12/23 20:00:06 thomas Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.46 1998/01/26 01:42:35 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -168,7 +168,7 @@ getTuple(PGconn *conn, PGresult *result, int binary) ...@@ -168,7 +168,7 @@ getTuple(PGconn *conn, PGresult *result, int binary)
if ((nfields % BYTELEN) > 0) if ((nfields % BYTELEN) > 0)
nbytes++; nbytes++;
if (pqGetnchar(bitmap, nbytes, pfin, pfdebug) == 1) if (nbytes >= MAX_FIELDS || pqGetnchar(bitmap, nbytes, pfin, pfdebug) == 1)
{ {
sprintf(conn->errorMessage, sprintf(conn->errorMessage,
"Error reading null-values bitmap from row data stream\n"); "Error reading null-values bitmap from row data stream\n");
...@@ -189,10 +189,10 @@ getTuple(PGconn *conn, PGresult *result, int binary) ...@@ -189,10 +189,10 @@ getTuple(PGconn *conn, PGresult *result, int binary)
else else
{ {
/* get the value length (the first four bytes are for length) */ /* get the value length (the first four bytes are for length) */
pqGetInt(&vlen, VARHDRSZ, pfin, pfdebug); pqGetInt(&vlen, 4, pfin, pfdebug);
if (binary == 0) if (binary == 0)
{ {
vlen = vlen - VARHDRSZ; vlen = vlen - 4;
} }
if (vlen < 0) if (vlen < 0)
vlen = 0; vlen = 0;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment