PostgreSQL Source Code  git master
fe-connect.c File Reference
#include "postgres_fe.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <netdb.h>
#include <time.h>
#include <unistd.h>
#include "common/ip.h"
#include "common/link-canary.h"
#include "common/scram-common.h"
#include "common/string.h"
#include "fe-auth.h"
#include "libpq-fe.h"
#include "libpq-int.h"
#include "mb/pg_wchar.h"
#include "pg_config_paths.h"
#include "port/pg_bswap.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
Include dependency graph for fe-connect.c:

Go to the source code of this file.

Data Structures

struct  _internalPQconninfoOption
 

Macros

#define PGPASSFILE   ".pgpass"
 
#define ERRCODE_APPNAME_UNKNOWN   "42704"
 
#define ERRCODE_INVALID_PASSWORD   "28P01"
 
#define ERRCODE_CANNOT_CONNECT_NOW   "57P03"
 
#define DefaultHost   "localhost"
 
#define DefaultOption   ""
 
#define DefaultChannelBinding   "disable"
 
#define DefaultTargetSessionAttrs   "any"
 
#define DefaultSSLMode   "disable"
 
#define DefaultSSLCertMode   "disable"
 
#define DefaultGSSMode   "disable"
 
#define MAX_ERRLEN   30000
 

Typedefs

typedef struct _internalPQconninfoOption internalPQconninfoOption
 

Functions

static bool connectOptions1 (PGconn *conn, const char *conninfo)
 
static bool connectOptions2 (PGconn *conn)
 
static int connectDBStart (PGconn *conn)
 
static int connectDBComplete (PGconn *conn)
 
static PGPing internal_ping (PGconn *conn)
 
static PGconnmakeEmptyPGconn (void)
 
static void pqFreeCommandQueue (PGcmdQueueEntry *queue)
 
static bool fillPGconn (PGconn *conn, PQconninfoOption *connOptions)
 
static void freePGconn (PGconn *conn)
 
static void closePGconn (PGconn *conn)
 
static void release_conn_addrinfo (PGconn *conn)
 
static void sendTerminateConn (PGconn *conn)
 
static PQconninfoOptionconninfo_init (PQExpBuffer errorMessage)
 
static PQconninfoOptionparse_connection_string (const char *connstr, PQExpBuffer errorMessage, bool use_defaults)
 
static int uri_prefix_length (const char *connstr)
 
static bool recognized_connection_string (const char *connstr)
 
static PQconninfoOptionconninfo_parse (const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
 
static PQconninfoOptionconninfo_array_parse (const char *const *keywords, const char *const *values, PQExpBuffer errorMessage, bool use_defaults, int expand_dbname)
 
static bool conninfo_add_defaults (PQconninfoOption *options, PQExpBuffer errorMessage)
 
static PQconninfoOptionconninfo_uri_parse (const char *uri, PQExpBuffer errorMessage, bool use_defaults)
 
static bool conninfo_uri_parse_options (PQconninfoOption *options, const char *uri, PQExpBuffer errorMessage)
 
static bool conninfo_uri_parse_params (char *params, PQconninfoOption *connOptions, PQExpBuffer errorMessage)
 
static char * conninfo_uri_decode (const char *str, PQExpBuffer errorMessage)
 
static bool get_hexdigit (char digit, int *value)
 
static const char * conninfo_getval (PQconninfoOption *connOptions, const char *keyword)
 
static PQconninfoOptionconninfo_storeval (PQconninfoOption *connOptions, const char *keyword, const char *value, PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode)
 
static PQconninfoOptionconninfo_find (PQconninfoOption *connOptions, const char *keyword)
 
static void defaultNoticeReceiver (void *arg, const PGresult *res)
 
static void defaultNoticeProcessor (void *arg, const char *message)
 
static int parseServiceInfo (PQconninfoOption *options, PQExpBuffer errorMessage)
 
static int parseServiceFile (const char *serviceFile, const char *service, PQconninfoOption *options, PQExpBuffer errorMessage, bool *group_found)
 
static char * pwdfMatchesString (char *buf, const char *token)
 
static char * passwordFromFile (const char *hostname, const char *port, const char *dbname, const char *username, const char *pgpassfile)
 
static void pgpassfileWarning (PGconn *conn)
 
static void default_threadlock (int acquire)
 
static bool sslVerifyProtocolVersion (const char *version)
 
static bool sslVerifyProtocolRange (const char *min, const char *max)
 
void pqDropConnection (PGconn *conn, bool flushInput)
 
static void pqDropServerData (PGconn *conn)
 
PGconnPQconnectdbParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PGPing PQpingParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PGconnPQconnectdb (const char *conninfo)
 
PGPing PQping (const char *conninfo)
 
PGconnPQconnectStartParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PGconnPQconnectStart (const char *conninfo)
 
static int count_comma_separated_elems (const char *input)
 
static char * parse_comma_separated_list (char **startptr, bool *more)
 
PQconninfoOptionPQconndefaults (void)
 
PGconnPQsetdbLogin (const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd)
 
static int connectNoDelay (PGconn *conn)
 
static void getHostaddr (PGconn *conn, char *host_addr, int host_addr_len)
 
static void emitHostIdentityInfo (PGconn *conn, const char *host_addr)
 
static void connectFailureMessage (PGconn *conn, int errorno)
 
static int useKeepalives (PGconn *conn)
 
static bool parse_int_param (const char *value, int *result, PGconn *conn, const char *context)
 
static int setKeepalivesIdle (PGconn *conn)
 
static int setKeepalivesInterval (PGconn *conn)
 
static int setKeepalivesCount (PGconn *conn)
 
static int setTCPUserTimeout (PGconn *conn)
 
PostgresPollingStatusType PQconnectPoll (PGconn *conn)
 
void PQfinish (PGconn *conn)
 
void PQreset (PGconn *conn)
 
int PQresetStart (PGconn *conn)
 
PostgresPollingStatusType PQresetPoll (PGconn *conn)
 
PGcancelPQgetCancel (PGconn *conn)
 
void PQfreeCancel (PGcancel *cancel)
 
static bool optional_setsockopt (int fd, int protoid, int optid, int value)
 
int PQcancel (PGcancel *cancel, char *errbuf, int errbufsize)
 
int PQrequestCancel (PGconn *conn)
 
int pqPacketSend (PGconn *conn, char pack_type, const void *buf, size_t buf_len)
 
PQconninfoOptionPQconninfoParse (const char *conninfo, char **errmsg)
 
PQconninfoOptionPQconninfo (PGconn *conn)
 
void PQconninfoFree (PQconninfoOption *connOptions)
 
char * PQdb (const PGconn *conn)
 
char * PQuser (const PGconn *conn)
 
char * PQpass (const PGconn *conn)
 
char * PQhost (const PGconn *conn)
 
char * PQhostaddr (const PGconn *conn)
 
char * PQport (const PGconn *conn)
 
char * PQtty (const PGconn *conn)
 
char * PQoptions (const PGconn *conn)
 
ConnStatusType PQstatus (const PGconn *conn)
 
PGTransactionStatusType PQtransactionStatus (const PGconn *conn)
 
const char * PQparameterStatus (const PGconn *conn, const char *paramName)
 
int PQprotocolVersion (const PGconn *conn)
 
int PQserverVersion (const PGconn *conn)
 
char * PQerrorMessage (const PGconn *conn)
 
int PQsocket (const PGconn *conn)
 
int PQbackendPID (const PGconn *conn)
 
PGpipelineStatus PQpipelineStatus (const PGconn *conn)
 
int PQconnectionNeedsPassword (const PGconn *conn)
 
int PQconnectionUsedPassword (const PGconn *conn)
 
int PQclientEncoding (const PGconn *conn)
 
int PQsetClientEncoding (PGconn *conn, const char *encoding)
 
PGVerbosity PQsetErrorVerbosity (PGconn *conn, PGVerbosity verbosity)
 
PGContextVisibility PQsetErrorContextVisibility (PGconn *conn, PGContextVisibility show_context)
 
PQnoticeReceiver PQsetNoticeReceiver (PGconn *conn, PQnoticeReceiver proc, void *arg)
 
PQnoticeProcessor PQsetNoticeProcessor (PGconn *conn, PQnoticeProcessor proc, void *arg)
 
bool pqGetHomeDirectory (char *buf, int bufsize)
 
pgthreadlock_t PQregisterThreadLock (pgthreadlock_t newhandler)
 

Variables

static const internalPQconninfoOption PQconninfoOptions []
 
static const PQEnvironmentOption EnvironmentOptions []
 
static const char uri_designator [] = "postgresql://"
 
static const char short_uri_designator [] = "postgres://"
 
pgthreadlock_t pg_g_threadlock = default_threadlock
 

Macro Definition Documentation

◆ DefaultChannelBinding

#define DefaultChannelBinding   "disable"

Definition at line 123 of file fe-connect.c.

◆ DefaultGSSMode

#define DefaultGSSMode   "disable"

Definition at line 137 of file fe-connect.c.

◆ DefaultHost

#define DefaultHost   "localhost"

Definition at line 118 of file fe-connect.c.

◆ DefaultOption

#define DefaultOption   ""

Definition at line 119 of file fe-connect.c.

◆ DefaultSSLCertMode

#define DefaultSSLCertMode   "disable"

Definition at line 131 of file fe-connect.c.

◆ DefaultSSLMode

#define DefaultSSLMode   "disable"

Definition at line 130 of file fe-connect.c.

◆ DefaultTargetSessionAttrs

#define DefaultTargetSessionAttrs   "any"

Definition at line 125 of file fe-connect.c.

◆ ERRCODE_APPNAME_UNKNOWN

#define ERRCODE_APPNAME_UNKNOWN   "42704"

Definition at line 88 of file fe-connect.c.

◆ ERRCODE_CANNOT_CONNECT_NOW

#define ERRCODE_CANNOT_CONNECT_NOW   "57P03"

Definition at line 93 of file fe-connect.c.

◆ ERRCODE_INVALID_PASSWORD

#define ERRCODE_INVALID_PASSWORD   "28P01"

Definition at line 91 of file fe-connect.c.

◆ MAX_ERRLEN

#define MAX_ERRLEN   30000

◆ PGPASSFILE

#define PGPASSFILE   ".pgpass"

Definition at line 77 of file fe-connect.c.

Typedef Documentation

◆ internalPQconninfoOption

Function Documentation

◆ closePGconn()

static void closePGconn ( PGconn conn)
static

Definition at line 4366 of file fe-connect.c.

4367 {
4368  /*
4369  * If possible, send Terminate message to close the connection politely.
4370  */
4372 
4373  /*
4374  * Must reset the blocking status so a possible reconnect will work.
4375  *
4376  * Don't call PQsetnonblocking() because it will fail if it's unable to
4377  * flush the connection.
4378  */
4379  conn->nonblocking = false;
4380 
4381  /*
4382  * Close the connection, reset all transient state, flush I/O buffers.
4383  * Note that this includes clearing conn's error state; we're no longer
4384  * interested in any failures associated with the old connection, and we
4385  * want a clean slate for any new connection attempt.
4386  */
4387  pqDropConnection(conn, true);
4388  conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just absent */
4392  pqClearAsyncResult(conn); /* deallocate result */
4395 
4396  /* Reset all state obtained from server, too */
4398 }
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:456
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:4339
static void release_conn_addrinfo(PGconn *conn)
Definition: fe-connect.c:4324
static void pqDropServerData(PGconn *conn)
Definition: fe-connect.c:569
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:776
@ CONNECTION_BAD
Definition: libpq-fe.h:61
@ PQTRANS_IDLE
Definition: libpq-fe.h:118
@ PQ_PIPELINE_OFF
Definition: libpq-fe.h:158
@ PGASYNC_IDLE
Definition: libpq-int.h:220
#define pqClearConnErrorState(conn)
Definition: libpq-int.h:867
PGconn * conn
Definition: streamutil.c:54
PGTransactionStatusType xactStatus
Definition: libpq-int.h:417
bool nonblocking
Definition: libpq-int.h:420
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:416
PGpipelineStatus pipelineStatus
Definition: libpq-int.h:422
ConnStatusType status
Definition: libpq-int.h:415

References pg_conn::asyncStatus, conn, CONNECTION_BAD, pg_conn::nonblocking, PGASYNC_IDLE, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, pqClearAsyncResult(), pqClearConnErrorState, pqDropConnection(), pqDropServerData(), PQTRANS_IDLE, release_conn_addrinfo(), sendTerminateConn(), pg_conn::status, and pg_conn::xactStatus.

Referenced by PQfinish(), PQreset(), and PQresetStart().

◆ connectDBComplete()

static int connectDBComplete ( PGconn conn)
static

Definition at line 2291 of file fe-connect.c.

2292 {
2294  time_t finish_time = ((time_t) -1);
2295  int timeout = 0;
2296  int last_whichhost = -2; /* certainly different from whichhost */
2297  struct addrinfo *last_addr_cur = NULL;
2298 
2299  if (conn == NULL || conn->status == CONNECTION_BAD)
2300  return 0;
2301 
2302  /*
2303  * Set up a time limit, if connect_timeout isn't zero.
2304  */
2305  if (conn->connect_timeout != NULL)
2306  {
2307  if (!parse_int_param(conn->connect_timeout, &timeout, conn,
2308  "connect_timeout"))
2309  {
2310  /* mark the connection as bad to report the parsing failure */
2312  return 0;
2313  }
2314 
2315  if (timeout > 0)
2316  {
2317  /*
2318  * Rounding could cause connection to fail unexpectedly quickly;
2319  * to prevent possibly waiting hardly-at-all, insist on at least
2320  * two seconds.
2321  */
2322  if (timeout < 2)
2323  timeout = 2;
2324  }
2325  else /* negative means 0 */
2326  timeout = 0;
2327  }
2328 
2329  for (;;)
2330  {
2331  int ret = 0;
2332 
2333  /*
2334  * (Re)start the connect_timeout timer if it's active and we are
2335  * considering a different host than we were last time through. If
2336  * we've already succeeded, though, needn't recalculate.
2337  */
2338  if (flag != PGRES_POLLING_OK &&
2339  timeout > 0 &&
2340  (conn->whichhost != last_whichhost ||
2341  conn->addr_cur != last_addr_cur))
2342  {
2343  finish_time = time(NULL) + timeout;
2344  last_whichhost = conn->whichhost;
2345  last_addr_cur = conn->addr_cur;
2346  }
2347 
2348  /*
2349  * Wait, if necessary. Note that the initial state (just after
2350  * PQconnectStart) is to wait for the socket to select for writing.
2351  */
2352  switch (flag)
2353  {
2354  case PGRES_POLLING_OK:
2355  return 1; /* success! */
2356 
2357  case PGRES_POLLING_READING:
2358  ret = pqWaitTimed(1, 0, conn, finish_time);
2359  if (ret == -1)
2360  {
2361  /* hard failure, eg select() problem, aborts everything */
2363  return 0;
2364  }
2365  break;
2366 
2367  case PGRES_POLLING_WRITING:
2368  ret = pqWaitTimed(0, 1, conn, finish_time);
2369  if (ret == -1)
2370  {
2371  /* hard failure, eg select() problem, aborts everything */
2373  return 0;
2374  }
2375  break;
2376 
2377  default:
2378  /* Just in case we failed to set it in PQconnectPoll */
2380  return 0;
2381  }
2382 
2383  if (ret == 1) /* connect_timeout elapsed */
2384  {
2385  /*
2386  * Give up on current server/address, try the next one.
2387  */
2388  conn->try_next_addr = true;
2390  }
2391 
2392  /*
2393  * Now try to advance the state machine.
2394  */
2395  flag = PQconnectPoll(conn);
2396  }
2397 }
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:2427
static bool parse_int_param(const char *value, int *result, PGconn *conn, const char *context)
Definition: fe-connect.c:1971
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
Definition: fe-misc.c:992
@ CONNECTION_NEEDED
Definition: libpq-fe.h:76
PostgresPollingStatusType
Definition: libpq-fe.h:85
@ PGRES_POLLING_OK
Definition: libpq-fe.h:89
@ PGRES_POLLING_READING
Definition: libpq-fe.h:87
@ PGRES_POLLING_WRITING
Definition: libpq-fe.h:88
struct addrinfo * addr_cur
Definition: libpq-int.h:475
char * connect_timeout
Definition: libpq-int.h:363
bool try_next_addr
Definition: libpq-int.h:472
int whichhost
Definition: libpq-int.h:431
char * flag(int b)
Definition: test-ctype.c:33

References pg_conn::addr_cur, conn, pg_conn::connect_timeout, CONNECTION_BAD, CONNECTION_NEEDED, flag(), parse_int_param(), PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PQconnectPoll(), pqWaitTimed(), pg_conn::status, pg_conn::try_next_addr, and pg_conn::whichhost.

Referenced by internal_ping(), PQconnectdb(), PQconnectdbParams(), PQreset(), and PQsetdbLogin().

◆ connectDBStart()

static int connectDBStart ( PGconn conn)
static

Definition at line 2221 of file fe-connect.c.

2222 {
2223  if (!conn)
2224  return 0;
2225 
2226  if (!conn->options_valid)
2227  goto connect_errReturn;
2228 
2229  /*
2230  * Check for bad linking to backend-internal versions of src/common
2231  * functions (see comments in link-canary.c for the reason we need this).
2232  * Nobody but developers should see this message, so we don't bother
2233  * translating it.
2234  */
2236  {
2238  "libpq is incorrectly linked to backend functions\n");
2239  goto connect_errReturn;
2240  }
2241 
2242  /* Ensure our buffers are empty */
2243  conn->inStart = conn->inCursor = conn->inEnd = 0;
2244  conn->outCount = 0;
2245 
2246  /*
2247  * Set up to try to connect to the first host. (Setting whichhost = -1 is
2248  * a bit of a cheat, but PQconnectPoll will advance it to 0 before
2249  * anything else looks at it.)
2250  */
2251  conn->whichhost = -1;
2252  conn->try_next_addr = false;
2253  conn->try_next_host = true;
2255 
2256  /* Also reset the target_server_type state if needed */
2259 
2260  /*
2261  * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
2262  * so that it can easily be re-executed if needed again during the
2263  * asynchronous startup process. However, we must run it once here,
2264  * because callers expect a success return from this routine to mean that
2265  * we are in PGRES_POLLING_WRITING connection state.
2266  */
2268  return 1;
2269 
2270 connect_errReturn:
2271 
2272  /*
2273  * If we managed to open a socket, close it immediately rather than
2274  * waiting till PQfinish. (The application cannot have gotten the socket
2275  * from PQsocket yet, so this doesn't risk breaking anything.)
2276  */
2277  pqDropConnection(conn, true);
2279  return 0;
2280 }
@ SERVER_TYPE_PREFER_STANDBY_PASS2
Definition: libpq-int.h:242
@ SERVER_TYPE_PREFER_STANDBY
Definition: libpq-int.h:241
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
bool try_next_host
Definition: libpq-int.h:473
int inCursor
Definition: libpq-int.h:495
int inEnd
Definition: libpq-int.h:496
int inStart
Definition: libpq-int.h:494
PQExpBufferData errorMessage
Definition: libpq-int.h:600
bool options_valid
Definition: libpq-int.h:419
PGTargetServerType target_server_type
Definition: libpq-int.h:471
int outCount
Definition: libpq-int.h:501

References appendPQExpBufferStr(), conn, CONNECTION_BAD, CONNECTION_NEEDED, pg_conn::errorMessage, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, pg_conn::options_valid, pg_conn::outCount, pg_link_canary_is_frontend(), PGRES_POLLING_WRITING, PQconnectPoll(), pqDropConnection(), SERVER_TYPE_PREFER_STANDBY, SERVER_TYPE_PREFER_STANDBY_PASS2, pg_conn::status, pg_conn::target_server_type, pg_conn::try_next_addr, pg_conn::try_next_host, and pg_conn::whichhost.

Referenced by PQconnectStart(), PQconnectStartParams(), PQreset(), PQresetStart(), and PQsetdbLogin().

◆ connectFailureMessage()

static void connectFailureMessage ( PGconn conn,
int  errorno 
)
static

Definition at line 1932 of file fe-connect.c.

