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 <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 <netdb.h>
#include <netinet/in.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 DefaultGSSMode   "disable"
 

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 *conninfo, 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 126 of file fe-connect.c.

◆ DefaultGSSMode

#define DefaultGSSMode   "disable"

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

◆ DefaultHost

#define DefaultHost   "localhost"

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

◆ DefaultOption

#define DefaultOption   ""

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

◆ DefaultSSLMode

#define DefaultSSLMode   "disable"

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

◆ DefaultTargetSessionAttrs

#define DefaultTargetSessionAttrs   "any"

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

◆ ERRCODE_APPNAME_UNKNOWN

#define ERRCODE_APPNAME_UNKNOWN   "42704"

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

◆ ERRCODE_CANNOT_CONNECT_NOW

#define ERRCODE_CANNOT_CONNECT_NOW   "57P03"

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

◆ ERRCODE_INVALID_PASSWORD

#define ERRCODE_INVALID_PASSWORD   "28P01"

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

◆ PGPASSFILE

#define PGPASSFILE   ".pgpass"

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

Typedef Documentation

◆ internalPQconninfoOption

Function Documentation

◆ closePGconn()

static void closePGconn ( PGconn conn)
static

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

4223 {
4224  /*
4225  * If possible, send Terminate message to close the connection politely.
4226  */
4228 
4229  /*
4230  * Must reset the blocking status so a possible reconnect will work.
4231  *
4232  * Don't call PQsetnonblocking() because it will fail if it's unable to
4233  * flush the connection.
4234  */
4235  conn->nonblocking = false;
4236 
4237  /*
4238  * Close the connection, reset all transient state, flush I/O buffers.
4239  * Note that this includes clearing conn's error state; we're no longer
4240  * interested in any failures associated with the old connection, and we
4241  * want a clean slate for any new connection attempt.
4242  */
4243  pqDropConnection(conn, true);
4244  conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just absent */
4248  pqClearAsyncResult(conn); /* deallocate result */
4251 
4252  /* Reset all state obtained from server, too */
4254 }
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:449
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:4195
static void release_conn_addrinfo(PGconn *conn)
Definition: fe-connect.c:4180
static void pqDropServerData(PGconn *conn)
Definition: fe-connect.c:563
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:778
@ 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:219
#define pqClearConnErrorState(conn)
Definition: libpq-int.h:851
PGconn * conn
Definition: streamutil.c:54
PGTransactionStatusType xactStatus
Definition: libpq-int.h:412
bool nonblocking
Definition: libpq-int.h:415
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:411
PGpipelineStatus pipelineStatus
Definition: libpq-int.h:417
ConnStatusType status
Definition: libpq-int.h:410

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 2126 of file fe-connect.c.

2127 {
2129  time_t finish_time = ((time_t) -1);
2130  int timeout = 0;
2131  int last_whichhost = -2; /* certainly different from whichhost */
2132  struct addrinfo *last_addr_cur = NULL;
2133 
2134  if (conn == NULL || conn->status == CONNECTION_BAD)
2135  return 0;
2136 
2137  /*
2138  * Set up a time limit, if connect_timeout isn't zero.
2139  */
2140  if (conn->connect_timeout != NULL)
2141  {
2142  if (!parse_int_param(conn->connect_timeout, &timeout, conn,
2143  "connect_timeout"))
2144  {
2145  /* mark the connection as bad to report the parsing failure */
2147  return 0;
2148  }
2149 
2150  if (timeout > 0)
2151  {
2152  /*
2153  * Rounding could cause connection to fail unexpectedly quickly;
2154  * to prevent possibly waiting hardly-at-all, insist on at least
2155  * two seconds.
2156  */
2157  if (timeout < 2)
2158  timeout = 2;
2159  }
2160  else /* negative means 0 */
2161  timeout = 0;
2162  }
2163 
2164  for (;;)
2165  {
2166  int ret = 0;
2167 
2168  /*
2169  * (Re)start the connect_timeout timer if it's active and we are
2170  * considering a different host than we were last time through. If
2171  * we've already succeeded, though, needn't recalculate.
2172  */
2173  if (flag != PGRES_POLLING_OK &&
2174  timeout > 0 &&
2175  (conn->whichhost != last_whichhost ||
2176  conn->addr_cur != last_addr_cur))
2177  {
2178  finish_time = time(NULL) + timeout;
2179  last_whichhost = conn->whichhost;
2180  last_addr_cur = conn->addr_cur;
2181  }
2182 
2183  /*
2184  * Wait, if necessary. Note that the initial state (just after
2185  * PQconnectStart) is to wait for the socket to select for writing.
2186  */
2187  switch (flag)
2188  {
2189  case PGRES_POLLING_OK:
2190  return 1; /* success! */
2191 
2192  case PGRES_POLLING_READING:
2193  ret = pqWaitTimed(1, 0, conn, finish_time);
2194  if (ret == -1)
2195  {
2196  /* hard failure, eg select() problem, aborts everything */
2198  return 0;
2199  }
2200  break;
2201 
2202  case PGRES_POLLING_WRITING:
2203  ret = pqWaitTimed(0, 1, conn, finish_time);
2204  if (ret == -1)
2205  {
2206  /* hard failure, eg select() problem, aborts everything */
2208  return 0;
2209  }
2210  break;
2211 
2212  default:
2213  /* Just in case we failed to set it in PQconnectPoll */
2215  return 0;
2216  }
2217 
2218  if (ret == 1) /* connect_timeout elapsed */
2219  {
2220  /*
2221  * Give up on current server/address, try the next one.
2222  */
2223  conn->try_next_addr = true;
2225  }
2226 
2227  /*
2228  * Now try to advance the state machine.
2229  */
2230  flag = PQconnectPoll(conn);
2231  }
2232 }
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:2262
static bool parse_int_param(const char *value, int *result, PGconn *conn, const char *context)
Definition: fe-connect.c:1800
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
Definition: fe-misc.c:996
@ 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:462
char * connect_timeout
Definition: libpq-int.h:360
bool try_next_addr
Definition: libpq-int.h:459
int whichhost
Definition: libpq-int.h:426
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 2056 of file fe-connect.c.

2057 {
2058  if (!conn)
2059  return 0;
2060 
2061  if (!conn->options_valid)
2062  goto connect_errReturn;
2063 
2064  /*
2065  * Check for bad linking to backend-internal versions of src/common
2066  * functions (see comments in link-canary.c for the reason we need this).
2067  * Nobody but developers should see this message, so we don't bother
2068  * translating it.
2069  */
2071  {
2073  "libpq is incorrectly linked to backend functions\n");
2074  goto connect_errReturn;
2075  }
2076 
2077  /* Ensure our buffers are empty */
2078  conn->inStart = conn->inCursor = conn->inEnd = 0;
2079  conn->outCount = 0;
2080 
2081  /*
2082  * Set up to try to connect to the first host. (Setting whichhost = -1 is
2083  * a bit of a cheat, but PQconnectPoll will advance it to 0 before
2084  * anything else looks at it.)
2085  */
2086  conn->whichhost = -1;
2087  conn->try_next_addr = false;
2088  conn->try_next_host = true;
2090 
2091  /* Also reset the target_server_type state if needed */
2094 
2095  /*
2096  * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
2097  * so that it can easily be re-executed if needed again during the
2098  * asynchronous startup process. However, we must run it once here,
2099  * because callers expect a success return from this routine to mean that
2100  * we are in PGRES_POLLING_WRITING connection state.
2101  */
2103  return 1;
2104 
2105 connect_errReturn:
2106 
2107  /*
2108  * If we managed to open a socket, close it immediately rather than
2109  * waiting till PQfinish. (The application cannot have gotten the socket
2110  * from PQsocket yet, so this doesn't risk breaking anything.)
2111  */
2112  pqDropConnection(conn, true);
2114  return 0;
2115 }
@ SERVER_TYPE_PREFER_STANDBY_PASS2
Definition: libpq-int.h:240
@ SERVER_TYPE_PREFER_STANDBY
Definition: libpq-int.h:239
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
bool try_next_host
Definition: libpq-int.h:460
int inCursor
Definition: libpq-int.h:482
int inEnd
Definition: libpq-int.h:483
int inStart
Definition: libpq-int.h:481
PQExpBufferData errorMessage
Definition: libpq-int.h:585
bool options_valid
Definition: libpq-int.h:414
PGTargetServerType target_server_type
Definition: libpq-int.h:458
int outCount
Definition: libpq-int.h:488

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 1757 of file fe-connect.c.

1758 {
1759  char sebuf[PG_STRERROR_R_BUFLEN];
1760 
1762  "%s\n",
1763  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)));
1764 
1765 #ifdef HAVE_UNIX_SOCKETS
1766  if (conn->raddr.addr.ss_family == AF_UNIX)
1768  libpq_gettext("\tIs the server running locally and accepting connections on that socket?\n"));
1769  else
1770 #endif
1772  libpq_gettext("\tIs the server running on that host and accepting TCP/IP connections?\n"));
1773 }
#define libpq_gettext(x)
Definition: libpq-int.h:878
#define SOCK_STRERROR
Definition: libpq-int.h:892
#define PG_STRERROR_R_BUFLEN
Definition: port.h:243
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
struct sockaddr_storage addr
Definition: pqcomm.h:64
SockAddr raddr
Definition: libpq-int.h:447

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

Referenced by PQconnectPoll().

◆ connectNoDelay()

static int connectNoDelay ( PGconn conn)
static

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

1638 {
1639 #ifdef TCP_NODELAY
1640  int on = 1;
1641 
1642  if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
1643  (char *) &on,
1644  sizeof(on)) < 0)
1645  {
1646  char sebuf[PG_STRERROR_R_BUFLEN];
1647 
1649  libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
1650  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1651  return 0;
1652  }
1653 #endif
1654 
1655  return 1;
1656 }
#define SOCK_ERRNO
Definition: libpq-int.h:891
pgsocket sock
Definition: libpq-int.h:444

References appendPQExpBuffer(), conn, pg_conn::errorMessage, libpq_gettext, 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 929 of file fe-connect.c.

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

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 1027 of file fe-connect.c.

