1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
2016-09-06 06:03:55 +02:00
|
|
|
* libpq-be.h
|
2001-11-12 06:43:25 +01:00
|
|
|
* This file contains definitions for structures and externs used
|
|
|
|
* by the postmaster during client authentication.
|
|
|
|
*
|
|
|
|
* Note that this is backend-internal and is NOT exported to clients.
|
|
|
|
* Structs that need to be client-visible are in pqcomm.h.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*
|
2024-01-04 02:49:05 +01:00
|
|
|
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/libpq/libpq-be.h
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#ifndef LIBPQ_BE_H
|
|
|
|
#define LIBPQ_BE_H
|
|
|
|
|
2004-02-21 07:29:58 +01:00
|
|
|
#include <sys/time.h>
|
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL
implementations, with no user-visible effects. There are now two #defines,
USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which
is defined when building with any SSL implementation. Currently, OpenSSL is
the only implementation so the two #defines go together, but USE_SSL is
supposed to be used for implementation-independent code.
The libpq SSL code is changed to use a custom BIO, which does all the raw
I/O, like we've been doing in the backend for a long time. That makes it
possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids
a couple of syscall for each send(). Probably doesn't make much performance
difference in practice - the SSL encryption is expensive enough to mask the
effect - but it was a natural result of this refactoring.
Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by
Alvaro Herrera, Andreas Karlsson, Jeff Janes.
2014-08-11 10:54:19 +02:00
|
|
|
#ifdef USE_OPENSSL
|
1999-09-27 05:13:16 +02:00
|
|
|
#include <openssl/ssl.h>
|
|
|
|
#include <openssl/err.h>
|
|
|
|
#endif
|
2005-07-30 17:17:26 +02:00
|
|
|
#include <netinet/tcp.h>
|
1999-09-27 05:13:16 +02:00
|
|
|
|
2007-07-10 15:14:22 +02:00
|
|
|
#ifdef ENABLE_GSS
|
2007-07-12 16:36:52 +02:00
|
|
|
#if defined(HAVE_GSSAPI_H)
|
|
|
|
#include <gssapi.h>
|
|
|
|
#else
|
2007-07-10 15:14:22 +02:00
|
|
|
#include <gssapi/gssapi.h>
|
2007-07-12 16:43:21 +02:00
|
|
|
#endif /* HAVE_GSSAPI_H */
|
|
|
|
#endif /* ENABLE_GSS */
|
2007-07-10 15:14:22 +02:00
|
|
|
|
2007-07-23 12:16:54 +02:00
|
|
|
#ifdef ENABLE_SSPI
|
|
|
|
#define SECURITY_WIN32
|
2017-04-11 15:21:25 +02:00
|
|
|
#if defined(WIN32) && !defined(_MSC_VER)
|
2009-04-20 00:37:13 +02:00
|
|
|
#include <ntsecapi.h>
|
|
|
|
#endif
|
2007-07-23 12:16:54 +02:00
|
|
|
#include <security.h>
|
|
|
|
#undef SECURITY_WIN32
|
|
|
|
|
|
|
|
#ifndef ENABLE_GSS
|
|
|
|
/*
|
|
|
|
* Define a fake structure compatible with GSSAPI on Unix.
|
|
|
|
*/
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
void *value;
|
|
|
|
int length;
|
|
|
|
} gss_buffer_desc;
|
|
|
|
#endif
|
|
|
|
#endif /* ENABLE_SSPI */
|
|
|
|
|
2011-09-09 19:23:41 +02:00
|
|
|
#include "datatype/timestamp.h"
|
2004-02-21 07:29:58 +01:00
|
|
|
#include "libpq/hba.h"
|
|
|
|
#include "libpq/pqcomm.h"
|
|
|
|
|
1998-01-26 02:42:53 +01:00
|
|
|
|
2007-07-10 15:14:22 +02:00
|
|
|
/*
|
|
|
|
* GSSAPI specific state information
|
|
|
|
*/
|
2007-07-23 12:16:54 +02:00
|
|
|
#if defined(ENABLE_GSS) | defined(ENABLE_SSPI)
|
2007-07-10 15:14:22 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
2007-07-23 12:16:54 +02:00
|
|
|
gss_buffer_desc outbuf; /* GSSAPI output token buffer */
|
|
|
|
#ifdef ENABLE_GSS
|
2007-07-10 15:14:22 +02:00
|
|
|
gss_cred_id_t cred; /* GSSAPI connection cred's */
|
|
|
|
gss_ctx_id_t ctx; /* GSSAPI connection context */
|
|
|
|
gss_name_t name; /* GSSAPI client name */
|
GSSAPI encryption support
On both the frontend and backend, prepare for GSSAPI encryption
support by moving common code for error handling into a separate file.
Fix a TODO for handling multiple status messages in the process.
Eliminate the OIDs, which have not been needed for some time.
Add frontend and backend encryption support functions. Keep the
context initiation for authentication-only separate on both the
frontend and backend in order to avoid concerns about changing the
requested flags to include encryption support.
In postmaster, pull GSSAPI authorization checking into a shared
function. Also share the initiator name between the encryption and
non-encryption codepaths.
For HBA, add "hostgssenc" and "hostnogssenc" entries that behave
similarly to their SSL counterparts. "hostgssenc" requires either
"gss", "trust", or "reject" for its authentication.
Similarly, add a "gssencmode" parameter to libpq. Supported values are
"disable", "require", and "prefer". Notably, negotiation will only be
attempted if credentials can be acquired. Move credential acquisition
into its own function to support this behavior.
Add a simple pg_stat_gssapi view similar to pg_stat_ssl, for monitoring
if GSSAPI authentication was used, what principal was used, and if
encryption is being used on the connection.
Finally, add documentation for everything new, and update existing
documentation on connection security.
Thanks to Michael Paquier for the Windows fixes.
Author: Robbie Harwood, with changes to the read/write functions by me.
Reviewed in various forms and at different times by: Michael Paquier,
Andres Freund, David Steele.
Discussion: https://www.postgresql.org/message-id/flat/jlg1tgq1ktm.fsf@thriss.redhat.com
2019-04-03 21:02:33 +02:00
|
|
|
char *princ; /* GSSAPI Principal used for auth, NULL if
|
|
|
|
* GSSAPI auth was not used */
|
|
|
|
bool auth; /* GSSAPI Authentication used */
|
|
|
|
bool enc; /* GSSAPI encryption in use */
|
2023-04-13 14:55:07 +02:00
|
|
|
bool delegated_creds; /* GSSAPI Delegated credentials */
|
2007-07-23 12:16:54 +02:00
|
|
|
#endif
|
2007-07-10 15:14:22 +02:00
|
|
|
} pg_gssinfo;
|
|
|
|
#endif
|
|
|
|
|
Allow parallel workers to retrieve some data from Port
This commit moves authn_id into a new global structure called
ClientConnectionInfo (mapping to a MyClientConnectionInfo for each
backend) which is intended to hold all the client information that
should be shared between the backend and any of its parallel workers,
access for extensions and triggers being the primary use case. There is
no need to push all the data of Port to the workers, and authn_id is
quite a generic concept so using a separate structure provides the best
balance (the name of the structure has been suggested by Robert Haas).
While on it, and per discussion as this would be useful for a potential
SYSTEM_USER that can be accessed through parallel workers, a second
field is added for the authentication method, copied directly from
Port.
ClientConnectionInfo is serialized and restored using a new parallel
key and a structure tracks the length of the authn_id, making the
addition of more fields straight-forward.
Author: Jacob Champion
Reviewed-by: Bertrand Drouvot, Stephen Frost, Robert Haas, Tom Lane,
Michael Paquier, Julien Rouhaud
Discussion: https://postgr.es/m/793d990837ae5c06a558d58d62de9378ab525d83.camel@vmware.com
2022-08-24 05:57:13 +02:00
|
|
|
/*
|
|
|
|
* ClientConnectionInfo includes the fields describing the client connection
|
|
|
|
* that are copied over to parallel workers as nothing from Port does that.
|
|
|
|
* The same rules apply for allocations here as for Port (everything must be
|
|
|
|
* malloc'd or palloc'd in TopMemoryContext).
|
|
|
|
*
|
|
|
|
* If you add a struct member here, remember to also handle serialization in
|
|
|
|
* SerializeClientConnectionInfo() and co.
|
|
|
|
*/
|
|
|
|
typedef struct ClientConnectionInfo
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Authenticated identity. The meaning of this identifier is dependent on
|
|
|
|
* auth_method; it is the identity (if any) that the user presented during
|
|
|
|
* the authentication cycle, before they were assigned a database role.
|
|
|
|
* (It is effectively the "SYSTEM-USERNAME" of a pg_ident usermap --
|
|
|
|
* though the exact string in use may be different, depending on pg_hba
|
|
|
|
* options.)
|
|
|
|
*
|
|
|
|
* authn_id is NULL if the user has not actually been authenticated, for
|
|
|
|
* example if the "trust" auth method is in use.
|
|
|
|
*/
|
|
|
|
const char *authn_id;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The HBA method that determined the above authn_id. This only has
|
|
|
|
* meaning if authn_id is not NULL; otherwise it's undefined.
|
|
|
|
*/
|
|
|
|
UserAuth auth_method;
|
|
|
|
} ClientConnectionInfo;
|
|
|
|
|
1998-01-26 02:42:53 +01:00
|
|
|
/*
|
2024-03-12 12:42:38 +01:00
|
|
|
* The Port structure holds state information about a client connection in a
|
|
|
|
* backend process. It is available in the global variable MyProcPort. The
|
|
|
|
* struct and all the data it points are kept in TopMemoryContext.
|
Fix assorted issues in client host name lookup.
The code for matching clients to pg_hba.conf lines that specify host names
(instead of IP address ranges) failed to complain if reverse DNS lookup
failed; instead it silently didn't match, so that you might end up getting
a surprising "no pg_hba.conf entry for ..." error, as seen in bug #9518
from Mike Blackwell. Since we don't want to make this a fatal error in
situations where pg_hba.conf contains a mixture of host names and IP
addresses (clients matching one of the numeric entries should not have to
have rDNS data), remember the lookup failure and mention it as DETAIL if
we get to "no pg_hba.conf entry". Apply the same approach to forward-DNS
lookup failures, too, rather than treating them as immediate hard errors.
Along the way, fix a couple of bugs that prevented us from detecting an
rDNS lookup error reliably, and make sure that we make only one rDNS lookup
attempt; formerly, if the lookup attempt failed, the code would try again
for each host name entry in pg_hba.conf. Since more or less the whole
point of this design is to ensure there's only one lookup attempt not one
per entry, the latter point represents a performance bug that seems
sufficient justification for back-patching.
Also, adjust src/port/getaddrinfo.c so that it plays as well as it can
with this code. Which is not all that well, since it does not have actual
support for rDNS lookup, but at least it should return the expected (and
required by spec) error codes so that the main code correctly perceives the
lack of functionality as a lookup failure. It's unlikely that PG is still
being used in production on any machines that require our getaddrinfo.c,
so I'm not excited about working harder than this.
To keep the code in the various branches similar, this includes
back-patching commits c424d0d1052cb4053c8712ac44123f9b9a9aa3f2 and
1997f34db4687e671690ed054c8f30bb501b1168 into 9.2 and earlier.
Back-patch to 9.1 where the facility for hostnames in pg_hba.conf was
introduced.
2014-04-02 23:11:24 +02:00
|
|
|
*
|
|
|
|
* remote_hostname is set if we did a successful reverse lookup of the
|
|
|
|
* client's IP address during connection setup.
|
|
|
|
* remote_hostname_resolv tracks the state of hostname verification:
|
|
|
|
* +1 = remote_hostname is known to resolve to client's IP address
|
|
|
|
* -1 = remote_hostname is known NOT to resolve to client's IP address
|
|
|
|
* 0 = we have not done the forward DNS lookup yet
|
|
|
|
* -2 = there was an error in name resolution
|
|
|
|
* If reverse lookup of the client IP address fails, remote_hostname will be
|
|
|
|
* left NULL while remote_hostname_resolv is set to -2. If reverse lookup
|
|
|
|
* succeeds but forward lookup fails, remote_hostname_resolv is also set to -2
|
|
|
|
* (the case is distinguishable because remote_hostname isn't NULL). In
|
|
|
|
* either of the -2 cases, remote_hostname_errcode saves the lookup return
|
|
|
|
* code for possible later use with gai_strerror.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1998-02-26 05:46:47 +01:00
|
|
|
|
1998-01-26 02:42:53 +01:00
|
|
|
typedef struct Port
|
|
|
|
{
|
2010-01-10 15:16:08 +01:00
|
|
|
pgsocket sock; /* File descriptor */
|
2010-01-15 10:19:10 +01:00
|
|
|
bool noblock; /* is the socket in non-blocking mode? */
|
2003-04-18 00:26:02 +02:00
|
|
|
ProtocolVersion proto; /* FE/BE protocol version */
|
2001-11-12 06:43:25 +01:00
|
|
|
SockAddr laddr; /* local addr (postmaster) */
|
|
|
|
SockAddr raddr; /* remote addr (client) */
|
2004-02-17 04:54:57 +01:00
|
|
|
char *remote_host; /* name (or ip addr) of remote host */
|
2010-10-15 21:53:39 +02:00
|
|
|
char *remote_hostname; /* name (not ip addr) of remote host, if
|
|
|
|
* available */
|
Fix assorted issues in client host name lookup.
The code for matching clients to pg_hba.conf lines that specify host names
(instead of IP address ranges) failed to complain if reverse DNS lookup
failed; instead it silently didn't match, so that you might end up getting
a surprising "no pg_hba.conf entry for ..." error, as seen in bug #9518
from Mike Blackwell. Since we don't want to make this a fatal error in
situations where pg_hba.conf contains a mixture of host names and IP
addresses (clients matching one of the numeric entries should not have to
have rDNS data), remember the lookup failure and mention it as DETAIL if
we get to "no pg_hba.conf entry". Apply the same approach to forward-DNS
lookup failures, too, rather than treating them as immediate hard errors.
Along the way, fix a couple of bugs that prevented us from detecting an
rDNS lookup error reliably, and make sure that we make only one rDNS lookup
attempt; formerly, if the lookup attempt failed, the code would try again
for each host name entry in pg_hba.conf. Since more or less the whole
point of this design is to ensure there's only one lookup attempt not one
per entry, the latter point represents a performance bug that seems
sufficient justification for back-patching.
Also, adjust src/port/getaddrinfo.c so that it plays as well as it can
with this code. Which is not all that well, since it does not have actual
support for rDNS lookup, but at least it should return the expected (and
required by spec) error codes so that the main code correctly perceives the
lack of functionality as a lookup failure. It's unlikely that PG is still
being used in production on any machines that require our getaddrinfo.c,
so I'm not excited about working harder than this.
To keep the code in the various branches similar, this includes
back-patching commits c424d0d1052cb4053c8712ac44123f9b9a9aa3f2 and
1997f34db4687e671690ed054c8f30bb501b1168 into 9.2 and earlier.
Back-patch to 9.1 where the facility for hostnames in pg_hba.conf was
introduced.
2014-04-02 23:11:24 +02:00
|
|
|
int remote_hostname_resolv; /* see above */
|
|
|
|
int remote_hostname_errcode; /* see above */
|
2004-02-17 04:54:57 +01:00
|
|
|
char *remote_port; /* text rep of remote port */
|
1998-01-26 02:42:53 +01:00
|
|
|
|
|
|
|
/*
|
2003-04-18 00:26:02 +02:00
|
|
|
* Information that needs to be saved from the startup packet and passed
|
|
|
|
* into backend execution. "char *" fields are NULL if not set.
|
|
|
|
* guc_options points to a List of alternating option names and values.
|
1998-01-26 02:42:53 +01:00
|
|
|
*/
|
2003-04-18 00:26:02 +02:00
|
|
|
char *database_name;
|
|
|
|
char *user_name;
|
|
|
|
char *cmdline_options;
|
|
|
|
List *guc_options;
|
1998-01-26 02:42:53 +01:00
|
|
|
|
2018-09-29 01:04:50 +02:00
|
|
|
/*
|
|
|
|
* The startup packet application name, only used here for the "connection
|
|
|
|
* authorized" log message. We shouldn't use this post-startup, instead
|
|
|
|
* the GUC should be used as application can change it afterward.
|
|
|
|
*/
|
|
|
|
char *application_name;
|
|
|
|
|
2003-04-18 00:26:02 +02:00
|
|
|
/*
|
|
|
|
* Information that needs to be held during the authentication cycle.
|
|
|
|
*/
|
2008-09-15 14:32:57 +02:00
|
|
|
HbaLine *hba;
|
1999-09-27 05:13:16 +02:00
|
|
|
|
2005-09-12 04:26:33 +02:00
|
|
|
/*
|
Add support TCP user timeout in libpq and the backend server
Similarly to the set of parameters for keepalive, a connection parameter
for libpq is added as well as a backend GUC, called tcp_user_timeout.
Increasing the TCP user timeout is useful to allow a connection to
survive extended periods without end-to-end connection, and decreasing
it allows application to fail faster. By default, the parameter is 0,
which makes the connection use the system default, and follows a logic
close to the keepalive parameters in its handling. When connecting
through a Unix-socket domain, the parameters have no effect.
Author: Ryohei Nagaura
Reviewed-by: Fabien Coelho, Robert Haas, Kyotaro Horiguchi, Kirk
Jamison, Mikalai Keida, Takayuki Tsunakawa, Andrei Yahorau
Discussion: https://postgr.es/m/EDA4195584F5064680D8130B1CA91C45367328@G01JPEXMBYT04
2019-04-06 08:23:37 +02:00
|
|
|
* TCP keepalive and user timeout settings.
|
2005-09-12 04:26:33 +02:00
|
|
|
*
|
|
|
|
* default values are 0 if AF_UNIX or not yet known; current values are 0
|
|
|
|
* if AF_UNIX or using the default. Also, -1 in a default value means we
|
|
|
|
* were unable to find out the default (getsockopt failed).
|
|
|
|
*/
|
|
|
|
int default_keepalives_idle;
|
|
|
|
int default_keepalives_interval;
|
|
|
|
int default_keepalives_count;
|
Add support TCP user timeout in libpq and the backend server
Similarly to the set of parameters for keepalive, a connection parameter
for libpq is added as well as a backend GUC, called tcp_user_timeout.
Increasing the TCP user timeout is useful to allow a connection to
survive extended periods without end-to-end connection, and decreasing
it allows application to fail faster. By default, the parameter is 0,
which makes the connection use the system default, and follows a logic
close to the keepalive parameters in its handling. When connecting
through a Unix-socket domain, the parameters have no effect.
Author: Ryohei Nagaura
Reviewed-by: Fabien Coelho, Robert Haas, Kyotaro Horiguchi, Kirk
Jamison, Mikalai Keida, Takayuki Tsunakawa, Andrei Yahorau
Discussion: https://postgr.es/m/EDA4195584F5064680D8130B1CA91C45367328@G01JPEXMBYT04
2019-04-06 08:23:37 +02:00
|
|
|
int default_tcp_user_timeout;
|
2005-09-12 04:26:33 +02:00
|
|
|
int keepalives_idle;
|
|
|
|
int keepalives_interval;
|
|
|
|
int keepalives_count;
|
Add support TCP user timeout in libpq and the backend server
Similarly to the set of parameters for keepalive, a connection parameter
for libpq is added as well as a backend GUC, called tcp_user_timeout.
Increasing the TCP user timeout is useful to allow a connection to
survive extended periods without end-to-end connection, and decreasing
it allows application to fail faster. By default, the parameter is 0,
which makes the connection use the system default, and follows a logic
close to the keepalive parameters in its handling. When connecting
through a Unix-socket domain, the parameters have no effect.
Author: Ryohei Nagaura
Reviewed-by: Fabien Coelho, Robert Haas, Kyotaro Horiguchi, Kirk
Jamison, Mikalai Keida, Takayuki Tsunakawa, Andrei Yahorau
Discussion: https://postgr.es/m/EDA4195584F5064680D8130B1CA91C45367328@G01JPEXMBYT04
2019-04-06 08:23:37 +02:00
|
|
|
int tcp_user_timeout;
|
2005-09-12 04:26:33 +02:00
|
|
|
|
GSSAPI encryption support
On both the frontend and backend, prepare for GSSAPI encryption
support by moving common code for error handling into a separate file.
Fix a TODO for handling multiple status messages in the process.
Eliminate the OIDs, which have not been needed for some time.
Add frontend and backend encryption support functions. Keep the
context initiation for authentication-only separate on both the
frontend and backend in order to avoid concerns about changing the
requested flags to include encryption support.
In postmaster, pull GSSAPI authorization checking into a shared
function. Also share the initiator name between the encryption and
non-encryption codepaths.
For HBA, add "hostgssenc" and "hostnogssenc" entries that behave
similarly to their SSL counterparts. "hostgssenc" requires either
"gss", "trust", or "reject" for its authentication.
Similarly, add a "gssencmode" parameter to libpq. Supported values are
"disable", "require", and "prefer". Notably, negotiation will only be
attempted if credentials can be acquired. Move credential acquisition
into its own function to support this behavior.
Add a simple pg_stat_gssapi view similar to pg_stat_ssl, for monitoring
if GSSAPI authentication was used, what principal was used, and if
encryption is being used on the connection.
Finally, add documentation for everything new, and update existing
documentation on connection security.
Thanks to Michael Paquier for the Windows fixes.
Author: Robbie Harwood, with changes to the read/write functions by me.
Reviewed in various forms and at different times by: Michael Paquier,
Andres Freund, David Steele.
Discussion: https://www.postgresql.org/message-id/flat/jlg1tgq1ktm.fsf@thriss.redhat.com
2019-04-03 21:02:33 +02:00
|
|
|
/*
|
|
|
|
* GSSAPI structures.
|
|
|
|
*/
|
2007-07-23 12:16:54 +02:00
|
|
|
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2007-07-10 15:14:22 +02:00
|
|
|
/*
|
2020-12-28 23:44:17 +01:00
|
|
|
* If GSSAPI is supported and used on this connection, store GSSAPI
|
|
|
|
* information. Even when GSSAPI is not compiled in, store a NULL pointer
|
|
|
|
* to keep struct offsets the same (for extension ABI compatibility).
|
2007-07-10 15:14:22 +02:00
|
|
|
*/
|
|
|
|
pg_gssinfo *gss;
|
|
|
|
#else
|
|
|
|
void *gss;
|
|
|
|
#endif
|
|
|
|
|
1999-09-27 05:13:16 +02:00
|
|
|
/*
|
2014-11-25 08:39:31 +01:00
|
|
|
* SSL structures.
|
1999-09-27 05:13:16 +02:00
|
|
|
*/
|
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL
implementations, with no user-visible effects. There are now two #defines,
USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which
is defined when building with any SSL implementation. Currently, OpenSSL is
the only implementation so the two #defines go together, but USE_SSL is
supposed to be used for implementation-independent code.
The libpq SSL code is changed to use a custom BIO, which does all the raw
I/O, like we've been doing in the backend for a long time. That makes it
possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids
a couple of syscall for each send(). Probably doesn't make much performance
difference in practice - the SSL encryption is expensive enough to mask the
effect - but it was a natural result of this refactoring.
Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by
Alvaro Herrera, Andreas Karlsson, Jeff Janes.
2014-08-11 10:54:19 +02:00
|
|
|
bool ssl_in_use;
|
|
|
|
char *peer_cn;
|
2021-03-29 21:31:22 +02:00
|
|
|
char *peer_dn;
|
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL
implementations, with no user-visible effects. There are now two #defines,
USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which
is defined when building with any SSL implementation. Currently, OpenSSL is
the only implementation so the two #defines go together, but USE_SSL is
supposed to be used for implementation-independent code.
The libpq SSL code is changed to use a custom BIO, which does all the raw
I/O, like we've been doing in the backend for a long time. That makes it
possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids
a couple of syscall for each send(). Probably doesn't make much performance
difference in practice - the SSL encryption is expensive enough to mask the
effect - but it was a natural result of this refactoring.
Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by
Alvaro Herrera, Andreas Karlsson, Jeff Janes.
2014-08-11 10:54:19 +02:00
|
|
|
bool peer_cert_valid;
|
2014-11-25 08:39:31 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* OpenSSL structures. (Keep these last so that the locations of other
|
2021-02-10 07:28:19 +01:00
|
|
|
* fields are the same whether or not you build with SSL enabled.)
|
2014-11-25 08:39:31 +01:00
|
|
|
*/
|
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL
implementations, with no user-visible effects. There are now two #defines,
USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which
is defined when building with any SSL implementation. Currently, OpenSSL is
the only implementation so the two #defines go together, but USE_SSL is
supposed to be used for implementation-independent code.
The libpq SSL code is changed to use a custom BIO, which does all the raw
I/O, like we've been doing in the backend for a long time. That makes it
possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids
a couple of syscall for each send(). Probably doesn't make much performance
difference in practice - the SSL encryption is expensive enough to mask the
effect - but it was a natural result of this refactoring.
Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by
Alvaro Herrera, Andreas Karlsson, Jeff Janes.
2014-08-11 10:54:19 +02:00
|
|
|
#ifdef USE_OPENSSL
|
1999-09-27 05:13:16 +02:00
|
|
|
SSL *ssl;
|
2002-06-14 06:36:58 +02:00
|
|
|
X509 *peer;
|
1999-09-27 05:13:16 +02:00
|
|
|
#endif
|
1998-01-26 02:42:53 +01:00
|
|
|
} Port;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
2024-03-12 12:42:38 +01:00
|
|
|
/*
|
|
|
|
* ClientSocket holds a socket for an accepted connection, along with the
|
|
|
|
* information about the remote endpoint. This is passed from postmaster to
|
|
|
|
* the backend process.
|
|
|
|
*/
|
|
|
|
typedef struct ClientSocket
|
|
|
|
{
|
|
|
|
pgsocket sock; /* File descriptor */
|
|
|
|
SockAddr raddr; /* remote addr (client) */
|
|
|
|
} ClientSocket;
|
|
|
|
|
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL
implementations, with no user-visible effects. There are now two #defines,
USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which
is defined when building with any SSL implementation. Currently, OpenSSL is
the only implementation so the two #defines go together, but USE_SSL is
supposed to be used for implementation-independent code.
The libpq SSL code is changed to use a custom BIO, which does all the raw
I/O, like we've been doing in the backend for a long time. That makes it
possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids
a couple of syscall for each send(). Probably doesn't make much performance
difference in practice - the SSL encryption is expensive enough to mask the
effect - but it was a natural result of this refactoring.
Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by
Alvaro Herrera, Andreas Karlsson, Jeff Janes.
2014-08-11 10:54:19 +02:00
|
|
|
#ifdef USE_SSL
|
2018-01-19 18:18:42 +01:00
|
|
|
/*
|
|
|
|
* Hardcoded DH parameters, used in ephemeral DH keying. (See also
|
|
|
|
* README.SSL for more details on EDH.)
|
|
|
|
*
|
2019-07-05 03:47:32 +02:00
|
|
|
* This is the 2048-bit DH parameter from RFC 3526. The generation of the
|
|
|
|
* prime is specified in RFC 2412 Appendix E, which also discusses the
|
|
|
|
* design choice of the generator. Note that when loaded with OpenSSL
|
|
|
|
* this causes DH_check() to fail on DH_NOT_SUITABLE_GENERATOR, where
|
|
|
|
* leaking a bit is preferred.
|
2018-01-19 18:18:42 +01:00
|
|
|
*/
|
|
|
|
#define FILE_DH2048 \
|
|
|
|
"-----BEGIN DH PARAMETERS-----\n\
|
2019-07-05 03:47:32 +02:00
|
|
|
MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n\
|
|
|
|
IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n\
|
|
|
|
awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n\
|
|
|
|
mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n\
|
|
|
|
fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n\
|
|
|
|
5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==\n\
|
2018-01-19 18:18:42 +01:00
|
|
|
-----END DH PARAMETERS-----\n"
|
|
|
|
|
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL
implementations, with no user-visible effects. There are now two #defines,
USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which
is defined when building with any SSL implementation. Currently, OpenSSL is
the only implementation so the two #defines go together, but USE_SSL is
supposed to be used for implementation-independent code.
The libpq SSL code is changed to use a custom BIO, which does all the raw
I/O, like we've been doing in the backend for a long time. That makes it
possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids
a couple of syscall for each send(). Probably doesn't make much performance
difference in practice - the SSL encryption is expensive enough to mask the
effect - but it was a natural result of this refactoring.
Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by
Alvaro Herrera, Andreas Karlsson, Jeff Janes.
2014-08-11 10:54:19 +02:00
|
|
|
/*
|
|
|
|
* These functions are implemented by the glue code specific to each
|
|
|
|
* SSL implementation (e.g. be-secure-openssl.c)
|
|
|
|
*/
|
2018-01-19 01:53:22 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize global SSL context.
|
|
|
|
*
|
|
|
|
* If isServerStart is true, report any errors as FATAL (so we don't return).
|
|
|
|
* Otherwise, log errors at LOG level and return -1 to indicate trouble,
|
|
|
|
* preserving the old SSL state if any. Returns 0 if OK.
|
|
|
|
*/
|
2017-01-04 18:43:52 +01:00
|
|
|
extern int be_tls_init(bool isServerStart);
|
2018-01-19 01:53:22 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Destroy global SSL context, if any.
|
|
|
|
*/
|
2017-01-03 03:37:12 +01:00
|
|
|
extern void be_tls_destroy(void);
|
2018-01-19 01:53:22 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Attempt to negotiate SSL connection.
|
|
|
|
*/
|
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL
implementations, with no user-visible effects. There are now two #defines,
USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which
is defined when building with any SSL implementation. Currently, OpenSSL is
the only implementation so the two #defines go together, but USE_SSL is
supposed to be used for implementation-independent code.
The libpq SSL code is changed to use a custom BIO, which does all the raw
I/O, like we've been doing in the backend for a long time. That makes it
possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids
a couple of syscall for each send(). Probably doesn't make much performance
difference in practice - the SSL encryption is expensive enough to mask the
effect - but it was a natural result of this refactoring.
Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by
Alvaro Herrera, Andreas Karlsson, Jeff Janes.
2014-08-11 10:54:19 +02:00
|
|
|
extern int be_tls_open_server(Port *port);
|
2018-01-19 01:53:22 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Close SSL connection.
|
|
|
|
*/
|
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL
implementations, with no user-visible effects. There are now two #defines,
USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which
is defined when building with any SSL implementation. Currently, OpenSSL is
the only implementation so the two #defines go together, but USE_SSL is
supposed to be used for implementation-independent code.
The libpq SSL code is changed to use a custom BIO, which does all the raw
I/O, like we've been doing in the backend for a long time. That makes it
possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids
a couple of syscall for each send(). Probably doesn't make much performance
difference in practice - the SSL encryption is expensive enough to mask the
effect - but it was a natural result of this refactoring.
Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by
Alvaro Herrera, Andreas Karlsson, Jeff Janes.
2014-08-11 10:54:19 +02:00
|
|
|
extern void be_tls_close(Port *port);
|
2018-01-19 01:53:22 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Read data from a secure connection.
|
|
|
|
*/
|
2015-02-13 20:46:14 +01:00
|
|
|
extern ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor);
|
2018-01-19 01:53:22 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Write data to a secure connection.
|
|
|
|
*/
|
2015-02-13 20:46:14 +01:00
|
|
|
extern ssize_t be_tls_write(Port *port, void *ptr, size_t len, int *waitfor);
|
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL
implementations, with no user-visible effects. There are now two #defines,
USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which
is defined when building with any SSL implementation. Currently, OpenSSL is
the only implementation so the two #defines go together, but USE_SSL is
supposed to be used for implementation-independent code.
The libpq SSL code is changed to use a custom BIO, which does all the raw
I/O, like we've been doing in the backend for a long time. That makes it
possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids
a couple of syscall for each send(). Probably doesn't make much performance
difference in practice - the SSL encryption is expensive enough to mask the
effect - but it was a natural result of this refactoring.
Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by
Alvaro Herrera, Andreas Karlsson, Jeff Janes.
2014-08-11 10:54:19 +02:00
|
|
|
|
2018-01-19 01:53:22 +01:00
|
|
|
/*
|
|
|
|
* Return information about the SSL connection.
|
|
|
|
*/
|
2015-04-12 19:07:46 +02:00
|
|
|
extern int be_tls_get_cipher_bits(Port *port);
|
2018-01-25 14:58:00 +01:00
|
|
|
extern const char *be_tls_get_version(Port *port);
|
|
|
|
extern const char *be_tls_get_cipher(Port *port);
|
2019-02-01 00:17:45 +01:00
|
|
|
extern void be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len);
|
|
|
|
extern void be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len);
|
|
|
|
extern void be_tls_get_peer_serial(Port *port, char *ptr, size_t len);
|
2018-01-19 01:53:22 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the server certificate hash for SCRAM channel binding type
|
|
|
|
* tls-server-end-point.
|
|
|
|
*
|
|
|
|
* The result is a palloc'd hash of the server certificate with its
|
|
|
|
* size, and NULL if there is no certificate available.
|
|
|
|
*/
|
2018-01-04 21:18:39 +01:00
|
|
|
extern char *be_tls_get_certificate_hash(Port *port, size_t *len);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
2020-03-25 22:13:17 +01:00
|
|
|
/* init hook for SSL, the default sets the password callback if appropriate */
|
2020-04-17 21:57:19 +02:00
|
|
|
#ifdef USE_OPENSSL
|
2020-03-25 22:13:17 +01:00
|
|
|
typedef void (*openssl_tls_init_hook_typ) (SSL_CTX *context, bool isServerStart);
|
2020-03-26 00:37:30 +01:00
|
|
|
extern PGDLLIMPORT openssl_tls_init_hook_typ openssl_tls_init_hook;
|
2020-04-17 21:57:19 +02:00
|
|
|
#endif
|
2020-03-25 22:13:17 +01:00
|
|
|
|
Remove support for tls-unique channel binding.
There are some problems with the tls-unique channel binding type. It's not
supported by all SSL libraries, and strictly speaking it's not defined for
TLS 1.3 at all, even though at least in OpenSSL, the functions used for it
still seem to work with TLS 1.3 connections. And since we had no
mechanism to negotiate what channel binding type to use, there would be
awkward interoperability issues if a server only supported some channel
binding types. tls-server-end-point seems feasible to support with any SSL
library, so let's just stick to that.
This removes the scram_channel_binding libpq option altogether, since there
is now only one supported channel binding type.
This also removes all the channel binding tests from the SSL test suite.
They were really just testing the scram_channel_binding option, which
is now gone. Channel binding is used if both client and server support it,
so it is used in the existing tests. It would be good to have some tests
specifically for channel binding, to make sure it really is used, and the
different combinations of a client and a server that support or doesn't
support it. The current set of settings we have make it hard to write such
tests, but I did test those things manually, by disabling
HAVE_BE_TLS_GET_CERTIFICATE_HASH and/or
HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH.
I also removed the SCRAM_CHANNEL_BINDING_TLS_END_POINT constant. This is a
matter of taste, but IMO it's more readable to just use the
"tls-server-end-point" string.
Refactor the checks on whether the SSL library supports the functions
needed for tls-server-end-point channel binding. Now the server won't
advertise, and the client won't choose, the SCRAM-SHA-256-PLUS variant, if
compiled with an OpenSSL version too old to support it.
In the passing, add some sanity checks to check that the chosen SASL
mechanism, SCRAM-SHA-256 or SCRAM-SHA-256-PLUS, matches whether the SCRAM
exchange used channel binding or not. For example, if the client selects
the non-channel-binding variant SCRAM-SHA-256, but in the SCRAM message
uses channel binding anyway. It's harmless from a security point of view,
I believe, and I'm not sure if there are some other conditions that would
cause the connection to fail, but it seems better to be strict about these
things and check explicitly.
Discussion: https://www.postgresql.org/message-id/ec787074-2305-c6f4-86aa-6902f98485a4%40iki.fi
2018-08-05 12:44:21 +02:00
|
|
|
#endif /* USE_SSL */
|
|
|
|
|
GSSAPI encryption support
On both the frontend and backend, prepare for GSSAPI encryption
support by moving common code for error handling into a separate file.
Fix a TODO for handling multiple status messages in the process.
Eliminate the OIDs, which have not been needed for some time.
Add frontend and backend encryption support functions. Keep the
context initiation for authentication-only separate on both the
frontend and backend in order to avoid concerns about changing the
requested flags to include encryption support.
In postmaster, pull GSSAPI authorization checking into a shared
function. Also share the initiator name between the encryption and
non-encryption codepaths.
For HBA, add "hostgssenc" and "hostnogssenc" entries that behave
similarly to their SSL counterparts. "hostgssenc" requires either
"gss", "trust", or "reject" for its authentication.
Similarly, add a "gssencmode" parameter to libpq. Supported values are
"disable", "require", and "prefer". Notably, negotiation will only be
attempted if credentials can be acquired. Move credential acquisition
into its own function to support this behavior.
Add a simple pg_stat_gssapi view similar to pg_stat_ssl, for monitoring
if GSSAPI authentication was used, what principal was used, and if
encryption is being used on the connection.
Finally, add documentation for everything new, and update existing
documentation on connection security.
Thanks to Michael Paquier for the Windows fixes.
Author: Robbie Harwood, with changes to the read/write functions by me.
Reviewed in various forms and at different times by: Michael Paquier,
Andres Freund, David Steele.
Discussion: https://www.postgresql.org/message-id/flat/jlg1tgq1ktm.fsf@thriss.redhat.com
2019-04-03 21:02:33 +02:00
|
|
|
#ifdef ENABLE_GSS
|
2019-04-04 17:11:46 +02:00
|
|
|
/*
|
|
|
|
* Return information about the GSSAPI authenticated connection
|
|
|
|
*/
|
|
|
|
extern bool be_gssapi_get_auth(Port *port);
|
|
|
|
extern bool be_gssapi_get_enc(Port *port);
|
|
|
|
extern const char *be_gssapi_get_princ(Port *port);
|
2023-05-21 03:32:54 +02:00
|
|
|
extern bool be_gssapi_get_delegation(Port *port);
|
2019-04-04 17:11:46 +02:00
|
|
|
|
GSSAPI encryption support
On both the frontend and backend, prepare for GSSAPI encryption
support by moving common code for error handling into a separate file.
Fix a TODO for handling multiple status messages in the process.
Eliminate the OIDs, which have not been needed for some time.
Add frontend and backend encryption support functions. Keep the
context initiation for authentication-only separate on both the
frontend and backend in order to avoid concerns about changing the
requested flags to include encryption support.
In postmaster, pull GSSAPI authorization checking into a shared
function. Also share the initiator name between the encryption and
non-encryption codepaths.
For HBA, add "hostgssenc" and "hostnogssenc" entries that behave
similarly to their SSL counterparts. "hostgssenc" requires either
"gss", "trust", or "reject" for its authentication.
Similarly, add a "gssencmode" parameter to libpq. Supported values are
"disable", "require", and "prefer". Notably, negotiation will only be
attempted if credentials can be acquired. Move credential acquisition
into its own function to support this behavior.
Add a simple pg_stat_gssapi view similar to pg_stat_ssl, for monitoring
if GSSAPI authentication was used, what principal was used, and if
encryption is being used on the connection.
Finally, add documentation for everything new, and update existing
documentation on connection security.
Thanks to Michael Paquier for the Windows fixes.
Author: Robbie Harwood, with changes to the read/write functions by me.
Reviewed in various forms and at different times by: Michael Paquier,
Andres Freund, David Steele.
Discussion: https://www.postgresql.org/message-id/flat/jlg1tgq1ktm.fsf@thriss.redhat.com
2019-04-03 21:02:33 +02:00
|
|
|
/* Read and write to a GSSAPI-encrypted connection. */
|
|
|
|
extern ssize_t be_gssapi_read(Port *port, void *ptr, size_t len);
|
|
|
|
extern ssize_t be_gssapi_write(Port *port, void *ptr, size_t len);
|
|
|
|
#endif /* ENABLE_GSS */
|
|
|
|
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT ProtocolVersion FrontendProtocol;
|
Allow parallel workers to retrieve some data from Port
This commit moves authn_id into a new global structure called
ClientConnectionInfo (mapping to a MyClientConnectionInfo for each
backend) which is intended to hold all the client information that
should be shared between the backend and any of its parallel workers,
access for extensions and triggers being the primary use case. There is
no need to push all the data of Port to the workers, and authn_id is
quite a generic concept so using a separate structure provides the best
balance (the name of the structure has been suggested by Robert Haas).
While on it, and per discussion as this would be useful for a potential
SYSTEM_USER that can be accessed through parallel workers, a second
field is added for the authentication method, copied directly from
Port.
ClientConnectionInfo is serialized and restored using a new parallel
key and a structure tracks the length of the authn_id, making the
addition of more fields straight-forward.
Author: Jacob Champion
Reviewed-by: Bertrand Drouvot, Stephen Frost, Robert Haas, Tom Lane,
Michael Paquier, Julien Rouhaud
Discussion: https://postgr.es/m/793d990837ae5c06a558d58d62de9378ab525d83.camel@vmware.com
2022-08-24 05:57:13 +02:00
|
|
|
extern PGDLLIMPORT ClientConnectionInfo MyClientConnectionInfo;
|
1998-01-26 02:42:53 +01:00
|
|
|
|
2005-07-30 17:17:26 +02:00
|
|
|
/* TCP keepalives configuration. These are no-ops on an AF_UNIX socket. */
|
|
|
|
|
|
|
|
extern int pq_getkeepalivesidle(Port *port);
|
|
|
|
extern int pq_getkeepalivesinterval(Port *port);
|
|
|
|
extern int pq_getkeepalivescount(Port *port);
|
Add support TCP user timeout in libpq and the backend server
Similarly to the set of parameters for keepalive, a connection parameter
for libpq is added as well as a backend GUC, called tcp_user_timeout.
Increasing the TCP user timeout is useful to allow a connection to
survive extended periods without end-to-end connection, and decreasing
it allows application to fail faster. By default, the parameter is 0,
which makes the connection use the system default, and follows a logic
close to the keepalive parameters in its handling. When connecting
through a Unix-socket domain, the parameters have no effect.
Author: Ryohei Nagaura
Reviewed-by: Fabien Coelho, Robert Haas, Kyotaro Horiguchi, Kirk
Jamison, Mikalai Keida, Takayuki Tsunakawa, Andrei Yahorau
Discussion: https://postgr.es/m/EDA4195584F5064680D8130B1CA91C45367328@G01JPEXMBYT04
2019-04-06 08:23:37 +02:00
|
|
|
extern int pq_gettcpusertimeout(Port *port);
|
2005-07-30 17:17:26 +02:00
|
|
|
|
|
|
|
extern int pq_setkeepalivesidle(int idle, Port *port);
|
|
|
|
extern int pq_setkeepalivesinterval(int interval, Port *port);
|
|
|
|
extern int pq_setkeepalivescount(int count, Port *port);
|
Add support TCP user timeout in libpq and the backend server
Similarly to the set of parameters for keepalive, a connection parameter
for libpq is added as well as a backend GUC, called tcp_user_timeout.
Increasing the TCP user timeout is useful to allow a connection to
survive extended periods without end-to-end connection, and decreasing
it allows application to fail faster. By default, the parameter is 0,
which makes the connection use the system default, and follows a logic
close to the keepalive parameters in its handling. When connecting
through a Unix-socket domain, the parameters have no effect.
Author: Ryohei Nagaura
Reviewed-by: Fabien Coelho, Robert Haas, Kyotaro Horiguchi, Kirk
Jamison, Mikalai Keida, Takayuki Tsunakawa, Andrei Yahorau
Discussion: https://postgr.es/m/EDA4195584F5064680D8130B1CA91C45367328@G01JPEXMBYT04
2019-04-06 08:23:37 +02:00
|
|
|
extern int pq_settcpusertimeout(int timeout, Port *port);
|
2005-07-30 17:17:26 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#endif /* LIBPQ_BE_H */
|