1933 {
1934  char sebuf[PG_STRERROR_R_BUFLEN];
1935 
1937  "%s\n",
1938  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)));
1939 
1940  if (conn->raddr.addr.ss_family == AF_UNIX)
1941  libpq_append_conn_error(conn, "\tIs the server running locally and accepting connections on that socket?");
1942  else
1943  libpq_append_conn_error(conn, "\tIs the server running on that host and accepting TCP/IP connections?");
1944 }
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1312
#define SOCK_STRERROR
Definition: libpq-int.h:916
#define PG_STRERROR_R_BUFLEN
Definition: port.h:256
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
struct sockaddr_storage addr
Definition: pqcomm.h:26
SockAddr raddr
Definition: libpq-int.h:452

References SockAddr::addr, appendPQExpBuffer(), conn, pg_conn::errorMessage, libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, pg_conn::raddr, and SOCK_STRERROR.

Referenced by PQconnectPoll().

◆ connectNoDelay()

static int connectNoDelay ( PGconn conn)
static

Definition at line 1817 of file fe-connect.c.

1818 {
1819 #ifdef TCP_NODELAY
1820  int on = 1;
1821 
1822  if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
1823  (char *) &on,
1824  sizeof(on)) < 0)
1825  {
1826  char sebuf[PG_STRERROR_R_BUFLEN];
1827 
1828  libpq_append_conn_error(conn, "could not set socket to TCP no delay mode: %s",
1829  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1830  return 0;
1831  }
1832 #endif
1833 
1834  return 1;
1835 }
#define SOCK_ERRNO
Definition: libpq-int.h:915
pgsocket sock
Definition: libpq-int.h:449

References conn, libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, pg_conn::sock, SOCK_ERRNO, and SOCK_STRERROR.

Referenced by PQconnectPoll().

◆ connectOptions1()

static bool connectOptions1 ( PGconn conn,
const char *  conninfo 
)
static

Definition at line 932 of file fe-connect.c.

933 {
934  PQconninfoOption *connOptions;
935 
936  /*
937  * Parse the conninfo string
938  */
939  connOptions = parse_connection_string(conninfo, &conn->errorMessage, true);
940  if (connOptions == NULL)
941  {
943  /* errorMessage is already set */
944  return false;
945  }
946 
947  /*
948  * Move option values into conn structure
949  */
950  if (!fillPGconn(conn, connOptions))
951  {
953  PQconninfoFree(connOptions);
954  return false;
955  }
956 
957  /*
958  * Free the option info - all is in conn now
959  */
960  PQconninfoFree(connOptions);
961 
962  return true;
963 }
static PQconninfoOption * parse_connection_string(const char *connstr, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:5693
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:6851
static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
Definition: fe-connect.c:892

References conn, CONNECTION_BAD, pg_conn::errorMessage, fillPGconn(), parse_connection_string(), PQconninfoFree(), and pg_conn::status.

Referenced by PQconnectStart(), and PQsetdbLogin().

◆ connectOptions2()

static bool connectOptions2 ( PGconn conn)
static

Definition at line 1030 of file fe-connect.c.

1031 {
1032  int i;
1033 
1034  /*
1035  * Allocate memory for details about each host to which we might possibly
1036  * try to connect. For that, count the number of elements in the hostaddr
1037  * or host options. If neither is given, assume one host.
1038  */
1039  conn->whichhost = 0;
1040  if (conn->pghostaddr && conn->pghostaddr[0] != '\0')
1042  else if (conn->pghost && conn->pghost[0] != '\0')
1044  else
1045  conn->nconnhost = 1;
1046  conn->connhost = (pg_conn_host *)
1047  calloc(conn->nconnhost, sizeof(pg_conn_host));
1048  if (conn->connhost == NULL)
1049  goto oom_error;
1050 
1051  /*
1052  * We now have one pg_conn_host structure per possible host. Fill in the
1053  * host and hostaddr fields for each, by splitting the parameter strings.
1054  */
1055  if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
1056  {
1057  char *s = conn->pghostaddr;
1058  bool more = true;
1059 
1060  for (i = 0; i < conn->nconnhost && more; i++)
1061  {
1063  if (conn->connhost[i].hostaddr == NULL)
1064  goto oom_error;
1065  }
1066 
1067  /*
1068  * If hostaddr was given, the array was allocated according to the
1069  * number of elements in the hostaddr list, so it really should be the
1070  * right size.
1071  */
1072  Assert(!more);
1073  Assert(i == conn->nconnhost);
1074  }
1075 
1076  if (conn->pghost != NULL && conn->pghost[0] != '\0')
1077  {
1078  char *s = conn->pghost;
1079  bool more = true;
1080 
1081  for (i = 0; i < conn->nconnhost && more; i++)
1082  {
1084  if (conn->connhost[i].host == NULL)
1085  goto oom_error;
1086  }
1087 
1088  /* Check for wrong number of host items. */
1089  if (more || i != conn->nconnhost)
1090  {
1092  libpq_append_conn_error(conn, "could not match %d host names to %d hostaddr values",
1094  return false;
1095  }
1096  }
1097 
1098  /*
1099  * Now, for each host slot, identify the type of address spec, and fill in
1100  * the default address if nothing was given.
1101  */
1102  for (i = 0; i < conn->nconnhost; i++)
1103  {
1104  pg_conn_host *ch = &conn->connhost[i];
1105 
1106  if (ch->hostaddr != NULL && ch->hostaddr[0] != '\0')
1107  ch->type = CHT_HOST_ADDRESS;
1108  else if (ch->host != NULL && ch->host[0] != '\0')
1109  {
1110  ch->type = CHT_HOST_NAME;
1111  if (is_unixsock_path(ch->host))
1112  ch->type = CHT_UNIX_SOCKET;
1113  }
1114  else
1115  {
1116  free(ch->host);
1117 
1118  /*
1119  * This bit selects the default host location. If you change
1120  * this, see also pg_regress.
1121  */
1122  if (DEFAULT_PGSOCKET_DIR[0])
1123  {
1124  ch->host = strdup(DEFAULT_PGSOCKET_DIR);
1125  ch->type = CHT_UNIX_SOCKET;
1126  }
1127  else
1128  {
1129  ch->host = strdup(DefaultHost);
1130  ch->type = CHT_HOST_NAME;
1131  }
1132  if (ch->host == NULL)
1133  goto oom_error;
1134  }
1135  }
1136 
1137  /*
1138  * Next, work out the port number corresponding to each host name.
1139  *
1140  * Note: unlike the above for host names, this could leave the port fields
1141  * as null or empty strings. We will substitute DEF_PGPORT whenever we
1142  * read such a port field.
1143  */
1144  if (conn->pgport != NULL && conn->pgport[0] != '\0')
1145  {
1146  char *s = conn->pgport;
1147  bool more = true;
1148 
1149  for (i = 0; i < conn->nconnhost && more; i++)
1150  {
1152  if (conn->connhost[i].port == NULL)
1153  goto oom_error;
1154  }
1155 
1156  /*
1157  * If exactly one port was given, use it for every host. Otherwise,
1158  * there must be exactly as many ports as there were hosts.
1159  */
1160  if (i == 1 && !more)
1161  {
1162  for (i = 1; i < conn->nconnhost; i++)
1163  {
1164  conn->connhost[i].port = strdup(conn->connhost[0].port);
1165  if (conn->connhost[i].port == NULL)
1166  goto oom_error;
1167  }
1168  }
1169  else if (more || i != conn->nconnhost)
1170  {
1172  libpq_append_conn_error(conn, "could not match %d port numbers to %d hosts",
1174  return false;
1175  }
1176  }
1177 
1178  /*
1179  * If user name was not given, fetch it. (Most likely, the fetch will
1180  * fail, since the only way we get here is if pg_fe_getauthname() failed
1181  * during conninfo_add_defaults(). But now we want an error message.)
1182  */
1183  if (conn->pguser == NULL || conn->pguser[0] == '\0')
1184  {
1185  free(conn->pguser);
1187  if (!conn->pguser)
1188  {
1190  return false;
1191  }
1192  }
1193 
1194  /*
1195  * If database name was not given, default it to equal user name
1196  */
1197  if (conn->dbName == NULL || conn->dbName[0] == '\0')
1198  {
1199  free(conn->dbName);
1200  conn->dbName = strdup(conn->pguser);
1201  if (!conn->dbName)
1202  goto oom_error;
1203  }
1204 
1205  /*
1206  * If password was not given, try to look it up in password file. Note
1207  * that the result might be different for each host/port pair.
1208  */
1209  if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
1210  {
1211  /* If password file wasn't specified, use ~/PGPASSFILE */
1212  if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
1213  {
1214  char homedir[MAXPGPATH];
1215 
1216  if (pqGetHomeDirectory(homedir, sizeof(homedir)))
1217  {
1218  free(conn->pgpassfile);
1220  if (!conn->pgpassfile)
1221  goto oom_error;
1222  snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s",
1223  homedir, PGPASSFILE);
1224  }
1225  }
1226 
1227  if (conn->pgpassfile != NULL && conn->pgpassfile[0] != '\0')
1228  {
1229  for (i = 0; i < conn->nconnhost; i++)
1230  {
1231  /*
1232  * Try to get a password for this host from file. We use host
1233  * for the hostname search key if given, else hostaddr (at
1234  * least one of them is guaranteed nonempty by now).
1235  */
1236  const char *pwhost = conn->connhost[i].host;
1237 
1238  if (pwhost == NULL || pwhost[0] == '\0')
1239  pwhost = conn->connhost[i].hostaddr;
1240 
1241  conn->connhost[i].password =
1242  passwordFromFile(pwhost,
1243  conn->connhost[i].port,
1244  conn->dbName,
1245  conn->pguser,
1246  conn->pgpassfile);
1247  }
1248  }
1249  }
1250 
1251  /*
1252  * parse and validate require_auth option
1253  */
1254  if (conn->require_auth && conn->require_auth[0])
1255  {
1256  char *s = conn->require_auth;
1257  bool first,
1258  more;
1259  bool negated = false;
1260 
1261  /*
1262  * By default, start from an empty set of allowed options and add to
1263  * it.
1264  */
1265  conn->auth_required = true;
1267 
1268  for (first = true, more = true; more; first = false)
1269  {
1270  char *method,
1271  *part;
1272  uint32 bits;
1273 
1274  part = parse_comma_separated_list(&s, &more);
1275  if (part == NULL)
1276  goto oom_error;
1277 
1278  /*
1279  * Check for negation, e.g. '!password'. If one element is
1280  * negated, they all have to be.
1281  */
1282  method = part;
1283  if (*method == '!')
1284  {
1285  if (first)
1286  {
1287  /*
1288  * Switch to a permissive set of allowed options, and
1289  * subtract from it.
1290  */
1291  conn->auth_required = false;
1292  conn->allowed_auth_methods = -1;
1293  }
1294  else if (!negated)
1295  {
1297  libpq_append_conn_error(conn, "negative require_auth method \"%s\" cannot be mixed with non-negative methods",
1298  method);
1299 
1300  free(part);
1301  return false;
1302  }
1303 
1304  negated = true;
1305  method++;
1306  }
1307  else if (negated)
1308  {
1310  libpq_append_conn_error(conn, "require_auth method \"%s\" cannot be mixed with negative methods",
1311  method);
1312 
1313  free(part);
1314  return false;
1315  }
1316 
1317  if (strcmp(method, "password") == 0)
1318  {
1319  bits = (1 << AUTH_REQ_PASSWORD);
1320  }
1321  else if (strcmp(method, "md5") == 0)
1322  {
1323  bits = (1 << AUTH_REQ_MD5);
1324  }
1325  else if (strcmp(method, "gss") == 0)
1326  {
1327  bits = (1 << AUTH_REQ_GSS);
1328  bits |= (1 << AUTH_REQ_GSS_CONT);
1329  }
1330  else if (strcmp(method, "sspi") == 0)
1331  {
1332  bits = (1 << AUTH_REQ_SSPI);
1333  bits |= (1 << AUTH_REQ_GSS_CONT);
1334  }
1335  else if (strcmp(method, "scram-sha-256") == 0)
1336  {
1337  /* This currently assumes that SCRAM is the only SASL method. */
1338  bits = (1 << AUTH_REQ_SASL);
1339  bits |= (1 << AUTH_REQ_SASL_CONT);
1340  bits |= (1 << AUTH_REQ_SASL_FIN);
1341  }
1342  else if (strcmp(method, "none") == 0)
1343  {
1344  /*
1345  * Special case: let the user explicitly allow (or disallow)
1346  * connections where the server does not send an explicit
1347  * authentication challenge, such as "trust" and "cert" auth.
1348  */
1349  if (negated) /* "!none" */
1350  {
1351  if (conn->auth_required)
1352  goto duplicate;
1353 
1354  conn->auth_required = true;
1355  }
1356  else /* "none" */
1357  {
1358  if (!conn->auth_required)
1359  goto duplicate;
1360 
1361  conn->auth_required = false;
1362  }
1363 
1364  free(part);
1365  continue; /* avoid the bitmask manipulation below */
1366  }
1367  else
1368  {
1370  libpq_append_conn_error(conn, "invalid require_auth method: \"%s\"",
1371  method);
1372 
1373  free(part);
1374  return false;
1375  }
1376 
1377  /* Update the bitmask. */
1378  if (negated)
1379  {
1380  if ((conn->allowed_auth_methods & bits) == 0)
1381  goto duplicate;
1382 
1383  conn->allowed_auth_methods &= ~bits;
1384  }
1385  else
1386  {
1387  if ((conn->allowed_auth_methods & bits) == bits)
1388  goto duplicate;
1389 
1390  conn->allowed_auth_methods |= bits;
1391  }
1392 
1393  free(part);
1394  continue;
1395 
1396  duplicate:
1397 
1398  /*
1399  * A duplicated method probably indicates a typo in a setting
1400  * where typos are extremely risky.
1401  */
1403  libpq_append_conn_error(conn, "require_auth method \"%s\" is specified more than once",
1404  part);
1405 
1406  free(part);
1407  return false;
1408  }
1409  }
1410 
1411  /*
1412  * validate channel_binding option
1413  */
1414  if (conn->channel_binding)
1415  {
1416  if (strcmp(conn->channel_binding, "disable") != 0
1417  && strcmp(conn->channel_binding, "prefer") != 0
1418  && strcmp(conn->channel_binding, "require") != 0)
1419  {
1421  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1422  "channel_binding", conn->channel_binding);
1423  return false;
1424  }
1425  }
1426  else
1427  {
1429  if (!conn->channel_binding)
1430  goto oom_error;
1431  }
1432 
1433  /*
1434  * validate sslmode option
1435  */
1436  if (conn->sslmode)
1437  {
1438  if (strcmp(conn->sslmode, "disable") != 0
1439  && strcmp(conn->sslmode, "allow") != 0
1440  && strcmp(conn->sslmode, "prefer") != 0
1441  && strcmp(conn->sslmode, "require") != 0
1442  && strcmp(conn->sslmode, "verify-ca") != 0
1443  && strcmp(conn->sslmode, "verify-full") != 0)
1444  {
1446  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1447  "sslmode", conn->sslmode);
1448  return false;
1449  }
1450 
1451 #ifndef USE_SSL
1452  switch (conn->sslmode[0])
1453  {
1454  case 'a': /* "allow" */
1455  case 'p': /* "prefer" */
1456 
1457  /*
1458  * warn user that an SSL connection will never be negotiated
1459  * since SSL was not compiled in?
1460  */
1461  break;
1462 
1463  case 'r': /* "require" */
1464  case 'v': /* "verify-ca" or "verify-full" */
1466  libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1467  "sslmode", conn->sslmode);
1468  return false;
1469  }
1470 #endif
1471  }
1472  else
1473  {
1474  conn->sslmode = strdup(DefaultSSLMode);
1475  if (!conn->sslmode)
1476  goto oom_error;
1477  }
1478 
1479  /*
1480  * Validate TLS protocol versions for ssl_min_protocol_version and
1481  * ssl_max_protocol_version.
1482  */
1484  {
1486  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1487  "ssl_min_protocol_version",
1489  return false;
1490  }
1492  {
1494  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1495  "ssl_max_protocol_version",
1497  return false;
1498  }
1499 
1500  /*
1501  * Check if the range of SSL protocols defined is correct. This is done
1502  * at this early step because this is independent of the SSL
1503  * implementation used, and this avoids unnecessary cycles with an
1504  * already-built SSL context when the connection is being established, as
1505  * it would be doomed anyway.
1506  */
1509  {
1511  libpq_append_conn_error(conn, "invalid SSL protocol version range");
1512  return false;
1513  }
1514 
1515  /*
1516  * validate sslcertmode option
1517  */
1518  if (conn->sslcertmode)
1519  {
1520  if (strcmp(conn->sslcertmode, "disable") != 0 &&
1521  strcmp(conn->sslcertmode, "allow") != 0 &&
1522  strcmp(conn->sslcertmode, "require") != 0)
1523  {
1525  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1526  "sslcertmode", conn->sslcertmode);
1527  return false;
1528  }
1529 #ifndef USE_SSL
1530  if (strcmp(conn->sslcertmode, "require") == 0)
1531  {
1533  libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1534  "sslcertmode", conn->sslcertmode);
1535  return false;
1536  }
1537 #endif
1538 #ifndef HAVE_SSL_CTX_SET_CERT_CB
1539 
1540  /*
1541  * Without a certificate callback, the current implementation can't
1542  * figure out if a certificate was actually requested, so "require" is
1543  * useless.
1544  */
1545  if (strcmp(conn->sslcertmode, "require") == 0)
1546  {
1548  libpq_append_conn_error(conn, "%s value \"%s\" is not supported (check OpenSSL version)",
1549  "sslcertmode", conn->sslcertmode);
1550  return false;
1551  }
1552 #endif
1553  }
1554  else
1555  {
1556  conn->sslcertmode = strdup(DefaultSSLCertMode);
1557  if (!conn->sslcertmode)
1558  goto oom_error;
1559  }
1560 
1561  /*
1562  * validate gssencmode option
1563  */
1564  if (conn->gssencmode)
1565  {
1566  if (strcmp(conn->gssencmode, "disable") != 0 &&
1567  strcmp(conn->gssencmode, "prefer") != 0 &&
1568  strcmp(conn->gssencmode, "require") != 0)
1569  {
1571  libpq_append_conn_error(conn, "invalid %s value: \"%s\"", "gssencmode", conn->gssencmode);
1572  return false;
1573  }
1574 #ifndef ENABLE_GSS
1575  if (strcmp(conn->gssencmode, "require") == 0)
1576  {
1578  libpq_append_conn_error(conn, "gssencmode value \"%s\" invalid when GSSAPI support is not compiled in",
1579  conn->gssencmode);
1580  return false;
1581  }
1582 #endif
1583  }
1584  else
1585  {
1586  conn->gssencmode = strdup(DefaultGSSMode);
1587  if (!conn->gssencmode)
1588  goto oom_error;
1589  }
1590 
1591  /*
1592  * validate target_session_attrs option, and set target_server_type
1593  */
1595  {
1596  if (strcmp(conn->target_session_attrs, "any") == 0)
1598  else if (strcmp(conn->target_session_attrs, "read-write") == 0)
1600  else if (strcmp(conn->target_session_attrs, "read-only") == 0)
1602  else if (strcmp(conn->target_session_attrs, "primary") == 0)
1604  else if (strcmp(conn->target_session_attrs, "standby") == 0)
1606  else if (strcmp(conn->target_session_attrs, "prefer-standby") == 0)
1608  else
1609  {
1611  libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1612  "target_session_attrs",
1614  return false;
1615  }
1616  }
1617  else
1619 
1620  /*
1621  * Resolve special "auto" client_encoding from the locale
1622  */
1624  strcmp(conn->client_encoding_initial, "auto") == 0)
1625  {
1629  goto oom_error;
1630  }
1631 
1632  /*
1633  * Only if we get this far is it appropriate to try to connect. (We need a
1634  * state flag, rather than just the boolean result of this function, in
1635  * case someone tries to PQreset() the PGconn.)
1636  */
1637  conn->options_valid = true;
1638 
1639  return true;
1640 
1641 oom_error:
1643  libpq_append_conn_error(conn, "out of memory");
1644  return false;
1645 }
unsigned int uint32
Definition: c.h:490
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:1216
#define DefaultHost
Definition: fe-connect.c:118
static char * passwordFromFile(const char *hostname, const char *port, const char *dbname, const char *username, const char *pgpassfile)
Definition: fe-connect.c:7273
static bool sslVerifyProtocolRange(const char *min, const char *max)
Definition: fe-connect.c:7462
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:7515
#define DefaultSSLMode
Definition: fe-connect.c:130
#define DefaultGSSMode
Definition: fe-connect.c:137
static int count_comma_separated_elems(const char *input)
Definition: fe-connect.c:969
#define DefaultChannelBinding
Definition: fe-connect.c:123
static bool sslVerifyProtocolVersion(const char *version)
Definition: fe-connect.c:7436
static char * parse_comma_separated_list(char **startptr, bool *more)
Definition: fe-connect.c:993
#define PGPASSFILE
Definition: fe-connect.c:77
#define DefaultSSLCertMode
Definition: fe-connect.c:131
#define calloc(a, b)
Definition: header.h:55
#define free(a)
Definition: header.h:65
#define malloc(a)
Definition: header.h:50
int i
Definition: isn.c:73
@ CHT_UNIX_SOCKET
Definition: libpq-int.h:303
@ CHT_HOST_ADDRESS
Definition: libpq-int.h:302
@ CHT_HOST_NAME
Definition: libpq-int.h:301
@ SERVER_TYPE_STANDBY
Definition: libpq-int.h:240
@ SERVER_TYPE_PRIMARY
Definition: libpq-int.h:239
@ SERVER_TYPE_ANY
Definition: libpq-int.h:236
@ SERVER_TYPE_READ_WRITE
Definition: libpq-int.h:237
@ SERVER_TYPE_READ_ONLY
Definition: libpq-int.h:238
Assert(fmt[strlen(fmt) - 1] !='\n')
#define MAXPGPATH
#define DEFAULT_PGSOCKET_DIR
#define snprintf
Definition: port.h:238
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:428
#define AUTH_REQ_SSPI
Definition: pqcomm.h:122
#define AUTH_REQ_SASL_CONT
Definition: pqcomm.h:124
#define AUTH_REQ_GSS
Definition: pqcomm.h:120
static bool is_unixsock_path(const char *path)
Definition: pqcomm.h:55
#define AUTH_REQ_MD5
Definition: pqcomm.h:118
#define AUTH_REQ_PASSWORD
Definition: pqcomm.h:116
#define AUTH_REQ_GSS_CONT
Definition: pqcomm.h:121
#define AUTH_REQ_SASL
Definition: pqcomm.h:123
#define AUTH_REQ_SASL_FIN
Definition: pqcomm.h:125
char * host
Definition: libpq-int.h:338
char * password
Definition: libpq-int.h:341
char * port
Definition: libpq-int.h:340
char * hostaddr
Definition: libpq-int.h:339
pg_conn_host_type type
Definition: libpq-int.h:337
int nconnhost
Definition: libpq-int.h:430
char * require_auth
Definition: libpq-int.h:400
char * channel_binding
Definition: libpq-int.h:374
char * pghost
Definition: libpq-int.h:353
char * ssl_max_protocol_version
Definition: libpq-int.h:398
char * pgpass
Definition: libpq-int.h:372
char * dbName
Definition: libpq-int.h:369
char * sslcertmode
Definition: libpq-int.h:387
uint32 allowed_auth_methods
Definition: libpq-int.h:464
char * target_session_attrs
Definition: libpq-int.h:399
bool auth_required
Definition: libpq-int.h:462
char * pguser
Definition: libpq-int.h:371
char * client_encoding_initial
Definition: libpq-int.h:365
char * sslmode
Definition: libpq-int.h:382
char * ssl_min_protocol_version
Definition: libpq-int.h:397
char * gssencmode
Definition: libpq-int.h:393
char * pghostaddr
Definition: libpq-int.h:357
char * pgpassfile
Definition: libpq-int.h:373
char * pgport
Definition: libpq-int.h:361
pg_conn_host * connhost
Definition: libpq-int.h:432