1028 {
1029  int i;
1030 
1031  /*
1032  * Allocate memory for details about each host to which we might possibly
1033  * try to connect. For that, count the number of elements in the hostaddr
1034  * or host options. If neither is given, assume one host.
1035  */
1036  conn->whichhost = 0;
1037  if (conn->pghostaddr && conn->pghostaddr[0] != '\0')
1039  else if (conn->pghost && conn->pghost[0] != '\0')
1041  else
1042  conn->nconnhost = 1;
1043  conn->connhost = (pg_conn_host *)
1044  calloc(conn->nconnhost, sizeof(pg_conn_host));
1045  if (conn->connhost == NULL)
1046  goto oom_error;
1047 
1048  /*
1049  * We now have one pg_conn_host structure per possible host. Fill in the
1050  * host and hostaddr fields for each, by splitting the parameter strings.
1051  */
1052  if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
1053  {
1054  char *s = conn->pghostaddr;
1055  bool more = true;
1056 
1057  for (i = 0; i < conn->nconnhost && more; i++)
1058  {
1060  if (conn->connhost[i].hostaddr == NULL)
1061  goto oom_error;
1062  }
1063 
1064  /*
1065  * If hostaddr was given, the array was allocated according to the
1066  * number of elements in the hostaddr list, so it really should be the
1067  * right size.
1068  */
1069  Assert(!more);
1070  Assert(i == conn->nconnhost);
1071  }
1072 
1073  if (conn->pghost != NULL && conn->pghost[0] != '\0')
1074  {
1075  char *s = conn->pghost;
1076  bool more = true;
1077 
1078  for (i = 0; i < conn->nconnhost && more; i++)
1079  {
1081  if (conn->connhost[i].host == NULL)
1082  goto oom_error;
1083  }
1084 
1085  /* Check for wrong number of host items. */
1086  if (more || i != conn->nconnhost)
1087  {
1090  libpq_gettext("could not match %d host names to %d hostaddr values\n"),
1092  return false;
1093  }
1094  }
1095 
1096  /*
1097  * Now, for each host slot, identify the type of address spec, and fill in
1098  * the default address if nothing was given.
1099  */
1100  for (i = 0; i < conn->nconnhost; i++)
1101  {
1102  pg_conn_host *ch = &conn->connhost[i];
1103 
1104  if (ch->hostaddr != NULL && ch->hostaddr[0] != '\0')
1105  ch->type = CHT_HOST_ADDRESS;
1106  else if (ch->host != NULL && ch->host[0] != '\0')
1107  {
1108  ch->type = CHT_HOST_NAME;
1109 #ifdef HAVE_UNIX_SOCKETS
1110  if (is_unixsock_path(ch->host))
1111  ch->type = CHT_UNIX_SOCKET;
1112 #endif
1113  }
1114  else
1115  {
1116  if (ch->host)
1117  free(ch->host);
1118 
1119  /*
1120  * This bit selects the default host location. If you change
1121  * this, see also pg_regress.
1122  */
1123 #ifdef HAVE_UNIX_SOCKETS
1124  if (DEFAULT_PGSOCKET_DIR[0])
1125  {
1126  ch->host = strdup(DEFAULT_PGSOCKET_DIR);
1127  ch->type = CHT_UNIX_SOCKET;
1128  }
1129  else
1130 #endif
1131  {
1132  ch->host = strdup(DefaultHost);
1133  ch->type = CHT_HOST_NAME;
1134  }
1135  if (ch->host == NULL)
1136  goto oom_error;
1137  }
1138  }
1139 
1140  /*
1141  * Next, work out the port number corresponding to each host name.
1142  *
1143  * Note: unlike the above for host names, this could leave the port fields
1144  * as null or empty strings. We will substitute DEF_PGPORT whenever we
1145  * read such a port field.
1146  */
1147  if (conn->pgport != NULL && conn->pgport[0] != '\0')
1148  {
1149  char *s = conn->pgport;
1150  bool more = true;
1151 
1152  for (i = 0; i < conn->nconnhost && more; i++)
1153  {
1155  if (conn->connhost[i].port == NULL)
1156  goto oom_error;
1157  }
1158 
1159  /*
1160  * If exactly one port was given, use it for every host. Otherwise,
1161  * there must be exactly as many ports as there were hosts.
1162  */
1163  if (i == 1 && !more)
1164  {
1165  for (i = 1; i < conn->nconnhost; i++)
1166  {
1167  conn->connhost[i].port = strdup(conn->connhost[0].port);
1168  if (conn->connhost[i].port == NULL)
1169  goto oom_error;
1170  }
1171  }
1172  else if (more || i != conn->nconnhost)
1173  {
1176  libpq_gettext("could not match %d port numbers to %d hosts\n"),
1178  return false;
1179  }
1180  }
1181 
1182  /*
1183  * If user name was not given, fetch it. (Most likely, the fetch will
1184  * fail, since the only way we get here is if pg_fe_getauthname() failed
1185  * during conninfo_add_defaults(). But now we want an error message.)
1186  */
1187  if (conn->pguser == NULL || conn->pguser[0] == '\0')
1188  {
1189  if (conn->pguser)
1190  free(conn->pguser);
1192  if (!conn->pguser)
1193  {
1195  return false;
1196  }
1197  }
1198 
1199  /*
1200  * If database name was not given, default it to equal user name
1201  */
1202  if (conn->dbName == NULL || conn->dbName[0] == '\0')
1203  {
1204  if (conn->dbName)
1205  free(conn->dbName);
1206  conn->dbName = strdup(conn->pguser);
1207  if (!conn->dbName)
1208  goto oom_error;
1209  }
1210 
1211  /*
1212  * If password was not given, try to look it up in password file. Note
1213  * that the result might be different for each host/port pair.
1214  */
1215  if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
1216  {
1217  /* If password file wasn't specified, use ~/PGPASSFILE */
1218  if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
1219  {
1220  char homedir[MAXPGPATH];
1221 
1222  if (pqGetHomeDirectory(homedir, sizeof(homedir)))
1223  {
1224  if (conn->pgpassfile)
1225  free(conn->pgpassfile);
1227  if (!conn->pgpassfile)
1228  goto oom_error;
1229  snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s",
1230  homedir, PGPASSFILE);
1231  }
1232  }
1233 
1234  if (conn->pgpassfile != NULL && conn->pgpassfile[0] != '\0')
1235  {
1236  for (i = 0; i < conn->nconnhost; i++)
1237  {
1238  /*
1239  * Try to get a password for this host from file. We use host
1240  * for the hostname search key if given, else hostaddr (at
1241  * least one of them is guaranteed nonempty by now).
1242  */
1243  const char *pwhost = conn->connhost[i].host;
1244 
1245  if (pwhost == NULL || pwhost[0] == '\0')
1246  pwhost = conn->connhost[i].hostaddr;
1247 
1248  conn->connhost[i].password =
1249  passwordFromFile(pwhost,
1250  conn->connhost[i].port,
1251  conn->dbName,
1252  conn->pguser,
1253  conn->pgpassfile);
1254  }
1255  }
1256  }
1257 
1258  /*
1259  * validate channel_binding option
1260  */
1261  if (conn->channel_binding)
1262  {
1263  if (strcmp(conn->channel_binding, "disable") != 0
1264  && strcmp(conn->channel_binding, "prefer") != 0
1265  && strcmp(conn->channel_binding, "require") != 0)
1266  {
1269  libpq_gettext("invalid %s value: \"%s\"\n"),
1270  "channel_binding", conn->channel_binding);
1271  return false;
1272  }
1273  }
1274  else
1275  {
1277  if (!conn->channel_binding)
1278  goto oom_error;
1279  }
1280 
1281  /*
1282  * validate sslmode option
1283  */
1284  if (conn->sslmode)
1285  {
1286  if (strcmp(conn->sslmode, "disable") != 0
1287  && strcmp(conn->sslmode, "allow") != 0
1288  && strcmp(conn->sslmode, "prefer") != 0
1289  && strcmp(conn->sslmode, "require") != 0
1290  && strcmp(conn->sslmode, "verify-ca") != 0
1291  && strcmp(conn->sslmode, "verify-full") != 0)
1292  {
1295  libpq_gettext("invalid %s value: \"%s\"\n"),
1296  "sslmode", conn->sslmode);
1297  return false;
1298  }
1299 
1300 #ifndef USE_SSL
1301  switch (conn->sslmode[0])
1302  {
1303  case 'a': /* "allow" */
1304  case 'p': /* "prefer" */
1305 
1306  /*
1307  * warn user that an SSL connection will never be negotiated
1308  * since SSL was not compiled in?
1309  */
1310  break;
1311 
1312  case 'r': /* "require" */
1313  case 'v': /* "verify-ca" or "verify-full" */
1316  libpq_gettext("sslmode value \"%s\" invalid when SSL support is not compiled in\n"),
1317  conn->sslmode);
1318  return false;
1319  }
1320 #endif
1321  }
1322  else
1323  {
1324  conn->sslmode = strdup(DefaultSSLMode);
1325  if (!conn->sslmode)
1326  goto oom_error;
1327  }
1328 
1329  /*
1330  * Validate TLS protocol versions for ssl_min_protocol_version and
1331  * ssl_max_protocol_version.
1332  */
1334  {
1337  libpq_gettext("invalid %s value: \"%s\"\n"),
1338  "ssl_min_protocol_version",
1340  return false;
1341  }
1343  {
1346  libpq_gettext("invalid %s value: \"%s\"\n"),
1347  "ssl_max_protocol_version",
1349  return false;
1350  }
1351 
1352  /*
1353  * Check if the range of SSL protocols defined is correct. This is done
1354  * at this early step because this is independent of the SSL
1355  * implementation used, and this avoids unnecessary cycles with an
1356  * already-built SSL context when the connection is being established, as
1357  * it would be doomed anyway.
1358  */
1361  {
1364  libpq_gettext("invalid SSL protocol version range\n"));
1365  return false;
1366  }
1367 
1368  /*
1369  * validate gssencmode option
1370  */
1371  if (conn->gssencmode)
1372  {
1373  if (strcmp(conn->gssencmode, "disable") != 0 &&
1374  strcmp(conn->gssencmode, "prefer") != 0 &&
1375  strcmp(conn->gssencmode, "require") != 0)
1376  {
1379  libpq_gettext("invalid %s value: \"%s\"\n"),
1380  "gssencmode",
1381  conn->gssencmode);
1382  return false;
1383  }
1384 #ifndef ENABLE_GSS
1385  if (strcmp(conn->gssencmode, "require") == 0)
1386  {
1389  libpq_gettext("gssencmode value \"%s\" invalid when GSSAPI support is not compiled in\n"),
1390  conn->gssencmode);
1391  return false;
1392  }
1393 #endif
1394  }
1395  else
1396  {
1397  conn->gssencmode = strdup(DefaultGSSMode);
1398  if (!conn->gssencmode)
1399  goto oom_error;
1400  }
1401 
1402  /*
1403  * validate target_session_attrs option, and set target_server_type
1404  */
1406  {
1407  if (strcmp(conn->target_session_attrs, "any") == 0)
1409  else if (strcmp(conn->target_session_attrs, "read-write") == 0)
1411  else if (strcmp(conn->target_session_attrs, "read-only") == 0)
1413  else if (strcmp(conn->target_session_attrs, "primary") == 0)
1415  else if (strcmp(conn->target_session_attrs, "standby") == 0)
1417  else if (strcmp(conn->target_session_attrs, "prefer-standby") == 0)
1419  else
1420  {
1423  libpq_gettext("invalid %s value: \"%s\"\n"),
1424  "target_session_attrs",
1426  return false;
1427  }
1428  }
1429  else
1431 
1432  /*
1433  * Resolve special "auto" client_encoding from the locale
1434  */
1436  strcmp(conn->client_encoding_initial, "auto") == 0)
1437  {
1441  goto oom_error;
1442  }
1443 
1444  /*
1445  * Only if we get this far is it appropriate to try to connect. (We need a
1446  * state flag, rather than just the boolean result of this function, in
1447  * case someone tries to PQreset() the PGconn.)
1448  */
1449  conn->options_valid = true;
1450 
1451  return true;
1452 
1453 oom_error:
1456  libpq_gettext("out of memory\n"));
1457  return false;
1458 }
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:1168
#define DefaultHost
Definition: fe-connect.c:121
static char * passwordFromFile(const char *hostname, const char *port, const char *dbname, const char *username, const char *pgpassfile)
Definition: fe-connect.c:7163
static bool sslVerifyProtocolRange(const char *min, const char *max)
Definition: fe-connect.c:7353
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:7406
#define DefaultSSLMode
Definition: fe-connect.c:132
#define DefaultGSSMode
Definition: fe-connect.c:138
static int count_comma_separated_elems(const char *input)
Definition: fe-connect.c:966
#define DefaultChannelBinding
Definition: fe-connect.c:126
static bool sslVerifyProtocolVersion(const char *version)
Definition: fe-connect.c:7327
static char * parse_comma_separated_list(char **startptr, bool *more)
Definition: fe-connect.c:990
#define PGPASSFILE
Definition: fe-connect.c:80
#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:301
@ CHT_HOST_ADDRESS
Definition: libpq-int.h:300
@ CHT_HOST_NAME
Definition: libpq-int.h:299
@ SERVER_TYPE_STANDBY
Definition: libpq-int.h:238
@ SERVER_TYPE_PRIMARY
Definition: libpq-int.h:237
@ SERVER_TYPE_ANY
Definition: libpq-int.h:234
@ SERVER_TYPE_READ_WRITE
Definition: libpq-int.h:235
@ SERVER_TYPE_READ_ONLY
Definition: libpq-int.h:236
Assert(fmt[strlen(fmt) - 1] !='\n')
#define MAXPGPATH
#define DEFAULT_PGSOCKET_DIR
#define snprintf
Definition: port.h:225
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:451
static bool is_unixsock_path(const char *path)
Definition: pqcomm.h:93
char * host
Definition: libpq-int.h:335
char * password
Definition: libpq-int.h:338
char * port
Definition: libpq-int.h:337
char * hostaddr
Definition: libpq-int.h:336
pg_conn_host_type type
Definition: libpq-int.h:334
int nconnhost
Definition: libpq-int.h:425
char * channel_binding
Definition: libpq-int.h:371
char * pghost
Definition: libpq-int.h:350
char * ssl_max_protocol_version
Definition: libpq-int.h:394
char * pgpass
Definition: libpq-int.h:369
char * dbName
Definition: libpq-int.h:366
char * target_session_attrs
Definition: libpq-int.h:395
char * pguser
Definition: libpq-int.h:368
char * client_encoding_initial
Definition: libpq-int.h:362
char * sslmode
Definition: libpq-int.h:379
char * ssl_min_protocol_version
Definition: libpq-int.h:393
char * gssencmode
Definition: libpq-int.h:389
char * pghostaddr
Definition: libpq-int.h:354
char * pgpassfile
Definition: libpq-int.h:370
char * pgport
Definition: libpq-int.h:358
pg_conn_host * connhost
Definition: libpq-int.h:427

