mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
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.
This commit is contained in:
@@ -1,122 +1,150 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "postgres.h"
|
||||
#include "libpq/pqcomm.h"
|
||||
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* These definitions for ntoh/hton are the other way around from the
|
||||
* default system definitions, so we roll our own here.
|
||||
/*
|
||||
* 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
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#ifndef BYTE_ORDER
|
||||
#error BYTE_ORDER must be defined as LITTLE_ENDIAN, BIG_ENDIAN or PDP_ENDIAN
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define ntoh_s(n) n
|
||||
#define ntoh_l(n) n
|
||||
#define hton_s(n) n
|
||||
#define hton_l(n) n
|
||||
#else /* BYTE_ORDER != LITTLE_ENDIAN */
|
||||
|
||||
#define ntoh_s(n) n
|
||||
#define ntoh_l(n) n
|
||||
#define hton_s(n) n
|
||||
#define hton_l(n) n
|
||||
|
||||
#else
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define ntoh_s(n) (u_short)(((u_char *)&n)[1] << 8 \
|
||||
| ((u_char *)&n)[0])
|
||||
#define ntoh_l(n) (uint32) (((u_char *)&n)[3] << 24 \
|
||||
| ((u_char *)&n)[2] << 16 \
|
||||
| ((u_char *)&n)[1] << 8 \
|
||||
| ((u_char *)&n)[0])
|
||||
#define hton_s(n) (ntoh_s(n))
|
||||
#define hton_l(n) (ntoh_l(n))
|
||||
|
||||
#define ntoh_s(n) (uint16)(((u_char *)&n)[1] << 8 \
|
||||
| ((u_char *)&n)[0])
|
||||
#define ntoh_l(n) (uint32)(((u_char *)&n)[3] << 24 \
|
||||
| ((u_char *)&n)[2] << 16 \
|
||||
| ((u_char *)&n)[1] << 8 \
|
||||
| ((u_char *)&n)[0])
|
||||
#define hton_s(n) (ntoh_s(n))
|
||||
#define hton_l(n) (ntoh_l(n))
|
||||
|
||||
#else
|
||||
/* BYTE_ORDER != BIG_ENDIAN */
|
||||
#if BYTE_ORDER == PDP_ENDIAN
|
||||
|
||||
#error PDP_ENDIAN macros not written yet
|
||||
|
||||
#else
|
||||
/* BYTE_ORDER != anything known */
|
||||
|
||||
#error BYTE_ORDER not defined as anything understood
|
||||
#endif /* BYTE_ORDER == PDP_ENDIAN */
|
||||
#endif /* BYTE_ORDER == BIG_ENDIAN */
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int
|
||||
pqPutShort(int integer, FILE *f)
|
||||
{
|
||||
int retval = 0;
|
||||
u_short n,
|
||||
s;
|
||||
uint16 n;
|
||||
|
||||
s = integer;
|
||||
n = hton_s(s);
|
||||
if (fwrite(&n, sizeof(u_short), 1, f) != 1)
|
||||
retval = EOF;
|
||||
#ifdef FRONTEND
|
||||
n = htons((uint16)integer);
|
||||
#else
|
||||
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
|
||||
pqPutLong(int integer, FILE *f)
|
||||
{
|
||||
int retval = 0;
|
||||
uint32 n;
|
||||
uint32 n;
|
||||
|
||||
n = hton_l(integer);
|
||||
if (fwrite(&n, sizeof(uint32), 1, f) != 1)
|
||||
retval = EOF;
|
||||
#ifdef FRONTEND
|
||||
n = htonl((uint32)integer);
|
||||
#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
|
||||
pqGetShort(int *result, FILE *f)
|
||||
{
|
||||
int retval = 0;
|
||||
u_short n;
|
||||
uint16 n;
|
||||
|
||||
if (fread(&n, sizeof(u_short), 1, f) != 1)
|
||||
retval = EOF;
|
||||
if (fread(&n, 2, 1, f) != 1)
|
||||
return EOF;
|
||||
|
||||
*result = ntoh_s(n);
|
||||
return retval;
|
||||
#ifdef FRONTEND
|
||||
*result = (int)ntohs(n);
|
||||
#else
|
||||
*result = (int)((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_s(n) : ntohs(n));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int
|
||||
pqGetLong(int *result, FILE *f)
|
||||
{
|
||||
int retval = 0;
|
||||
uint32 n;
|
||||
uint32 n;
|
||||
|
||||
if (fread(&n, sizeof(uint32), 1, f) != 1)
|
||||
retval = EOF;
|
||||
if (fread(&n, 4, 1, f) != 1)
|
||||
return EOF;
|
||||
|
||||
*result = ntoh_l(n);
|
||||
return retval;
|
||||
#ifdef FRONTEND
|
||||
*result = (int)ntohl(n);
|
||||
#else
|
||||
*result = (int)((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_l(n) : ntohl(n));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* 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.
|
||||
*/
|
||||
int
|
||||
pqGetNBytes(char *s, size_t len, FILE *f)
|
||||
{
|
||||
int cnt;
|
||||
int cnt;
|
||||
|
||||
if (f == NULL)
|
||||
return EOF;
|
||||
|
||||
cnt = fread(s, 1, len, f);
|
||||
s[cnt] = '\0';
|
||||
/* mjl: actually needs up to len+1 bytes, is this okay? XXX */
|
||||
|
||||
return (cnt == len) ? 0 : EOF;
|
||||
}
|
||||
@@ -126,7 +154,7 @@ int
|
||||
pqPutNBytes(const char *s, size_t len, FILE *f)
|
||||
{
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
return EOF;
|
||||
|
||||
if (fwrite(s, 1, len, f) != len)
|
||||
return EOF;
|
||||
@@ -138,15 +166,27 @@ pqPutNBytes(const char *s, size_t len, FILE *f)
|
||||
int
|
||||
pqGetString(char *s, size_t len, FILE *f)
|
||||
{
|
||||
int c;
|
||||
int c;
|
||||
|
||||
if (f == NULL)
|
||||
return EOF;
|
||||
|
||||
while (len-- && (c = getc(f)) != EOF && c)
|
||||
*s++ = 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;
|
||||
len--;
|
||||
}
|
||||
|
||||
*s = '\0';
|
||||
/* mjl: actually needs up to len+1 bytes, is this okay? XXX */
|
||||
|
||||
if (c == EOF)
|
||||
return EOF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -183,5 +223,3 @@ pqPutByte(int c, FILE *f)
|
||||
|
||||
return (putc(c, f) == c) ? 0 : EOF;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
Reference in New Issue
Block a user