References pg_conn::allowed_auth_methods, Assert(), AUTH_REQ_GSS, AUTH_REQ_GSS_CONT, AUTH_REQ_MD5, AUTH_REQ_PASSWORD, AUTH_REQ_SASL, AUTH_REQ_SASL_CONT, AUTH_REQ_SASL_FIN, AUTH_REQ_SSPI, pg_conn::auth_required, calloc, pg_conn::channel_binding, CHT_HOST_ADDRESS, CHT_HOST_NAME, CHT_UNIX_SOCKET, pg_conn::client_encoding_initial, conn, CONNECTION_BAD, pg_conn::connhost, count_comma_separated_elems(), pg_conn::dbName, DEFAULT_PGSOCKET_DIR, DefaultChannelBinding, DefaultGSSMode, DefaultHost, DefaultSSLCertMode, DefaultSSLMode, pg_conn::errorMessage, free, pg_conn::gssencmode, pg_conn_host::host, pg_conn_host::hostaddr, i, is_unixsock_path(), libpq_append_conn_error(), malloc, MAXPGPATH, pg_conn::nconnhost, pg_conn::options_valid, parse_comma_separated_list(), pg_conn_host::password, passwordFromFile(), pg_encoding_to_char(), pg_fe_getauthname(), pg_get_encoding_from_locale(), pg_conn::pghost, pg_conn::pghostaddr, pg_conn::pgpass, PGPASSFILE, pg_conn::pgpassfile, pg_conn::pgport, pg_conn::pguser, pg_conn_host::port, pqGetHomeDirectory(), pg_conn::require_auth, SERVER_TYPE_ANY, SERVER_TYPE_PREFER_STANDBY, SERVER_TYPE_PRIMARY, SERVER_TYPE_READ_ONLY, SERVER_TYPE_READ_WRITE, SERVER_TYPE_STANDBY, snprintf, pg_conn::ssl_max_protocol_version, pg_conn::ssl_min_protocol_version, pg_conn::sslcertmode, pg_conn::sslmode, sslVerifyProtocolRange(), sslVerifyProtocolVersion(), pg_conn::status, pg_conn::target_server_type, pg_conn::target_session_attrs, pg_conn_host::type, and pg_conn::whichhost.

Referenced by PQconnectStart(), PQconnectStartParams(), and PQsetdbLogin().

◆ conninfo_add_defaults()

static bool conninfo_add_defaults ( PQconninfoOption options,
PQExpBuffer  errorMessage 
)
static

Definition at line 6081 of file fe-connect.c.

6082 {
6084  char *tmp;
6085 
6086  /*
6087  * If there's a service spec, use it to obtain any not-explicitly-given
6088  * parameters. Ignore error if no error message buffer is passed because
6089  * there is no way to pass back the failure message.
6090  */
6091  if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
6092  return false;
6093 
6094  /*
6095  * Get the fallback resources for parameters not specified in the conninfo
6096  * string nor the service.
6097  */
6098  for (option = options; option->keyword != NULL; option++)
6099  {
6100  if (option->val != NULL)
6101  continue; /* Value was in conninfo or service */
6102 
6103  /*
6104  * Try to get the environment variable fallback
6105  */
6106  if (option->envvar != NULL)
6107  {
6108  if ((tmp = getenv(option->envvar)) != NULL)
6109  {
6110  option->val = strdup(tmp);
6111  if (!option->val)
6112  {
6113  if (errorMessage)
6114  libpq_append_error(errorMessage, "out of memory");
6115  return false;
6116  }
6117  continue;
6118  }
6119  }
6120 
6121  /*
6122  * Interpret the deprecated PGREQUIRESSL environment variable. Per
6123  * tradition, translate values starting with "1" to sslmode=require,
6124  * and ignore other values. Given both PGREQUIRESSL=1 and PGSSLMODE,
6125  * PGSSLMODE takes precedence; the opposite was true before v9.3.
6126  */
6127  if (strcmp(option->keyword, "sslmode") == 0)
6128  {
6129  const char *requiresslenv = getenv("PGREQUIRESSL");
6130 
6131  if (requiresslenv != NULL && requiresslenv[0] == '1')
6132  {
6133  option->val = strdup("require");
6134  if (!option->val)
6135  {
6136  if (errorMessage)
6137  libpq_append_error(errorMessage, "out of memory");
6138  return false;
6139  }
6140  continue;
6141  }
6142  }
6143 
6144  /*
6145  * No environment variable specified or the variable isn't set - try
6146  * compiled-in default
6147  */
6148  if (option->compiled != NULL)
6149  {
6150  option->val = strdup(option->compiled);
6151  if (!option->val)
6152  {
6153  if (errorMessage)
6154  libpq_append_error(errorMessage, "out of memory");
6155  return false;
6156  }
6157  continue;
6158  }
6159 
6160  /*
6161  * Special handling for "user" option. Note that if pg_fe_getauthname
6162  * fails, we just leave the value as NULL; there's no need for this to
6163  * be an error condition if the caller provides a user name. The only
6164  * reason we do this now at all is so that callers of PQconndefaults
6165  * will see a correct default (barring error, of course).
6166  */
6167  if (strcmp(option->keyword, "user") == 0)
6168  {
6169  option->val = pg_fe_getauthname(NULL);
6170  continue;
6171  }
6172  }
6173 
6174  return true;
6175 }
static int parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5386
void libpq_append_error(PQExpBuffer errorMessage, const char *fmt,...)
Definition: fe-misc.c:1283
int val
Definition: getopt_long.h:21

References libpq_append_error(), parseServiceInfo(), pg_fe_getauthname(), and option::val.

Referenced by conninfo_array_parse(), conninfo_parse(), conninfo_uri_parse(), and PQconndefaults().

◆ conninfo_array_parse()

static PQconninfoOption * conninfo_array_parse ( const char *const *  keywords,
const char *const *  values,
PQExpBuffer  errorMessage,
bool  use_defaults,
int  expand_dbname 
)
static

Definition at line 5923 of file fe-connect.c.