References appendPQExpBuffer(), appendPQExpBufferStr(), Assert(), 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, DefaultSSLMode, pg_conn::errorMessage, free, pg_conn::gssencmode, pg_conn_host::host, pg_conn_host::hostaddr, i, is_unixsock_path(), libpq_gettext, 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(), 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::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 5959 of file fe-connect.c.

5960 {
5962  char *tmp;
5963 
5964  /*
5965  * If there's a service spec, use it to obtain any not-explicitly-given
5966  * parameters. Ignore error if no error message buffer is passed because
5967  * there is no way to pass back the failure message.
5968  */
5969  if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
5970  return false;
5971 
5972  /*
5973  * Get the fallback resources for parameters not specified in the conninfo
5974  * string nor the service.
5975  */
5976  for (option = options; option->keyword != NULL; option++)
5977  {
5978  if (option->val != NULL)
5979  continue; /* Value was in conninfo or service */
5980 
5981  /*
5982  * Try to get the environment variable fallback
5983  */
5984  if (option->envvar != NULL)
5985  {
5986  if ((tmp = getenv(option->envvar)) != NULL)
5987  {
5988  option->val = strdup(tmp);
5989  if (!option->val)
5990  {
5991  if (errorMessage)
5992  appendPQExpBufferStr(errorMessage,
5993  libpq_gettext("out of memory\n"));
5994  return false;
5995  }
5996  continue;
5997  }
5998  }
5999 
6000  /*
6001  * Interpret the deprecated PGREQUIRESSL environment variable. Per
6002  * tradition, translate values starting with "1" to sslmode=require,
6003  * and ignore other values. Given both PGREQUIRESSL=1 and PGSSLMODE,
6004  * PGSSLMODE takes precedence; the opposite was true before v9.3.
6005  */
6006  if (strcmp(option->keyword, "sslmode") == 0)
6007  {
6008  const char *requiresslenv = getenv("PGREQUIRESSL");
6009 
6010  if (requiresslenv != NULL && requiresslenv[0] == '1')
6011  {
6012  option->val = strdup("require");
6013  if (!option->val)
6014  {
6015  if (errorMessage)
6016  appendPQExpBufferStr(errorMessage,
6017  libpq_gettext("out of memory\n"));
6018  return false;
6019  }
6020  continue;
6021  }
6022  }
6023 
6024  /*
6025  * No environment variable specified or the variable isn't set - try
6026  * compiled-in default
6027  */
6028  if (option->compiled != NULL)
6029  {
6030  option->val = strdup(option->compiled);
6031  if (!option->val)
6032  {
6033  if (errorMessage)
6034  appendPQExpBufferStr(errorMessage,
6035  libpq_gettext("out of memory\n"));
6036  return false;
6037  }
6038  continue;
6039  }
6040 
6041  /*
6042  * Special handling for "user" option. Note that if pg_fe_getauthname
6043  * fails, we just leave the value as NULL; there's no need for this to
6044  * be an error condition if the caller provides a user name. The only
6045  * reason we do this now at all is so that callers of PQconndefaults
6046  * will see a correct default (barring error, of course).
6047  */
6048  if (strcmp(option->keyword, "user") == 0)
6049  {
6050  option->val = pg_fe_getauthname(NULL);
6051  continue;
6052  }
6053  }
6054 
6055  return true;
6056 }
static int parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5252
int val
Definition: getopt_long.h:21

References appendPQExpBufferStr(), libpq_gettext, 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 5795 of file fe-connect.c.