5926 {
5928  PQconninfoOption *dbname_options = NULL;
5930  int i = 0;
5931 
5932  /*
5933  * If expand_dbname is non-zero, check keyword "dbname" to see if val is
5934  * actually a recognized connection string.
5935  */
5936  while (expand_dbname && keywords[i])
5937  {
5938  const char *pname = keywords[i];
5939  const char *pvalue = values[i];
5940 
5941  /* first find "dbname" if any */
5942  if (strcmp(pname, "dbname") == 0 && pvalue)
5943  {
5944  /*
5945  * If value is a connection string, parse it, but do not use
5946  * defaults here -- those get picked up later. We only want to
5947  * override for those parameters actually passed.
5948  */
5949  if (recognized_connection_string(pvalue))
5950  {
5951  dbname_options = parse_connection_string(pvalue, errorMessage, false);
5952  if (dbname_options == NULL)
5953  return NULL;
5954  }
5955  break;
5956  }
5957  ++i;
5958  }
5959 
5960  /* Make a working copy of PQconninfoOptions */
5961  options = conninfo_init(errorMessage);
5962  if (options == NULL)
5963  {
5964  PQconninfoFree(dbname_options);
5965  return NULL;
5966  }
5967 
5968  /* Parse the keywords/values arrays */
5969  i = 0;
5970  while (keywords[i])
5971  {
5972  const char *pname = keywords[i];
5973  const char *pvalue = values[i];
5974 
5975  if (pvalue != NULL && pvalue[0] != '\0')
5976  {
5977  /* Search for the param record */
5978  for (option = options; option->keyword != NULL; option++)
5979  {
5980  if (strcmp(option->keyword, pname) == 0)
5981  break;
5982  }
5983 
5984  /* Check for invalid connection option */
5985  if (option->keyword == NULL)
5986  {
5987  libpq_append_error(errorMessage, "invalid connection option \"%s\"", pname);
5989  PQconninfoFree(dbname_options);
5990  return NULL;
5991  }
5992 
5993  /*
5994  * If we are on the first dbname parameter, and we have a parsed
5995  * connection string, copy those parameters across, overriding any
5996  * existing previous settings.
5997  */
5998  if (strcmp(pname, "dbname") == 0 && dbname_options)
5999  {
6000  PQconninfoOption *str_option;
6001 
6002  for (str_option = dbname_options; str_option->keyword != NULL; str_option++)
6003  {
6004  if (str_option->val != NULL)
6005  {
6006  int k;
6007 
6008  for (k = 0; options[k].keyword; k++)
6009  {
6010  if (strcmp(options[k].keyword, str_option->keyword) == 0)
6011  {
6012  free(options[k].val);
6013  options[k].val = strdup(str_option->val);
6014  if (!options[k].val)
6015  {
6016  libpq_append_error(errorMessage, "out of memory");
6018  PQconninfoFree(dbname_options);
6019  return NULL;
6020  }
6021  break;
6022  }
6023  }
6024  }
6025  }
6026 
6027  /*
6028  * Forget the parsed connection string, so that any subsequent
6029  * dbname parameters will not be expanded.
6030  */
6031  PQconninfoFree(dbname_options);
6032  dbname_options = NULL;
6033  }
6034  else
6035  {
6036  /*
6037  * Store the value, overriding previous settings
6038  */
6039  free(option->val);
6040  option->val = strdup(pvalue);
6041  if (!option->val)
6042  {
6043  libpq_append_error(errorMessage, "out of memory");
6045  PQconninfoFree(dbname_options);
6046  return NULL;
6047  }
6048  }
6049  }
6050  ++i;
6051  }
6052  PQconninfoFree(dbname_options);
6053 
6054  /*
6055  * Add in defaults if the caller wants that.
6056  */
6057  if (use_defaults)
6058  {
6059  if (!conninfo_add_defaults(options, errorMessage))
6060  {
6062  return NULL;
6063  }
6064  }
6065 
6066  return options;
6067 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:5654
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:6081
static bool recognized_connection_string(const char *connstr)
Definition: fe-connect.c:5736
long val
Definition: informix.c:664
static char ** options

References conninfo_add_defaults(), conninfo_init(), free, i, _PQconninfoOption::keyword, libpq_append_error(), options, parse_connection_string(), PQconninfoFree(), recognized_connection_string(), option::val, val, _PQconninfoOption::val, and values.

Referenced by PQconnectStartParams().

◆ conninfo_find()

static PQconninfoOption * conninfo_find ( PQconninfoOption connOptions,
const char *  keyword 
)
static

Definition at line 6789 of file fe-connect.c.

6790 {
6792 
6793  for (option = connOptions; option->keyword != NULL; option++)
6794  {
6795  if (strcmp(option->keyword, keyword) == 0)
6796  return option;
6797  }
6798 
6799  return NULL;
6800 }

Referenced by conninfo_getval(), and conninfo_storeval().

◆ conninfo_getval()

static const char * conninfo_getval ( PQconninfoOption connOptions,
const char *  keyword 
)
static

Definition at line 6699 of file fe-connect.c.

6701 {
6703 
6704  option = conninfo_find(connOptions, keyword);
6705 
6706  return option ? option->val : NULL;
6707 }
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:6789

References conninfo_find(), and option::val.

Referenced by fillPGconn(), and parseServiceInfo().

◆ conninfo_init()

static PQconninfoOption * conninfo_init ( PQExpBuffer  errorMessage)
static

Definition at line 5654 of file fe-connect.c.

5655 {
5657  PQconninfoOption *opt_dest;
5658  const internalPQconninfoOption *cur_opt;
5659 
5660  /*
5661  * Get enough memory for all options in PQconninfoOptions, even if some
5662  * end up being filtered out.
5663  */
5665  if (options == NULL)
5666  {
5667  libpq_append_error(errorMessage, "out of memory");
5668  return NULL;
5669  }
5670  opt_dest = options;
5671 
5672  for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
5673  {
5674  /* Only copy the public part of the struct, not the full internal */
5675  memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
5676  opt_dest++;
5677  }
5678  MemSet(opt_dest, 0, sizeof(PQconninfoOption));
5679 
5680  return options;
5681 }
#define MemSet(start, val, len)
Definition: c.h:1004
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:190

References _internalPQconninfoOption::keyword, libpq_append_error(), malloc, MemSet, options, and PQconninfoOptions.

Referenced by conninfo_array_parse(), conninfo_parse(), conninfo_uri_parse(), PQconndefaults(), and PQconninfo().

◆ conninfo_parse()

static PQconninfoOption * conninfo_parse ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

Definition at line 5747 of file fe-connect.c.

5749 {
5750  char *pname;
5751  char *pval;
5752  char *buf;
5753  char *cp;
5754  char *cp2;
5756 
5757  /* Make a working copy of PQconninfoOptions */
5758  options = conninfo_init(errorMessage);
5759  if (options == NULL)
5760  return NULL;
5761 
5762  /* Need a modifiable copy of the input string */
5763  if ((buf = strdup(conninfo)) == NULL)
5764  {
5765  libpq_append_error(errorMessage, "out of memory");
5767  return NULL;
5768  }
5769  cp = buf;
5770 
5771  while (*cp)
5772  {
5773  /* Skip blanks before the parameter name */
5774  if (isspace((unsigned char) *cp))
5775  {
5776  cp++;
5777  continue;
5778  }
5779 
5780  /* Get the parameter name */
5781  pname = cp;
5782  while (*cp)
5783  {
5784  if (*cp == '=')
5785  break;
5786  if (isspace((unsigned char) *cp))
5787  {
5788  *cp++ = '\0';
5789  while (*cp)
5790  {
5791  if (!isspace((unsigned char) *cp))
5792  break;
5793  cp++;
5794  }
5795  break;
5796  }
5797  cp++;
5798  }
5799 
5800  /* Check that there is a following '=' */
5801  if (*cp != '=')
5802  {
5803  libpq_append_error(errorMessage,
5804  "missing \"=\" after \"%s\" in connection info string",
5805  pname);
5807  free(buf);
5808  return NULL;
5809  }
5810  *cp++ = '\0';
5811 
5812  /* Skip blanks after the '=' */
5813  while (*cp)
5814  {
5815  if (!isspace((unsigned char) *cp))
5816  break;
5817  cp++;
5818  }
5819 
5820  /* Get the parameter value */
5821  pval = cp;
5822 
5823  if (*cp != '\'')
5824  {
5825  cp2 = pval;
5826  while (*cp)
5827  {
5828  if (isspace((unsigned char) *cp))
5829  {
5830  *cp++ = '\0';
5831  break;
5832  }
5833  if (*cp == '\\')
5834  {
5835  cp++;
5836  if (*cp != '\0')
5837  *cp2++ = *cp++;
5838  }
5839  else
5840  *cp2++ = *cp++;
5841  }
5842  *cp2 = '\0';
5843  }
5844  else
5845  {
5846  cp2 = pval;
5847  cp++;
5848  for (;;)
5849  {
5850  if (*cp == '\0')
5851  {
5852  libpq_append_error(errorMessage, "unterminated quoted string in connection info string");
5854  free(buf);
5855  return NULL;
5856  }
5857  if (*cp == '\\')
5858  {
5859  cp++;
5860  if (*cp != '\0')
5861  *cp2++ = *cp++;
5862  continue;
5863  }
5864  if (*cp == '\'')
5865  {
5866  *cp2 = '\0';
5867  cp++;
5868  break;
5869  }
5870  *cp2++ = *cp++;
5871  }
5872  }
5873 
5874  /*
5875  * Now that we have the name and the value, store the record.
5876  */
5877  if (!conninfo_storeval(options, pname, pval, errorMessage, false, false))
5878  {
5880  free(buf);
5881  return NULL;
5882  }
5883  }
5884 
5885  /* Done with the modifiable input string */
5886  free(buf);
5887 
5888  /*
5889  * Add in defaults if the caller wants that.
5890  */
5891  if (use_defaults)
5892  {
5893  if (!conninfo_add_defaults(options, errorMessage))
5894  {
5896  return NULL;
5897  }
5898  }
5899 
5900  return options;
5901 }
static PQconninfoOption * conninfo_storeval(PQconninfoOption *connOptions, const char *keyword, const char *value, PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode)
Definition: fe-connect.c:6725
static char * buf
Definition: pg_test_fsync.c:67

References buf, conninfo_add_defaults(), conninfo_init(), conninfo_storeval(), free, libpq_append_error(), options, and PQconninfoFree().

Referenced by parse_connection_string().

◆ conninfo_storeval()

static PQconninfoOption * conninfo_storeval ( PQconninfoOption connOptions,
const char *  keyword,
const char *  value,
PQExpBuffer  errorMessage,
bool  ignoreMissing,
bool  uri_decode 
)
static

Definition at line 6725 of file fe-connect.c.

6729 {
6731  char *value_copy;
6732 
6733  /*
6734  * For backwards compatibility, requiressl=1 gets translated to
6735  * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
6736  * (which is the default for sslmode).
6737  */
6738  if (strcmp(keyword, "requiressl") == 0)
6739  {
6740  keyword = "sslmode";
6741  if (value[0] == '1')
6742  value = "require";
6743  else
6744  value = "prefer";
6745  }
6746 
6747  option = conninfo_find(connOptions, keyword);
6748  if (option == NULL)
6749  {
6750  if (!ignoreMissing)
6751  libpq_append_error(errorMessage,
6752  "invalid connection option \"%s\"",
6753  keyword);
6754  return NULL;
6755  }
6756 
6757  if (uri_decode)
6758  {
6759  value_copy = conninfo_uri_decode(value, errorMessage);
6760  if (value_copy == NULL)
6761  /* conninfo_uri_decode already set an error message */
6762  return NULL;
6763  }
6764  else
6765  {
6766  value_copy = strdup(value);
6767  if (value_copy == NULL)
6768  {
6769  libpq_append_error(errorMessage, "out of memory");
6770  return NULL;
6771  }
6772  }
6773 
6774  free(option->val);
6775  option->val = value_copy;
6776 
6777  return option;
6778 }
static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
Definition: fe-connect.c:6610
static struct @143 value

References conninfo_find(), conninfo_uri_decode(), free, libpq_append_error(), option::val, and value.

Referenced by conninfo_parse(), conninfo_uri_parse_options(), conninfo_uri_parse_params(), and PQconninfo().

◆ conninfo_uri_decode()

static char * conninfo_uri_decode ( const char *  str,
PQExpBuffer  errorMessage 
)
static

Definition at line 6610 of file fe-connect.c.

6611 {
6612  char *buf;
6613  char *p;
6614  const char *q = str;
6615 
6616  buf = malloc(strlen(str) + 1);
6617  if (buf == NULL)
6618  {
6619  libpq_append_error(errorMessage, "out of memory");
6620  return NULL;
6621  }
6622  p = buf;
6623 
6624  for (;;)
6625  {
6626  if (*q != '%')
6627  {
6628  /* copy and check for NUL terminator */
6629  if (!(*(p++) = *(q++)))
6630  break;
6631  }
6632  else
6633  {
6634  int hi;
6635  int lo;
6636  int c;
6637 
6638  ++q; /* skip the percent sign itself */
6639 
6640  /*
6641  * Possible EOL will be caught by the first call to
6642  * get_hexdigit(), so we never dereference an invalid q pointer.
6643  */
6644  if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
6645  {
6646  libpq_append_error(errorMessage,
6647  "invalid percent-encoded token: \"%s\"",
6648  str);
6649  free(buf);
6650  return NULL;
6651  }
6652 
6653  c = (hi << 4) | lo;
6654  if (c == 0)
6655  {
6656  libpq_append_error(errorMessage,
6657  "forbidden value %%00 in percent-encoded value: \"%s\"",
6658  str);
6659  free(buf);
6660  return NULL;
6661  }
6662  *(p++) = c;
6663  }
6664  }
6665 
6666  return buf;
6667 }
static bool get_hexdigit(char digit, int *value)
Definition: fe-connect.c:6678
char * c

References buf, free, get_hexdigit(), libpq_append_error(), malloc, and generate_unaccent_rules::str.

Referenced by conninfo_storeval(), and conninfo_uri_parse_params().

◆ conninfo_uri_parse()

static PQconninfoOption * conninfo_uri_parse ( const char *  uri,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

Definition at line 6183 of file fe-connect.c.

6185 {
6187 
6188  /* Make a working copy of PQconninfoOptions */
6189  options = conninfo_init(errorMessage);
6190  if (options == NULL)
6191  return NULL;
6192 
6193  if (!conninfo_uri_parse_options(options, uri, errorMessage))
6194  {
6196  return NULL;
6197  }
6198 
6199  /*
6200  * Add in defaults if the caller wants that.
6201  */
6202  if (use_defaults)
6203  {
6204  if (!conninfo_add_defaults(options, errorMessage))
6205  {
6207  return NULL;
6208  }
6209  }
6210 
6211  return options;
6212 }
static bool conninfo_uri_parse_options(PQconninfoOption *options, const char *uri, PQExpBuffer errorMessage)
Definition: fe-connect.c:6236

References conninfo_add_defaults(), conninfo_init(), conninfo_uri_parse_options(), options, and PQconninfoFree().

Referenced by parse_connection_string().

◆ conninfo_uri_parse_options()

static bool conninfo_uri_parse_options ( PQconninfoOption options,
const char *  uri,
PQExpBuffer  errorMessage 
)
static

Definition at line 6236 of file fe-connect.c.

6238 {
6239  int prefix_len;
6240  char *p;
6241  char *buf = NULL;
6242  char *start;
6243  char prevchar = '\0';
6244  char *user = NULL;
6245  char *host = NULL;
6246  bool retval = false;
6247  PQExpBufferData hostbuf;
6248  PQExpBufferData portbuf;
6249 
6250  initPQExpBuffer(&hostbuf);
6251  initPQExpBuffer(&portbuf);
6252  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
6253  {
6254  libpq_append_error(errorMessage, "out of memory");
6255  goto cleanup;
6256  }
6257 
6258  /* need a modifiable copy of the input URI */
6259  buf = strdup(uri);
6260  if (buf == NULL)
6261  {
6262  libpq_append_error(errorMessage, "out of memory");
6263  goto cleanup;
6264  }
6265  start = buf;
6266 
6267  /* Skip the URI prefix */
6268  prefix_len = uri_prefix_length(uri);
6269  if (prefix_len == 0)
6270  {
6271  /* Should never happen */
6272  libpq_append_error(errorMessage,
6273  "invalid URI propagated to internal parser routine: \"%s\"",
6274  uri);
6275  goto cleanup;
6276  }
6277  start += prefix_len;
6278  p = start;
6279 
6280  /* Look ahead for possible user credentials designator */
6281  while (*p && *p != '@' && *p != '/')
6282  ++p;
6283  if (*p == '@')
6284  {
6285  /*
6286  * Found username/password designator, so URI should be of the form
6287  * "scheme://user[:password]@[netloc]".
6288  */
6289  user = start;
6290 
6291  p = user;
6292  while (*p != ':' && *p != '@')
6293  ++p;
6294 
6295  /* Save last char and cut off at end of user name */
6296  prevchar = *p;
6297  *p = '\0';
6298 
6299  if (*user &&
6300  !conninfo_storeval(options, "user", user,
6301  errorMessage, false, true))
6302  goto cleanup;
6303 
6304  if (prevchar == ':')
6305  {
6306  const char *password = p + 1;
6307 
6308  while (*p != '@')
6309  ++p;
6310  *p = '\0';
6311 
6312  if (*password &&
6313  !conninfo_storeval(options, "password", password,
6314  errorMessage, false, true))
6315  goto cleanup;
6316  }
6317 
6318  /* Advance past end of parsed user name or password token */
6319  ++p;
6320  }
6321  else
6322  {
6323  /*
6324  * No username/password designator found. Reset to start of URI.
6325  */
6326  p = start;
6327  }
6328 
6329  /*
6330  * There may be multiple netloc[:port] pairs, each separated from the next
6331  * by a comma. When we initially enter this loop, "p" has been
6332  * incremented past optional URI credential information at this point and
6333  * now points at the "netloc" part of the URI. On subsequent loop
6334  * iterations, "p" has been incremented past the comma separator and now
6335  * points at the start of the next "netloc".
6336  */
6337  for (;;)
6338  {
6339  /*
6340  * Look for IPv6 address.
6341  */
6342  if (*p == '[')
6343  {
6344  host = ++p;
6345  while (*p && *p != ']')
6346  ++p;
6347  if (!*p)
6348  {
6349  libpq_append_error(errorMessage,
6350  "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"",
6351  uri);
6352  goto cleanup;
6353  }
6354  if (p == host)
6355  {
6356  libpq_append_error(errorMessage,
6357  "IPv6 host address may not be empty in URI: \"%s\"",
6358  uri);
6359  goto cleanup;
6360  }
6361 
6362  /* Cut off the bracket and advance */
6363  *(p++) = '\0';
6364 
6365  /*
6366  * The address may be followed by a port specifier or a slash or a
6367  * query or a separator comma.
6368  */
6369  if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
6370  {
6371  libpq_append_error(errorMessage,
6372  "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"",
6373  *p, (int) (p - buf + 1), uri);
6374  goto cleanup;
6375  }
6376  }
6377  else
6378  {
6379  /* not an IPv6 address: DNS-named or IPv4 netloc */
6380  host = p;
6381 
6382  /*
6383  * Look for port specifier (colon) or end of host specifier
6384  * (slash) or query (question mark) or host separator (comma).
6385  */
6386  while (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
6387  ++p;
6388  }
6389 
6390  /* Save the hostname terminator before we null it */
6391  prevchar = *p;
6392  *p = '\0';
6393 
6394  appendPQExpBufferStr(&hostbuf, host);
6395 
6396  if (prevchar == ':')
6397  {
6398  const char *port = ++p; /* advance past host terminator */
6399 
6400  while (*p && *p != '/' && *p != '?' && *p != ',')
6401  ++p;
6402 
6403  prevchar = *p;
6404  *p = '\0';
6405 
6406  appendPQExpBufferStr(&portbuf, port);
6407  }
6408 
6409  if (prevchar != ',')
6410  break;
6411  ++p; /* advance past comma separator */
6412  appendPQExpBufferChar(&hostbuf, ',');
6413  appendPQExpBufferChar(&portbuf, ',');
6414  }
6415 
6416  /* Save final values for host and port. */
6417  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
6418  goto cleanup;
6419  if (hostbuf.data[0] &&
6420  !conninfo_storeval(options, "host", hostbuf.data,
6421  errorMessage, false, true))
6422  goto cleanup;
6423  if (portbuf.data[0] &&
6424  !conninfo_storeval(options, "port", portbuf.data,
6425  errorMessage, false, true))
6426  goto cleanup;
6427 
6428  if (prevchar && prevchar != '?')
6429  {
6430  const char *dbname = ++p; /* advance past host terminator */
6431 
6432  /* Look for query parameters */
6433  while (*p && *p != '?')
6434  ++p;
6435 
6436  prevchar = *p;
6437  *p = '\0';
6438 
6439  /*
6440  * Avoid setting dbname to an empty string, as it forces the default
6441  * value (username) and ignores $PGDATABASE, as opposed to not setting
6442  * it at all.
6443  */
6444  if (*dbname &&
6445  !conninfo_storeval(options, "dbname", dbname,
6446  errorMessage, false, true))
6447  goto cleanup;
6448  }
6449 
6450  if (prevchar)
6451  {
6452  ++p; /* advance past terminator */
6453 
6454  if (!conninfo_uri_parse_params(p, options, errorMessage))
6455  goto cleanup;
6456  }
6457 
6458  /* everything parsed okay */
6459  retval = true;
6460 
6461 cleanup:
6462  termPQExpBuffer(&hostbuf);
6463  termPQExpBuffer(&portbuf);
6464  free(buf);
6465  return retval;
6466 }
static void cleanup(void)
Definition: bootstrap.c:696
static int uri_prefix_length(const char *connstr)
Definition: fe-connect.c:5713
static bool conninfo_uri_parse_params(char *params, PQconninfoOption *connOptions, PQExpBuffer errorMessage)
Definition: fe-connect.c:6477
static char * user
Definition: pg_regress.c:93
static int port
Definition: pg_regress.c:90
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
static char * password
Definition: streamutil.c:53
char * dbname
Definition: streamutil.c:51

References appendPQExpBufferChar(), appendPQExpBufferStr(), buf, cleanup(), conninfo_storeval(), conninfo_uri_parse_params(), PQExpBufferData::data, dbname, free, initPQExpBuffer(), libpq_append_error(), password, port, PQExpBufferDataBroken, termPQExpBuffer(), uri_prefix_length(), and user.

Referenced by conninfo_uri_parse().

◆ conninfo_uri_parse_params()

static bool conninfo_uri_parse_params ( char *  params,
PQconninfoOption connOptions,
PQExpBuffer  errorMessage 
)
static

Definition at line 6477 of file fe-connect.c.

6480 {
6481  while (*params)
6482  {
6483  char *keyword = params;
6484  char *value = NULL;
6485  char *p = params;
6486  bool malloced = false;
6487  int oldmsglen;
6488 
6489  /*
6490  * Scan the params string for '=' and '&', marking the end of keyword
6491  * and value respectively.
6492  */
6493  for (;;)
6494  {
6495  if (*p == '=')
6496  {
6497  /* Was there '=' already? */
6498  if (value != NULL)
6499  {
6500  libpq_append_error(errorMessage,
6501  "extra key/value separator \"=\" in URI query parameter: \"%s\"",
6502  keyword);
6503  return false;
6504  }
6505  /* Cut off keyword, advance to value */
6506  *p++ = '\0';
6507  value = p;
6508  }
6509  else if (*p == '&' || *p == '\0')
6510  {
6511  /*
6512  * If not at the end, cut off value and advance; leave p
6513  * pointing to start of the next parameter, if any.
6514  */
6515  if (*p != '\0')
6516  *p++ = '\0';
6517  /* Was there '=' at all? */
6518  if (value == NULL)
6519  {
6520  libpq_append_error(errorMessage,
6521  "missing key/value separator \"=\" in URI query parameter: \"%s\"",
6522  keyword);
6523  return false;
6524  }
6525  /* Got keyword and value, go process them. */
6526  break;
6527  }
6528  else
6529  ++p; /* Advance over all other bytes. */
6530  }
6531 
6532  keyword = conninfo_uri_decode(keyword, errorMessage);
6533  if (keyword == NULL)
6534  {
6535  /* conninfo_uri_decode already set an error message */
6536  return false;
6537  }
6538  value = conninfo_uri_decode(value, errorMessage);
6539  if (value == NULL)
6540  {
6541  /* conninfo_uri_decode already set an error message */
6542  free(keyword);
6543  return false;
6544  }
6545  malloced = true;
6546 
6547  /*
6548  * Special keyword handling for improved JDBC compatibility.
6549  */
6550  if (strcmp(keyword, "ssl") == 0 &&
6551  strcmp(value, "true") == 0)
6552  {
6553  free(keyword);
6554  free(value);
6555  malloced = false;
6556 
6557  keyword = "sslmode";
6558  value = "require";
6559  }
6560 
6561  /*
6562  * Store the value if the corresponding option exists; ignore
6563  * otherwise. At this point both keyword and value are not
6564  * URI-encoded.
6565  */
6566  oldmsglen = errorMessage->len;
6567  if (!conninfo_storeval(connOptions, keyword, value,
6568  errorMessage, true, false))
6569  {
6570  /* Insert generic message if conninfo_storeval didn't give one. */
6571  if (errorMessage->len == oldmsglen)
6572  libpq_append_error(errorMessage,
6573  "invalid URI query parameter: \"%s\"",
6574  keyword);
6575  /* And fail. */
6576  if (malloced)
6577  {
6578  free(keyword);
6579  free(value);
6580  }
6581  return false;
6582  }
6583 
6584  if (malloced)
6585  {
6586  free(keyword);
6587  free(value);
6588  }
6589 
6590  /* Proceed to next key=value pair, if any */
6591  params = p;
6592  }
6593 
6594  return true;
6595 }

References conninfo_storeval(), conninfo_uri_decode(), free, PQExpBufferData::len, libpq_append_error(), and value.

Referenced by conninfo_uri_parse_options().

◆ count_comma_separated_elems()

static int count_comma_separated_elems ( const char *  input)
static

Definition at line 969 of file fe-connect.c.

970 {
971  int n;
972 
973  n = 1;
974  for (; *input != '\0'; input++)
975  {
976  if (*input == ',')
977  n++;
978  }
979 
980  return n;
981 }
FILE * input

References input.

Referenced by connectOptions2().

◆ default_threadlock()

static void default_threadlock ( int  acquire)
static

Definition at line 7547 of file fe-connect.c.

7548 {
7549 #ifdef ENABLE_THREAD_SAFETY
7550 #ifndef WIN32
7551  static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
7552 #else
7553  static pthread_mutex_t singlethread_lock = NULL;
7554  static long mutex_initlock = 0;
7555 
7556  if (singlethread_lock == NULL)
7557  {
7558  while (InterlockedExchange(&mutex_initlock, 1) == 1)
7559  /* loop, another thread own the lock */ ;
7560  if (singlethread_lock == NULL)
7561  {
7562  if (pthread_mutex_init(&singlethread_lock, NULL))
7563  Assert(false);
7564  }
7565  InterlockedExchange(&mutex_initlock, 0);
7566  }
7567 #endif
7568  if (acquire)
7569  {
7570  if (pthread_mutex_lock(&singlethread_lock))
7571  Assert(false);
7572  }
7573  else
7574  {
7575  if (pthread_mutex_unlock(&singlethread_lock))
7576  Assert(false);
7577  }
7578 #endif
7579 }
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:54
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:45
int pthread_mutex_init(pthread_mutex_t *mp, void *attr)
Definition: pthread-win32.c:35
CRITICAL_SECTION * pthread_mutex_t
Definition: pthread-win32.h:8

References Assert(), pthread_mutex_init(), pthread_mutex_lock(), and pthread_mutex_unlock().

Referenced by PQregisterThreadLock().

◆ defaultNoticeProcessor()

static void defaultNoticeProcessor ( void *  arg,
const char *  message 
)
static

Definition at line 7224 of file fe-connect.c.

7225 {
7226  (void) arg; /* not used */
7227  /* Note: we expect the supplied string to end with a newline already. */
7228  fprintf(stderr, "%s", message);
7229 }
void * arg
#define fprintf
Definition: port.h:242

References arg, and fprintf.

Referenced by makeEmptyPGconn().

◆ defaultNoticeReceiver()

static void defaultNoticeReceiver ( void *  arg,
const PGresult res 
)
static

Definition at line 7209 of file fe-connect.c.

7210 {
7211  (void) arg; /* not used */
7212  if (res->noticeHooks.noticeProc != NULL)
7215 }
char * PQresultErrorMessage(const PGresult *res)
Definition: fe-exec.c:3256
void * noticeProcArg
Definition: libpq-int.h:157
PQnoticeProcessor noticeProc
Definition: libpq-int.h:156
PGNoticeHooks noticeHooks
Definition: libpq-int.h:188

References arg, pg_result::noticeHooks, PGNoticeHooks::noticeProc, PGNoticeHooks::noticeProcArg, PQresultErrorMessage(), and res.

Referenced by makeEmptyPGconn().

◆ emitHostIdentityInfo()

static void emitHostIdentityInfo ( PGconn conn,
const char *  host_addr 
)
static

Definition at line 1876 of file fe-connect.c.

1877 {
1878  if (conn->raddr.addr.ss_family == AF_UNIX)
1879  {
1880  char service[NI_MAXHOST];
1881 
1883  NULL, 0,
1884  service, sizeof(service),
1885  NI_NUMERICSERV);
1887  libpq_gettext("connection to server on socket \"%s\" failed: "),
1888  service);
1889  }
1890  else
1891  {
1892  const char *displayed_host;
1893  const char *displayed_port;
1894 
1895  /* To which host and port were we actually connecting? */
1897  displayed_host = conn->connhost[conn->whichhost].hostaddr;
1898  else
1899  displayed_host = conn->connhost[conn->whichhost].host;
1900  displayed_port = conn->connhost[conn->whichhost].port;
1901  if (displayed_port == NULL || displayed_port[0] == '\0')
1902  displayed_port = DEF_PGPORT_STR;
1903 
1904  /*
1905  * If the user did not supply an IP address using 'hostaddr', and
1906  * 'host' was missing or does not match our lookup, display the
1907  * looked-up IP address.
1908  */
1910  host_addr[0] &&
1911  strcmp(displayed_host, host_addr) != 0)
1913  libpq_gettext("connection to server at \"%s\" (%s), port %s failed: "),
1914  displayed_host, host_addr,
1915  displayed_port);
1916  else
1918  libpq_gettext("connection to server at \"%s\", port %s failed: "),
1919  displayed_host,
1920  displayed_port);
1921  }
1922 }
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:114
#define libpq_gettext(x)
Definition: libpq-int.h:894
socklen_t salen
Definition: pqcomm.h:27

References SockAddr::addr, appendPQExpBuffer(), CHT_HOST_ADDRESS, conn, pg_conn::connhost, pg_conn::errorMessage, pg_conn_host::host, pg_conn_host::hostaddr, libpq_gettext, pg_getnameinfo_all(), pg_conn_host::port, pg_conn::raddr, SockAddr::salen, pg_conn_host::type, and pg_conn::whichhost.

Referenced by PQconnectPoll().

◆ fillPGconn()

static bool fillPGconn ( PGconn conn,
PQconninfoOption connOptions 
)
static

Definition at line 892 of file fe-connect.c.

893 {
895 
896  for (option = PQconninfoOptions; option->keyword; option++)
897  {
898  if (option->connofs >= 0)
899  {
900  const char *tmp = conninfo_getval(connOptions, option->keyword);
901 
902  if (tmp)
903  {
904  char **connmember = (char **) ((char *) conn + option->connofs);
905 
906  free(*connmember);
907  *connmember = strdup(tmp);
908  if (*connmember == NULL)
909  {
910  libpq_append_conn_error(conn, "out of memory");
911  return false;
912  }
913  }
914  }
915  }
916 
917  return true;
918 }
static const char * conninfo_getval(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:6699

References conn, conninfo_getval(), free, libpq_append_conn_error(), and PQconninfoOptions.

Referenced by connectOptions1(), and PQconnectStartParams().

◆ freePGconn()

static void freePGconn ( PGconn conn)
static

Definition at line 4234 of file fe-connect.c.

4235 {
4236  /* let any event procs clean up their state data */
4237  for (int i = 0; i < conn->nEvents; i++)
4238  {
4239  PGEventConnDestroy evt;
4240 
4241  evt.conn = conn;
4242  (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
4243  conn->events[i].passThrough);
4244  free(conn->events[i].name);
4245  }
4246 
4247  /* clean up pg_conn_host structures */
4248  for (int i = 0; i < conn->nconnhost; ++i)
4249  {
4250  free(conn->connhost[i].host);
4252  free(conn->connhost[i].port);
4253  if (conn->connhost[i].password != NULL)
4254  {
4257  }
4258  }
4259  free(conn->connhost);
4260 
4262  free(conn->events);
4263  free(conn->pghost);
4264  free(conn->pghostaddr);
4265  free(conn->pgport);
4268  free(conn->pgoptions);
4269  free(conn->appname);
4270  free(conn->fbappname);
4271  free(conn->dbName);
4272  free(conn->replication);
4273  free(conn->pguser);
4274  if (conn->pgpass)
4275  {
4276  explicit_bzero(conn->pgpass, strlen(conn->pgpass));
4277  free(conn->pgpass);
4278  }
4279  free(conn->pgpassfile);
4281  free(conn->keepalives);
4285  free(conn->sslmode);
4286  free(conn->sslcert);
4287  free(conn->sslkey);
4288  if (conn->sslpassword)
4289  {
4291  free(conn->sslpassword);
4292  }
4293  free(conn->sslcertmode);
4294  free(conn->sslrootcert);
4295  free(conn->sslcrl);
4296  free(conn->sslcrldir);
4298  free(conn->sslsni);
4299  free(conn->requirepeer);
4303  free(conn->gssencmode);
4304  free(conn->krbsrvname);
4305  free(conn->gsslib);
4306  free(conn->connip);
4307  /* Note that conn->Pfdebug is not ours to close or free */
4309  free(conn->inBuffer);
4310  free(conn->outBuffer);
4311  free(conn->rowBuf);
4315 
4316  free(conn);
4317 }
@ PGEVT_CONNDESTROY
Definition: libpq-events.h:31
void explicit_bzero(void *buf, size_t len)
void * passThrough
Definition: libpq-int.h:164
char * name
Definition: libpq-int.h:163
PGEventProc proc
Definition: libpq-int.h:162
char * replication
Definition: libpq-int.h:370
char * write_err_msg
Definition: libpq-int.h:460
char * sslrootcert
Definition: libpq-int.h:388
PGdataValue * rowBuf
Definition: libpq-int.h:509
char * sslcompression
Definition: libpq-int.h:383
char * inBuffer
Definition: libpq-int.h:492
char * sslcrldir
Definition: libpq-int.h:390
char * pgoptions
Definition: libpq-int.h:366
char * sslcrl
Definition: libpq-int.h:389
char * fbappname
Definition: libpq-int.h:368
char * sslcert
Definition: libpq-int.h:385
char * sslpassword
Definition: libpq-int.h:386
PQExpBufferData workBuffer
Definition: libpq-int.h:604
char * keepalives_idle
Definition: libpq-int.h:377
char * connip
Definition: libpq-int.h:433
char * keepalives
Definition: libpq-int.h:376
char * keepalives_interval
Definition: libpq-int.h:378
char * appname
Definition: libpq-int.h:367
char * pgtcp_user_timeout
Definition: libpq-int.h:364
int nEvents
Definition: libpq-int.h:411
char * sslkey
Definition: libpq-int.h:384
char * krbsrvname
Definition: libpq-int.h:394
char * gsslib
Definition: libpq-int.h:395
char * keepalives_count
Definition: libpq-int.h:380
char * requirepeer
Definition: libpq-int.h:392
char * sslsni
Definition: libpq-int.h:391
PGEvent * events
Definition: libpq-int.h:410
char * outBuffer
Definition: libpq-int.h:499

References pg_conn::appname, pg_conn::channel_binding, pg_conn::client_encoding_initial, conn, PGEventConnDestroy::conn, pg_conn::connect_timeout, pg_conn::connhost, pg_conn::connip, pg_conn::dbName, pg_conn::errorMessage, pg_conn::events, explicit_bzero(), pg_conn::fbappname, free, pg_conn::gssencmode, pg_conn::gsslib, pg_conn_host::host, pg_conn_host::hostaddr, i, pg_conn::inBuffer, pg_conn::keepalives, pg_conn::keepalives_count, pg_conn::keepalives_idle, pg_conn::keepalives_interval, pg_conn::krbsrvname, PGEvent::name, pg_conn::nconnhost, pg_conn::nEvents, pg_conn::outBuffer, PGEvent::passThrough, pg_conn_host::password, PGEVT_CONNDESTROY, pg_conn::pghost, pg_conn::pghostaddr, pg_conn::pgoptions, pg_conn::pgpass, pg_conn::pgpassfile, pg_conn::pgport, pg_conn::pgtcp_user_timeout, pg_conn::pguser, pg_conn_host::port, PGEvent::proc, pg_conn::replication, pg_conn::require_auth, pg_conn::requirepeer, pg_conn::rowBuf, pg_conn::ssl_max_protocol_version, pg_conn::ssl_min_protocol_version, pg_conn::sslcert, pg_conn::sslcertmode, pg_conn::sslcompression, pg_conn::sslcrl, pg_conn::sslcrldir, pg_conn::sslkey, pg_conn::sslmode, pg_conn::sslpassword, pg_conn::sslrootcert, pg_conn::sslsni, pg_conn::target_session_attrs, termPQExpBuffer(), pg_conn::workBuffer, and pg_conn::write_err_msg.

Referenced by makeEmptyPGconn(), and PQfinish().

◆ get_hexdigit()

static bool get_hexdigit ( char  digit,
int *  value 
)
static

Definition at line 6678 of file fe-connect.c.

6679 {
6680  if ('0' <= digit && digit <= '9')
6681  *value = digit - '0';
6682  else if ('A' <= digit && digit <= 'F')
6683  *value = digit - 'A' + 10;
6684  else if ('a' <= digit && digit <= 'f')
6685  *value = digit - 'a' + 10;
6686  else
6687  return false;
6688 
6689  return true;
6690 }

References value.

Referenced by conninfo_uri_decode().

◆ getHostaddr()

static void getHostaddr ( PGconn conn,
char *  host_addr,
int  host_addr_len 
)
static

Definition at line 1843 of file fe-connect.c.

1844 {
1845  struct sockaddr_storage *addr = &conn->raddr.addr;
1846 
1847  if (addr->ss_family == AF_INET)
1848  {
1849  if (pg_inet_net_ntop(AF_INET,
1850  &((struct sockaddr_in *) addr)->sin_addr.s_addr,
1851  32,
1852  host_addr, host_addr_len) == NULL)
1853  host_addr[0] = '\0';
1854  }
1855  else if (addr->ss_family == AF_INET6)
1856  {
1857  if (pg_inet_net_ntop(AF_INET6,
1858  &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
1859  128,
1860  host_addr, host_addr_len) == NULL)
1861  host_addr[0] = '\0';
1862  }
1863  else
1864  host_addr[0] = '\0';
1865 }
char * pg_inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
Definition: inet_net_ntop.c:77

References SockAddr::addr, conn, pg_inet_net_ntop(), and pg_conn::raddr.

Referenced by PQconnectPoll().

◆ internal_ping()

static PGPing internal_ping ( PGconn conn)
static

Definition at line 4072 of file fe-connect.c.

4073 {
4074  /* Say "no attempt" if we never got to PQconnectPoll */
4075  if (!conn || !conn->options_valid)
4076  return PQPING_NO_ATTEMPT;
4077 
4078  /* Attempt to complete the connection */
4079  if (conn->status != CONNECTION_BAD)
4080  (void) connectDBComplete(conn);
4081 
4082  /* Definitely OK if we succeeded */
4083  if (conn->status != CONNECTION_BAD)
4084  return PQPING_OK;
4085 
4086  /*
4087  * Here begins the interesting part of "ping": determine the cause of the
4088  * failure in sufficient detail to decide what to return. We do not want
4089  * to report that the server is not up just because we didn't have a valid
4090  * password, for example. In fact, any sort of authentication request
4091  * implies the server is up. (We need this check since the libpq side of
4092  * things might have pulled the plug on the connection before getting an
4093  * error as such from the postmaster.)
4094  */
4095  if (conn->auth_req_received)
4096  return PQPING_OK;
4097 
4098  /*
4099  * If we failed to get any ERROR response from the postmaster, report
4100  * PQPING_NO_RESPONSE. This result could be somewhat misleading for a
4101  * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
4102  * out of support. Another corner case where the server could return a
4103  * failure without a SQLSTATE is fork failure, but PQPING_NO_RESPONSE
4104  * isn't totally unreasonable for that anyway. We expect that every other
4105  * failure case in a modern server will produce a report with a SQLSTATE.
4106  *
4107  * NOTE: whenever we get around to making libpq generate SQLSTATEs for
4108  * client-side errors, we should either not store those into
4109  * last_sqlstate, or add an extra flag so we can tell client-side errors
4110  * apart from server-side ones.
4111  */
4112  if (strlen(conn->last_sqlstate) != 5)
4113  return PQPING_NO_RESPONSE;
4114 
4115  /*
4116  * Report PQPING_REJECT if server says it's not accepting connections.
4117  */
4118  if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
4119  return PQPING_REJECT;
4120 
4121  /*
4122  * Any other SQLSTATE can be taken to indicate that the server is up.
4123  * Presumably it didn't like our username, password, or database name; or
4124  * perhaps it had some transient failure, but that should not be taken as
4125  * meaning "it's down".
4126  */
4127  return PQPING_OK;
4128 }
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:2291
#define ERRCODE_CANNOT_CONNECT_NOW
Definition: fe-connect.c:93
@ PQPING_OK
Definition: libpq-fe.h:147
@ PQPING_REJECT
Definition: libpq-fe.h:148
@ PQPING_NO_RESPONSE
Definition: libpq-fe.h:149
@ PQPING_NO_ATTEMPT
Definition: libpq-fe.h:150
bool auth_req_received
Definition: libpq-int.h:455
char last_sqlstate[6]
Definition: libpq-int.h:418

References pg_conn::auth_req_received, conn, connectDBComplete(), CONNECTION_BAD, ERRCODE_CANNOT_CONNECT_NOW, pg_conn::last_sqlstate, pg_conn::options_valid, PQPING_NO_ATTEMPT, PQPING_NO_RESPONSE, PQPING_OK, PQPING_REJECT, and pg_conn::status.

Referenced by PQping(), and PQpingParams().

◆ makeEmptyPGconn()

static PGconn * makeEmptyPGconn ( void  )
static

Definition at line 4136 of file fe-connect.c.

4137 {
4138  PGconn *conn;
4139 
4140 #ifdef WIN32
4141 
4142  /*
4143  * Make sure socket support is up and running in this process.
4144  *
4145  * Note: the Windows documentation says that we should eventually do a
4146  * matching WSACleanup() call, but experience suggests that that is at
4147  * least as likely to cause problems as fix them. So we don't.
4148  */
4149  static bool wsastartup_done = false;
4150 
4151  if (!wsastartup_done)
4152  {
4153  WSADATA wsaData;
4154 
4155  if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
4156  return NULL;
4157  wsastartup_done = true;
4158  }
4159 
4160  /* Forget any earlier error */
4161  WSASetLastError(0);
4162 #endif /* WIN32 */
4163 
4164  conn = (PGconn *) malloc(sizeof(PGconn));
4165  if (conn == NULL)
4166  return conn;
4167 
4168  /* Zero all pointers and booleans */
4169  MemSet(conn, 0, sizeof(PGconn));
4170 
4171  /* install default notice hooks */
4174 
4179  conn->options_valid = false;
4180  conn->nonblocking = false;
4182  conn->std_strings = false; /* unless server says differently */
4188  conn->Pfdebug = NULL;
4189 
4190  /*
4191  * We try to send at least 8K at a time, which is the usual size of pipe
4192  * buffers on Unix systems. That way, when we are sending a large amount
4193  * of data, we avoid incurring extra kernel context swaps for partial
4194  * bufferloads. The output buffer is initially made 16K in size, and we
4195  * try to dump it after accumulating 8K.
4196  *
4197  * With the same goal of minimizing context swaps, the input buffer will
4198  * be enlarged anytime it has less than 8K free, so we initially allocate
4199  * twice that.
4200  */
4201  conn->inBufSize = 16 * 1024;
4202  conn->inBuffer = (char *) malloc(conn->inBufSize);
4203  conn->outBufSize = 16 * 1024;
4204  conn->outBuffer = (char *) malloc(conn->outBufSize);
4205  conn->rowBufLen = 32;
4206  conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
4209 
4210  if (conn->inBuffer == NULL ||
4211  conn->outBuffer == NULL ||
4212  conn->rowBuf == NULL ||
4215  {
4216  /* out of memory already :-( */
4217  freePGconn(conn);
4218  conn = NULL;
4219  }
4220 
4221  return conn;
4222 }
static void defaultNoticeReceiver(void *arg, const PGresult *res)
Definition: fe-connect.c:7209
static void defaultNoticeProcessor(void *arg, const char *message)
Definition: fe-connect.c:7224
static void freePGconn(PGconn *conn)
Definition: fe-connect.c:4234
@ PQSHOW_CONTEXT_ERRORS
Definition: libpq-fe.h:136
@ PQERRORS_DEFAULT
Definition: libpq-fe.h:128
@ PG_BOOL_UNKNOWN
Definition: libpq-int.h:248
@ PG_SQL_ASCII
Definition: pg_wchar.h:226
#define PGINVALID_SOCKET
Definition: port.h:31
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
PQnoticeReceiver noticeRec
Definition: libpq-int.h:154
bool std_strings
Definition: libpq-int.h:484
PGTernaryBool in_hot_standby
Definition: libpq-int.h:486
int inBufSize
Definition: libpq-int.h:493
int client_encoding
Definition: libpq-int.h:483
PGTernaryBool default_transaction_read_only
Definition: libpq-int.h:485
PGVerbosity verbosity
Definition: libpq-int.h:487
int rowBufLen
Definition: libpq-int.h:510
int outBufSize
Definition: libpq-int.h:500
PGNoticeHooks noticeHooks
Definition: libpq-int.h:407
FILE * Pfdebug
Definition: libpq-int.h:403
PGContextVisibility show_context
Definition: libpq-int.h:488

References pg_conn::asyncStatus, pg_conn::client_encoding, conn, CONNECTION_BAD, pg_conn::default_transaction_read_only, defaultNoticeProcessor(), defaultNoticeReceiver(), pg_conn::errorMessage, freePGconn(), pg_conn::in_hot_standby, pg_conn::inBuffer, pg_conn::inBufSize, initPQExpBuffer(), malloc, MemSet, pg_conn::nonblocking, pg_conn::noticeHooks, PGNoticeHooks::noticeProc, PGNoticeHooks::noticeRec, pg_conn::options_valid, pg_conn::outBuffer, pg_conn::outBufSize, pg_conn::Pfdebug, PG_BOOL_UNKNOWN, PG_SQL_ASCII, PGASYNC_IDLE, PGINVALID_SOCKET, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, PQERRORS_DEFAULT, PQExpBufferBroken, PQSHOW_CONTEXT_ERRORS, PQTRANS_IDLE, pg_conn::rowBuf, pg_conn::rowBufLen, pg_conn::show_context, pg_conn::sock, pg_conn::status, pg_conn::std_strings, pg_conn::verbosity, pg_conn::workBuffer, and pg_conn::xactStatus.

Referenced by PQconnectStart(), PQconnectStartParams(), and PQsetdbLogin().

◆ optional_setsockopt()

static bool optional_setsockopt ( int  fd,
int  protoid,
int  optid,
int  value 
)
static

Definition at line 4592 of file fe-connect.c.

4593 {
4594  if (value < 0)
4595  return true;
4596  if (setsockopt(fd, protoid, optid, (char *) &value, sizeof(value)) < 0)
4597  return false;
4598  return true;
4599 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105

References fd(), and value.

Referenced by PQcancel().

◆ parse_comma_separated_list()

static char* parse_comma_separated_list ( char **  startptr,
bool more 
)
static

Definition at line 993 of file fe-connect.c.

994 {
995  char *p;
996  char *s = *startptr;
997  char *e;
998  int len;
999 
1000  /*
1001  * Search for the end of the current element; a comma or end-of-string
1002  * acts as a terminator.
1003  */
1004  e = s;
1005  while (*e != '\0' && *e != ',')
1006  ++e;
1007  *more = (*e == ',');
1008 
1009  len = e - s;
1010  p = (char *) malloc(sizeof(char) * (len + 1));
1011  if (p)
1012  {
1013  memcpy(p, s, len);
1014  p[len] = '\0';
1015  }
1016  *startptr = e + 1;
1017 
1018  return p;
1019 }
const void size_t len
e
Definition: preproc-init.c:82

References len, and malloc.

Referenced by connectOptions2().

◆ parse_connection_string()

static PQconninfoOption * parse_connection_string ( const char *  connstr,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

Definition at line 5693 of file fe-connect.c.

5695 {
5696  /* Parse as URI if connection string matches URI prefix */
5697  if (uri_prefix_length(connstr) != 0)
5698  return conninfo_uri_parse(connstr, errorMessage, use_defaults);
5699 
5700  /* Parse as default otherwise */
5701  return conninfo_parse(connstr, errorMessage, use_defaults);
5702 }
static PQconninfoOption * conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:6183
static PQconninfoOption * conninfo_parse(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:5747
static char * connstr
Definition: pg_dumpall.c:88

References conninfo_parse(), conninfo_uri_parse(), connstr, and uri_prefix_length().

Referenced by connectOptions1(), conninfo_array_parse(), and PQconninfoParse().

◆ parse_int_param()

static bool parse_int_param ( const char *  value,
int *  result,
PGconn conn,
const char *  context 
)
static

Definition at line 1971 of file fe-connect.c.

1973 {
1974  char *end;
1975  long numval;
1976 
1977  Assert(value != NULL);
1978 
1979  *result = 0;
1980 
1981  /* strtol(3) skips leading whitespaces */
1982  errno = 0;
1983  numval = strtol(value, &end, 10);
1984 
1985  /*
1986  * If no progress was done during the parsing or an error happened, fail.
1987  * This tests properly for overflows of the result.
1988  */
1989  if (value == end || errno != 0 || numval != (int) numval)
1990  goto error;
1991 
1992  /*
1993  * Skip any trailing whitespace; if anything but whitespace remains before
1994  * the terminating character, fail
1995  */
1996  while (*end != '\0' && isspace((unsigned char) *end))
1997  end++;
1998 
1999  if (*end != '\0')
2000  goto error;
2001 
2002  *result = numval;
2003  return true;
2004 
2005 error:
2006  libpq_append_conn_error(conn, "invalid integer value \"%s\" for connection option \"%s\"",
2007  value, context);
2008  return false;
2009 }
static void error(void)
Definition: sql-dyntest.c:147

References Assert(), conn, error(), libpq_append_conn_error(), and value.

Referenced by connectDBComplete(), PQconnectPoll(), PQgetCancel(), setKeepalivesCount(), setKeepalivesIdle(), setKeepalivesInterval(), and setTCPUserTimeout().

◆ parseServiceFile()

static int parseServiceFile ( const char *  serviceFile,
const char *  service,
PQconninfoOption options,
PQExpBuffer  errorMessage,
bool group_found 
)
static

Definition at line 5454 of file fe-connect.c.

5459 {
5460  int result = 0,
5461  linenr = 0,
5462  i;
5463  FILE *f;
5464  char *line;
5465  char buf[1024];
5466 
5467  *group_found = false;
5468 
5469  f = fopen(serviceFile, "r");
5470  if (f == NULL)
5471  {
5472  libpq_append_error(errorMessage, "service file \"%s\" not found", serviceFile);
5473  return 1;
5474  }
5475 
5476  while ((line = fgets(buf, sizeof(buf), f)) != NULL)
5477  {
5478  int len;
5479 
5480  linenr++;
5481 
5482  if (strlen(line) >= sizeof(buf) - 1)
5483  {
5484  libpq_append_error(errorMessage,
5485  "line %d too long in service file \"%s\"",
5486  linenr,
5487  serviceFile);
5488  result = 2;
5489  goto exit;
5490  }
5491 
5492  /* ignore whitespace at end of line, especially the newline */
5493  len = strlen(line);
5494  while (len > 0 && isspace((unsigned char) line[len - 1]))
5495  line[--len] = '\0';
5496 
5497  /* ignore leading whitespace too */
5498  while (*line && isspace((unsigned char) line[0]))
5499  line++;
5500 
5501  /* ignore comments and empty lines */
5502  if (line[0] == '\0' || line[0] == '#')
5503  continue;
5504 
5505  /* Check for right groupname */
5506  if (line[0] == '[')
5507  {
5508  if (*group_found)
5509  {
5510  /* end of desired group reached; return success */
5511  goto exit;
5512  }
5513 
5514  if (strncmp(line + 1, service, strlen(service)) == 0 &&
5515  line[strlen(service) + 1] == ']')
5516  *group_found = true;
5517  else
5518  *group_found = false;
5519  }
5520  else
5521  {
5522  if (*group_found)
5523  {
5524  /*
5525  * Finally, we are in the right group and can parse the line
5526  */
5527  char *key,
5528  *val;
5529  bool found_keyword;
5530 
5531 #ifdef USE_LDAP
5532  if (strncmp(line, "ldap", 4) == 0)
5533  {
5534  int rc = ldapServiceLookup(line, options, errorMessage);
5535 
5536  /* if rc = 2, go on reading for fallback */
5537  switch (rc)
5538  {
5539  case 0:
5540  goto exit;
5541  case 1:
5542  case 3:
5543  result = 3;
5544  goto exit;
5545  case 2:
5546  continue;
5547  }
5548  }
5549 #endif
5550 
5551  key = line;
5552  val = strchr(line, '=');
5553  if (val == NULL)
5554  {
5555  libpq_append_error(errorMessage,
5556  "syntax error in service file \"%s\", line %d",
5557  serviceFile,
5558  linenr);
5559  result = 3;
5560  goto exit;
5561  }
5562  *val++ = '\0';
5563 
5564  if (strcmp(key, "service") == 0)
5565  {
5566  libpq_append_error(errorMessage,
5567  "nested service specifications not supported in service file \"%s\", line %d",
5568  serviceFile,
5569  linenr);
5570  result = 3;
5571  goto exit;
5572  }
5573 
5574  /*
5575  * Set the parameter --- but don't override any previous
5576  * explicit setting.
5577  */
5578  found_keyword = false;
5579  for (i = 0; options[i].keyword; i++)
5580  {
5581  if (strcmp(options[i].keyword, key) == 0)
5582  {
5583  if (options[i].val == NULL)
5584  options[i].val = strdup(val);
5585  if (!options[i].val)
5586  {
5587  libpq_append_error(errorMessage, "out of memory");
5588  result = 3;
5589  goto exit;
5590  }
5591  found_keyword = true;
5592  break;
5593  }
5594  }
5595 
5596  if (!found_keyword)
5597  {
5598  libpq_append_error(errorMessage,
5599  "syntax error in service file \"%s\", line %d",
5600  serviceFile,
5601  linenr);
5602  result = 3;
5603  goto exit;
5604  }
5605  }
5606  }
5607  }
5608 
5609 exit:
5610  fclose(f);
5611 
5612  return result;
5613 }
exit(1)

References buf, exit(), i, sort-test::key, len, libpq_append_error(), and val.

Referenced by parseServiceInfo().

◆ parseServiceInfo()

static int parseServiceInfo ( PQconninfoOption options,
PQExpBuffer  errorMessage 
)
static

Definition at line 5386 of file fe-connect.c.

5387 {
5388  const char *service = conninfo_getval(options, "service");
5389  char serviceFile[MAXPGPATH];
5390  char *env;
5391  bool group_found = false;
5392  int status;
5393  struct stat stat_buf;
5394 
5395  /*
5396  * We have to special-case the environment variable PGSERVICE here, since
5397  * this is and should be called before inserting environment defaults for
5398  * other connection options.
5399  */
5400  if (service == NULL)
5401  service = getenv("PGSERVICE");
5402 
5403  /* If no service name given, nothing to do */
5404  if (service == NULL)
5405  return 0;
5406 
5407  /*
5408  * Try PGSERVICEFILE if specified, else try ~/.pg_service.conf (if that
5409  * exists).
5410  */
5411  if ((env = getenv("PGSERVICEFILE")) != NULL)
5412  strlcpy(serviceFile, env, sizeof(serviceFile));
5413  else
5414  {
5415  char homedir[MAXPGPATH];
5416 
5417  if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
5418  goto next_file;
5419  snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
5420  if (stat(serviceFile, &stat_buf) != 0)
5421  goto next_file;
5422  }
5423 
5424  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
5425  if (group_found || status != 0)
5426  return status;
5427 
5428 next_file:
5429 
5430  /*
5431  * This could be used by any application so we can't use the binary
5432  * location to find our config files.
5433  */
5434  snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
5435  getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
5436  if (stat(serviceFile, &stat_buf) != 0)
5437  goto last_file;
5438 
5439  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
5440  if (status != 0)
5441  return status;
5442 
5443 last_file:
5444  if (!group_found)
5445  {
5446  libpq_append_error(errorMessage, "definition of service \"%s\" not found", service);
5447  return 3;
5448  }
5449 
5450  return 0;
5451 }
static int parseServiceFile(const char *serviceFile, const char *service, PQconninfoOption *options, PQExpBuffer errorMessage, bool *group_found)
Definition: fe-connect.c:5454
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define stat
Definition: win32_port.h:286

References conninfo_getval(), libpq_append_error(), MAXPGPATH, parseServiceFile(), pqGetHomeDirectory(), snprintf, stat, status(), and strlcpy().

Referenced by conninfo_add_defaults().

◆ passwordFromFile()

static char * passwordFromFile ( const char *  hostname,
const char *  port,
const char *  dbname,
const char *  username,
const char *  pgpassfile 
)
static

Definition at line 7273 of file fe-connect.c.

7275 {
7276  FILE *fp;
7277  struct stat stat_buf;
7279 
7280  if (dbname == NULL || dbname[0] == '\0')
7281  return NULL;
7282 
7283  if (username == NULL || username[0] == '\0')
7284  return NULL;
7285 
7286  /* 'localhost' matches pghost of '' or the default socket directory */
7287  if (hostname == NULL || hostname[0] == '\0')
7289  else if (is_unixsock_path(hostname))
7290 
7291  /*
7292  * We should probably use canonicalize_path(), but then we have to
7293  * bring path.c into libpq, and it doesn't seem worth it.
7294  */
7295  if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
7297 
7298  if (port == NULL || port[0] == '\0')
7299  port = DEF_PGPORT_STR;
7300 
7301  /* If password file cannot be opened, ignore it. */
7302  if (stat(pgpassfile, &stat_buf) != 0)
7303  return NULL;
7304 
7305 #ifndef WIN32
7306  if (!S_ISREG(stat_buf.st_mode))
7307  {
7308  fprintf(stderr,
7309  libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
7310  pgpassfile);
7311  return NULL;
7312  }
7313 
7314  /* If password file is insecure, alert the user and ignore it. */
7315  if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
7316  {
7317  fprintf(stderr,
7318  libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
7319  pgpassfile);
7320  return NULL;
7321  }
7322 #else
7323 
7324  /*
7325  * On Win32, the directory is protected, so we don't have to check the
7326  * file.
7327  */
7328 #endif
7329 
7330  fp = fopen(pgpassfile, "r");
7331  if (fp == NULL)
7332  return NULL;
7333 
7334  /* Use an expansible buffer to accommodate any reasonable line length */
7335  initPQExpBuffer(&buf);
7336 
7337  while (!feof(fp) && !ferror(fp))
7338  {
7339  /* Make sure there's a reasonable amount of room in the buffer */
7340  if (!enlargePQExpBuffer(&buf, 128))
7341  break;
7342 
7343  /* Read some data, appending it to what we already have */
7344  if (fgets(buf.data + buf.len, buf.maxlen - buf.len, fp) == NULL)
7345  break;
7346  buf.len += strlen(buf.data + buf.len);
7347 
7348  /* If we don't yet have a whole line, loop around to read more */
7349  if (!(buf.len > 0 && buf.data[buf.len - 1] == '\n') && !feof(fp))
7350  continue;
7351 
7352  /* ignore comments */
7353  if (buf.data[0] != '#')
7354  {
7355  char *t = buf.data;
7356  int len;
7357 
7358  /* strip trailing newline and carriage return */
7359  len = pg_strip_crlf(t);
7360 
7361  if (len > 0 &&
7362  (t = pwdfMatchesString(t, hostname)) != NULL &&
7363  (t = pwdfMatchesString(t, port)) != NULL &&
7364  (t = pwdfMatchesString(t, dbname)) != NULL &&
7365  (t = pwdfMatchesString(t, username)) != NULL)
7366  {
7367  /* Found a match. */
7368  char *ret,
7369  *p1,
7370  *p2;
7371 
7372  ret = strdup(t);
7373 
7374  fclose(fp);
7375  explicit_bzero(buf.data, buf.maxlen);
7376  termPQExpBuffer(&buf);
7377 
7378  if (!ret)
7379  {
7380  /* Out of memory. XXX: an error message would be nice. */
7381  return NULL;
7382  }
7383 
7384  /* De-escape password. */
7385  for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
7386  {
7387  if (*p1 == '\\' && p1[1] != '\0')
7388  ++p1;
7389  *p2 = *p1;
7390  }
7391  *p2 = '\0';
7392 
7393  return ret;
7394  }
7395  }
7396 
7397  /* No match, reset buffer to prepare for next line. */
7398  buf.len = 0;
7399  }
7400 
7401  fclose(fp);
7402  explicit_bzero(buf.data, buf.maxlen);
7403  termPQExpBuffer(&buf);
7404  return NULL;
7405 }
static char * pwdfMatchesString(char *buf, const char *token)
Definition: fe-connect.c:7236
static char * hostname
Definition: pg_regress.c:89
const char * username
Definition: pgbench.c:306
int enlargePQExpBuffer(PQExpBuffer str, size_t needed)
Definition: pqexpbuffer.c:172
int pg_strip_crlf(char *str)
Definition: string.c:155
#define S_IRWXG
Definition: win32_port.h:312
#define S_IRWXO
Definition: win32_port.h:324
#define S_ISREG(m)
Definition: win32_port.h:330

References buf, dbname, DEFAULT_PGSOCKET_DIR, DefaultHost, enlargePQExpBuffer(), explicit_bzero(), fprintf, hostname, initPQExpBuffer(), is_unixsock_path(), len, libpq_gettext, p2, pg_strip_crlf(), port, pwdfMatchesString(), S_IRWXG, S_IRWXO, S_ISREG, stat::st_mode, stat, termPQExpBuffer(), and username.

Referenced by connectOptions2().

◆ pgpassfileWarning()

static void pgpassfileWarning ( PGconn conn)
static

Definition at line 7413 of file fe-connect.c.

7414 {
7415  /* If it was 'invalid authorization', add pgpassfile mention */
7416  /* only works with >= 9.0 servers */
7417  if (conn->password_needed &&
7418  conn->connhost[conn->whichhost].password != NULL &&
7419  conn->result)
7420  {
7421  const char *sqlstate = PQresultErrorField(conn->result,
7423 
7424  if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
7425  libpq_append_conn_error(conn, "password retrieved from file \"%s\"",
7426  conn->pgpassfile);
7427  }
7428 }
#define ERRCODE_INVALID_PASSWORD
Definition: fe-connect.c:91
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3295
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:56
PGresult * result
Definition: libpq-int.h:521
bool password_needed
Definition: libpq-int.h:456

References conn, pg_conn::connhost, ERRCODE_INVALID_PASSWORD, libpq_append_conn_error(), pg_conn_host::password, pg_conn::password_needed, PG_DIAG_SQLSTATE, pg_conn::pgpassfile, PQresultErrorField(), pg_conn::result, and pg_conn::whichhost.

Referenced by PQconnectPoll().

◆ PQbackendPID()

int PQbackendPID ( const PGconn conn)

Definition at line 7052 of file fe-connect.c.

7053 {
7054  if (!conn || conn->status != CONNECTION_OK)
7055  return 0;
7056  return conn->be_pid;
7057 }
@ CONNECTION_OK
Definition: libpq-fe.h:60
int be_pid
Definition: libpq-int.h:480

References pg_conn::be_pid, conn, CONNECTION_OK, and pg_conn::status.

Referenced by get_prompt(), libpqrcv_get_backend_pid(), main(), and StartLogStreamer().

◆ PQcancel()

int PQcancel ( PGcancel cancel,
char *  errbuf,
int  errbufsize 
)

Definition at line 4624 of file fe-connect.c.

4625 {
4626  int save_errno = SOCK_ERRNO;
4627  pgsocket tmpsock = PGINVALID_SOCKET;
4628  int maxlen;
4629  struct
4630  {
4631  uint32 packetlen;
4633  } crp;
4634 
4635  if (!cancel)
4636  {
4637  strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
4638  /* strlcpy probably doesn't change errno, but be paranoid */
4639  SOCK_ERRNO_SET(save_errno);
4640  return false;
4641  }
4642 
4643  /*
4644  * We need to open a temporary connection to the postmaster. Do this with
4645  * only kernel calls.
4646  */
4647  if ((tmpsock = socket(cancel->raddr.addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
4648  {
4649  strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
4650  goto cancel_errReturn;
4651  }
4652 
4653  /*
4654  * Since this connection will only be used to send a single packet of
4655  * data, we don't need NODELAY. We also don't set the socket to
4656  * nonblocking mode, because the API definition of PQcancel requires the
4657  * cancel to be sent in a blocking way.
4658  *
4659  * We do set socket options related to keepalives and other TCP timeouts.
4660  * This ensures that this function does not block indefinitely when
4661  * reasonable keepalive and timeout settings have been provided.
4662  */
4663  if (cancel->raddr.addr.ss_family != AF_UNIX &&
4664  cancel->keepalives != 0)
4665  {
4666 #ifndef WIN32
4667  if (!optional_setsockopt(tmpsock, SOL_SOCKET, SO_KEEPALIVE, 1))
4668  {
4669  strlcpy(errbuf, "PQcancel() -- setsockopt(SO_KEEPALIVE) failed: ", errbufsize);
4670  goto cancel_errReturn;
4671  }
4672 
4673 #ifdef PG_TCP_KEEPALIVE_IDLE
4674  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
4675  cancel->keepalives_idle))
4676  {
4677  strlcpy(errbuf, "PQcancel() -- setsockopt(" PG_TCP_KEEPALIVE_IDLE_STR ") failed: ", errbufsize);
4678  goto cancel_errReturn;
4679  }
4680 #endif
4681 
4682 #ifdef TCP_KEEPINTVL
4683  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_KEEPINTVL,
4684  cancel->keepalives_interval))
4685  {
4686  strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPINTVL) failed: ", errbufsize);
4687  goto cancel_errReturn;
4688  }
4689 #endif
4690 
4691 #ifdef TCP_KEEPCNT
4692  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_KEEPCNT,
4693  cancel->keepalives_count))
4694  {
4695  strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPCNT) failed: ", errbufsize);
4696  goto cancel_errReturn;
4697  }
4698 #endif
4699 
4700 #else /* WIN32 */
4701 
4702 #ifdef SIO_KEEPALIVE_VALS
4703  if (!setKeepalivesWin32(tmpsock,
4704  cancel->keepalives_idle,
4705  cancel->keepalives_interval))
4706  {
4707  strlcpy(errbuf, "PQcancel() -- WSAIoctl(SIO_KEEPALIVE_VALS) failed: ", errbufsize);
4708  goto cancel_errReturn;
4709  }
4710 #endif /* SIO_KEEPALIVE_VALS */
4711 #endif /* WIN32 */
4712 
4713  /* TCP_USER_TIMEOUT works the same way on Unix and Windows */
4714 #ifdef TCP_USER_TIMEOUT
4715  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_USER_TIMEOUT,
4716  cancel->pgtcp_user_timeout))
4717  {
4718  strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_USER_TIMEOUT) failed: ", errbufsize);
4719  goto cancel_errReturn;
4720  }
4721 #endif
4722  }
4723 
4724 retry3:
4725  if (connect(tmpsock, (struct sockaddr *) &cancel->raddr.addr,
4726  cancel->raddr.salen) < 0)
4727  {
4728  if (SOCK_ERRNO == EINTR)
4729  /* Interrupted system call - we'll just try again */
4730  goto retry3;
4731  strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
4732  goto cancel_errReturn;
4733  }
4734 
4735  /* Create and send the cancel request packet. */
4736 
4737  crp.packetlen = pg_hton32((uint32) sizeof(crp));
4738  crp.cp.cancelRequestCode = (MsgType) pg_hton32(CANCEL_REQUEST_CODE);
4739  crp.cp.backendPID = pg_hton32(cancel->be_pid);
4740  crp.cp.cancelAuthCode = pg_hton32(cancel->be_key);
4741 
4742 retry4:
4743  if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
4744  {
4745  if (SOCK_ERRNO == EINTR)
4746  /* Interrupted system call - we'll just try again */
4747  goto retry4;
4748  strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
4749  goto cancel_errReturn;
4750  }
4751 
4752  /*
4753  * Wait for the postmaster to close the connection, which indicates that
4754  * it's processed the request. Without this delay, we might issue another
4755  * command only to find that our cancel zaps that command instead of the
4756  * one we thought we were canceling. Note we don't actually expect this
4757  * read to obtain any data, we are just waiting for EOF to be signaled.
4758  */
4759 retry5:
4760  if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
4761  {
4762  if (SOCK_ERRNO == EINTR)
4763  /* Interrupted system call - we'll just try again */
4764  goto retry5;
4765  /* we ignore other error conditions */
4766  }
4767 
4768  /* All done */
4769  closesocket(tmpsock);
4770  SOCK_ERRNO_SET(save_errno);
4771  return true;
4772 
4773 cancel_errReturn:
4774 
4775  /*
4776  * Make sure we don't overflow the error buffer. Leave space for the \n at
4777  * the end, and for the terminating zero.
4778  */
4779  maxlen = errbufsize - strlen(errbuf) - 2;
4780  if (maxlen >= 0)
4781  {
4782  /*
4783  * We can't invoke strerror here, since it's not signal-safe. Settle
4784  * for printing the decimal value of errno. Even that has to be done
4785  * the hard way.
4786  */
4787  int val = SOCK_ERRNO;
4788  char buf[32];
4789  char *bufp;
4790 
4791  bufp = buf + sizeof(buf) - 1;
4792  *bufp = '\0';
4793  do
4794  {
4795  *(--bufp) = (val % 10) + '0';
4796  val /= 10;
4797  } while (val > 0);
4798  bufp -= 6;
4799  memcpy(bufp, "error ", 6);
4800  strncat(errbuf, bufp, maxlen);
4801  strcat(errbuf, "\n");
4802  }
4803  if (tmpsock != PGINVALID_SOCKET)
4804  closesocket(tmpsock);
4805  SOCK_ERRNO_SET(save_errno);
4806  return false;
4807 }
static bool optional_setsockopt(int fd, int protoid, int optid, int value)
Definition: fe-connect.c:4592
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:917
#define pg_hton32(x)
Definition: pg_bswap.h:121
int pgsocket
Definition: port.h:29
#define closesocket
Definition: port.h:349
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:139
ProtocolVersion MsgType
Definition: pqcomm.h:89
int pgtcp_user_timeout
Definition: libpq-int.h:616
int keepalives_interval
Definition: libpq-int.h:619
int keepalives_idle
Definition: libpq-int.h:618
int keepalives_count
Definition: libpq-int.h:621
SockAddr raddr
Definition: libpq-int.h:613
int be_pid
Definition: libpq-int.h:614
int keepalives
Definition: libpq-int.h:617
int be_key
Definition: libpq-int.h:615
#define EINTR
Definition: win32_port.h:376
#define recv(s, buf, len, flags)
Definition: win32_port.h:500
#define send(s, buf, len, flags)
Definition: win32_port.h:501
#define socket(af, type, protocol)
Definition: win32_port.h:494
#define connect(s, name, namelen)
Definition: win32_port.h:498