5798 {
5800  PQconninfoOption *dbname_options = NULL;
5802  int i = 0;
5803 
5804  /*
5805  * If expand_dbname is non-zero, check keyword "dbname" to see if val is
5806  * actually a recognized connection string.
5807  */
5808  while (expand_dbname && keywords[i])
5809  {
5810  const char *pname = keywords[i];
5811  const char *pvalue = values[i];
5812 
5813  /* first find "dbname" if any */
5814  if (strcmp(pname, "dbname") == 0 && pvalue)
5815  {
5816  /*
5817  * If value is a connection string, parse it, but do not use
5818  * defaults here -- those get picked up later. We only want to
5819  * override for those parameters actually passed.
5820  */
5821  if (recognized_connection_string(pvalue))
5822  {
5823  dbname_options = parse_connection_string(pvalue, errorMessage, false);
5824  if (dbname_options == NULL)
5825  return NULL;
5826  }
5827  break;
5828  }
5829  ++i;
5830  }
5831 
5832  /* Make a working copy of PQconninfoOptions */
5833  options = conninfo_init(errorMessage);
5834  if (options == NULL)
5835  {
5836  PQconninfoFree(dbname_options);
5837  return NULL;
5838  }
5839 
5840  /* Parse the keywords/values arrays */
5841  i = 0;
5842  while (keywords[i])
5843  {
5844  const char *pname = keywords[i];
5845  const char *pvalue = values[i];
5846 
5847  if (pvalue != NULL && pvalue[0] != '\0')
5848  {
5849  /* Search for the param record */
5850  for (option = options; option->keyword != NULL; option++)
5851  {
5852  if (strcmp(option->keyword, pname) == 0)
5853  break;
5854  }
5855 
5856  /* Check for invalid connection option */
5857  if (option->keyword == NULL)
5858  {
5859  appendPQExpBuffer(errorMessage,
5860  libpq_gettext("invalid connection option \"%s\"\n"),
5861  pname);
5863  PQconninfoFree(dbname_options);
5864  return NULL;
5865  }
5866 
5867  /*
5868  * If we are on the first dbname parameter, and we have a parsed
5869  * connection string, copy those parameters across, overriding any
5870  * existing previous settings.
5871  */
5872  if (strcmp(pname, "dbname") == 0 && dbname_options)
5873  {
5874  PQconninfoOption *str_option;
5875 
5876  for (str_option = dbname_options; str_option->keyword != NULL; str_option++)
5877  {
5878  if (str_option->val != NULL)
5879  {
5880  int k;
5881 
5882  for (k = 0; options[k].keyword; k++)
5883  {
5884  if (strcmp(options[k].keyword, str_option->keyword) == 0)
5885  {
5886  if (options[k].val)
5887  free(options[k].val);
5888  options[k].val = strdup(str_option->val);
5889  if (!options[k].val)
5890  {
5891  appendPQExpBufferStr(errorMessage,
5892  libpq_gettext("out of memory\n"));
5894  PQconninfoFree(dbname_options);
5895  return NULL;
5896  }
5897  break;
5898  }
5899  }
5900  }
5901  }
5902 
5903  /*
5904  * Forget the parsed connection string, so that any subsequent
5905  * dbname parameters will not be expanded.
5906  */
5907  PQconninfoFree(dbname_options);
5908  dbname_options = NULL;
5909  }
5910  else
5911  {
5912  /*
5913  * Store the value, overriding previous settings
5914  */
5915  if (option->val)
5916  free(option->val);
5917  option->val = strdup(pvalue);
5918  if (!option->val)
5919  {
5920  appendPQExpBufferStr(errorMessage,
5921  libpq_gettext("out of memory\n"));
5923  PQconninfoFree(dbname_options);
5924  return NULL;
5925  }
5926  }
5927  }
5928  ++i;
5929  }
5930  PQconninfoFree(dbname_options);
5931 
5932  /*
5933  * Add in defaults if the caller wants that.
5934  */
5935  if (use_defaults)
5936  {
5937  if (!conninfo_add_defaults(options, errorMessage))
5938  {
5940  return NULL;
5941  }
5942  }
5943 
5944  return options;
5945 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:5523
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5959
static bool recognized_connection_string(const char *connstr)
Definition: fe-connect.c:5606
long val
Definition: informix.c:664
static char ** options

References appendPQExpBuffer(), appendPQExpBufferStr(), conninfo_add_defaults(), conninfo_init(), free, i, _PQconninfoOption::keyword, libpq_gettext, 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 6674 of file fe-connect.c.

6675 {
6677 
6678  for (option = connOptions; option->keyword != NULL; option++)
6679  {
6680  if (strcmp(option->keyword, keyword) == 0)
6681  return option;
6682  }
6683 
6684  return NULL;
6685 }

Referenced by conninfo_getval(), and conninfo_storeval().

◆ conninfo_getval()

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

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

6585 {
6587 
6588  option = conninfo_find(connOptions, keyword);
6589 
6590  return option ? option->val : NULL;
6591 }
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:6674

References conninfo_find(), and option::val.

Referenced by fillPGconn(), and parseServiceInfo().

◆ conninfo_init()

static PQconninfoOption * conninfo_init ( PQExpBuffer  errorMessage)
static

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

5524 {
5526  PQconninfoOption *opt_dest;
5527  const internalPQconninfoOption *cur_opt;
5528 
5529  /*
5530  * Get enough memory for all options in PQconninfoOptions, even if some
5531  * end up being filtered out.
5532  */
5534  if (options == NULL)
5535  {
5536  appendPQExpBufferStr(errorMessage,
5537  libpq_gettext("out of memory\n"));
5538  return NULL;
5539  }
5540  opt_dest = options;
5541 
5542  for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
5543  {
5544  /* Only copy the public part of the struct, not the full internal */
5545  memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
5546  opt_dest++;
5547  }
5548  MemSet(opt_dest, 0, sizeof(PQconninfoOption));
5549 
5550  return options;
5551 }
#define MemSet(start, val, len)
Definition: c.h:1008
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:191

References appendPQExpBufferStr(), _internalPQconninfoOption::keyword, libpq_gettext, 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 5617 of file fe-connect.c.

5619 {
5620  char *pname;
5621  char *pval;
5622  char *buf;
5623  char *cp;
5624  char *cp2;
5626 
5627  /* Make a working copy of PQconninfoOptions */
5628  options = conninfo_init(errorMessage);
5629  if (options == NULL)
5630  return NULL;
5631 
5632  /* Need a modifiable copy of the input string */
5633  if ((buf = strdup(conninfo)) == NULL)
5634  {
5635  appendPQExpBufferStr(errorMessage,
5636  libpq_gettext("out of memory\n"));
5638  return NULL;
5639  }
5640  cp = buf;
5641 
5642  while (*cp)
5643  {
5644  /* Skip blanks before the parameter name */
5645  if (isspace((unsigned char) *cp))
5646  {
5647  cp++;
5648  continue;
5649  }
5650 
5651  /* Get the parameter name */
5652  pname = cp;
5653  while (*cp)
5654  {
5655  if (*cp == '=')
5656  break;
5657  if (isspace((unsigned char) *cp))
5658  {
5659  *cp++ = '\0';
5660  while (*cp)
5661  {
5662  if (!isspace((unsigned char) *cp))
5663  break;
5664  cp++;
5665  }
5666  break;
5667  }
5668  cp++;
5669  }
5670 
5671  /* Check that there is a following '=' */
5672  if (*cp != '=')
5673  {
5674  appendPQExpBuffer(errorMessage,
5675  libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
5676  pname);
5678  free(buf);
5679  return NULL;
5680  }
5681  *cp++ = '\0';
5682 
5683  /* Skip blanks after the '=' */
5684  while (*cp)
5685  {
5686  if (!isspace((unsigned char) *cp))
5687  break;
5688  cp++;
5689  }
5690 
5691  /* Get the parameter value */
5692  pval = cp;
5693 
5694  if (*cp != '\'')
5695  {
5696  cp2 = pval;
5697  while (*cp)
5698  {
5699  if (isspace((unsigned char) *cp))
5700  {
5701  *cp++ = '\0';
5702  break;
5703  }
5704  if (*cp == '\\')
5705  {
5706  cp++;
5707  if (*cp != '\0')
5708  *cp2++ = *cp++;
5709  }
5710  else
5711  *cp2++ = *cp++;
5712  }
5713  *cp2 = '\0';
5714  }
5715  else
5716  {
5717  cp2 = pval;
5718  cp++;
5719  for (;;)
5720  {
5721  if (*cp == '\0')
5722  {
5723  appendPQExpBufferStr(errorMessage,
5724  libpq_gettext("unterminated quoted string in connection info string\n"));
5726  free(buf);
5727  return NULL;
5728  }
5729  if (*cp == '\\')
5730  {
5731  cp++;
5732  if (*cp != '\0')
5733  *cp2++ = *cp++;
5734  continue;
5735  }
5736  if (*cp == '\'')
5737  {
5738  *cp2 = '\0';
5739  cp++;
5740  break;
5741  }
5742  *cp2++ = *cp++;
5743  }
5744  }
5745 
5746  /*
5747  * Now that we have the name and the value, store the record.
5748  */
5749  if (!conninfo_storeval(options, pname, pval, errorMessage, false, false))
5750  {
5752  free(buf);
5753  return NULL;
5754  }
5755  }
5756 
5757  /* Done with the modifiable input string */
5758  free(buf);
5759 
5760  /*
5761  * Add in defaults if the caller wants that.
5762  */
5763  if (use_defaults)
5764  {
5765  if (!conninfo_add_defaults(options, errorMessage))
5766  {
5768  return NULL;
5769  }
5770  }
5771 
5772  return options;
5773 }
static PQconninfoOption * conninfo_storeval(PQconninfoOption *connOptions, const char *keyword, const char *value, PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode)
Definition: fe-connect.c:6609
static char * buf
Definition: pg_test_fsync.c:67

References appendPQExpBuffer(), appendPQExpBufferStr(), buf, conninfo_add_defaults(), conninfo_init(), conninfo_storeval(), free, libpq_gettext, 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 6609 of file fe-connect.c.

6613 {
6615  char *value_copy;
6616 
6617  /*
6618  * For backwards compatibility, requiressl=1 gets translated to
6619  * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
6620  * (which is the default for sslmode).
6621  */
6622  if (strcmp(keyword, "requiressl") == 0)
6623  {
6624  keyword = "sslmode";
6625  if (value[0] == '1')
6626  value = "require";
6627  else
6628  value = "prefer";
6629  }
6630 
6631  option = conninfo_find(connOptions, keyword);
6632  if (option == NULL)
6633  {
6634  if (!ignoreMissing)
6635  appendPQExpBuffer(errorMessage,
6636  libpq_gettext("invalid connection option \"%s\"\n"),
6637  keyword);
6638  return NULL;
6639  }
6640 
6641  if (uri_decode)
6642  {
6643  value_copy = conninfo_uri_decode(value, errorMessage);
6644  if (value_copy == NULL)
6645  /* conninfo_uri_decode already set an error message */
6646  return NULL;
6647  }
6648  else
6649  {
6650  value_copy = strdup(value);
6651  if (value_copy == NULL)
6652  {
6653  appendPQExpBufferStr(errorMessage, libpq_gettext("out of memory\n"));
6654  return NULL;
6655  }
6656  }
6657 
6658  if (option->val)
6659  free(option->val);
6660  option->val = value_copy;
6661 
6662  return option;
6663 }
static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
Definition: fe-connect.c:6494
static struct @151 value

References appendPQExpBuffer(), appendPQExpBufferStr(), conninfo_find(), conninfo_uri_decode(), free, libpq_gettext, 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 6494 of file fe-connect.c.

6495 {
6496  char *buf;
6497  char *p;
6498  const char *q = str;
6499 
6500  buf = malloc(strlen(str) + 1);
6501  if (buf == NULL)
6502  {
6503  appendPQExpBufferStr(errorMessage, libpq_gettext("out of memory\n"));
6504  return NULL;
6505  }
6506  p = buf;
6507 
6508  for (;;)
6509  {
6510  if (*q != '%')
6511  {
6512  /* copy and check for NUL terminator */
6513  if (!(*(p++) = *(q++)))
6514  break;
6515  }
6516  else
6517  {
6518  int hi;
6519  int lo;
6520  int c;
6521 
6522  ++q; /* skip the percent sign itself */
6523 
6524  /*
6525  * Possible EOL will be caught by the first call to
6526  * get_hexdigit(), so we never dereference an invalid q pointer.
6527  */
6528  if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
6529  {
6530  appendPQExpBuffer(errorMessage,
6531  libpq_gettext("invalid percent-encoded token: \"%s\"\n"),
6532  str);
6533  free(buf);
6534  return NULL;
6535  }
6536 
6537  c = (hi << 4) | lo;
6538  if (c == 0)
6539  {
6540  appendPQExpBuffer(errorMessage,
6541  libpq_gettext("forbidden value %%00 in percent-encoded value: \"%s\"\n"),
6542  str);
6543  free(buf);
6544  return NULL;
6545  }
6546  *(p++) = c;
6547  }
6548  }
6549 
6550  return buf;
6551 }
static bool get_hexdigit(char digit, int *value)
Definition: fe-connect.c:6562
char * c

References appendPQExpBuffer(), appendPQExpBufferStr(), buf, free, get_hexdigit(), libpq_gettext, 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 6064 of file fe-connect.c.

6066 {
6068 
6069  /* Make a working copy of PQconninfoOptions */
6070  options = conninfo_init(errorMessage);
6071  if (options == NULL)
6072  return NULL;
6073 
6074  if (!conninfo_uri_parse_options(options, uri, errorMessage))
6075  {
6077  return NULL;
6078  }
6079 
6080  /*
6081  * Add in defaults if the caller wants that.
6082  */
6083  if (use_defaults)
6084  {
6085  if (!conninfo_add_defaults(options, errorMessage))
6086  {
6088  return NULL;
6089  }
6090  }
6091 
6092  return options;
6093 }
static bool conninfo_uri_parse_options(PQconninfoOption *options, const char *uri, PQExpBuffer errorMessage)
Definition: fe-connect.c:6117

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 6117 of file fe-connect.c.

6119 {
6120  int prefix_len;
6121  char *p;
6122  char *buf = NULL;
6123  char *start;
6124  char prevchar = '\0';
6125  char *user = NULL;
6126  char *host = NULL;
6127  bool retval = false;
6128  PQExpBufferData hostbuf;
6129  PQExpBufferData portbuf;
6130 
6131  initPQExpBuffer(&hostbuf);
6132  initPQExpBuffer(&portbuf);
6133  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
6134  {
6135  appendPQExpBufferStr(errorMessage,
6136  libpq_gettext("out of memory\n"));
6137  goto cleanup;
6138  }
6139 
6140  /* need a modifiable copy of the input URI */
6141  buf = strdup(uri);
6142  if (buf == NULL)
6143  {
6144  appendPQExpBufferStr(errorMessage,
6145  libpq_gettext("out of memory\n"));
6146  goto cleanup;
6147  }
6148  start = buf;
6149 
6150  /* Skip the URI prefix */
6151  prefix_len = uri_prefix_length(uri);
6152  if (prefix_len == 0)
6153  {
6154  /* Should never happen */
6155  appendPQExpBuffer(errorMessage,
6156  libpq_gettext("invalid URI propagated to internal parser routine: \"%s\"\n"),
6157  uri);
6158  goto cleanup;
6159  }
6160  start += prefix_len;
6161  p = start;
6162 
6163  /* Look ahead for possible user credentials designator */
6164  while (*p && *p != '@' && *p != '/')
6165  ++p;
6166  if (*p == '@')
6167  {
6168  /*
6169  * Found username/password designator, so URI should be of the form
6170  * "scheme://user[:password]@[netloc]".
6171  */
6172  user = start;
6173 
6174  p = user;
6175  while (*p != ':' && *p != '@')
6176  ++p;
6177 
6178  /* Save last char and cut off at end of user name */
6179  prevchar = *p;
6180  *p = '\0';
6181 
6182  if (*user &&
6183  !conninfo_storeval(options, "user", user,
6184  errorMessage, false, true))
6185  goto cleanup;
6186 
6187  if (prevchar == ':')
6188  {
6189  const char *password = p + 1;
6190 
6191  while (*p != '@')
6192  ++p;
6193  *p = '\0';
6194 
6195  if (*password &&
6196  !conninfo_storeval(options, "password", password,
6197  errorMessage, false, true))
6198  goto cleanup;
6199  }
6200 
6201  /* Advance past end of parsed user name or password token */
6202  ++p;
6203  }
6204  else
6205  {
6206  /*
6207  * No username/password designator found. Reset to start of URI.
6208  */
6209  p = start;
6210  }
6211 
6212  /*
6213  * There may be multiple netloc[:port] pairs, each separated from the next
6214  * by a comma. When we initially enter this loop, "p" has been
6215  * incremented past optional URI credential information at this point and
6216  * now points at the "netloc" part of the URI. On subsequent loop
6217  * iterations, "p" has been incremented past the comma separator and now
6218  * points at the start of the next "netloc".
6219  */
6220  for (;;)
6221  {
6222  /*
6223  * Look for IPv6 address.
6224  */
6225  if (*p == '[')
6226  {
6227  host = ++p;
6228  while (*p && *p != ']')
6229  ++p;
6230  if (!*p)
6231  {
6232  appendPQExpBuffer(errorMessage,
6233  libpq_gettext("end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n"),
6234  uri);
6235  goto cleanup;
6236  }
6237  if (p == host)
6238  {
6239  appendPQExpBuffer(errorMessage,
6240  libpq_gettext("IPv6 host address may not be empty in URI: \"%s\"\n"),
6241  uri);
6242  goto cleanup;
6243  }
6244 
6245  /* Cut off the bracket and advance */
6246  *(p++) = '\0';
6247 
6248  /*
6249  * The address may be followed by a port specifier or a slash or a
6250  * query or a separator comma.
6251  */
6252  if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
6253  {
6254  appendPQExpBuffer(errorMessage,
6255  libpq_gettext("unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n"),
6256  *p, (int) (p - buf + 1), uri);
6257  goto cleanup;
6258  }
6259  }
6260  else
6261  {
6262  /* not an IPv6 address: DNS-named or IPv4 netloc */
6263  host = p;
6264 
6265  /*
6266  * Look for port specifier (colon) or end of host specifier
6267  * (slash) or query (question mark) or host separator (comma).
6268  */
6269  while (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
6270  ++p;
6271  }
6272 
6273  /* Save the hostname terminator before we null it */
6274  prevchar = *p;
6275  *p = '\0';
6276 
6277  appendPQExpBufferStr(&hostbuf, host);
6278 
6279  if (prevchar == ':')
6280  {
6281  const char *port = ++p; /* advance past host terminator */
6282 
6283  while (*p && *p != '/' && *p != '?' && *p != ',')
6284  ++p;
6285 
6286  prevchar = *p;
6287  *p = '\0';
6288 
6289  appendPQExpBufferStr(&portbuf, port);
6290  }
6291 
6292  if (prevchar != ',')
6293  break;
6294  ++p; /* advance past comma separator */
6295  appendPQExpBufferChar(&hostbuf, ',');
6296  appendPQExpBufferChar(&portbuf, ',');
6297  }
6298 
6299  /* Save final values for host and port. */
6300  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
6301  goto cleanup;
6302  if (hostbuf.data[0] &&
6303  !conninfo_storeval(options, "host", hostbuf.data,
6304  errorMessage, false, true))
6305  goto cleanup;
6306  if (portbuf.data[0] &&
6307  !conninfo_storeval(options, "port", portbuf.data,
6308  errorMessage, false, true))
6309  goto cleanup;
6310 
6311  if (prevchar && prevchar != '?')
6312  {
6313  const char *dbname = ++p; /* advance past host terminator */
6314 
6315  /* Look for query parameters */
6316  while (*p && *p != '?')
6317  ++p;
6318 
6319  prevchar = *p;
6320  *p = '\0';
6321 
6322  /*
6323  * Avoid setting dbname to an empty string, as it forces the default
6324  * value (username) and ignores $PGDATABASE, as opposed to not setting
6325  * it at all.
6326  */
6327  if (*dbname &&
6328  !conninfo_storeval(options, "dbname", dbname,
6329  errorMessage, false, true))
6330  goto cleanup;
6331  }
6332 
6333  if (prevchar)
6334  {
6335  ++p; /* advance past terminator */
6336 
6337  if (!conninfo_uri_parse_params(p, options, errorMessage))
6338  goto cleanup;
6339  }
6340 
6341  /* everything parsed okay */
6342  retval = true;
6343 
6344 cleanup:
6345  termPQExpBuffer(&hostbuf);
6346  termPQExpBuffer(&portbuf);
6347  if (buf)
6348  free(buf);
6349  return retval;
6350 }
static void cleanup(void)
Definition: bootstrap.c:697
static int uri_prefix_length(const char *connstr)
Definition: fe-connect.c:5583
static bool conninfo_uri_parse_params(char *params, PQconninfoOption *connOptions, PQExpBuffer errorMessage)
Definition: fe-connect.c:6361
static char * user
Definition: pg_regress.c:95
static int port
Definition: pg_regress.c:92
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
static char * password
Definition: streamutil.c:53
char * dbname
Definition: streamutil.c:51

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), buf, cleanup(), conninfo_storeval(), conninfo_uri_parse_params(), PQExpBufferData::data, dbname, free, initPQExpBuffer(), libpq_gettext, 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 6361 of file fe-connect.c.

6364 {
6365  while (*params)
6366  {
6367  char *keyword = params;
6368  char *value = NULL;
6369  char *p = params;
6370  bool malloced = false;
6371  int oldmsglen;
6372 
6373  /*
6374  * Scan the params string for '=' and '&', marking the end of keyword
6375  * and value respectively.
6376  */
6377  for (;;)
6378  {
6379  if (*p == '=')
6380  {
6381  /* Was there '=' already? */
6382  if (value != NULL)
6383  {
6384  appendPQExpBuffer(errorMessage,
6385  libpq_gettext("extra key/value separator \"=\" in URI query parameter: \"%s\"\n"),
6386  keyword);
6387  return false;
6388  }
6389  /* Cut off keyword, advance to value */
6390  *p++ = '\0';
6391  value = p;
6392  }
6393  else if (*p == '&' || *p == '\0')
6394  {
6395  /*
6396  * If not at the end, cut off value and advance; leave p
6397  * pointing to start of the next parameter, if any.
6398  */
6399  if (*p != '\0')
6400  *p++ = '\0';
6401  /* Was there '=' at all? */
6402  if (value == NULL)
6403  {
6404  appendPQExpBuffer(errorMessage,
6405  libpq_gettext("missing key/value separator \"=\" in URI query parameter: \"%s\"\n"),
6406  keyword);
6407  return false;
6408  }
6409  /* Got keyword and value, go process them. */
6410  break;
6411  }
6412  else
6413  ++p; /* Advance over all other bytes. */
6414  }
6415 
6416  keyword = conninfo_uri_decode(keyword, errorMessage);
6417  if (keyword == NULL)
6418  {
6419  /* conninfo_uri_decode already set an error message */
6420  return false;
6421  }
6422  value = conninfo_uri_decode(value, errorMessage);
6423  if (value == NULL)
6424  {
6425  /* conninfo_uri_decode already set an error message */
6426  free(keyword);
6427  return false;
6428  }
6429  malloced = true;
6430 
6431  /*
6432  * Special keyword handling for improved JDBC compatibility.
6433  */
6434  if (strcmp(keyword, "ssl") == 0 &&
6435  strcmp(value, "true") == 0)
6436  {
6437  free(keyword);
6438  free(value);
6439  malloced = false;
6440 
6441  keyword = "sslmode";
6442  value = "require";
6443  }
6444 
6445  /*
6446  * Store the value if the corresponding option exists; ignore
6447  * otherwise. At this point both keyword and value are not
6448  * URI-encoded.
6449  */
6450  oldmsglen = errorMessage->len;
6451  if (!conninfo_storeval(connOptions, keyword, value,
6452  errorMessage, true, false))
6453  {
6454  /* Insert generic message if conninfo_storeval didn't give one. */
6455  if (errorMessage->len == oldmsglen)
6456  appendPQExpBuffer(errorMessage,
6457  libpq_gettext("invalid URI query parameter: \"%s\"\n"),
6458  keyword);
6459  /* And fail. */
6460  if (malloced)
6461  {
6462  free(keyword);
6463  free(value);
6464  }
6465  return false;
6466  }
6467 
6468  if (malloced)
6469  {
6470  free(keyword);
6471  free(value);
6472  }
6473 
6474  /* Proceed to next key=value pair, if any */
6475  params = p;
6476  }
6477 
6478  return true;
6479 }

References appendPQExpBuffer(), conninfo_storeval(), conninfo_uri_decode(), free, PQExpBufferData::len, libpq_gettext, 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 966 of file fe-connect.c.

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

Referenced by connectOptions2().

◆ default_threadlock()

static void default_threadlock ( int  acquire)
static

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

7439 {
7440 #ifdef ENABLE_THREAD_SAFETY
7441 #ifndef WIN32
7442  static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
7443 #else
7444  static pthread_mutex_t singlethread_lock = NULL;
7445  static long mutex_initlock = 0;
7446 
7447  if (singlethread_lock == NULL)
7448  {
7449  while (InterlockedExchange(&mutex_initlock, 1) == 1)
7450  /* loop, another thread own the lock */ ;
7451  if (singlethread_lock == NULL)
7452  {
7453  if (pthread_mutex_init(&singlethread_lock, NULL))
7454  Assert(false);
7455  }
7456  InterlockedExchange(&mutex_initlock, 0);
7457  }
7458 #endif
7459  if (acquire)
7460  {
7461  if (pthread_mutex_lock(&singlethread_lock))
7462  Assert(false);
7463  }
7464  else
7465  {
7466  if (pthread_mutex_unlock(&singlethread_lock))
7467  Assert(false);
7468  }
7469 #endif
7470 }
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 7114 of file fe-connect.c.

7115 {
7116  (void) arg; /* not used */
7117  /* Note: we expect the supplied string to end with a newline already. */
7118  fprintf(stderr, "%s", message);
7119 }
void * arg
#define fprintf
Definition: port.h:229

References arg, and fprintf.

Referenced by makeEmptyPGconn().

◆ defaultNoticeReceiver()

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

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

7100 {
7101  (void) arg; /* not used */
7102  if (res->noticeHooks.noticeProc != NULL)
7105 }
char * PQresultErrorMessage(const PGresult *res)
Definition: fe-exec.c:3286
void * noticeProcArg
Definition: libpq-int.h:156
PQnoticeProcessor noticeProc
Definition: libpq-int.h:155
PGNoticeHooks noticeHooks
Definition: libpq-int.h:187

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 1699 of file fe-connect.c.

1700 {
1701 #ifdef HAVE_UNIX_SOCKETS
1702  if (conn->raddr.addr.ss_family == AF_UNIX)
1703  {
1704  char service[NI_MAXHOST];
1705 
1707  NULL, 0,
1708  service, sizeof(service),
1709  NI_NUMERICSERV);
1711  libpq_gettext("connection to server on socket \"%s\" failed: "),
1712  service);
1713  }
1714  else
1715 #endif /* HAVE_UNIX_SOCKETS */
1716  {
1717  const char *displayed_host;
1718  const char *displayed_port;
1719 
1720  /* To which host and port were we actually connecting? */
1722  displayed_host = conn->connhost[conn->whichhost].hostaddr;
1723  else
1724  displayed_host = conn->connhost[conn->whichhost].host;
1725  displayed_port = conn->connhost[conn->whichhost].port;
1726  if (displayed_port == NULL || displayed_port[0] == '\0')
1727  displayed_port = DEF_PGPORT_STR;
1728 
1729  /*
1730  * If the user did not supply an IP address using 'hostaddr', and
1731  * 'host' was missing or does not match our lookup, display the
1732  * looked-up IP address.
1733  */
1735  host_addr[0] &&
1736  strcmp(displayed_host, host_addr) != 0)
1738  libpq_gettext("connection to server at \"%s\" (%s), port %s failed: "),
1739  displayed_host, host_addr,
1740  displayed_port);
1741  else
1743  libpq_gettext("connection to server at \"%s\", port %s failed: "),
1744  displayed_host,
1745  displayed_port);
1746  }
1747 }
#define NI_MAXHOST
Definition: getaddrinfo.h:88
#define NI_NUMERICSERV
Definition: getaddrinfo.h:81
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:122
socklen_t salen
Definition: pqcomm.h:65