References SockAddr::addr, pg_cancel::be_key, pg_cancel::be_pid, buf, CANCEL_REQUEST_CODE, closesocket, connect, EINTR, pg_cancel::keepalives, pg_cancel::keepalives_count, pg_cancel::keepalives_idle, pg_cancel::keepalives_interval, optional_setsockopt(), pg_hton32, PGINVALID_SOCKET, pg_cancel::pgtcp_user_timeout, pg_cancel::raddr, recv, SockAddr::salen, send, SOCK_ERRNO, SOCK_ERRNO_SET, socket, strlcpy(), and val.

Referenced by dblink_cancel_query(), DisconnectDatabase(), disconnectDatabase(), handle_sigint(), pgfdw_cancel_query(), PQrequestCancel(), ShutdownWorkersHard(), sigTermHandler(), and try_complete_step().

◆ PQclientEncoding()

◆ PQconndefaults()

PQconninfoOption* PQconndefaults ( void  )

Definition at line 1664 of file fe-connect.c.

1665 {
1666  PQExpBufferData errorBuf;
1667  PQconninfoOption *connOptions;
1668 
1669  /* We don't actually report any errors here, but callees want a buffer */
1670  initPQExpBuffer(&errorBuf);
1671  if (PQExpBufferDataBroken(errorBuf))
1672  return NULL; /* out of memory already :-( */
1673 
1674  connOptions = conninfo_init(&errorBuf);
1675  if (connOptions != NULL)
1676  {
1677  /* pass NULL errorBuf to ignore errors */
1678  if (!conninfo_add_defaults(connOptions, NULL))
1679  {
1680  PQconninfoFree(connOptions);
1681  connOptions = NULL;
1682  }
1683  }
1684 
1685  termPQExpBuffer(&errorBuf);
1686  return connOptions;
1687 }

References conninfo_add_defaults(), conninfo_init(), initPQExpBuffer(), PQconninfoFree(), PQExpBufferDataBroken, and termPQExpBuffer().

Referenced by check_pghost_envvar(), dblink_fdw_validator(), do_connect(), get_connect_string(), InitPgFdwOptions(), and main().

◆ PQconnectdb()

PGconn* PQconnectdb ( const char *  conninfo)

Definition at line 718 of file fe-connect.c.

719 {
720  PGconn *conn = PQconnectStart(conninfo);
721 
722  if (conn && conn->status != CONNECTION_BAD)
723  (void) connectDBComplete(conn);
724 
725  return conn;
726 }
PGconn * PQconnectStart(const char *conninfo)
Definition: fe-connect.c:846

References conn, connectDBComplete(), CONNECTION_BAD, PQconnectStart(), and pg_conn::status.

Referenced by get_db_conn(), and main().

◆ PQconnectdbParams()

PGconn* PQconnectdbParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)

Definition at line 663 of file fe-connect.c.

666 {
667  PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
668 
669  if (conn && conn->status != CONNECTION_BAD)
670  (void) connectDBComplete(conn);
671 
672  return conn;
673 }
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:765

References conn, connectDBComplete(), CONNECTION_BAD, PQconnectStartParams(), pg_conn::status, and values.

Referenced by ConnectDatabase(), connectDatabase(), do_connect(), doConnect(), ECPGconnect(), GetConnection(), main(), sql_conn(), and vacuumlo().

◆ PQconnectionNeedsPassword()

int PQconnectionNeedsPassword ( const PGconn conn)

Definition at line 7069 of file fe-connect.c.

7070 {
7071  char *password;
7072 
7073  if (!conn)
7074  return false;
7075  password = PQpass(conn);
7076  if (conn->password_needed &&
7077  (password == NULL || password[0] == '\0'))
7078  return true;
7079  else
7080  return false;
7081 }
char * PQpass(const PGconn *conn)
Definition: fe-connect.c:6880

References conn, password, pg_conn::password_needed, and PQpass().

Referenced by ConnectDatabase(), connectDatabase(), do_connect(), doConnect(), GetConnection(), main(), sql_conn(), and vacuumlo().

◆ PQconnectionUsedPassword()

int PQconnectionUsedPassword ( const PGconn conn)

Definition at line 7084 of file fe-connect.c.

7085 {
7086  if (!conn)
7087  return false;
7088  if (conn->password_needed)
7089  return true;
7090  else
7091  return false;
7092 }

References conn, and pg_conn::password_needed.

Referenced by connect_pg_server(), ConnectDatabase(), and dblink_security_check().

◆ PQconnectPoll()

PostgresPollingStatusType PQconnectPoll ( PGconn conn)

Definition at line 2427 of file fe-connect.c.