References SockAddr::addr, appendPQExpBuffer(), CHT_HOST_ADDRESS, conn, pg_conn::connhost, pg_conn::errorMessage, pg_conn_host::host, pg_conn_host::hostaddr, libpq_gettext, NI_MAXHOST, NI_NUMERICSERV, 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 887 of file fe-connect.c.

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

References appendPQExpBufferStr(), conn, conninfo_getval(), pg_conn::errorMessage, free, libpq_gettext, and PQconninfoOptions.

Referenced by connectOptions1(), and PQconnectStartParams().

◆ freePGconn()

static void freePGconn ( PGconn conn)
static

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

4046 {
4047  int i;
4048 
4049  /* let any event procs clean up their state data */
4050  for (i = 0; i < conn->nEvents; i++)
4051  {
4052  PGEventConnDestroy evt;
4053 
4054  evt.conn = conn;
4055  (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
4056  conn->events[i].passThrough);
4057  free(conn->events[i].name);
4058  }
4059 
4060  /* clean up pg_conn_host structures */
4061  if (conn->connhost != NULL)
4062  {
4063  for (i = 0; i < conn->nconnhost; ++i)
4064  {
4065  if (conn->connhost[i].host != NULL)
4066  free(conn->connhost[i].host);
4067  if (conn->connhost[i].hostaddr != NULL)
4069  if (conn->connhost[i].port != NULL)
4070  free(conn->connhost[i].port);
4071  if (conn->connhost[i].password != NULL)
4072  {
4075  }
4076  }
4077  free(conn->connhost);
4078  }
4079 
4082  if (conn->events)
4083  free(conn->events);
4084  if (conn->pghost)
4085  free(conn->pghost);
4086  if (conn->pghostaddr)
4087  free(conn->pghostaddr);
4088  if (conn->pgport)
4089  free(conn->pgport);
4090  if (conn->connect_timeout)
4092  if (conn->pgtcp_user_timeout)
4094  if (conn->pgoptions)
4095  free(conn->pgoptions);
4096  if (conn->appname)
4097  free(conn->appname);
4098  if (conn->fbappname)
4099  free(conn->fbappname);
4100  if (conn->dbName)
4101  free(conn->dbName);
4102  if (conn->replication)
4103  free(conn->replication);
4104  if (conn->pguser)
4105  free(conn->pguser);
4106  if (conn->pgpass)
4107  {
4108  explicit_bzero(conn->pgpass, strlen(conn->pgpass));
4109  free(conn->pgpass);
4110  }
4111  if (conn->pgpassfile)
4112  free(conn->pgpassfile);
4113  if (conn->channel_binding)
4115  if (conn->keepalives)
4116  free(conn->keepalives);
4117  if (conn->keepalives_idle)
4121  if (conn->keepalives_count)
4123  if (conn->sslmode)
4124  free(conn->sslmode);
4125  if (conn->sslcert)
4126  free(conn->sslcert);
4127  if (conn->sslkey)
4128  free(conn->sslkey);
4129  if (conn->sslpassword)
4130  {
4132  free(conn->sslpassword);
4133  }
4134  if (conn->sslrootcert)
4135  free(conn->sslrootcert);
4136  if (conn->sslcrl)
4137  free(conn->sslcrl);
4138  if (conn->sslcrldir)
4139  free(conn->sslcrldir);
4140  if (conn->sslcompression)
4142  if (conn->sslsni)
4143  free(conn->sslsni);
4144  if (conn->requirepeer)
4145  free(conn->requirepeer);
4150  if (conn->gssencmode)
4151  free(conn->gssencmode);
4152  if (conn->krbsrvname)
4153  free(conn->krbsrvname);
4154  if (conn->gsslib)
4155  free(conn->gsslib);
4156  if (conn->connip)
4157  free(conn->connip);
4158  /* Note that conn->Pfdebug is not ours to close or free */
4159  if (conn->write_err_msg)
4161  if (conn->inBuffer)
4162  free(conn->inBuffer);
4163  if (conn->outBuffer)
4164  free(conn->outBuffer);
4165  if (conn->rowBuf)
4166  free(conn->rowBuf);
4171 
4172  free(conn);
4173 }
@ PGEVT_CONNDESTROY
Definition: libpq-events.h:31
void explicit_bzero(void *buf, size_t len)
void * passThrough
Definition: libpq-int.h:163
char * name
Definition: libpq-int.h:162
PGEventProc proc
Definition: libpq-int.h:161
char * replication
Definition: libpq-int.h:367
char * write_err_msg
Definition: libpq-int.h:455
char * sslrootcert
Definition: libpq-int.h:384
PGdataValue * rowBuf
Definition: libpq-int.h:496
char * sslcompression
Definition: libpq-int.h:380
char * inBuffer
Definition: libpq-int.h:479
char * sslcrldir
Definition: libpq-int.h:386
char * pgoptions
Definition: libpq-int.h:363
char * sslcrl
Definition: libpq-int.h:385
char * fbappname
Definition: libpq-int.h:365
char * sslcert
Definition: libpq-int.h:382
char * sslpassword
Definition: libpq-int.h:383
PQExpBufferData workBuffer
Definition: libpq-int.h:589
char * keepalives_idle
Definition: libpq-int.h:374
char * connip
Definition: libpq-int.h:428
char * keepalives
Definition: libpq-int.h:373
char * keepalives_interval
Definition: libpq-int.h:375
char * appname
Definition: libpq-int.h:364
char * pgtcp_user_timeout
Definition: libpq-int.h:361
int nEvents
Definition: libpq-int.h:406
char * sslkey
Definition: libpq-int.h:381
char * krbsrvname
Definition: libpq-int.h:390
char * gsslib
Definition: libpq-int.h:391
char * keepalives_count
Definition: libpq-int.h:377
char * requirepeer
Definition: libpq-int.h:388
char * sslsni
Definition: libpq-int.h:387
PGEvent * events
Definition: libpq-int.h:405
char * outBuffer
Definition: libpq-int.h:486

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::requirepeer, pg_conn::rowBuf, pg_conn::ssl_max_protocol_version, pg_conn::ssl_min_protocol_version, pg_conn::sslcert, 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 6562 of file fe-connect.c.