2428 {
2429  bool reset_connection_state_machine = false;
2430  bool need_new_connection = false;
2431  PGresult *res;
2432  char sebuf[PG_STRERROR_R_BUFLEN];
2433  int optval;
2434 
2435  if (conn == NULL)
2436  return PGRES_POLLING_FAILED;
2437 
2438  /* Get the new data */
2439  switch (conn->status)
2440  {
2441  /*
2442  * We really shouldn't have been polled in these two cases, but we
2443  * can handle it.
2444  */
2445  case CONNECTION_BAD:
2446  return PGRES_POLLING_FAILED;
2447  case CONNECTION_OK:
2448  return PGRES_POLLING_OK;
2449 
2450  /* These are reading states */
2452  case CONNECTION_AUTH_OK:
2454  case CONNECTION_CONSUME:
2456  {
2457  /* Load waiting data */
2458  int n = pqReadData(conn);
2459 
2460  if (n < 0)
2461  goto error_return;
2462  if (n == 0)
2463  return PGRES_POLLING_READING;
2464 
2465  break;
2466  }
2467 
2468  /* These are writing states, so we just proceed. */
2469  case CONNECTION_STARTED:
2470  case CONNECTION_MADE:
2471  break;
2472 
2473  /* Special cases: proceed without waiting. */
2475  case CONNECTION_NEEDED:
2478  break;
2479 
2480  default:
2481  libpq_append_conn_error(conn, "invalid connection state, probably indicative of memory corruption");
2482  goto error_return;
2483  }
2484 
2485 
2486 keep_going: /* We will come back to here until there is
2487  * nothing left to do. */
2488 
2489  /* Time to advance to next address, or next host if no more addresses? */
2490  if (conn->try_next_addr)
2491  {
2492  if (conn->addr_cur && conn->addr_cur->ai_next)
2493  {
2494  conn->addr_cur = conn->addr_cur->ai_next;
2495  reset_connection_state_machine = true;
2496  }
2497  else
2498  conn->try_next_host = true;
2499  conn->try_next_addr = false;
2500  }
2501 
2502  /* Time to advance to next connhost[] entry? */
2503  if (conn->try_next_host)
2504  {
2505  pg_conn_host *ch;
2506  struct addrinfo hint;
2507  int thisport;
2508  int ret;
2509  char portstr[MAXPGPATH];
2510 
2511  if (conn->whichhost + 1 < conn->nconnhost)
2512  conn->whichhost++;
2513  else
2514  {
2515  /*
2516  * Oops, no more hosts.
2517  *
2518  * If we are trying to connect in "prefer-standby" mode, then drop
2519  * the standby requirement and start over.
2520  *
2521  * Otherwise, an appropriate error message is already set up, so
2522  * we just need to set the right status.
2523  */
2525  conn->nconnhost > 0)
2526  {
2528  conn->whichhost = 0;
2529  }
2530  else
2531  goto error_return;
2532  }
2533 
2534  /* Drop any address info for previous host */
2536 
2537  /*
2538  * Look up info for the new host. On failure, log the problem in
2539  * conn->errorMessage, then loop around to try the next host. (Note
2540  * we don't clear try_next_host until we've succeeded.)
2541  */
2542  ch = &conn->connhost[conn->whichhost];
2543 
2544  /* Initialize hint structure */
2545  MemSet(&hint, 0, sizeof(hint));
2546  hint.ai_socktype = SOCK_STREAM;
2547  conn->addrlist_family = hint.ai_family = AF_UNSPEC;
2548 
2549  /* Figure out the port number we're going to use. */
2550  if (ch->port == NULL || ch->port[0] == '\0')
2551  thisport = DEF_PGPORT;
2552  else
2553  {
2554  if (!parse_int_param(ch->port, &thisport, conn, "port"))
2555  goto error_return;
2556 
2557  if (thisport < 1 || thisport > 65535)
2558  {
2559  libpq_append_conn_error(conn, "invalid port number: \"%s\"", ch->port);
2560  goto keep_going;
2561  }
2562  }
2563  snprintf(portstr, sizeof(portstr), "%d", thisport);
2564 
2565  /* Use pg_getaddrinfo_all() to resolve the address */
2566  switch (ch->type)
2567  {
2568  case CHT_HOST_NAME:
2569  ret = pg_getaddrinfo_all(ch->host, portstr, &hint,
2570  &conn->addrlist);
2571  if (ret || !conn->addrlist)
2572  {
2573  libpq_append_conn_error(conn, "could not translate host name \"%s\" to address: %s",
2574  ch->host, gai_strerror(ret));
2575  goto keep_going;
2576  }
2577  break;
2578 
2579  case CHT_HOST_ADDRESS:
2580  hint.ai_flags = AI_NUMERICHOST;
2581  ret = pg_getaddrinfo_all(ch->hostaddr, portstr, &hint,
2582  &conn->addrlist);
2583  if (ret || !conn->addrlist)
2584  {
2585  libpq_append_conn_error(conn, "could not parse network address \"%s\": %s",
2586  ch->hostaddr, gai_strerror(ret));
2587  goto keep_going;
2588  }
2589  break;
2590 
2591  case CHT_UNIX_SOCKET:
2592  conn->addrlist_family = hint.ai_family = AF_UNIX;
2593  UNIXSOCK_PATH(portstr, thisport, ch->host);
2594  if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
2595  {
2596  libpq_append_conn_error(conn, "Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
2597  portstr,
2598  (int) (UNIXSOCK_PATH_BUFLEN - 1));
2599  goto keep_going;
2600  }
2601 
2602  /*
2603  * NULL hostname tells pg_getaddrinfo_all to parse the service
2604  * name as a Unix-domain socket path.
2605  */
2606  ret = pg_getaddrinfo_all(NULL, portstr, &hint,
2607  &conn->addrlist);
2608  if (ret || !conn->addrlist)
2609  {
2610  libpq_append_conn_error(conn, "could not translate Unix-domain socket path \"%s\" to address: %s",
2611  portstr, gai_strerror(ret));
2612  goto keep_going;
2613  }
2614  break;
2615  }
2616 
2617  /* OK, scan this addrlist for a working server address */
2618  conn->addr_cur = conn->addrlist;
2619  reset_connection_state_machine = true;
2620  conn->try_next_host = false;
2621  }
2622 
2623  /* Reset connection state machine? */
2624  if (reset_connection_state_machine)
2625  {
2626  /*
2627  * (Re) initialize our connection control variables for a set of
2628  * connection attempts to a single server address. These variables
2629  * must persist across individual connection attempts, but we must
2630  * reset them when we start to consider a new server.
2631  */
2632  conn->pversion = PG_PROTOCOL(3, 0);
2633  conn->send_appname = true;
2634 #ifdef USE_SSL
2635  /* initialize these values based on SSL mode */
2636  conn->allow_ssl_try = (conn->sslmode[0] != 'd'); /* "disable" */
2637  conn->wait_ssl_try = (conn->sslmode[0] == 'a'); /* "allow" */
2638 #endif
2639 #ifdef ENABLE_GSS
2640  conn->try_gss = (conn->gssencmode[0] != 'd'); /* "disable" */
2641 #endif
2642 
2643  reset_connection_state_machine = false;
2644  need_new_connection = true;
2645  }
2646 
2647  /* Force a new connection (perhaps to the same server as before)? */
2648  if (need_new_connection)
2649  {
2650  /* Drop any existing connection */
2651  pqDropConnection(conn, true);
2652 
2653  /* Reset all state obtained from old server */
2655 
2656  /* Drop any PGresult we might have, too */
2661 
2662  /* Reset conn->status to put the state machine in the right state */
2664 
2665  need_new_connection = false;
2666  }
2667 
2668  /* Now try to advance the state machine for this connection */
2669  switch (conn->status)
2670  {
2671  case CONNECTION_NEEDED:
2672  {
2673  /*
2674  * Try to initiate a connection to one of the addresses
2675  * returned by pg_getaddrinfo_all(). conn->addr_cur is the
2676  * next one to try.
2677  *
2678  * The extra level of braces here is historical. It's not
2679  * worth reindenting this whole switch case to remove 'em.
2680  */
2681  {
2682  struct addrinfo *addr_cur = conn->addr_cur;
2683  char host_addr[NI_MAXHOST];
2684  int sock_type;
2685 
2686  /*
2687  * Advance to next possible host, if we've tried all of
2688  * the addresses for the current host.
2689  */
2690  if (addr_cur == NULL)
2691  {
2692  conn->try_next_host = true;
2693  goto keep_going;
2694  }
2695 
2696  /* Remember current address for possible use later */
2697  memcpy(&conn->raddr.addr, addr_cur->ai_addr,
2698  addr_cur->ai_addrlen);
2699  conn->raddr.salen = addr_cur->ai_addrlen;
2700 
2701  /*
2702  * Set connip, too. Note we purposely ignore strdup
2703  * failure; not a big problem if it fails.
2704  */
2705  if (conn->connip != NULL)
2706  {
2707  free(conn->connip);
2708  conn->connip = NULL;
2709  }
2710  getHostaddr(conn, host_addr, NI_MAXHOST);
2711  if (host_addr[0])
2712  conn->connip = strdup(host_addr);
2713 
2714  /* Try to create the socket */
2715  sock_type = SOCK_STREAM;
2716 #ifdef SOCK_CLOEXEC
2717 
2718  /*
2719  * Atomically mark close-on-exec, if possible on this
2720  * platform, so that there isn't a window where a
2721  * subprogram executed by another thread inherits the
2722  * socket. See fallback code below.
2723  */
2724  sock_type |= SOCK_CLOEXEC;
2725 #endif
2726 #ifdef SOCK_NONBLOCK
2727 
2728  /*
2729  * We might as well skip a system call for nonblocking
2730  * mode too, if we can.
2731  */
2732  sock_type |= SOCK_NONBLOCK;
2733 #endif
2734  conn->sock = socket(addr_cur->ai_family, sock_type, 0);
2735  if (conn->sock == PGINVALID_SOCKET)
2736  {
2737  int errorno = SOCK_ERRNO;
2738 
2739  /*
2740  * Silently ignore socket() failure if we have more
2741  * addresses to try; this reduces useless chatter in
2742  * cases where the address list includes both IPv4 and
2743  * IPv6 but kernel only accepts one family.
2744  */
2745  if (addr_cur->ai_next != NULL ||
2746  conn->whichhost + 1 < conn->nconnhost)
2747  {
2748  conn->try_next_addr = true;
2749  goto keep_going;
2750  }
2751  emitHostIdentityInfo(conn, host_addr);
2752  libpq_append_conn_error(conn, "could not create socket: %s",
2753  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)));
2754  goto error_return;
2755  }
2756 
2757  /*
2758  * Once we've identified a target address, all errors
2759  * except the preceding socket()-failure case should be
2760  * prefixed with host-identity information. (If the
2761  * connection succeeds, the contents of conn->errorMessage
2762  * won't matter, so this is harmless.)
2763  */
2764  emitHostIdentityInfo(conn, host_addr);
2765 
2766  /*
2767  * Select socket options: no delay of outgoing data for
2768  * TCP sockets, nonblock mode, close-on-exec. Try the
2769  * next address if any of this fails.
2770  */
2771  if (addr_cur->ai_family != AF_UNIX)
2772  {
2773  if (!connectNoDelay(conn))
2774  {
2775  /* error message already created */
2776  conn->try_next_addr = true;
2777  goto keep_going;
2778  }
2779  }
2780 #ifndef SOCK_NONBLOCK
2781  if (!pg_set_noblock(conn->sock))
2782  {
2783  libpq_append_conn_error(conn, "could not set socket to nonblocking mode: %s",
2784  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2785  conn->try_next_addr = true;
2786  goto keep_going;
2787  }
2788 #endif
2789 
2790 #ifndef SOCK_CLOEXEC
2791 #ifdef F_SETFD
2792  if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
2793  {
2794  libpq_append_conn_error(conn, "could not set socket to close-on-exec mode: %s",
2795  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2796  conn->try_next_addr = true;
2797  goto keep_going;
2798  }
2799 #endif /* F_SETFD */
2800 #endif
2801 
2802  if (addr_cur->ai_family != AF_UNIX)
2803  {
2804 #ifndef WIN32
2805  int on = 1;
2806 #endif
2807  int usekeepalives = useKeepalives(conn);
2808  int err = 0;
2809 
2810  if (usekeepalives < 0)
2811  {
2812  libpq_append_conn_error(conn, "keepalives parameter must be an integer");
2813  err = 1;
2814  }
2815  else if (usekeepalives == 0)
2816  {
2817  /* Do nothing */
2818  }
2819 #ifndef WIN32
2820  else if (setsockopt(conn->sock,
2821  SOL_SOCKET, SO_KEEPALIVE,
2822  (char *) &on, sizeof(on)) < 0)
2823  {
2824  libpq_append_conn_error(conn, "%s(%s) failed: %s",
2825  "setsockopt",
2826  "SO_KEEPALIVE",
2827  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2828  err = 1;
2829  }
2830  else if (!setKeepalivesIdle(conn)
2832  || !setKeepalivesCount(conn))
2833  err = 1;
2834 #else /* WIN32 */
2835 #ifdef SIO_KEEPALIVE_VALS
2836  else if (!prepKeepalivesWin32(conn))
2837  err = 1;
2838 #endif /* SIO_KEEPALIVE_VALS */
2839 #endif /* WIN32 */
2840  else if (!setTCPUserTimeout(conn))
2841  err = 1;
2842 
2843  if (err)
2844  {
2845  conn->try_next_addr = true;
2846  goto keep_going;
2847  }
2848  }
2849 
2850  /*----------
2851  * We have three methods of blocking SIGPIPE during
2852  * send() calls to this socket:
2853  *
2854  * - setsockopt(sock, SO_NOSIGPIPE)
2855  * - send(sock, ..., MSG_NOSIGNAL)
2856  * - setting the signal mask to SIG_IGN during send()
2857  *
2858  * The third method requires three syscalls per send,
2859  * so we prefer either of the first two, but they are
2860  * less portable. The state is tracked in the following
2861  * members of PGconn:
2862  *
2863  * conn->sigpipe_so - we have set up SO_NOSIGPIPE
2864  * conn->sigpipe_flag - we're specifying MSG_NOSIGNAL
2865  *
2866  * If we can use SO_NOSIGPIPE, then set sigpipe_so here
2867  * and we're done. Otherwise, set sigpipe_flag so that
2868  * we will try MSG_NOSIGNAL on sends. If we get an error
2869  * with MSG_NOSIGNAL, we'll clear that flag and revert to
2870  * signal masking.
2871  *----------
2872  */
2873  conn->sigpipe_so = false;
2874 #ifdef MSG_NOSIGNAL
2875  conn->sigpipe_flag = true;
2876 #else
2877  conn->sigpipe_flag = false;
2878 #endif /* MSG_NOSIGNAL */
2879 
2880 #ifdef SO_NOSIGPIPE
2881  optval = 1;
2882  if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE,
2883  (char *) &optval, sizeof(optval)) == 0)
2884  {
2885  conn->sigpipe_so = true;
2886  conn->sigpipe_flag = false;
2887  }
2888 #endif /* SO_NOSIGPIPE */
2889 
2890  /*
2891  * Start/make connection. This should not block, since we
2892  * are in nonblock mode. If it does, well, too bad.
2893  */
2894  if (connect(conn->sock, addr_cur->ai_addr,
2895  addr_cur->ai_addrlen) < 0)
2896  {
2897  if (SOCK_ERRNO == EINPROGRESS ||
2898 #ifdef WIN32
2899  SOCK_ERRNO == EWOULDBLOCK ||
2900 #endif
2901  SOCK_ERRNO == EINTR)
2902  {
2903  /*
2904  * This is fine - we're in non-blocking mode, and
2905  * the connection is in progress. Tell caller to
2906  * wait for write-ready on socket.
2907  */
2909  return PGRES_POLLING_WRITING;
2910  }
2911  /* otherwise, trouble */
2912  }
2913  else
2914  {
2915  /*
2916  * Hm, we're connected already --- seems the "nonblock
2917  * connection" wasn't. Advance the state machine and
2918  * go do the next stuff.
2919  */
2921  goto keep_going;
2922  }
2923 
2924  /*
2925  * This connection failed. Add the error report to
2926  * conn->errorMessage, then try the next address if any.
2927  */
2929  conn->try_next_addr = true;
2930  goto keep_going;
2931  }
2932  }
2933 
2934  case CONNECTION_STARTED:
2935  {
2936  socklen_t optlen = sizeof(optval);
2937 
2938  /*
2939  * Write ready, since we've made it here, so the connection
2940  * has been made ... or has failed.
2941  */
2942 
2943  /*
2944  * Now check (using getsockopt) that there is not an error
2945  * state waiting for us on the socket.
2946  */
2947 
2948  if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
2949  (char *) &optval, &optlen) == -1)
2950  {
2951  libpq_append_conn_error(conn, "could not get socket error status: %s",
2952  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2953  goto error_return;
2954  }
2955  else if (optval != 0)
2956  {
2957  /*
2958  * When using a nonblocking connect, we will typically see
2959  * connect failures at this point, so provide a friendly
2960  * error message.
2961  */
2962  connectFailureMessage(conn, optval);
2963 
2964  /*
2965  * Try the next address if any, just as in the case where
2966  * connect() returned failure immediately.
2967  */
2968  conn->try_next_addr = true;
2969  goto keep_going;
2970  }
2971 
2972  /* Fill in the client address */
2973  conn->laddr.salen = sizeof(conn->laddr.addr);
2974  if (getsockname(conn->sock,
2975  (struct sockaddr *) &conn->laddr.addr,
2976  &conn->laddr.salen) < 0)
2977  {
2978  libpq_append_conn_error(conn, "could not get client address from socket: %s",
2979  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2980  goto error_return;
2981  }
2982 
2983  /*
2984  * Make sure we can write before advancing to next step.
2985  */
2987  return PGRES_POLLING_WRITING;
2988  }
2989 
2990  case CONNECTION_MADE:
2991  {
2992  char *startpacket;
2993  int packetlen;
2994 
2995  /*
2996  * Implement requirepeer check, if requested and it's a
2997  * Unix-domain socket.
2998  */
2999  if (conn->requirepeer && conn->requirepeer[0] &&
3000  conn->raddr.addr.ss_family == AF_UNIX)
3001  {
3002 #ifndef WIN32
3003  char *remote_username;
3004 #endif
3005  uid_t uid;
3006  gid_t gid;
3007 
3008  errno = 0;
3009  if (getpeereid(conn->sock, &uid, &gid) != 0)
3010  {
3011  /*
3012  * Provide special error message if getpeereid is a
3013  * stub
3014  */
3015  if (errno == ENOSYS)
3016  libpq_append_conn_error(conn, "requirepeer parameter is not supported on this platform");
3017  else
3018  libpq_append_conn_error(conn, "could not get peer credentials: %s",
3019  strerror_r(errno, sebuf, sizeof(sebuf)));
3020  goto error_return;
3021  }
3022 
3023 #ifndef WIN32
3024  remote_username = pg_fe_getusername(uid,
3025  &conn->errorMessage);
3026  if (remote_username == NULL)
3027  goto error_return; /* message already logged */
3028 
3029  if (strcmp(remote_username, conn->requirepeer) != 0)
3030  {
3031  libpq_append_conn_error(conn, "requirepeer specifies \"%s\", but actual peer user name is \"%s\"",
3032  conn->requirepeer, remote_username);
3033  free(remote_username);
3034  goto error_return;
3035  }
3036  free(remote_username);
3037 #else /* WIN32 */
3038  /* should have failed with ENOSYS above */
3039  Assert(false);
3040 #endif /* WIN32 */
3041  }
3042 
3043  if (conn->raddr.addr.ss_family == AF_UNIX)
3044  {
3045  /* Don't request SSL or GSSAPI over Unix sockets */
3046 #ifdef USE_SSL
3047  conn->allow_ssl_try = false;
3048 #endif
3049 #ifdef ENABLE_GSS
3050  conn->try_gss = false;
3051 #endif
3052  }
3053 
3054 #ifdef ENABLE_GSS
3055 
3056  /*
3057  * If GSSAPI encryption is enabled, then call
3058  * pg_GSS_have_cred_cache() which will return true if we can
3059  * acquire credentials (and give us a handle to use in
3060  * conn->gcred), and then send a packet to the server asking
3061  * for GSSAPI Encryption (and skip past SSL negotiation and
3062  * regular startup below).
3063  */
3064  if (conn->try_gss && !conn->gctx)
3065  conn->try_gss = pg_GSS_have_cred_cache(&conn->gcred);
3066  if (conn->try_gss && !conn->gctx)
3067  {
3069 
3070  if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
3071  {
3072  libpq_append_conn_error(conn, "could not send GSSAPI negotiation packet: %s",
3073  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3074  goto error_return;
3075  }
3076 
3077  /* Ok, wait for response */
3079  return PGRES_POLLING_READING;
3080  }
3081  else if (!conn->gctx && conn->gssencmode[0] == 'r')
3082  {
3084  "GSSAPI encryption required but was impossible (possibly no credential cache, no server support, or using a local socket)");
3085  goto error_return;
3086  }
3087 #endif
3088 
3089 #ifdef USE_SSL
3090 
3091  /*
3092  * Enable the libcrypto callbacks before checking if SSL needs
3093  * to be done. This is done before sending the startup packet
3094  * as depending on the type of authentication done, like MD5
3095  * or SCRAM that use cryptohashes, the callbacks would be
3096  * required even without a SSL connection
3097  */
3098  if (pqsecure_initialize(conn, false, true) < 0)
3099  goto error_return;
3100 
3101  /*
3102  * If SSL is enabled and we haven't already got encryption of
3103  * some sort running, request SSL instead of sending the
3104  * startup message.
3105  */
3106  if (conn->allow_ssl_try && !conn->wait_ssl_try &&
3107  !conn->ssl_in_use
3108 #ifdef ENABLE_GSS
3109  && !conn->gssenc
3110 #endif
3111  )
3112  {
3113  ProtocolVersion pv;
3114 
3115  /*
3116  * Send the SSL request packet.
3117  *
3118  * Theoretically, this could block, but it really
3119  * shouldn't since we only got here if the socket is
3120  * write-ready.
3121  */
3123  if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
3124  {
3125  libpq_append_conn_error(conn, "could not send SSL negotiation packet: %s",
3126  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3127  goto error_return;
3128  }
3129  /* Ok, wait for response */
3131  return PGRES_POLLING_READING;
3132  }
3133 #endif /* USE_SSL */
3134 
3135  /*
3136  * Build the startup packet.
3137  */
3138  startpacket = pqBuildStartupPacket3(conn, &packetlen,
3140  if (!startpacket)
3141  {
3142  libpq_append_conn_error(conn, "out of memory");
3143  goto error_return;
3144  }
3145 
3146  /*
3147  * Send the startup packet.
3148  *
3149  * Theoretically, this could block, but it really shouldn't
3150  * since we only got here if the socket is write-ready.
3151  */
3152  if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
3153  {
3154  libpq_append_conn_error(conn, "could not send startup packet: %s",
3155  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
3156  free(startpacket);
3157  goto error_return;
3158  }
3159 
3160  free(startpacket);
3161 
3163  return PGRES_POLLING_READING;
3164  }
3165 
3166  /*
3167  * Handle SSL negotiation: wait for postmaster messages and
3168  * respond as necessary.
3169  */
3171  {
3172 #ifdef USE_SSL
3173  PostgresPollingStatusType pollres;
3174 
3175  /*
3176  * On first time through, get the postmaster's response to our
3177  * SSL negotiation packet.
3178  */
3179  if (!conn->ssl_in_use)
3180  {
3181  /*
3182  * We use pqReadData here since it has the logic to
3183  * distinguish no-data-yet from connection closure. Since
3184  * conn->ssl isn't set, a plain recv() will occur.
3185  */
3186  char SSLok;
3187  int rdresult;
3188 
3189  rdresult = pqReadData(conn);
3190  if (rdresult < 0)
3191  {
3192  /* errorMessage is already filled in */
3193  goto error_return;
3194  }
3195  if (rdresult == 0)
3196  {
3197  /* caller failed to wait for data */
3198  return PGRES_POLLING_READING;
3199  }
3200  if (pqGetc(&SSLok, conn) < 0)
3201  {
3202  /* should not happen really */
3203  return PGRES_POLLING_READING;
3204  }
3205  if (SSLok == 'S')
3206  {
3207  /* mark byte consumed */
3208  conn->inStart = conn->inCursor;
3209 
3210  /*
3211  * Set up global SSL state if required. The crypto
3212  * state has already been set if libpq took care of
3213  * doing that, so there is no need to make that happen
3214  * again.
3215  */
3216  if (pqsecure_initialize(conn, true, false) != 0)
3217  goto error_return;
3218  }
3219  else if (SSLok == 'N')
3220  {
3221  /* mark byte consumed */
3222  conn->inStart = conn->inCursor;
3223  /* OK to do without SSL? */
3224  if (conn->sslmode[0] == 'r' || /* "require" */
3225  conn->sslmode[0] == 'v') /* "verify-ca" or
3226  * "verify-full" */
3227  {
3228  /* Require SSL, but server does not want it */
3229  libpq_append_conn_error(conn, "server does not support SSL, but SSL was required");
3230  goto error_return;
3231  }
3232  /* Otherwise, proceed with normal startup */
3233  conn->allow_ssl_try = false;
3234  /* We can proceed using this connection */
3236  return PGRES_POLLING_WRITING;
3237  }
3238  else if (SSLok == 'E')
3239  {
3240  /*
3241  * Server failure of some sort, such as failure to
3242  * fork a backend process. We need to process and
3243  * report the error message, which might be formatted
3244  * according to either protocol 2 or protocol 3.
3245  * Rather than duplicate the code for that, we flip
3246  * into AWAITING_RESPONSE state and let the code there
3247  * deal with it. Note we have *not* consumed the "E"
3248  * byte here.
3249  */
3251  goto keep_going;
3252  }
3253  else
3254  {
3255  libpq_append_conn_error(conn, "received invalid response to SSL negotiation: %c",
3256  SSLok);
3257  goto error_return;
3258  }
3259  }
3260 
3261  /*
3262  * Begin or continue the SSL negotiation process.
3263  */
3264  pollres = pqsecure_open_client(conn);
3265  if (pollres == PGRES_POLLING_OK)
3266  {
3267  /*
3268  * At this point we should have no data already buffered.
3269  * If we do, it was received before we performed the SSL
3270  * handshake, so it wasn't encrypted and indeed may have
3271  * been injected by a man-in-the-middle.
3272  */
3273  if (conn->inCursor != conn->inEnd)
3274  {
3275  libpq_append_conn_error(conn, "received unencrypted data after SSL response");
3276  goto error_return;
3277  }
3278 
3279  /* SSL handshake done, ready to send startup packet */
3281  return PGRES_POLLING_WRITING;
3282  }
3283  if (pollres == PGRES_POLLING_FAILED)
3284  {
3285  /*
3286  * Failed ... if sslmode is "prefer" then do a non-SSL
3287  * retry
3288  */
3289  if (conn->sslmode[0] == 'p' /* "prefer" */
3290  && conn->allow_ssl_try /* redundant? */
3291  && !conn->wait_ssl_try) /* redundant? */
3292  {
3293  /* only retry once */
3294  conn->allow_ssl_try = false;
3295  need_new_connection = true;
3296  goto keep_going;
3297  }
3298  /* Else it's a hard failure */
3299  goto error_return;
3300  }
3301  /* Else, return POLLING_READING or POLLING_WRITING status */
3302  return pollres;
3303 #else /* !USE_SSL */
3304  /* can't get here */
3305  goto error_return;
3306 #endif /* USE_SSL */
3307  }
3308 
3310  {
3311 #ifdef ENABLE_GSS
3312  PostgresPollingStatusType pollres;
3313 
3314  /*
3315  * If we haven't yet, get the postmaster's response to our
3316  * negotiation packet
3317  */
3318  if (conn->try_gss && !conn->gctx)
3319  {
3320  char gss_ok;
3321  int rdresult = pqReadData(conn);
3322 
3323  if (rdresult < 0)
3324  /* pqReadData fills in error message */
3325  goto error_return;
3326  else if (rdresult == 0)
3327  /* caller failed to wait for data */
3328  return PGRES_POLLING_READING;
3329  if (pqGetc(&gss_ok, conn) < 0)
3330  /* shouldn't happen... */
3331  return PGRES_POLLING_READING;
3332 
3333  if (gss_ok == 'E')
3334  {
3335  /*
3336  * Server failure of some sort. Assume it's a
3337  * protocol version support failure, and let's see if
3338  * we can't recover (if it's not, we'll get a better
3339  * error message on retry). Server gets fussy if we
3340  * don't hang up the socket, though.
3341  */
3342  conn->try_gss = false;
3343  need_new_connection = true;
3344  goto keep_going;
3345  }
3346 
3347  /* mark byte consumed */
3348  conn->inStart = conn->inCursor;
3349 
3350  if (gss_ok == 'N')
3351  {
3352  /* Server doesn't want GSSAPI; fall back if we can */
3353  if (conn->gssencmode[0] == 'r')
3354  {
3355  libpq_append_conn_error(conn, "server doesn't support GSSAPI encryption, but it was required");
3356  goto error_return;
3357  }
3358 
3359  conn->try_gss = false;
3360  /* We can proceed using this connection */
3362  return PGRES_POLLING_WRITING;
3363  }
3364  else if (gss_ok != 'G')
3365  {
3366  libpq_append_conn_error(conn, "received invalid response to GSSAPI negotiation: %c",
3367  gss_ok);
3368  goto error_return;
3369  }
3370  }
3371 
3372  /* Begin or continue GSSAPI negotiation */
3373  pollres = pqsecure_open_gss(conn);
3374  if (pollres == PGRES_POLLING_OK)
3375  {
3376  /*
3377  * At this point we should have no data already buffered.
3378  * If we do, it was received before we performed the GSS
3379  * handshake, so it wasn't encrypted and indeed may have
3380  * been injected by a man-in-the-middle.
3381  */
3382  if (conn->inCursor != conn->inEnd)
3383  {
3384  libpq_append_conn_error(conn, "received unencrypted data after GSSAPI encryption response");
3385  goto error_return;
3386  }
3387 
3388  /* All set for startup packet */
3390  return PGRES_POLLING_WRITING;
3391  }
3392  else if (pollres == PGRES_POLLING_FAILED)
3393  {
3394  if (conn->gssencmode[0] == 'p')
3395  {
3396  /*
3397  * We failed, but we can retry on "prefer". Have to
3398  * drop the current connection to do so, though.
3399  */
3400  conn->try_gss = false;
3401  need_new_connection = true;
3402  goto keep_going;
3403  }
3404  /* Else it's a hard failure */
3405  goto error_return;
3406  }
3407  /* Else, return POLLING_READING or POLLING_WRITING status */
3408  return pollres;
3409 #else /* !ENABLE_GSS */
3410  /* unreachable */
3411  goto error_return;
3412 #endif /* ENABLE_GSS */
3413  }
3414 
3415  /*
3416  * Handle authentication exchange: wait for postmaster messages
3417  * and respond as necessary.
3418  */
3420  {
3421  char beresp;
3422  int msgLength;
3423  int avail;
3424  AuthRequest areq;
3425  int res;
3426 
3427  /*
3428  * Scan the message from current point (note that if we find
3429  * the message is incomplete, we will return without advancing
3430  * inStart, and resume here next time).
3431  */
3432  conn->inCursor = conn->inStart;
3433 
3434  /* Read type byte */
3435  if (pqGetc(&beresp, conn))
3436  {
3437  /* We'll come back when there is more data */
3438  return PGRES_POLLING_READING;
3439  }
3440 
3441  /*
3442  * Validate message type: we expect only an authentication
3443  * request, NegotiateProtocolVersion, or an error here.
3444  * Anything else probably means it's not Postgres on the other
3445  * end at all.
3446  */
3447  if (!(beresp == 'R' || beresp == 'v' || beresp == 'E'))
3448  {
3449  libpq_append_conn_error(conn, "expected authentication request from server, but received %c",
3450  beresp);
3451  goto error_return;
3452  }
3453 
3454  /* Read message length word */
3455  if (pqGetInt(&msgLength, 4, conn))
3456  {
3457  /* We'll come back when there is more data */
3458  return PGRES_POLLING_READING;
3459  }
3460 
3461  /*
3462  * Try to validate message length before using it.
3463  *
3464  * Authentication requests can't be very large, although GSS
3465  * auth requests may not be that small. Same for
3466  * NegotiateProtocolVersion.
3467  *
3468  * Errors can be a little larger, but not huge. If we see a
3469  * large apparent length in an error, it means we're really
3470  * talking to a pre-3.0-protocol server; cope. (Before
3471  * version 14, the server also used the old protocol for
3472  * errors that happened before processing the startup packet.)
3473  */
3474  if (beresp == 'R' && (msgLength < 8 || msgLength > 2000))
3475  {
3476  libpq_append_conn_error(conn, "received invalid authentication request");
3477  goto error_return;
3478  }
3479  if (beresp == 'v' && (msgLength < 8 || msgLength > 2000))
3480  {
3481  libpq_append_conn_error(conn, "received invalid protocol negotiation message");
3482  goto error_return;
3483  }
3484 
3485 #define MAX_ERRLEN 30000
3486  if (beresp == 'E' && (msgLength < 8 || msgLength > MAX_ERRLEN))
3487  {
3488  /* Handle error from a pre-3.0 server */
3489  conn->inCursor = conn->inStart + 1; /* reread data */
3491  {
3492  /*
3493  * We may not have authenticated the server yet, so
3494  * don't let the buffer grow forever.
3495  */
3496  avail = conn->inEnd - conn->inCursor;
3497  if (avail > MAX_ERRLEN)
3498  {
3499  libpq_append_conn_error(conn, "received invalid error message");
3500  goto error_return;
3501  }
3502 
3503  /* We'll come back when there is more data */
3504  return PGRES_POLLING_READING;
3505  }
3506  /* OK, we read the message; mark data consumed */
3507  conn->inStart = conn->inCursor;
3508 
3509  /*
3510  * Before 7.2, the postmaster didn't always end its
3511  * messages with a newline, so add one if needed to
3512  * conform to libpq conventions.
3513  */
3514  if (conn->errorMessage.len == 0 ||
3515  conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
3516  {
3518  }
3519 
3520  goto error_return;
3521  }
3522 #undef MAX_ERRLEN
3523 
3524  /*
3525  * Can't process if message body isn't all here yet.
3526  *
3527  * After this check passes, any further EOF during parsing
3528  * implies that the server sent a bad/truncated message.
3529  * Reading more bytes won't help in that case, so don't return
3530  * PGRES_POLLING_READING after this point.
3531  */
3532  msgLength -= 4;
3533  avail = conn->inEnd - conn->inCursor;
3534  if (avail < msgLength)
3535  {
3536  /*
3537  * Before returning, try to enlarge the input buffer if
3538  * needed to hold the whole message; see notes in
3539  * pqParseInput3.
3540  */
3541  if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
3542  conn))
3543  goto error_return;
3544  /* We'll come back when there is more data */
3545  return PGRES_POLLING_READING;
3546  }
3547 
3548  /* Handle errors. */