6563 {
6564  if ('0' <= digit && digit <= '9')
6565  *value = digit - '0';
6566  else if ('A' <= digit && digit <= 'F')
6567  *value = digit - 'A' + 10;
6568  else if ('a' <= digit && digit <= 'f')
6569  *value = digit - 'a' + 10;
6570  else
6571  return false;
6572 
6573  return true;
6574 }

References value.

Referenced by conninfo_uri_decode().

◆ getHostaddr()

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

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

1665 {
1666  struct sockaddr_storage *addr = &conn->raddr.addr;
1667 
1668  if (addr->ss_family == AF_INET)
1669  {
1670  if (pg_inet_net_ntop(AF_INET,
1671  &((struct sockaddr_in *) addr)->sin_addr.s_addr,
1672  32,
1673  host_addr, host_addr_len) == NULL)
1674  host_addr[0] = '\0';
1675  }
1676 #ifdef HAVE_IPV6
1677  else if (addr->ss_family == AF_INET6)
1678  {
1679  if (pg_inet_net_ntop(AF_INET6,
1680  &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
1681  128,
1682  host_addr, host_addr_len) == NULL)
1683  host_addr[0] = '\0';
1684  }
1685 #endif
1686  else
1687  host_addr[0] = '\0';
1688 }
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 3883 of file fe-connect.c.

3884 {
3885  /* Say "no attempt" if we never got to PQconnectPoll */
3886  if (!conn || !conn->options_valid)
3887  return PQPING_NO_ATTEMPT;
3888 
3889  /* Attempt to complete the connection */
3890  if (conn->status != CONNECTION_BAD)
3891  (void) connectDBComplete(conn);
3892 
3893  /* Definitely OK if we succeeded */
3894  if (conn->status != CONNECTION_BAD)
3895  return PQPING_OK;
3896 
3897  /*
3898  * Here begins the interesting part of "ping": determine the cause of the
3899  * failure in sufficient detail to decide what to return. We do not want
3900  * to report that the server is not up just because we didn't have a valid
3901  * password, for example. In fact, any sort of authentication request
3902  * implies the server is up. (We need this check since the libpq side of
3903  * things might have pulled the plug on the connection before getting an
3904  * error as such from the postmaster.)
3905  */
3906  if (conn->auth_req_received)
3907  return PQPING_OK;
3908 
3909  /*
3910  * If we failed to get any ERROR response from the postmaster, report
3911  * PQPING_NO_RESPONSE. This result could be somewhat misleading for a
3912  * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
3913  * out of support. Another corner case where the server could return a
3914  * failure without a SQLSTATE is fork failure, but PQPING_NO_RESPONSE
3915  * isn't totally unreasonable for that anyway. We expect that every other
3916  * failure case in a modern server will produce a report with a SQLSTATE.
3917  *
3918  * NOTE: whenever we get around to making libpq generate SQLSTATEs for
3919  * client-side errors, we should either not store those into
3920  * last_sqlstate, or add an extra flag so we can tell client-side errors
3921  * apart from server-side ones.
3922  */
3923  if (strlen(conn->last_sqlstate) != 5)
3924  return PQPING_NO_RESPONSE;
3925 
3926  /*
3927  * Report PQPING_REJECT if server says it's not accepting connections.
3928  */
3929  if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
3930  return PQPING_REJECT;
3931 
3932  /*
3933  * Any other SQLSTATE can be taken to indicate that the server is up.
3934  * Presumably it didn't like our username, password, or database name; or
3935  * perhaps it had some transient failure, but that should not be taken as
3936  * meaning "it's down".
3937  */
3938  return PQPING_OK;
3939 }
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:2126
#define ERRCODE_CANNOT_CONNECT_NOW
Definition: fe-connect.c:96
@ 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:450
char last_sqlstate[6]
Definition: libpq-int.h:413

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 3947 of file fe-connect.c.

3948 {
3949  PGconn *conn;
3950 
3951 #ifdef WIN32
3952 
3953  /*
3954  * Make sure socket support is up and running in this process.
3955  *
3956  * Note: the Windows documentation says that we should eventually do a
3957  * matching WSACleanup() call, but experience suggests that that is at
3958  * least as likely to cause problems as fix them. So we don't.
3959  */
3960  static bool wsastartup_done = false;
3961 
3962  if (!wsastartup_done)
3963  {
3964  WSADATA wsaData;
3965 
3966  if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
3967  return NULL;
3968  wsastartup_done = true;
3969  }
3970 
3971  /* Forget any earlier error */
3972  WSASetLastError(0);
3973 #endif /* WIN32 */
3974 
3975  conn = (PGconn *) malloc(sizeof(PGconn));
3976  if (conn == NULL)
3977  return conn;
3978 
3979  /* Zero all pointers and booleans */
3980  MemSet(conn, 0, sizeof(PGconn));
3981 
3982  /* install default notice hooks */
3985 
3990  conn->options_valid = false;
3991  conn->nonblocking = false;
3993  conn->std_strings = false; /* unless server says differently */
3999  conn->Pfdebug = NULL;
4000 
4001  /*
4002  * We try to send at least 8K at a time, which is the usual size of pipe
4003  * buffers on Unix systems. That way, when we are sending a large amount
4004  * of data, we avoid incurring extra kernel context swaps for partial
4005  * bufferloads. The output buffer is initially made 16K in size, and we
4006  * try to dump it after accumulating 8K.
4007  *
4008  * With the same goal of minimizing context swaps, the input buffer will
4009  * be enlarged anytime it has less than 8K free, so we initially allocate
4010  * twice that.
4011  */
4012  conn->inBufSize = 16 * 1024;
4013  conn->inBuffer = (char *) malloc(conn->inBufSize);
4014  conn->outBufSize = 16 * 1024;
4015  conn->outBuffer = (char *) malloc(conn->outBufSize);
4016  conn->rowBufLen = 32;
4017  conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
4020 
4021  if (conn->inBuffer == NULL ||
4022  conn->outBuffer == NULL ||
4023  conn->rowBuf == NULL ||
4026  {
4027  /* out of memory already :-( */
4028  freePGconn(conn);
4029  conn = NULL;
4030  }
4031 
4032  return conn;
4033 }
static void defaultNoticeReceiver(void *arg, const PGresult *res)
Definition: fe-connect.c:7099
static void defaultNoticeProcessor(void *arg, const char *message)
Definition: fe-connect.c:7114
static void freePGconn(PGconn *conn)
Definition: fe-connect.c:4045
@ PQSHOW_CONTEXT_ERRORS
Definition: libpq-fe.h:136
@ PQERRORS_DEFAULT
Definition: libpq-fe.h:128
@ PG_BOOL_UNKNOWN
Definition: libpq-int.h:246
@ PG_SQL_ASCII
Definition: pg_wchar.h:224
#define PGINVALID_SOCKET
Definition: port.h:31
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
PQnoticeReceiver noticeRec
Definition: libpq-int.h:153
bool std_strings
Definition: libpq-int.h:471
PGTernaryBool in_hot_standby
Definition: libpq-int.h:473
int inBufSize
Definition: libpq-int.h:480
int client_encoding
Definition: libpq-int.h:470
PGTernaryBool default_transaction_read_only
Definition: libpq-int.h:472
PGVerbosity verbosity
Definition: libpq-int.h:474
int rowBufLen
Definition: libpq-int.h:497
int outBufSize
Definition: libpq-int.h:487
PGNoticeHooks noticeHooks
Definition: libpq-int.h:402
FILE * Pfdebug
Definition: libpq-int.h:398
PGContextVisibility show_context
Definition: libpq-int.h:475

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 4449 of file fe-connect.c.

4450 {
4451  if (value < 0)
4452  return true;
4453  if (setsockopt(fd, protoid, optid, (char *) &value, sizeof(value)) < 0)
4454  return false;
4455  return true;
4456 }
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 990 of file fe-connect.c.

991 {
992  char *p;
993  char *s = *startptr;
994  char *e;
995  int len;
996 
997  /*
998  * Search for the end of the current element; a comma or end-of-string
999  * acts as a terminator.
1000  */
1001  e = s;
1002  while (*e != '\0' && *e != ',')
1003  ++e;
1004  *more = (*e == ',');
1005 
1006  len = e - s;
1007  p = (char *) malloc(sizeof(char) * (len + 1));
1008  if (p)
1009  {
1010  memcpy(p, s, len);
1011  p[len] = '\0';
1012  }
1013  *startptr = e + 1;
1014 
1015  return p;
1016 }
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 *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

5565 {
5566  /* Parse as URI if connection string matches URI prefix */
5567  if (uri_prefix_length(connstr) != 0)
5568  return conninfo_uri_parse(connstr, errorMessage, use_defaults);
5569 
5570  /* Parse as default otherwise */
5571  return conninfo_parse(connstr, errorMessage, use_defaults);
5572 }
static PQconninfoOption * conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:6064
static PQconninfoOption * conninfo_parse(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:5617
static char * connstr
Definition: pg_dumpall.c:63

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 1800 of file fe-connect.c.

1802 {
1803  char *end;
1804  long numval;
1805 
1806  Assert(value != NULL);
1807 
1808  *result = 0;
1809 
1810  /* strtol(3) skips leading whitespaces */
1811  errno = 0;
1812  numval = strtol(value, &end, 10);
1813 
1814  /*
1815  * If no progress was done during the parsing or an error happened, fail.
1816  * This tests properly for overflows of the result.
1817  */
1818  if (value == end || errno != 0 || numval != (int) numval)
1819  goto error;
1820 
1821  /*
1822  * Skip any trailing whitespace; if anything but whitespace remains before
1823  * the terminating character, fail
1824  */
1825  while (*end != '\0' && isspace((unsigned char) *end))
1826  end++;
1827 
1828  if (*end != '\0')
1829  goto error;
1830 
1831  *result = numval;
1832  return true;
1833 
1834 error:
1836  libpq_gettext("invalid integer value \"%s\" for connection option \"%s\"\n"),
1837  value, context);
1838  return false;
1839 }
static void error(void)
Definition: sql-dyntest.c:147

References appendPQExpBuffer(), Assert(), conn, error(), pg_conn::errorMessage, libpq_gettext, 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 5321 of file fe-connect.c.

5326 {
5327  int result = 0,
5328  linenr = 0,
5329  i;
5330  FILE *f;
5331  char *line;
5332  char buf[1024];
5333 
5334  *group_found = false;
5335 
5336  f = fopen(serviceFile, "r");
5337  if (f == NULL)
5338  {
5339  appendPQExpBuffer(errorMessage, libpq_gettext("service file \"%s\" not found\n"),
5340  serviceFile);
5341  return 1;
5342  }
5343 
5344  while ((line = fgets(buf, sizeof(buf), f)) != NULL)
5345  {
5346  int len;
5347 
5348  linenr++;
5349 
5350  if (strlen(line) >= sizeof(buf) - 1)
5351  {
5352  appendPQExpBuffer(errorMessage,
5353  libpq_gettext("line %d too long in service file \"%s\"\n"),
5354  linenr,
5355  serviceFile);
5356  result = 2;
5357  goto exit;
5358  }
5359 
5360  /* ignore whitespace at end of line, especially the newline */
5361  len = strlen(line);
5362  while (len > 0 && isspace((unsigned char) line[len - 1]))
5363  line[--len] = '\0';
5364 
5365  /* ignore leading whitespace too */
5366  while (*line && isspace((unsigned char) line[0]))
5367  line++;
5368 
5369  /* ignore comments and empty lines */
5370  if (line[0] == '\0' || line[0] == '#')
5371  continue;
5372 
5373  /* Check for right groupname */
5374  if (line[0] == '[')
5375  {
5376  if (*group_found)
5377  {
5378  /* end of desired group reached; return success */
5379  goto exit;
5380  }
5381 
5382  if (strncmp(line + 1, service, strlen(service)) == 0 &&
5383  line[strlen(service) + 1] == ']')
5384  *group_found = true;
5385  else
5386  *group_found = false;
5387  }
5388  else
5389  {
5390  if (*group_found)
5391  {
5392  /*
5393  * Finally, we are in the right group and can parse the line
5394  */
5395  char *key,
5396  *val;
5397  bool found_keyword;
5398 
5399 #ifdef USE_LDAP
5400  if (strncmp(line, "ldap", 4) == 0)
5401  {
5402  int rc = ldapServiceLookup(line, options, errorMessage);
5403 
5404  /* if rc = 2, go on reading for fallback */
5405  switch (rc)
5406  {
5407  case 0:
5408  goto exit;
5409  case 1:
5410  case 3:
5411  result = 3;
5412  goto exit;
5413  case 2:
5414  continue;
5415  }
5416  }
5417 #endif
5418 
5419  key = line;
5420  val = strchr(line, '=');
5421  if (val == NULL)
5422  {
5423  appendPQExpBuffer(errorMessage,
5424  libpq_gettext("syntax error in service file \"%s\", line %d\n"),
5425  serviceFile,
5426  linenr);
5427  result = 3;
5428  goto exit;
5429  }
5430  *val++ = '\0';
5431 
5432  if (strcmp(key, "service") == 0)
5433  {
5434  appendPQExpBuffer(errorMessage,
5435  libpq_gettext("nested service specifications not supported in service file \"%s\", line %d\n"),
5436  serviceFile,
5437  linenr);
5438  result = 3;
5439  goto exit;
5440  }
5441 
5442  /*
5443  * Set the parameter --- but don't override any previous
5444  * explicit setting.
5445  */
5446  found_keyword = false;
5447  for (i = 0; options[i].keyword; i++)
5448  {
5449  if (strcmp(options[i].keyword, key) == 0)
5450  {
5451  if (options[i].val == NULL)
5452  options[i].val = strdup(val);
5453  if (!options[i].val)
5454  {
5455  appendPQExpBufferStr(errorMessage,
5456  libpq_gettext("out of memory\n"));
5457  result = 3;
5458  goto exit;
5459  }
5460  found_keyword = true;
5461  break;
5462  }
5463  }
5464 
5465  if (!found_keyword)
5466  {
5467  appendPQExpBuffer(errorMessage,
5468  libpq_gettext("syntax error in service file \"%s\", line %d\n"),
5469  serviceFile,
5470  linenr);
5471  result = 3;
5472  goto exit;
5473  }
5474  }
5475  }
5476  }
5477 
5478 exit:
5479  fclose(f);
5480 
5481  return result;
5482 }
exit(1)

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

Referenced by parseServiceInfo().

◆ parseServiceInfo()

static int parseServiceInfo ( PQconninfoOption options,
PQExpBuffer  errorMessage 
)
static

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

5253 {
5254  const char *service = conninfo_getval(options, "service");
5255  char serviceFile[MAXPGPATH];
5256  char *env;
5257  bool group_found = false;
5258  int status;
5259  struct stat stat_buf;
5260 
5261  /*
5262  * We have to special-case the environment variable PGSERVICE here, since
5263  * this is and should be called before inserting environment defaults for
5264  * other connection options.
5265  */
5266  if (service == NULL)
5267  service = getenv("PGSERVICE");
5268 
5269  /* If no service name given, nothing to do */
5270  if (service == NULL)
5271  return 0;
5272 
5273  /*
5274  * Try PGSERVICEFILE if specified, else try ~/.pg_service.conf (if that
5275  * exists).
5276  */
5277  if ((env = getenv("PGSERVICEFILE")) != NULL)
5278  strlcpy(serviceFile, env, sizeof(serviceFile));
5279  else
5280  {
5281  char homedir[MAXPGPATH];
5282 
5283  if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
5284  goto next_file;
5285  snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
5286  if (stat(serviceFile, &stat_buf) != 0)
5287  goto next_file;
5288  }
5289 
5290  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
5291  if (group_found || status != 0)
5292  return status;
5293 
5294 next_file:
5295 
5296  /*
5297  * This could be used by any application so we can't use the binary
5298  * location to find our config files.
5299  */
5300  snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
5301  getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
5302  if (stat(serviceFile, &stat_buf) != 0)
5303  goto last_file;
5304 
5305  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
5306  if (status != 0)
5307  return status;
5308 
5309 last_file:
5310  if (!group_found)
5311  {
5312  appendPQExpBuffer(errorMessage,
5313  libpq_gettext("definition of service \"%s\" not found\n"), service);
5314  return 3;
5315  }
5316 
5317  return 0;
5318 }
static int parseServiceFile(const char *serviceFile, const char *service, PQconninfoOption *options, PQExpBuffer errorMessage, bool *group_found)
Definition: fe-connect.c:5321
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:229
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define stat
Definition: win32_port.h:283

References appendPQExpBuffer(), conninfo_getval(), libpq_gettext, 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 7163 of file fe-connect.c.

7165 {
7166  FILE *fp;
7167  struct stat stat_buf;
7169 
7170  if (dbname == NULL || dbname[0] == '\0')
7171  return NULL;
7172 
7173  if (username == NULL || username[0] == '\0')
7174  return NULL;
7175 
7176  /* 'localhost' matches pghost of '' or the default socket directory */
7177  if (hostname == NULL || hostname[0] == '\0')
7179  else if (is_unixsock_path(hostname))
7180 
7181  /*
7182  * We should probably use canonicalize_path(), but then we have to
7183  * bring path.c into libpq, and it doesn't seem worth it.
7184  */
7185  if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
7187 
7188  if (port == NULL || port[0] == '\0')
7189  port = DEF_PGPORT_STR;
7190 
7191  /* If password file cannot be opened, ignore it. */
7192  if (stat(pgpassfile, &stat_buf) != 0)
7193  return NULL;
7194 
7195 #ifndef WIN32
7196  if (!S_ISREG(stat_buf.st_mode))
7197  {
7198  fprintf(stderr,
7199  libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
7200  pgpassfile);
7201  return NULL;
7202  }
7203 
7204  /* If password file is insecure, alert the user and ignore it. */
7205  if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
7206  {
7207  fprintf(stderr,
7208  libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
7209  pgpassfile);
7210  return NULL;
7211  }
7212 #else
7213 
7214  /*
7215  * On Win32, the directory is protected, so we don't have to check the
7216  * file.
7217  */
7218 #endif
7219 
7220  fp = fopen(pgpassfile, "r");
7221  if (fp == NULL)
7222  return NULL;
7223 
7224  /* Use an expansible buffer to accommodate any reasonable line length */
7225  initPQExpBuffer(&buf);
7226 
7227  while (!feof(fp) && !ferror(fp))
7228  {
7229  /* Make sure there's a reasonable amount of room in the buffer */
7230  if (!enlargePQExpBuffer(&buf, 128))
7231  break;
7232 
7233  /* Read some data, appending it to what we already have */
7234  if (fgets(buf.data + buf.len, buf.maxlen - buf.len, fp) == NULL)
7235  break;
7236  buf.len += strlen(buf.data + buf.len);
7237 
7238  /* If we don't yet have a whole line, loop around to read more */
7239  if (!(buf.len > 0 && buf.data[buf.len - 1] == '\n') && !feof(fp))
7240  continue;
7241 
7242  /* ignore comments */
7243  if (buf.data[0] != '#')
7244  {
7245  char *t = buf.data;
7246  int len;
7247 
7248  /* strip trailing newline and carriage return */
7249  len = pg_strip_crlf(t);
7250 
7251  if (len > 0 &&
7252  (t = pwdfMatchesString(t, hostname)) != NULL &&
7253  (t = pwdfMatchesString(t, port)) != NULL &&
7254  (t = pwdfMatchesString(t, dbname)) != NULL &&
7255  (t = pwdfMatchesString(t, username)) != NULL)
7256  {
7257  /* Found a match. */
7258  char *ret,
7259  *p1,
7260  *p2;
7261 
7262  ret = strdup(t);
7263 
7264  fclose(fp);
7265  explicit_bzero(buf.data, buf.maxlen);
7266  termPQExpBuffer(&buf);
7267 
7268  if (!ret)
7269  {
7270  /* Out of memory. XXX: an error message would be nice. */
7271  return NULL;
7272  }
7273 
7274  /* De-escape password. */
7275  for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
7276  {
7277  if (*p1 == '\\' && p1[1] != '\0')
7278  ++p1;
7279  *p2 = *p1;
7280  }
7281  *p2 = '\0';
7282 
7283  return ret;
7284  }
7285  }
7286 
7287  /* No match, reset buffer to prepare for next line. */
7288  buf.len = 0;
7289  }
7290 
7291  fclose(fp);
7292  explicit_bzero(buf.data, buf.maxlen);
7293  termPQExpBuffer(&buf);
7294  return NULL;
7295 }
static char * pwdfMatchesString(char *buf, const char *token)
Definition: fe-connect.c:7126
static char * hostname
Definition: pg_regress.c:91
const char * username
Definition: pgbench.c:309
int enlargePQExpBuffer(PQExpBuffer str, size_t needed)
Definition: pqexpbuffer.c:174
int pg_strip_crlf(char *str)
Definition: string.c:121
#define S_IRWXG
Definition: win32_port.h:309
#define S_IRWXO
Definition: win32_port.h:321
#define S_ISREG(m)
Definition: win32_port.h:327

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 7303 of file fe-connect.c.

7304 {
7305  /* If it was 'invalid authorization', add pgpassfile mention */
7306  /* only works with >= 9.0 servers */
7307  if (conn->password_needed &&
7308  conn->connhost[conn->whichhost].password != NULL &&
7309  conn->result)
7310  {
7311  const char *sqlstate = PQresultErrorField(conn->result,
7313 
7314  if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
7316  libpq_gettext("password retrieved from file \"%s\"\n"),
7317  conn->pgpassfile);
7318  }
7319 }
#define ERRCODE_INVALID_PASSWORD
Definition: fe-connect.c:94
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3325
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
PGresult * result
Definition: libpq-int.h:508
bool password_needed
Definition: libpq-int.h:451

References appendPQExpBuffer(), conn, pg_conn::connhost, ERRCODE_INVALID_PASSWORD, pg_conn::errorMessage, libpq_gettext, 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 6942 of file fe-connect.c.

6943 {
6944  if (!conn || conn->status != CONNECTION_OK)
6945  return 0;
6946  return conn->be_pid;
6947 }
@ CONNECTION_OK
Definition: libpq-fe.h:60
int be_pid
Definition: libpq-int.h:467

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 4481 of file fe-connect.c.

4482 {
4483  int save_errno = SOCK_ERRNO;
4484  pgsocket tmpsock = PGINVALID_SOCKET;
4485  int maxlen;
4486  struct
4487  {
4488  uint32 packetlen;
4490  } crp;
4491 
4492  if (!cancel)
4493  {
4494  strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
4495  /* strlcpy probably doesn't change errno, but be paranoid */
4496  SOCK_ERRNO_SET(save_errno);
4497  return false;
4498  }
4499 
4500  /*
4501  * We need to open a temporary connection to the postmaster. Do this with
4502  * only kernel calls.
4503  */
4504  if ((tmpsock = socket(cancel->raddr.addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
4505  {
4506  strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
4507  goto cancel_errReturn;
4508  }
4509 
4510  /*
4511  * Since this connection will only be used to send a single packet of
4512  * data, we don't need NODELAY. We also don't set the socket to
4513  * nonblocking mode, because the API definition of PQcancel requires the
4514  * cancel to be sent in a blocking way.
4515  *
4516  * We do set socket options related to keepalives and other TCP timeouts.
4517  * This ensures that this function does not block indefinitely when
4518  * reasonable keepalive and timeout settings have been provided.
4519  */
4520  if (cancel->raddr.addr.ss_family != AF_UNIX &&
4521  cancel->keepalives != 0)
4522  {
4523 #ifndef WIN32
4524  if (!optional_setsockopt(tmpsock, SOL_SOCKET, SO_KEEPALIVE, 1))
4525  {
4526  strlcpy(errbuf, "PQcancel() -- setsockopt(SO_KEEPALIVE) failed: ", errbufsize);
4527  goto cancel_errReturn;
4528  }
4529 
4530 #ifdef PG_TCP_KEEPALIVE_IDLE
4531  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
4532  cancel->keepalives_idle))
4533  {
4534  strlcpy(errbuf, "PQcancel() -- setsockopt(" PG_TCP_KEEPALIVE_IDLE_STR ") failed: ", errbufsize);
4535  goto cancel_errReturn;
4536  }
4537 #endif
4538 
4539 #ifdef TCP_KEEPINTVL
4540  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_KEEPINTVL,
4541  cancel->keepalives_interval))
4542  {
4543  strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPINTVL) failed: ", errbufsize);
4544  goto cancel_errReturn;
4545  }
4546 #endif
4547 
4548 #ifdef TCP_KEEPCNT
4549  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_KEEPCNT,
4550  cancel->keepalives_count))
4551  {
4552  strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPCNT) failed: ", errbufsize);
4553  goto cancel_errReturn;
4554  }
4555 #endif
4556 
4557 #else /* WIN32 */
4558 
4559 #ifdef SIO_KEEPALIVE_VALS
4560  if (!setKeepalivesWin32(tmpsock,
4561  cancel->keepalives_idle,
4562  cancel->keepalives_interval))
4563  {
4564  strlcpy(errbuf, "PQcancel() -- WSAIoctl(SIO_KEEPALIVE_VALS) failed: ", errbufsize);
4565  goto cancel_errReturn;
4566  }
4567 #endif /* SIO_KEEPALIVE_VALS */
4568 #endif /* WIN32 */
4569 
4570  /* TCP_USER_TIMEOUT works the same way on Unix and Windows */
4571 #ifdef TCP_USER_TIMEOUT
4572  if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_USER_TIMEOUT,
4573  cancel->pgtcp_user_timeout))
4574  {
4575  strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_USER_TIMEOUT) failed: ", errbufsize);
4576  goto cancel_errReturn;
4577  }
4578 #endif
4579  }
4580 
4581 retry3:
4582  if (connect(tmpsock, (struct sockaddr *) &cancel->raddr.addr,
4583  cancel->raddr.salen) < 0)
4584  {
4585  if (SOCK_ERRNO == EINTR)
4586  /* Interrupted system call - we'll just try again */
4587  goto retry3;
4588  strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
4589  goto cancel_errReturn;
4590  }
4591 
4592  /* Create and send the cancel request packet. */
4593 
4594  crp.packetlen = pg_hton32((uint32) sizeof(crp));
4595  crp.cp.cancelRequestCode = (MsgType) pg_hton32(CANCEL_REQUEST_CODE);
4596  crp.cp.backendPID = pg_hton32(cancel->be_pid);
4597  crp.cp.cancelAuthCode = pg_hton32(cancel->be_key);
4598 
4599 retry4:
4600  if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
4601  {
4602  if (SOCK_ERRNO == EINTR)
4603  /* Interrupted system call - we'll just try again */
4604  goto retry4;
4605  strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
4606  goto cancel_errReturn;
4607  }
4608 
4609  /*
4610  * Wait for the postmaster to close the connection, which indicates that
4611  * it's processed the request. Without this delay, we might issue another
4612  * command only to find that our cancel zaps that command instead of the
4613  * one we thought we were canceling. Note we don't actually expect this
4614  * read to obtain any data, we are just waiting for EOF to be signaled.
4615  */
4616 retry5:
4617  if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
4618  {
4619  if (SOCK_ERRNO == EINTR)
4620  /* Interrupted system call - we'll just try again */
4621  goto retry5;
4622  /* we ignore other error conditions */
4623  }
4624 
4625  /* All done */
4626  closesocket(tmpsock);
4627  SOCK_ERRNO_SET(save_errno);
4628  return true;
4629 
4630 cancel_errReturn:
4631 
4632  /*
4633  * Make sure we don't overflow the error buffer. Leave space for the \n at
4634  * the end, and for the terminating zero.
4635  */
4636  maxlen = errbufsize - strlen(errbuf) - 2;
4637  if (maxlen >= 0)
4638  {
4639  /*
4640  * We can't invoke strerror here, since it's not signal-safe. Settle
4641  * for printing the decimal value of errno. Even that has to be done
4642  * the hard way.
4643  */
4644  int val = SOCK_ERRNO;
4645  char buf[32];
4646  char *bufp;
4647 
4648  bufp = buf + sizeof(buf) - 1;
4649  *bufp = '\0';
4650  do
4651  {
4652  *(--bufp) = (val % 10) + '0';
4653  val /= 10;
4654  } while (val > 0);
4655  bufp -= 6;
4656  memcpy(bufp, "error ", 6);
4657  strncat(errbuf, bufp, maxlen);
4658  strcat(errbuf, "\n");
4659  }
4660  if (tmpsock != PGINVALID_SOCKET)
4661  closesocket(tmpsock);
4662  SOCK_ERRNO_SET(save_errno);
4663  return false;
4664 }
unsigned int uint32
Definition: c.h:441
static bool optional_setsockopt(int fd, int protoid, int optid, int value)
Definition: fe-connect.c:4449
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:893
#define pg_hton32(x)
Definition: pg_bswap.h:121
int pgsocket
Definition: port.h:29
#define closesocket
Definition: port.h:342
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:176
ProtocolVersion MsgType
Definition: pqcomm.h:127
int pgtcp_user_timeout
Definition: libpq-int.h:601
int keepalives_interval
Definition: libpq-int.h:604
int keepalives_idle
Definition: libpq-int.h:603
int keepalives_count
Definition: libpq-int.h:606
SockAddr raddr
Definition: libpq-int.h:598
int be_pid
Definition: libpq-int.h:599
int keepalives
Definition: libpq-int.h:602
int be_key
Definition: libpq-int.h:600
#define EINTR
Definition: win32_port.h:351
#define recv(s, buf, len, flags)
Definition: win32_port.h:475
#define send(s, buf, len, flags)
Definition: win32_port.h:476
#define socket(af, type, protocol)
Definition: win32_port.h:469
#define connect(s, name, namelen)
Definition: win32_port.h:473

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 1477 of file fe-connect.c.

1478 {
1479  PQExpBufferData errorBuf;
1480  PQconninfoOption *connOptions;
1481 
1482  /* We don't actually report any errors here, but callees want a buffer */
1483  initPQExpBuffer(&errorBuf);
1484  if (PQExpBufferDataBroken(errorBuf))
1485  return NULL; /* out of memory already :-( */
1486 
1487  connOptions = conninfo_init(&errorBuf);
1488  if (connOptions != NULL)
1489  {
1490  /* pass NULL errorBuf to ignore errors */
1491  if (!conninfo_add_defaults(connOptions, NULL))
1492  {
1493  PQconninfoFree(connOptions);
1494  connOptions = NULL;
1495  }
1496  }
1497 
1498  termPQExpBuffer(&errorBuf);
1499  return connOptions;
1500 }

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 713 of file fe-connect.c.

714 {
715  PGconn *conn = PQconnectStart(conninfo);
716 
717  if (conn && conn->status != CONNECTION_BAD)
718  (void) connectDBComplete(conn);
719 
720  return conn;
721 }
PGconn * PQconnectStart(const char *conninfo)
Definition: fe-connect.c:841

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

Referenced by dblink_connect(), dblink_get_conn(), get_db_conn(), and main().

◆ PQconnectdbParams()

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

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

661 {
662  PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
663 
664  if (conn && conn->status != CONNECTION_BAD)
665  (void) connectDBComplete(conn);
666 
667  return conn;
668 }
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:760

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

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

◆ PQconnectionNeedsPassword()

int PQconnectionNeedsPassword ( const PGconn conn)

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

6960 {
6961  char *password;
6962 
6963  if (!conn)
6964  return false;
6965  password = PQpass(conn);
6966  if (conn->password_needed &&
6967  (password == NULL || password[0] == '\0'))
6968  return true;
6969  else
6970  return false;
6971 }
char * PQpass(const PGconn *conn)
Definition: fe-connect.c:6770

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 6974 of file fe-connect.c.

6975 {
6976  if (!conn)
6977  return false;
6978  if (conn->password_needed)
6979  return true;
6980  else
6981  return false;
6982 }

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 2262 of file fe-connect.c.

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