LCOV - code coverage report
Current view: top level - src/interfaces/libpq - fe-connect.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 1740 2665 65.3 %
Date: 2025-04-01 14:15:22 Functions: 97 110 88.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * fe-connect.c
       4             :  *    functions related to setting up a connection to the backend
       5             :  *
       6             :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/interfaces/libpq/fe-connect.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : 
      16             : #include "postgres_fe.h"
      17             : 
      18             : #include <sys/stat.h>
      19             : #include <fcntl.h>
      20             : #include <ctype.h>
      21             : #include <netdb.h>
      22             : #include <time.h>
      23             : #include <unistd.h>
      24             : 
      25             : #include "common/base64.h"
      26             : #include "common/ip.h"
      27             : #include "common/link-canary.h"
      28             : #include "common/scram-common.h"
      29             : #include "common/string.h"
      30             : #include "fe-auth.h"
      31             : #include "fe-auth-oauth.h"
      32             : #include "libpq-fe.h"
      33             : #include "libpq-int.h"
      34             : #include "mb/pg_wchar.h"
      35             : #include "pg_config_paths.h"
      36             : #include "port/pg_bswap.h"
      37             : 
      38             : #ifdef WIN32
      39             : #include "win32.h"
      40             : #ifdef _WIN32_IE
      41             : #undef _WIN32_IE
      42             : #endif
      43             : #define _WIN32_IE 0x0500
      44             : #ifdef near
      45             : #undef near
      46             : #endif
      47             : #define near
      48             : #include <shlobj.h>
      49             : #include <mstcpip.h>
      50             : #else
      51             : #include <sys/socket.h>
      52             : #include <netdb.h>
      53             : #include <netinet/in.h>
      54             : #include <netinet/tcp.h>
      55             : #include <pwd.h>
      56             : #endif
      57             : 
      58             : #ifdef WIN32
      59             : #include "pthread-win32.h"
      60             : #else
      61             : #include <pthread.h>
      62             : #endif
      63             : 
      64             : #ifdef USE_LDAP
      65             : #ifdef WIN32
      66             : #include <winldap.h>
      67             : #else
      68             : /* OpenLDAP deprecates RFC 1823, but we want standard conformance */
      69             : #define LDAP_DEPRECATED 1
      70             : #include <ldap.h>
      71             : typedef struct timeval LDAP_TIMEVAL;
      72             : #endif
      73             : static int  ldapServiceLookup(const char *purl, PQconninfoOption *options,
      74             :                               PQExpBuffer errorMessage);
      75             : #endif
      76             : 
      77             : #ifndef WIN32
      78             : #define PGPASSFILE ".pgpass"
      79             : #else
      80             : #define PGPASSFILE "pgpass.conf"
      81             : #endif
      82             : 
      83             : /*
      84             :  * Pre-9.0 servers will return this SQLSTATE if asked to set
      85             :  * application_name in a startup packet.  We hard-wire the value rather
      86             :  * than looking into errcodes.h since it reflects historical behavior
      87             :  * rather than that of the current code.
      88             :  */
      89             : #define ERRCODE_APPNAME_UNKNOWN "42704"
      90             : 
      91             : /* This is part of the protocol so just define it */
      92             : #define ERRCODE_INVALID_PASSWORD "28P01"
      93             : /* This too */
      94             : #define ERRCODE_CANNOT_CONNECT_NOW "57P03"
      95             : 
      96             : /*
      97             :  * Cope with the various platform-specific ways to spell TCP keepalive socket
      98             :  * options.  This doesn't cover Windows, which as usual does its own thing.
      99             :  */
     100             : #if defined(TCP_KEEPIDLE)
     101             : /* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
     102             : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPIDLE
     103             : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPIDLE"
     104             : #elif defined(TCP_KEEPALIVE_THRESHOLD)
     105             : /* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris >= 11 */
     106             : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE_THRESHOLD
     107             : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE_THRESHOLD"
     108             : #elif defined(TCP_KEEPALIVE) && defined(__darwin__)
     109             : /* TCP_KEEPALIVE is the name of this option on macOS */
     110             : /* Caution: Solaris has this symbol but it means something different */
     111             : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE
     112             : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE"
     113             : #endif
     114             : 
     115             : /*
     116             :  * fall back options if they are not specified by arguments or defined
     117             :  * by environment variables
     118             :  */
     119             : #define DefaultHost     "localhost"
     120             : #define DefaultOption   ""
     121             : #ifdef USE_SSL
     122             : #define DefaultChannelBinding   "prefer"
     123             : #else
     124             : #define DefaultChannelBinding   "disable"
     125             : #endif
     126             : #define DefaultTargetSessionAttrs   "any"
     127             : #define DefaultLoadBalanceHosts "disable"
     128             : #ifdef USE_SSL
     129             : #define DefaultSSLMode "prefer"
     130             : #define DefaultSSLCertMode "allow"
     131             : #else
     132             : #define DefaultSSLMode  "disable"
     133             : #define DefaultSSLCertMode "disable"
     134             : #endif
     135             : #define DefaultSSLNegotiation   "postgres"
     136             : #ifdef ENABLE_GSS
     137             : #include "fe-gssapi-common.h"
     138             : #define DefaultGSSMode "prefer"
     139             : #else
     140             : #define DefaultGSSMode "disable"
     141             : #endif
     142             : 
     143             : /* ----------
     144             :  * Definition of the conninfo parameters and their fallback resources.
     145             :  *
     146             :  * If Environment-Var and Compiled-in are specified as NULL, no
     147             :  * fallback is available. If after all no value can be determined
     148             :  * for an option, an error is returned.
     149             :  *
     150             :  * The value for the username is treated specially in conninfo_add_defaults.
     151             :  * If the value is not obtained any other way, the username is determined
     152             :  * by pg_fe_getauthname().
     153             :  *
     154             :  * The Label and Disp-Char entries are provided for applications that
     155             :  * want to use PQconndefaults() to create a generic database connection
     156             :  * dialog. Disp-Char is defined as follows:
     157             :  *      ""        Normal input field
     158             :  *      "*"       Password field - hide value
     159             :  *      "D"       Debug option - don't show by default
     160             :  *
     161             :  * PQconninfoOptions[] is a constant static array that we use to initialize
     162             :  * a dynamically allocated working copy.  All the "val" fields in
     163             :  * PQconninfoOptions[] *must* be NULL.  In a working copy, non-null "val"
     164             :  * fields point to malloc'd strings that should be freed when the working
     165             :  * array is freed (see PQconninfoFree).
     166             :  *
     167             :  * The first part of each struct is identical to the one in libpq-fe.h,
     168             :  * which is required since we memcpy() data between the two!
     169             :  * ----------
     170             :  */
     171             : typedef struct _internalPQconninfoOption
     172             : {
     173             :     char       *keyword;        /* The keyword of the option            */
     174             :     char       *envvar;         /* Fallback environment variable name   */
     175             :     char       *compiled;       /* Fallback compiled in default value   */
     176             :     char       *val;            /* Option's current value, or NULL      */
     177             :     char       *label;          /* Label for field in connect dialog    */
     178             :     char       *dispchar;       /* Indicates how to display this field in a
     179             :                                  * connect dialog. Values are: "" Display
     180             :                                  * entered value as is "*" Password field -
     181             :                                  * hide value "D"  Debug option - don't show
     182             :                                  * by default */
     183             :     int         dispsize;       /* Field size in characters for dialog  */
     184             :     /* ---
     185             :      * Anything above this comment must be synchronized with
     186             :      * PQconninfoOption in libpq-fe.h, since we memcpy() data
     187             :      * between them!
     188             :      * ---
     189             :      */
     190             :     off_t       connofs;        /* Offset into PGconn struct, -1 if not there */
     191             : } internalPQconninfoOption;
     192             : 
     193             : static const internalPQconninfoOption PQconninfoOptions[] = {
     194             :     {"service", "PGSERVICE", NULL, NULL,
     195             :         "Database-Service", "", 20,
     196             :     offsetof(struct pg_conn, pgservice)},
     197             : 
     198             :     {"user", "PGUSER", NULL, NULL,
     199             :         "Database-User", "", 20,
     200             :     offsetof(struct pg_conn, pguser)},
     201             : 
     202             :     {"password", "PGPASSWORD", NULL, NULL,
     203             :         "Database-Password", "*", 20,
     204             :     offsetof(struct pg_conn, pgpass)},
     205             : 
     206             :     {"passfile", "PGPASSFILE", NULL, NULL,
     207             :         "Database-Password-File", "", 64,
     208             :     offsetof(struct pg_conn, pgpassfile)},
     209             : 
     210             :     {"channel_binding", "PGCHANNELBINDING", DefaultChannelBinding, NULL,
     211             :         "Channel-Binding", "", 8,   /* sizeof("require") == 8 */
     212             :     offsetof(struct pg_conn, channel_binding)},
     213             : 
     214             :     {"connect_timeout", "PGCONNECT_TIMEOUT", NULL, NULL,
     215             :         "Connect-timeout", "", 10,  /* strlen(INT32_MAX) == 10 */
     216             :     offsetof(struct pg_conn, connect_timeout)},
     217             : 
     218             :     {"dbname", "PGDATABASE", NULL, NULL,
     219             :         "Database-Name", "", 20,
     220             :     offsetof(struct pg_conn, dbName)},
     221             : 
     222             :     {"host", "PGHOST", NULL, NULL,
     223             :         "Database-Host", "", 40,
     224             :     offsetof(struct pg_conn, pghost)},
     225             : 
     226             :     {"hostaddr", "PGHOSTADDR", NULL, NULL,
     227             :         "Database-Host-IP-Address", "", 45,
     228             :     offsetof(struct pg_conn, pghostaddr)},
     229             : 
     230             :     {"port", "PGPORT", DEF_PGPORT_STR, NULL,
     231             :         "Database-Port", "", 6,
     232             :     offsetof(struct pg_conn, pgport)},
     233             : 
     234             :     {"client_encoding", "PGCLIENTENCODING", NULL, NULL,
     235             :         "Client-Encoding", "", 10,
     236             :     offsetof(struct pg_conn, client_encoding_initial)},
     237             : 
     238             :     {"options", "PGOPTIONS", DefaultOption, NULL,
     239             :         "Backend-Options", "", 40,
     240             :     offsetof(struct pg_conn, pgoptions)},
     241             : 
     242             :     {"application_name", "PGAPPNAME", NULL, NULL,
     243             :         "Application-Name", "", 64,
     244             :     offsetof(struct pg_conn, appname)},
     245             : 
     246             :     {"fallback_application_name", NULL, NULL, NULL,
     247             :         "Fallback-Application-Name", "", 64,
     248             :     offsetof(struct pg_conn, fbappname)},
     249             : 
     250             :     {"keepalives", NULL, NULL, NULL,
     251             :         "TCP-Keepalives", "", 1,    /* should be just '0' or '1' */
     252             :     offsetof(struct pg_conn, keepalives)},
     253             : 
     254             :     {"keepalives_idle", NULL, NULL, NULL,
     255             :         "TCP-Keepalives-Idle", "", 10,  /* strlen(INT32_MAX) == 10 */
     256             :     offsetof(struct pg_conn, keepalives_idle)},
     257             : 
     258             :     {"keepalives_interval", NULL, NULL, NULL,
     259             :         "TCP-Keepalives-Interval", "", 10,  /* strlen(INT32_MAX) == 10 */
     260             :     offsetof(struct pg_conn, keepalives_interval)},
     261             : 
     262             :     {"keepalives_count", NULL, NULL, NULL,
     263             :         "TCP-Keepalives-Count", "", 10, /* strlen(INT32_MAX) == 10 */
     264             :     offsetof(struct pg_conn, keepalives_count)},
     265             : 
     266             :     {"tcp_user_timeout", NULL, NULL, NULL,
     267             :         "TCP-User-Timeout", "", 10, /* strlen(INT32_MAX) == 10 */
     268             :     offsetof(struct pg_conn, pgtcp_user_timeout)},
     269             : 
     270             :     /*
     271             :      * ssl options are allowed even without client SSL support because the
     272             :      * client can still handle SSL modes "disable" and "allow". Other
     273             :      * parameters have no effect on non-SSL connections, so there is no reason
     274             :      * to exclude them since none of them are mandatory.
     275             :      */
     276             :     {"sslmode", "PGSSLMODE", DefaultSSLMode, NULL,
     277             :         "SSL-Mode", "", 12,     /* sizeof("verify-full") == 12 */
     278             :     offsetof(struct pg_conn, sslmode)},
     279             : 
     280             :     {"sslnegotiation", "PGSSLNEGOTIATION", DefaultSSLNegotiation, NULL,
     281             :         "SSL-Negotiation", "", 9,   /* sizeof("postgres") == 9  */
     282             :     offsetof(struct pg_conn, sslnegotiation)},
     283             : 
     284             :     {"sslcompression", "PGSSLCOMPRESSION", "0", NULL,
     285             :         "SSL-Compression", "", 1,
     286             :     offsetof(struct pg_conn, sslcompression)},
     287             : 
     288             :     {"sslcert", "PGSSLCERT", NULL, NULL,
     289             :         "SSL-Client-Cert", "", 64,
     290             :     offsetof(struct pg_conn, sslcert)},
     291             : 
     292             :     {"sslkey", "PGSSLKEY", NULL, NULL,
     293             :         "SSL-Client-Key", "", 64,
     294             :     offsetof(struct pg_conn, sslkey)},
     295             : 
     296             :     {"sslcertmode", "PGSSLCERTMODE", NULL, NULL,
     297             :         "SSL-Client-Cert-Mode", "", 8,  /* sizeof("disable") == 8 */
     298             :     offsetof(struct pg_conn, sslcertmode)},
     299             : 
     300             :     {"sslpassword", NULL, NULL, NULL,
     301             :         "SSL-Client-Key-Password", "*", 20,
     302             :     offsetof(struct pg_conn, sslpassword)},
     303             : 
     304             :     {"sslrootcert", "PGSSLROOTCERT", NULL, NULL,
     305             :         "SSL-Root-Certificate", "", 64,
     306             :     offsetof(struct pg_conn, sslrootcert)},
     307             : 
     308             :     {"sslcrl", "PGSSLCRL", NULL, NULL,
     309             :         "SSL-Revocation-List", "", 64,
     310             :     offsetof(struct pg_conn, sslcrl)},
     311             : 
     312             :     {"sslcrldir", "PGSSLCRLDIR", NULL, NULL,
     313             :         "SSL-Revocation-List-Dir", "", 64,
     314             :     offsetof(struct pg_conn, sslcrldir)},
     315             : 
     316             :     {"sslsni", "PGSSLSNI", "1", NULL,
     317             :         "SSL-SNI", "", 1,
     318             :     offsetof(struct pg_conn, sslsni)},
     319             : 
     320             :     {"requirepeer", "PGREQUIREPEER", NULL, NULL,
     321             :         "Require-Peer", "", 10,
     322             :     offsetof(struct pg_conn, requirepeer)},
     323             : 
     324             :     {"require_auth", "PGREQUIREAUTH", NULL, NULL,
     325             :         "Require-Auth", "", 14, /* sizeof("scram-sha-256") == 14 */
     326             :     offsetof(struct pg_conn, require_auth)},
     327             : 
     328             :     {"ssl_min_protocol_version", "PGSSLMINPROTOCOLVERSION", "TLSv1.2", NULL,
     329             :         "SSL-Minimum-Protocol-Version", "", 8,  /* sizeof("TLSv1.x") == 8 */
     330             :     offsetof(struct pg_conn, ssl_min_protocol_version)},
     331             : 
     332             :     {"ssl_max_protocol_version", "PGSSLMAXPROTOCOLVERSION", NULL, NULL,
     333             :         "SSL-Maximum-Protocol-Version", "", 8,  /* sizeof("TLSv1.x") == 8 */
     334             :     offsetof(struct pg_conn, ssl_max_protocol_version)},
     335             : 
     336             :     /*
     337             :      * As with SSL, all GSS options are exposed even in builds that don't have
     338             :      * support.
     339             :      */
     340             :     {"gssencmode", "PGGSSENCMODE", DefaultGSSMode, NULL,
     341             :         "GSSENC-Mode", "", 8,   /* sizeof("disable") == 8 */
     342             :     offsetof(struct pg_conn, gssencmode)},
     343             : 
     344             :     /* Kerberos and GSSAPI authentication support specifying the service name */
     345             :     {"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
     346             :         "Kerberos-service-name", "", 20,
     347             :     offsetof(struct pg_conn, krbsrvname)},
     348             : 
     349             :     {"gsslib", "PGGSSLIB", NULL, NULL,
     350             :         "GSS-library", "", 7,   /* sizeof("gssapi") == 7 */
     351             :     offsetof(struct pg_conn, gsslib)},
     352             : 
     353             :     {"gssdelegation", "PGGSSDELEGATION", "0", NULL,
     354             :         "GSS-delegation", "", 1,
     355             :     offsetof(struct pg_conn, gssdelegation)},
     356             : 
     357             :     {"replication", NULL, NULL, NULL,
     358             :         "Replication", "D", 5,
     359             :     offsetof(struct pg_conn, replication)},
     360             : 
     361             :     {"target_session_attrs", "PGTARGETSESSIONATTRS",
     362             :         DefaultTargetSessionAttrs, NULL,
     363             :         "Target-Session-Attrs", "", 15, /* sizeof("prefer-standby") = 15 */
     364             :     offsetof(struct pg_conn, target_session_attrs)},
     365             : 
     366             :     {"load_balance_hosts", "PGLOADBALANCEHOSTS",
     367             :         DefaultLoadBalanceHosts, NULL,
     368             :         "Load-Balance-Hosts", "", 8,    /* sizeof("disable") = 8 */
     369             :     offsetof(struct pg_conn, load_balance_hosts)},
     370             : 
     371             :     {"scram_client_key", NULL, NULL, NULL, "SCRAM-Client-Key", "D", SCRAM_MAX_KEY_LEN * 2,
     372             :     offsetof(struct pg_conn, scram_client_key)},
     373             : 
     374             :     {"scram_server_key", NULL, NULL, NULL, "SCRAM-Server-Key", "D", SCRAM_MAX_KEY_LEN * 2,
     375             :     offsetof(struct pg_conn, scram_server_key)},
     376             : 
     377             :     /* OAuth v2 */
     378             :     {"oauth_issuer", NULL, NULL, NULL,
     379             :         "OAuth-Issuer", "", 40,
     380             :     offsetof(struct pg_conn, oauth_issuer)},
     381             : 
     382             :     {"oauth_client_id", NULL, NULL, NULL,
     383             :         "OAuth-Client-ID", "", 40,
     384             :     offsetof(struct pg_conn, oauth_client_id)},
     385             : 
     386             :     {"oauth_client_secret", NULL, NULL, NULL,
     387             :         "OAuth-Client-Secret", "", 40,
     388             :     offsetof(struct pg_conn, oauth_client_secret)},
     389             : 
     390             :     {"oauth_scope", NULL, NULL, NULL,
     391             :         "OAuth-Scope", "", 15,
     392             :     offsetof(struct pg_conn, oauth_scope)},
     393             : 
     394             :     /* Terminating entry --- MUST BE LAST */
     395             :     {NULL, NULL, NULL, NULL,
     396             :     NULL, NULL, 0}
     397             : };
     398             : 
     399             : static const PQEnvironmentOption EnvironmentOptions[] =
     400             : {
     401             :     /* common user-interface settings */
     402             :     {
     403             :         "PGDATESTYLE", "datestyle"
     404             :     },
     405             :     {
     406             :         "PGTZ", "timezone"
     407             :     },
     408             :     /* internal performance-related settings */
     409             :     {
     410             :         "PGGEQO", "geqo"
     411             :     },
     412             :     {
     413             :         NULL, NULL
     414             :     }
     415             : };
     416             : 
     417             : static const pg_fe_sasl_mech *supported_sasl_mechs[] =
     418             : {
     419             :     &pg_scram_mech,
     420             :     &pg_oauth_mech,
     421             : };
     422             : #define SASL_MECHANISM_COUNT lengthof(supported_sasl_mechs)
     423             : 
     424             : /* The connection URI must start with either of the following designators: */
     425             : static const char uri_designator[] = "postgresql://";
     426             : static const char short_uri_designator[] = "postgres://";
     427             : 
     428             : static bool connectOptions1(PGconn *conn, const char *conninfo);
     429             : static bool init_allowed_encryption_methods(PGconn *conn);
     430             : #if defined(USE_SSL) || defined(ENABLE_GSS)
     431             : static int  encryption_negotiation_failed(PGconn *conn);
     432             : #endif
     433             : static bool connection_failed(PGconn *conn);
     434             : static bool select_next_encryption_method(PGconn *conn, bool have_valid_connection);
     435             : static PGPing internal_ping(PGconn *conn);
     436             : static void pqFreeCommandQueue(PGcmdQueueEntry *queue);
     437             : static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions);
     438             : static void freePGconn(PGconn *conn);
     439             : static void release_conn_addrinfo(PGconn *conn);
     440             : static int  store_conn_addrinfo(PGconn *conn, struct addrinfo *addrlist);
     441             : static void sendTerminateConn(PGconn *conn);
     442             : static PQconninfoOption *conninfo_init(PQExpBuffer errorMessage);
     443             : static PQconninfoOption *parse_connection_string(const char *connstr,
     444             :                                                  PQExpBuffer errorMessage, bool use_defaults);
     445             : static int  uri_prefix_length(const char *connstr);
     446             : static bool recognized_connection_string(const char *connstr);
     447             : static PQconninfoOption *conninfo_parse(const char *conninfo,
     448             :                                         PQExpBuffer errorMessage, bool use_defaults);
     449             : static PQconninfoOption *conninfo_array_parse(const char *const *keywords,
     450             :                                               const char *const *values, PQExpBuffer errorMessage,
     451             :                                               bool use_defaults, int expand_dbname);
     452             : static bool conninfo_add_defaults(PQconninfoOption *options,
     453             :                                   PQExpBuffer errorMessage);
     454             : static PQconninfoOption *conninfo_uri_parse(const char *uri,
     455             :                                             PQExpBuffer errorMessage, bool use_defaults);
     456             : static bool conninfo_uri_parse_options(PQconninfoOption *options,
     457             :                                        const char *uri, PQExpBuffer errorMessage);
     458             : static bool conninfo_uri_parse_params(char *params,
     459             :                                       PQconninfoOption *connOptions,
     460             :                                       PQExpBuffer errorMessage);
     461             : static char *conninfo_uri_decode(const char *str, PQExpBuffer errorMessage);
     462             : static bool get_hexdigit(char digit, int *value);
     463             : static const char *conninfo_getval(PQconninfoOption *connOptions,
     464             :                                    const char *keyword);
     465             : static PQconninfoOption *conninfo_storeval(PQconninfoOption *connOptions,
     466             :                                            const char *keyword, const char *value,
     467             :                                            PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode);
     468             : static PQconninfoOption *conninfo_find(PQconninfoOption *connOptions,
     469             :                                        const char *keyword);
     470             : static void defaultNoticeReceiver(void *arg, const PGresult *res);
     471             : static void defaultNoticeProcessor(void *arg, const char *message);
     472             : static int  parseServiceInfo(PQconninfoOption *options,
     473             :                              PQExpBuffer errorMessage);
     474             : static int  parseServiceFile(const char *serviceFile,
     475             :                              const char *service,
     476             :                              PQconninfoOption *options,
     477             :                              PQExpBuffer errorMessage,
     478             :                              bool *group_found);
     479             : static char *pwdfMatchesString(char *buf, const char *token);
     480             : static char *passwordFromFile(const char *hostname, const char *port, const char *dbname,
     481             :                               const char *username, const char *pgpassfile);
     482             : static void pgpassfileWarning(PGconn *conn);
     483             : static void default_threadlock(int acquire);
     484             : static bool sslVerifyProtocolVersion(const char *version);
     485             : static bool sslVerifyProtocolRange(const char *min, const char *max);
     486             : 
     487             : 
     488             : /* global variable because fe-auth.c needs to access it */
     489             : pgthreadlock_t pg_g_threadlock = default_threadlock;
     490             : 
     491             : 
     492             : /*
     493             :  *      pqDropConnection
     494             :  *
     495             :  * Close any physical connection to the server, and reset associated
     496             :  * state inside the connection object.  We don't release state that
     497             :  * would be needed to reconnect, though, nor local state that might still
     498             :  * be useful later.
     499             :  *
     500             :  * We can always flush the output buffer, since there's no longer any hope
     501             :  * of sending that data.  However, unprocessed input data might still be
     502             :  * valuable, so the caller must tell us whether to flush that or not.
     503             :  */
     504             : void
     505       57664 : pqDropConnection(PGconn *conn, bool flushInput)
     506             : {
     507             :     /* Drop any SSL state */
     508       57664 :     pqsecure_close(conn);
     509             : 
     510             :     /* Close the socket itself */
     511       57664 :     if (conn->sock != PGINVALID_SOCKET)
     512       28062 :         closesocket(conn->sock);
     513       57664 :     conn->sock = PGINVALID_SOCKET;
     514             : 
     515             :     /* Optionally discard any unread data */
     516       57664 :     if (flushInput)
     517       57430 :         conn->inStart = conn->inCursor = conn->inEnd = 0;
     518             : 
     519             :     /* Always discard any unsent data */
     520       57664 :     conn->outCount = 0;
     521             : 
     522             :     /* Likewise, discard any pending pipelined commands */
     523       57664 :     pqFreeCommandQueue(conn->cmd_queue_head);
     524       57664 :     conn->cmd_queue_head = conn->cmd_queue_tail = NULL;
     525       57664 :     pqFreeCommandQueue(conn->cmd_queue_recycle);
     526       57664 :     conn->cmd_queue_recycle = NULL;
     527             : 
     528             :     /* Free authentication/encryption state */
     529       57664 :     if (conn->cleanup_async_auth)
     530             :     {
     531             :         /*
     532             :          * Any in-progress async authentication should be torn down first so
     533             :          * that cleanup_async_auth() can depend on the other authentication
     534             :          * state if necessary.
     535             :          */
     536           0 :         conn->cleanup_async_auth(conn);
     537           0 :         conn->cleanup_async_auth = NULL;
     538             :     }
     539       57664 :     conn->async_auth = NULL;
     540             :     /* cleanup_async_auth() should have done this, but make sure */
     541       57664 :     conn->altsock = PGINVALID_SOCKET;
     542             : #ifdef ENABLE_GSS
     543             :     {
     544             :         OM_uint32   min_s;
     545             : 
     546             :         if (conn->gcred != GSS_C_NO_CREDENTIAL)
     547             :         {
     548             :             gss_release_cred(&min_s, &conn->gcred);
     549             :             conn->gcred = GSS_C_NO_CREDENTIAL;
     550             :         }
     551             :         if (conn->gctx)
     552             :             gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
     553             :         if (conn->gtarg_nam)
     554             :             gss_release_name(&min_s, &conn->gtarg_nam);
     555             :         if (conn->gss_SendBuffer)
     556             :         {
     557             :             free(conn->gss_SendBuffer);
     558             :             conn->gss_SendBuffer = NULL;
     559             :         }
     560             :         if (conn->gss_RecvBuffer)
     561             :         {
     562             :             free(conn->gss_RecvBuffer);
     563             :             conn->gss_RecvBuffer = NULL;
     564             :         }
     565             :         if (conn->gss_ResultBuffer)
     566             :         {
     567             :             free(conn->gss_ResultBuffer);
     568             :             conn->gss_ResultBuffer = NULL;
     569             :         }
     570             :         conn->gssenc = false;
     571             :     }
     572             : #endif
     573             : #ifdef ENABLE_SSPI
     574             :     if (conn->sspitarget)
     575             :     {
     576             :         free(conn->sspitarget);
     577             :         conn->sspitarget = NULL;
     578             :     }
     579             :     if (conn->sspicred)
     580             :     {
     581             :         FreeCredentialsHandle(conn->sspicred);
     582             :         free(conn->sspicred);
     583             :         conn->sspicred = NULL;
     584             :     }
     585             :     if (conn->sspictx)
     586             :     {
     587             :         DeleteSecurityContext(conn->sspictx);
     588             :         free(conn->sspictx);
     589             :         conn->sspictx = NULL;
     590             :     }
     591             :     conn->usesspi = 0;
     592             : #endif
     593       57664 :     if (conn->sasl_state)
     594             :     {
     595         112 :         conn->sasl->free(conn->sasl_state);
     596         112 :         conn->sasl_state = NULL;
     597             :     }
     598       57664 : }
     599             : 
     600             : /*
     601             :  * pqFreeCommandQueue
     602             :  * Free all the entries of PGcmdQueueEntry queue passed.
     603             :  */
     604             : static void
     605      115328 : pqFreeCommandQueue(PGcmdQueueEntry *queue)
     606             : {
     607      143784 :     while (queue != NULL)
     608             :     {
     609       28456 :         PGcmdQueueEntry *cur = queue;
     610             : 
     611       28456 :         queue = cur->next;
     612       28456 :         free(cur->query);
     613       28456 :         free(cur);
     614             :     }
     615      115328 : }
     616             : 
     617             : /*
     618             :  *      pqDropServerData
     619             :  *
     620             :  * Clear all connection state data that was received from (or deduced about)
     621             :  * the server.  This is essential to do between connection attempts to
     622             :  * different servers, else we may incorrectly hold over some data from the
     623             :  * old server.
     624             :  *
     625             :  * It would be better to merge this into pqDropConnection, perhaps, but
     626             :  * right now we cannot because that function is called immediately on
     627             :  * detection of connection loss (cf. pqReadData, for instance).  This data
     628             :  * should be kept until we are actually starting a new connection.
     629             :  */
     630             : static void
     631       56990 : pqDropServerData(PGconn *conn)
     632             : {
     633             :     PGnotify   *notify;
     634             :     pgParameterStatus *pstatus;
     635             : 
     636             :     /* Forget pending notifies */
     637       56990 :     notify = conn->notifyHead;
     638       56990 :     while (notify != NULL)
     639             :     {
     640           0 :         PGnotify   *prev = notify;
     641             : 
     642           0 :         notify = notify->next;
     643           0 :         free(prev);
     644             :     }
     645       56990 :     conn->notifyHead = conn->notifyTail = NULL;
     646             : 
     647             :     /* Reset ParameterStatus data, as well as variables deduced from it */
     648       56990 :     pstatus = conn->pstatus;
     649      462710 :     while (pstatus != NULL)
     650             :     {
     651      405720 :         pgParameterStatus *prev = pstatus;
     652             : 
     653      405720 :         pstatus = pstatus->next;
     654      405720 :         free(prev);
     655             :     }
     656       56990 :     conn->pstatus = NULL;
     657       56990 :     conn->client_encoding = PG_SQL_ASCII;
     658       56990 :     conn->std_strings = false;
     659       56990 :     conn->default_transaction_read_only = PG_BOOL_UNKNOWN;
     660       56990 :     conn->in_hot_standby = PG_BOOL_UNKNOWN;
     661       56990 :     conn->scram_sha_256_iterations = SCRAM_SHA_256_DEFAULT_ITERATIONS;
     662       56990 :     conn->sversion = 0;
     663             : 
     664             :     /* Drop large-object lookup data */
     665       56990 :     free(conn->lobjfuncs);
     666       56990 :     conn->lobjfuncs = NULL;
     667             : 
     668             :     /* Reset assorted other per-connection state */
     669       56990 :     conn->last_sqlstate[0] = '\0';
     670       56990 :     conn->auth_req_received = false;
     671       56990 :     conn->client_finished_auth = false;
     672       56990 :     conn->password_needed = false;
     673       56990 :     conn->gssapi_used = false;
     674       56990 :     conn->write_failed = false;
     675       56990 :     free(conn->write_err_msg);
     676       56990 :     conn->write_err_msg = NULL;
     677       56990 :     conn->oauth_want_retry = false;
     678             : 
     679             :     /*
     680             :      * Cancel connections need to retain their be_pid and be_key across
     681             :      * PQcancelReset invocations, otherwise they would not have access to the
     682             :      * secret token of the connection they are supposed to cancel.
     683             :      */
     684       56990 :     if (!conn->cancelRequest)
     685             :     {
     686       56978 :         conn->be_pid = 0;
     687       56978 :         conn->be_key = 0;
     688             :     }
     689       56990 : }
     690             : 
     691             : 
     692             : /*
     693             :  *      Connecting to a Database
     694             :  *
     695             :  * There are now six different ways a user of this API can connect to the
     696             :  * database.  Two are not recommended for use in new code, because of their
     697             :  * lack of extensibility with respect to the passing of options to the
     698             :  * backend.  These are PQsetdb and PQsetdbLogin (the former now being a macro
     699             :  * to the latter).
     700             :  *
     701             :  * If it is desired to connect in a synchronous (blocking) manner, use the
     702             :  * function PQconnectdb or PQconnectdbParams. The former accepts a string of
     703             :  * option = value pairs (or a URI) which must be parsed; the latter takes two
     704             :  * NULL terminated arrays instead.
     705             :  *
     706             :  * To connect in an asynchronous (non-blocking) manner, use the functions
     707             :  * PQconnectStart or PQconnectStartParams (which differ in the same way as
     708             :  * PQconnectdb and PQconnectdbParams) and PQconnectPoll.
     709             :  *
     710             :  * The non-exported functions pqConnectDBStart, pqConnectDBComplete are
     711             :  * part of the connection procedure implementation.
     712             :  */
     713             : 
     714             : /*
     715             :  *      PQconnectdbParams
     716             :  *
     717             :  * establishes a connection to a postgres backend through the postmaster
     718             :  * using connection information in two arrays.
     719             :  *
     720             :  * The keywords array is defined as
     721             :  *
     722             :  *     const char *params[] = {"option1", "option2", NULL}
     723             :  *
     724             :  * The values array is defined as
     725             :  *
     726             :  *     const char *values[] = {"value1", "value2", NULL}
     727             :  *
     728             :  * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL
     729             :  * if a memory allocation failed.
     730             :  * If the status field of the connection returned is CONNECTION_BAD,
     731             :  * then some fields may be null'ed out instead of having valid values.
     732             :  *
     733             :  * You should call PQfinish (if conn is not NULL) regardless of whether this
     734             :  * call succeeded.
     735             :  */
     736             : PGconn *
     737       23472 : PQconnectdbParams(const char *const *keywords,
     738             :                   const char *const *values,
     739             :                   int expand_dbname)
     740             : {
     741       23472 :     PGconn     *conn = PQconnectStartParams(keywords, values, expand_dbname);
     742             : 
     743       23472 :     if (conn && conn->status != CONNECTION_BAD)
     744       23384 :         (void) pqConnectDBComplete(conn);
     745             : 
     746       23472 :     return conn;
     747             : }
     748             : 
     749             : /*
     750             :  *      PQpingParams
     751             :  *
     752             :  * check server status, accepting parameters identical to PQconnectdbParams
     753             :  */
     754             : PGPing
     755         672 : PQpingParams(const char *const *keywords,
     756             :              const char *const *values,
     757             :              int expand_dbname)
     758             : {
     759         672 :     PGconn     *conn = PQconnectStartParams(keywords, values, expand_dbname);
     760             :     PGPing      ret;
     761             : 
     762         672 :     ret = internal_ping(conn);
     763         672 :     PQfinish(conn);
     764             : 
     765         672 :     return ret;
     766             : }
     767             : 
     768             : /*
     769             :  *      PQconnectdb
     770             :  *
     771             :  * establishes a connection to a postgres backend through the postmaster
     772             :  * using connection information in a string.
     773             :  *
     774             :  * The conninfo string is either a whitespace-separated list of
     775             :  *
     776             :  *     option = value
     777             :  *
     778             :  * definitions or a URI (refer to the documentation for details.) Value
     779             :  * might be a single value containing no whitespaces or a single quoted
     780             :  * string. If a single quote should appear anywhere in the value, it must be
     781             :  * escaped with a backslash like \'
     782             :  *
     783             :  * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL
     784             :  * if a memory allocation failed.
     785             :  * If the status field of the connection returned is CONNECTION_BAD,
     786             :  * then some fields may be null'ed out instead of having valid values.
     787             :  *
     788             :  * You should call PQfinish (if conn is not NULL) regardless of whether this
     789             :  * call succeeded.
     790             :  */
     791             : PGconn *
     792        1678 : PQconnectdb(const char *conninfo)
     793             : {
     794        1678 :     PGconn     *conn = PQconnectStart(conninfo);
     795             : 
     796        1678 :     if (conn && conn->status != CONNECTION_BAD)
     797        1678 :         (void) pqConnectDBComplete(conn);
     798             : 
     799        1678 :     return conn;
     800             : }
     801             : 
     802             : /*
     803             :  *      PQping
     804             :  *
     805             :  * check server status, accepting parameters identical to PQconnectdb
     806             :  */
     807             : PGPing
     808           0 : PQping(const char *conninfo)
     809             : {
     810           0 :     PGconn     *conn = PQconnectStart(conninfo);
     811             :     PGPing      ret;
     812             : 
     813           0 :     ret = internal_ping(conn);
     814           0 :     PQfinish(conn);
     815             : 
     816           0 :     return ret;
     817             : }
     818             : 
     819             : /*
     820             :  *      PQconnectStartParams
     821             :  *
     822             :  * Begins the establishment of a connection to a postgres backend through the
     823             :  * postmaster using connection information in a struct.
     824             :  *
     825             :  * See comment for PQconnectdbParams for the definition of the string format.
     826             :  *
     827             :  * Returns a PGconn*.  If NULL is returned, a malloc error has occurred, and
     828             :  * you should not attempt to proceed with this connection.  If the status
     829             :  * field of the connection returned is CONNECTION_BAD, an error has
     830             :  * occurred. In this case you should call PQfinish on the result, (perhaps
     831             :  * inspecting the error message first).  Other fields of the structure may not
     832             :  * be valid if that occurs.  If the status field is not CONNECTION_BAD, then
     833             :  * this stage has succeeded - call PQconnectPoll, using select(2) to see when
     834             :  * this is necessary.
     835             :  *
     836             :  * See PQconnectPoll for more info.
     837             :  */
     838             : PGconn *
     839       26304 : PQconnectStartParams(const char *const *keywords,
     840             :                      const char *const *values,
     841             :                      int expand_dbname)
     842             : {
     843             :     PGconn     *conn;
     844             :     PQconninfoOption *connOptions;
     845             : 
     846             :     /*
     847             :      * Allocate memory for the conn structure.  Note that we also expect this
     848             :      * to initialize conn->errorMessage to empty.  All subsequent steps during
     849             :      * connection initialization will only append to that buffer.
     850             :      */
     851       26304 :     conn = pqMakeEmptyPGconn();
     852       26304 :     if (conn == NULL)
     853           0 :         return NULL;
     854             : 
     855             :     /*
     856             :      * Parse the conninfo arrays
     857             :      */
     858       26304 :     connOptions = conninfo_array_parse(keywords, values,
     859             :                                        &conn->errorMessage,
     860             :                                        true, expand_dbname);
     861       26304 :     if (connOptions == NULL)
     862             :     {
     863          10 :         conn->status = CONNECTION_BAD;
     864             :         /* errorMessage is already set */
     865          10 :         return conn;
     866             :     }
     867             : 
     868             :     /*
     869             :      * Move option values into conn structure
     870             :      */
     871       26294 :     if (!fillPGconn(conn, connOptions))
     872             :     {
     873           0 :         PQconninfoFree(connOptions);
     874           0 :         return conn;
     875             :     }
     876             : 
     877             :     /*
     878             :      * Free the option info - all is in conn now
     879             :      */
     880       26294 :     PQconninfoFree(connOptions);
     881             : 
     882             :     /*
     883             :      * Compute derived options
     884             :      */
     885       26294 :     if (!pqConnectOptions2(conn))
     886          78 :         return conn;
     887             : 
     888             :     /*
     889             :      * Connect to the database
     890             :      */
     891       26216 :     if (!pqConnectDBStart(conn))
     892             :     {
     893             :         /* Just in case we failed to set it in pqConnectDBStart */
     894         440 :         conn->status = CONNECTION_BAD;
     895             :     }
     896             : 
     897       26216 :     return conn;
     898             : }
     899             : 
     900             : /*
     901             :  *      PQconnectStart
     902             :  *
     903             :  * Begins the establishment of a connection to a postgres backend through the
     904             :  * postmaster using connection information in a string.
     905             :  *
     906             :  * See comment for PQconnectdb for the definition of the string format.
     907             :  *
     908             :  * Returns a PGconn*.  If NULL is returned, a malloc error has occurred, and
     909             :  * you should not attempt to proceed with this connection.  If the status
     910             :  * field of the connection returned is CONNECTION_BAD, an error has
     911             :  * occurred. In this case you should call PQfinish on the result, (perhaps
     912             :  * inspecting the error message first).  Other fields of the structure may not
     913             :  * be valid if that occurs.  If the status field is not CONNECTION_BAD, then
     914             :  * this stage has succeeded - call PQconnectPoll, using select(2) to see when
     915             :  * this is necessary.
     916             :  *
     917             :  * See PQconnectPoll for more info.
     918             :  */
     919             : PGconn *
     920        2186 : PQconnectStart(const char *conninfo)
     921             : {
     922             :     PGconn     *conn;
     923             : 
     924             :     /*
     925             :      * Allocate memory for the conn structure.  Note that we also expect this
     926             :      * to initialize conn->errorMessage to empty.  All subsequent steps during
     927             :      * connection initialization will only append to that buffer.
     928             :      */
     929        2186 :     conn = pqMakeEmptyPGconn();
     930        2186 :     if (conn == NULL)
     931           0 :         return NULL;
     932             : 
     933             :     /*
     934             :      * Parse the conninfo string
     935             :      */
     936        2186 :     if (!connectOptions1(conn, conninfo))
     937           4 :         return conn;
     938             : 
     939             :     /*
     940             :      * Compute derived options
     941             :      */
     942        2182 :     if (!pqConnectOptions2(conn))
     943           0 :         return conn;
     944             : 
     945             :     /*
     946             :      * Connect to the database
     947             :      */
     948        2182 :     if (!pqConnectDBStart(conn))
     949             :     {
     950             :         /* Just in case we failed to set it in pqConnectDBStart */
     951           0 :         conn->status = CONNECTION_BAD;
     952             :     }
     953             : 
     954        2182 :     return conn;
     955             : }
     956             : 
     957             : /*
     958             :  * Move option values into conn structure
     959             :  *
     960             :  * Don't put anything cute here --- intelligence should be in
     961             :  * pqConnectOptions2 ...
     962             :  *
     963             :  * Returns true on success. On failure, returns false and sets error message.
     964             :  */
     965             : static bool
     966       28476 : fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
     967             : {
     968             :     const internalPQconninfoOption *option;
     969             : 
     970     1366848 :     for (option = PQconninfoOptions; option->keyword; option++)
     971             :     {
     972     1338372 :         if (option->connofs >= 0)
     973             :         {
     974     1338372 :             const char *tmp = conninfo_getval(connOptions, option->keyword);
     975             : 
     976     1338372 :             if (tmp)
     977             :             {
     978      515266 :                 char      **connmember = (char **) ((char *) conn + option->connofs);
     979             : 
     980      515266 :                 free(*connmember);
     981      515266 :                 *connmember = strdup(tmp);
     982      515266 :                 if (*connmember == NULL)
     983             :                 {
     984           0 :                     libpq_append_conn_error(conn, "out of memory");
     985           0 :                     return false;
     986             :                 }
     987             :             }
     988             :         }
     989             :     }
     990             : 
     991       28476 :     return true;
     992             : }
     993             : 
     994             : /*
     995             :  * Copy over option values from srcConn to dstConn
     996             :  *
     997             :  * Don't put anything cute here --- intelligence should be in
     998             :  * pqConnectOptions2 ...
     999             :  *
    1000             :  * Returns true on success. On failure, returns false and sets error message of
    1001             :  * dstConn.
    1002             :  */
    1003             : bool
    1004          10 : pqCopyPGconn(PGconn *srcConn, PGconn *dstConn)
    1005             : {
    1006             :     const internalPQconninfoOption *option;
    1007             : 
    1008             :     /* copy over connection options */
    1009         480 :     for (option = PQconninfoOptions; option->keyword; option++)
    1010             :     {
    1011         470 :         if (option->connofs >= 0)
    1012             :         {
    1013         470 :             const char **tmp = (const char **) ((char *) srcConn + option->connofs);
    1014             : 
    1015         470 :             if (*tmp)
    1016             :             {
    1017         198 :                 char      **dstConnmember = (char **) ((char *) dstConn + option->connofs);
    1018             : 
    1019         198 :                 if (*dstConnmember)
    1020           0 :                     free(*dstConnmember);
    1021         198 :                 *dstConnmember = strdup(*tmp);
    1022         198 :                 if (*dstConnmember == NULL)
    1023             :                 {
    1024           0 :                     libpq_append_conn_error(dstConn, "out of memory");
    1025           0 :                     return false;
    1026             :                 }
    1027             :             }
    1028             :         }
    1029             :     }
    1030          10 :     return true;
    1031             : }
    1032             : 
    1033             : /*
    1034             :  *      connectOptions1
    1035             :  *
    1036             :  * Internal subroutine to set up connection parameters given an already-
    1037             :  * created PGconn and a conninfo string.  Derived settings should be
    1038             :  * processed by calling pqConnectOptions2 next.  (We split them because
    1039             :  * PQsetdbLogin overrides defaults in between.)
    1040             :  *
    1041             :  * Returns true if OK, false if trouble (in which case errorMessage is set
    1042             :  * and so is conn->status).
    1043             :  */
    1044             : static bool
    1045        2186 : connectOptions1(PGconn *conn, const char *conninfo)
    1046             : {
    1047             :     PQconninfoOption *connOptions;
    1048             : 
    1049             :     /*
    1050             :      * Parse the conninfo string
    1051             :      */
    1052        2186 :     connOptions = parse_connection_string(conninfo, &conn->errorMessage, true);
    1053        2186 :     if (connOptions == NULL)
    1054             :     {
    1055           4 :         conn->status = CONNECTION_BAD;
    1056             :         /* errorMessage is already set */
    1057           4 :         return false;
    1058             :     }
    1059             : 
    1060             :     /*
    1061             :      * Move option values into conn structure
    1062             :      */
    1063        2182 :     if (!fillPGconn(conn, connOptions))
    1064             :     {
    1065           0 :         conn->status = CONNECTION_BAD;
    1066           0 :         PQconninfoFree(connOptions);
    1067           0 :         return false;
    1068             :     }
    1069             : 
    1070             :     /*
    1071             :      * Free the option info - all is in conn now
    1072             :      */
    1073        2182 :     PQconninfoFree(connOptions);
    1074             : 
    1075        2182 :     return true;
    1076             : }
    1077             : 
    1078             : /*
    1079             :  * Count the number of elements in a simple comma-separated list.
    1080             :  */
    1081             : static int
    1082       28486 : count_comma_separated_elems(const char *input)
    1083             : {
    1084             :     int         n;
    1085             : 
    1086       28486 :     n = 1;
    1087      481732 :     for (; *input != '\0'; input++)
    1088             :     {
    1089      453246 :         if (*input == ',')
    1090         266 :             n++;
    1091             :     }
    1092             : 
    1093       28486 :     return n;
    1094             : }
    1095             : 
    1096             : /*
    1097             :  * Parse a simple comma-separated list.
    1098             :  *
    1099             :  * On each call, returns a malloc'd copy of the next element, and sets *more
    1100             :  * to indicate whether there are any more elements in the list after this,
    1101             :  * and updates *startptr to point to the next element, if any.
    1102             :  *
    1103             :  * On out of memory, returns NULL.
    1104             :  */
    1105             : static char *
    1106       58026 : parse_comma_separated_list(char **startptr, bool *more)
    1107             : {
    1108             :     char       *p;
    1109       58026 :     char       *s = *startptr;
    1110             :     char       *e;
    1111             :     int         len;
    1112             : 
    1113             :     /*
    1114             :      * Search for the end of the current element; a comma or end-of-string
    1115             :      * acts as a terminator.
    1116             :      */
    1117       58026 :     e = s;
    1118      664582 :     while (*e != '\0' && *e != ',')
    1119      606556 :         ++e;
    1120       58026 :     *more = (*e == ',');
    1121             : 
    1122       58026 :     len = e - s;
    1123       58026 :     p = (char *) malloc(sizeof(char) * (len + 1));
    1124       58026 :     if (p)
    1125             :     {
    1126       58026 :         memcpy(p, s, len);
    1127       58026 :         p[len] = '\0';
    1128             :     }
    1129       58026 :     *startptr = e + 1;
    1130             : 
    1131       58026 :     return p;
    1132             : }
    1133             : 
    1134             : /*
    1135             :  * Initializes the prng_state field of the connection. We want something
    1136             :  * unpredictable, so if possible, use high-quality random bits for the
    1137             :  * seed. Otherwise, fall back to a seed based on the connection address,
    1138             :  * timestamp and PID.
    1139             :  */
    1140             : static void
    1141         110 : libpq_prng_init(PGconn *conn)
    1142             : {
    1143             :     uint64      rseed;
    1144         110 :     struct timeval tval = {0};
    1145             : 
    1146         110 :     if (pg_prng_strong_seed(&conn->prng_state))
    1147         110 :         return;
    1148             : 
    1149           0 :     gettimeofday(&tval, NULL);
    1150             : 
    1151           0 :     rseed = ((uintptr_t) conn) ^
    1152           0 :         ((uint64) getpid()) ^
    1153           0 :         ((uint64) tval.tv_usec) ^
    1154           0 :         ((uint64) tval.tv_sec);
    1155             : 
    1156           0 :     pg_prng_seed(&conn->prng_state, rseed);
    1157             : }
    1158             : 
    1159             : /*
    1160             :  * Fills the connection's allowed_sasl_mechs list with all supported SASL
    1161             :  * mechanisms.
    1162             :  */
    1163             : static inline void
    1164          40 : fill_allowed_sasl_mechs(PGconn *conn)
    1165             : {
    1166             :     /*---
    1167             :      * We only support two mechanisms at the moment, so rather than deal with a
    1168             :      * linked list, conn->allowed_sasl_mechs is an array of static length. We
    1169             :      * rely on the compile-time assertion here to keep us honest.
    1170             :      *
    1171             :      * To add a new mechanism to require_auth,
    1172             :      * - add it to supported_sasl_mechs,
    1173             :      * - update the length of conn->allowed_sasl_mechs,
    1174             :      * - handle the new mechanism name in the require_auth portion of
    1175             :      *   pqConnectOptions2(), below.
    1176             :      */
    1177             :     StaticAssertDecl(lengthof(conn->allowed_sasl_mechs) == SASL_MECHANISM_COUNT,
    1178             :                      "conn->allowed_sasl_mechs[] is not sufficiently large for holding all supported SASL mechanisms");
    1179             : 
    1180         120 :     for (int i = 0; i < SASL_MECHANISM_COUNT; i++)
    1181          80 :         conn->allowed_sasl_mechs[i] = supported_sasl_mechs[i];
    1182          40 : }
    1183             : 
    1184             : /*
    1185             :  * Clears the connection's allowed_sasl_mechs list.
    1186             :  */
    1187             : static inline void
    1188         120 : clear_allowed_sasl_mechs(PGconn *conn)
    1189             : {
    1190         360 :     for (int i = 0; i < lengthof(conn->allowed_sasl_mechs); i++)
    1191         240 :         conn->allowed_sasl_mechs[i] = NULL;
    1192         120 : }
    1193             : 
    1194             : /*
    1195             :  * Helper routine that searches the static allowed_sasl_mechs list for a
    1196             :  * specific mechanism.
    1197             :  */
    1198             : static inline int
    1199         104 : index_of_allowed_sasl_mech(PGconn *conn, const pg_fe_sasl_mech *mech)
    1200             : {
    1201         192 :     for (int i = 0; i < lengthof(conn->allowed_sasl_mechs); i++)
    1202             :     {
    1203         148 :         if (conn->allowed_sasl_mechs[i] == mech)
    1204          60 :             return i;
    1205             :     }
    1206             : 
    1207          44 :     return -1;
    1208             : }
    1209             : 
    1210             : /*
    1211             :  *      pqConnectOptions2
    1212             :  *
    1213             :  * Compute derived connection options after absorbing all user-supplied info.
    1214             :  *
    1215             :  * Returns true if OK, false if trouble (in which case errorMessage is set
    1216             :  * and so is conn->status).
    1217             :  */
    1218             : bool
    1219       28486 : pqConnectOptions2(PGconn *conn)
    1220             : {
    1221             :     int         i;
    1222             : 
    1223             :     /*
    1224             :      * Allocate memory for details about each host to which we might possibly
    1225             :      * try to connect.  For that, count the number of elements in the hostaddr
    1226             :      * or host options.  If neither is given, assume one host.
    1227             :      */
    1228       28486 :     conn->whichhost = 0;
    1229       28486 :     if (conn->pghostaddr && conn->pghostaddr[0] != '\0')
    1230         346 :         conn->nconnhost = count_comma_separated_elems(conn->pghostaddr);
    1231       28140 :     else if (conn->pghost && conn->pghost[0] != '\0')
    1232       28140 :         conn->nconnhost = count_comma_separated_elems(conn->pghost);
    1233             :     else
    1234           0 :         conn->nconnhost = 1;
    1235       28486 :     conn->connhost = (pg_conn_host *)
    1236       28486 :         calloc(conn->nconnhost, sizeof(pg_conn_host));
    1237       28486 :     if (conn->connhost == NULL)
    1238           0 :         goto oom_error;
    1239             : 
    1240             :     /*
    1241             :      * We now have one pg_conn_host structure per possible host.  Fill in the
    1242             :      * host and hostaddr fields for each, by splitting the parameter strings.
    1243             :      */
    1244       28486 :     if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
    1245             :     {
    1246         346 :         char       *s = conn->pghostaddr;
    1247         346 :         bool        more = true;
    1248             : 
    1249         692 :         for (i = 0; i < conn->nconnhost && more; i++)
    1250             :         {
    1251         346 :             conn->connhost[i].hostaddr = parse_comma_separated_list(&s, &more);
    1252         346 :             if (conn->connhost[i].hostaddr == NULL)
    1253           0 :                 goto oom_error;
    1254             :         }
    1255             : 
    1256             :         /*
    1257             :          * If hostaddr was given, the array was allocated according to the
    1258             :          * number of elements in the hostaddr list, so it really should be the
    1259             :          * right size.
    1260             :          */
    1261             :         Assert(!more);
    1262             :         Assert(i == conn->nconnhost);
    1263             :     }
    1264             : 
    1265       28486 :     if (conn->pghost != NULL && conn->pghost[0] != '\0')
    1266             :     {
    1267       28486 :         char       *s = conn->pghost;
    1268       28486 :         bool        more = true;
    1269             : 
    1270       57238 :         for (i = 0; i < conn->nconnhost && more; i++)
    1271             :         {
    1272       28752 :             conn->connhost[i].host = parse_comma_separated_list(&s, &more);
    1273       28752 :             if (conn->connhost[i].host == NULL)
    1274           0 :                 goto oom_error;
    1275             :         }
    1276             : 
    1277             :         /* Check for wrong number of host items. */
    1278       28486 :         if (more || i != conn->nconnhost)
    1279             :         {
    1280           0 :             conn->status = CONNECTION_BAD;
    1281           0 :             libpq_append_conn_error(conn, "could not match %d host names to %d hostaddr values",
    1282           0 :                                     count_comma_separated_elems(conn->pghost), conn->nconnhost);
    1283           0 :             return false;
    1284             :         }
    1285             :     }
    1286             : 
    1287             :     /*
    1288             :      * Now, for each host slot, identify the type of address spec, and fill in
    1289             :      * the default address if nothing was given.
    1290             :      */
    1291       57238 :     for (i = 0; i < conn->nconnhost; i++)
    1292             :     {
    1293       28752 :         pg_conn_host *ch = &conn->connhost[i];
    1294             : 
    1295       28752 :         if (ch->hostaddr != NULL && ch->hostaddr[0] != '\0')
    1296         346 :             ch->type = CHT_HOST_ADDRESS;
    1297       28406 :         else if (ch->host != NULL && ch->host[0] != '\0')
    1298             :         {
    1299       28406 :             ch->type = CHT_HOST_NAME;
    1300       28406 :             if (is_unixsock_path(ch->host))
    1301       28114 :                 ch->type = CHT_UNIX_SOCKET;
    1302             :         }
    1303             :         else
    1304             :         {
    1305           0 :             free(ch->host);
    1306             : 
    1307             :             /*
    1308             :              * This bit selects the default host location.  If you change
    1309             :              * this, see also pg_regress.
    1310             :              */
    1311           0 :             if (DEFAULT_PGSOCKET_DIR[0])
    1312             :             {
    1313           0 :                 ch->host = strdup(DEFAULT_PGSOCKET_DIR);
    1314           0 :                 ch->type = CHT_UNIX_SOCKET;
    1315             :             }
    1316             :             else
    1317             :             {
    1318           0 :                 ch->host = strdup(DefaultHost);
    1319           0 :                 ch->type = CHT_HOST_NAME;
    1320             :             }
    1321           0 :             if (ch->host == NULL)
    1322           0 :                 goto oom_error;
    1323             :         }
    1324             :     }
    1325             : 
    1326             :     /*
    1327             :      * Next, work out the port number corresponding to each host name.
    1328             :      *
    1329             :      * Note: unlike the above for host names, this could leave the port fields
    1330             :      * as null or empty strings.  We will substitute DEF_PGPORT whenever we
    1331             :      * read such a port field.
    1332             :      */
    1333       28486 :     if (conn->pgport != NULL && conn->pgport[0] != '\0')
    1334             :     {
    1335       28486 :         char       *s = conn->pgport;
    1336       28486 :         bool        more = true;
    1337             : 
    1338       57238 :         for (i = 0; i < conn->nconnhost && more; i++)
    1339             :         {
    1340       28752 :             conn->connhost[i].port = parse_comma_separated_list(&s, &more);
    1341       28752 :             if (conn->connhost[i].port == NULL)
    1342           0 :                 goto oom_error;
    1343             :         }
    1344             : 
    1345             :         /*
    1346             :          * If exactly one port was given, use it for every host.  Otherwise,
    1347             :          * there must be exactly as many ports as there were hosts.
    1348             :          */
    1349       28486 :         if (i == 1 && !more)
    1350             :         {
    1351       28336 :             for (i = 1; i < conn->nconnhost; i++)
    1352             :             {
    1353           0 :                 conn->connhost[i].port = strdup(conn->connhost[0].port);
    1354           0 :                 if (conn->connhost[i].port == NULL)
    1355           0 :                     goto oom_error;
    1356             :             }
    1357             :         }
    1358         150 :         else if (more || i != conn->nconnhost)
    1359             :         {
    1360           0 :             conn->status = CONNECTION_BAD;
    1361           0 :             libpq_append_conn_error(conn, "could not match %d port numbers to %d hosts",
    1362           0 :                                     count_comma_separated_elems(conn->pgport), conn->nconnhost);
    1363           0 :             return false;
    1364             :         }
    1365             :     }
    1366             : 
    1367             :     /*
    1368             :      * If user name was not given, fetch it.  (Most likely, the fetch will
    1369             :      * fail, since the only way we get here is if pg_fe_getauthname() failed
    1370             :      * during conninfo_add_defaults().  But now we want an error message.)
    1371             :      */
    1372       28486 :     if (conn->pguser == NULL || conn->pguser[0] == '\0')
    1373             :     {
    1374           0 :         free(conn->pguser);
    1375           0 :         conn->pguser = pg_fe_getauthname(&conn->errorMessage);
    1376           0 :         if (!conn->pguser)
    1377             :         {
    1378           0 :             conn->status = CONNECTION_BAD;
    1379           0 :             return false;
    1380             :         }
    1381             :     }
    1382             : 
    1383             :     /*
    1384             :      * If database name was not given, default it to equal user name
    1385             :      */
    1386       28486 :     if (conn->dbName == NULL || conn->dbName[0] == '\0')
    1387             :     {
    1388          12 :         free(conn->dbName);
    1389          12 :         conn->dbName = strdup(conn->pguser);
    1390          12 :         if (!conn->dbName)
    1391           0 :             goto oom_error;
    1392             :     }
    1393             : 
    1394             :     /*
    1395             :      * If password was not given, try to look it up in password file.  Note
    1396             :      * that the result might be different for each host/port pair.
    1397             :      */
    1398       28486 :     if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
    1399             :     {
    1400             :         /* If password file wasn't specified, use ~/PGPASSFILE */
    1401       28026 :         if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
    1402             :         {
    1403             :             char        homedir[MAXPGPATH];
    1404             : 
    1405       27664 :             if (pqGetHomeDirectory(homedir, sizeof(homedir)))
    1406             :             {
    1407       27664 :                 free(conn->pgpassfile);
    1408       27664 :                 conn->pgpassfile = malloc(MAXPGPATH);
    1409       27664 :                 if (!conn->pgpassfile)
    1410           0 :                     goto oom_error;
    1411       27664 :                 snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s",
    1412             :                          homedir, PGPASSFILE);
    1413             :             }
    1414             :         }
    1415             : 
    1416       28026 :         if (conn->pgpassfile != NULL && conn->pgpassfile[0] != '\0')
    1417             :         {
    1418       56318 :             for (i = 0; i < conn->nconnhost; i++)
    1419             :             {
    1420             :                 /*
    1421             :                  * Try to get a password for this host from file.  We use host
    1422             :                  * for the hostname search key if given, else hostaddr (at
    1423             :                  * least one of them is guaranteed nonempty by now).
    1424             :                  */
    1425       28292 :                 const char *pwhost = conn->connhost[i].host;
    1426             : 
    1427       28292 :                 if (pwhost == NULL || pwhost[0] == '\0')
    1428           0 :                     pwhost = conn->connhost[i].hostaddr;
    1429             : 
    1430       28292 :                 conn->connhost[i].password =
    1431       28292 :                     passwordFromFile(pwhost,
    1432       28292 :                                      conn->connhost[i].port,
    1433       28292 :                                      conn->dbName,
    1434       28292 :                                      conn->pguser,
    1435       28292 :                                      conn->pgpassfile);
    1436             :             }
    1437             :         }
    1438             :     }
    1439             : 
    1440             :     /*
    1441             :      * parse and validate require_auth option
    1442             :      */
    1443       28486 :     if (conn->require_auth && conn->require_auth[0])
    1444             :     {
    1445         120 :         char       *s = conn->require_auth;
    1446             :         bool        first,
    1447             :                     more;
    1448         120 :         bool        negated = false;
    1449             : 
    1450             :         /*
    1451             :          * By default, start from an empty set of allowed methods and
    1452             :          * mechanisms, and add to it.
    1453             :          */
    1454         120 :         conn->auth_required = true;
    1455         120 :         conn->allowed_auth_methods = 0;
    1456         120 :         clear_allowed_sasl_mechs(conn);
    1457             : 
    1458         278 :         for (first = true, more = true; more; first = false)
    1459             :         {
    1460             :             char       *method,
    1461             :                        *part;
    1462         176 :             uint32      bits = 0;
    1463         176 :             const pg_fe_sasl_mech *mech = NULL;
    1464             : 
    1465         176 :             part = parse_comma_separated_list(&s, &more);
    1466         176 :             if (part == NULL)
    1467           0 :                 goto oom_error;
    1468             : 
    1469             :             /*
    1470             :              * Check for negation, e.g. '!password'. If one element is
    1471             :              * negated, they all have to be.
    1472             :              */
    1473         176 :             method = part;
    1474         176 :             if (*method == '!')
    1475             :             {
    1476          68 :                 if (first)
    1477             :                 {
    1478             :                     /*
    1479             :                      * Switch to a permissive set of allowed methods and
    1480             :                      * mechanisms, and subtract from it.
    1481             :                      */
    1482          40 :                     conn->auth_required = false;
    1483          40 :                     conn->allowed_auth_methods = -1;
    1484          40 :                     fill_allowed_sasl_mechs(conn);
    1485             :                 }
    1486          28 :                 else if (!negated)
    1487             :                 {
    1488           2 :                     conn->status = CONNECTION_BAD;
    1489           2 :                     libpq_append_conn_error(conn, "negative require_auth method \"%s\" cannot be mixed with non-negative methods",
    1490             :                                             method);
    1491             : 
    1492           2 :                     free(part);
    1493          18 :                     return false;
    1494             :                 }
    1495             : 
    1496          66 :                 negated = true;
    1497          66 :                 method++;
    1498             :             }
    1499         108 :             else if (negated)
    1500             :             {
    1501           2 :                 conn->status = CONNECTION_BAD;
    1502           2 :                 libpq_append_conn_error(conn, "require_auth method \"%s\" cannot be mixed with negative methods",
    1503             :                                         method);
    1504             : 
    1505           2 :                 free(part);
    1506           2 :                 return false;
    1507             :             }
    1508             : 
    1509             :             /*
    1510             :              * First group: methods that can be handled solely with the
    1511             :              * authentication request codes.
    1512             :              */
    1513         172 :             if (strcmp(method, "password") == 0)
    1514             :             {
    1515          40 :                 bits = (1 << AUTH_REQ_PASSWORD);
    1516             :             }
    1517         132 :             else if (strcmp(method, "md5") == 0)
    1518             :             {
    1519          32 :                 bits = (1 << AUTH_REQ_MD5);
    1520             :             }
    1521         100 :             else if (strcmp(method, "gss") == 0)
    1522             :             {
    1523           4 :                 bits = (1 << AUTH_REQ_GSS);
    1524           4 :                 bits |= (1 << AUTH_REQ_GSS_CONT);
    1525             :             }
    1526          96 :             else if (strcmp(method, "sspi") == 0)
    1527             :             {
    1528           4 :                 bits = (1 << AUTH_REQ_SSPI);
    1529           4 :                 bits |= (1 << AUTH_REQ_GSS_CONT);
    1530             :             }
    1531             : 
    1532             :             /*
    1533             :              * Next group: SASL mechanisms. All of these use the same request
    1534             :              * codes, so the list of allowed mechanisms is tracked separately.
    1535             :              *
    1536             :              * supported_sasl_mechs must contain all mechanisms handled here.
    1537             :              */
    1538          92 :             else if (strcmp(method, "scram-sha-256") == 0)
    1539             :             {
    1540          62 :                 mech = &pg_scram_mech;
    1541             :             }
    1542          30 :             else if (strcmp(method, "oauth") == 0)
    1543             :             {
    1544           0 :                 mech = &pg_oauth_mech;
    1545             :             }
    1546             : 
    1547             :             /*
    1548             :              * Final group: meta-options.
    1549             :              */
    1550          30 :             else if (strcmp(method, "none") == 0)
    1551             :             {
    1552             :                 /*
    1553             :                  * Special case: let the user explicitly allow (or disallow)
    1554             :                  * connections where the server does not send an explicit
    1555             :                  * authentication challenge, such as "trust" and "cert" auth.
    1556             :                  */
    1557          28 :                 if (negated)    /* "!none" */
    1558             :                 {
    1559          14 :                     if (conn->auth_required)
    1560           2 :                         goto duplicate;
    1561             : 
    1562          12 :                     conn->auth_required = true;
    1563             :                 }
    1564             :                 else            /* "none" */
    1565             :                 {
    1566          14 :                     if (!conn->auth_required)
    1567           2 :                         goto duplicate;
    1568             : 
    1569          12 :                     conn->auth_required = false;
    1570             :                 }
    1571             : 
    1572          24 :                 free(part);
    1573          24 :                 continue;       /* avoid the bitmask manipulation below */
    1574             :             }
    1575             :             else
    1576             :             {
    1577           2 :                 conn->status = CONNECTION_BAD;
    1578           2 :                 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1579             :                                         "require_auth", method);
    1580             : 
    1581           2 :                 free(part);
    1582           2 :                 return false;
    1583             :             }
    1584             : 
    1585         142 :             if (mech)
    1586             :             {
    1587             :                 /*
    1588             :                  * Update the mechanism set only. The method bitmask will be
    1589             :                  * updated for SASL further down.
    1590             :                  */
    1591             :                 Assert(!bits);
    1592             : 
    1593          62 :                 if (negated)
    1594             :                 {
    1595             :                     /* Remove the existing mechanism from the list. */
    1596          18 :                     i = index_of_allowed_sasl_mech(conn, mech);
    1597          18 :                     if (i < 0)
    1598           2 :                         goto duplicate;
    1599             : 
    1600          16 :                     conn->allowed_sasl_mechs[i] = NULL;
    1601             :                 }
    1602             :                 else
    1603             :                 {
    1604             :                     /*
    1605             :                      * Find a space to put the new mechanism (after making
    1606             :                      * sure it's not already there).
    1607             :                      */
    1608          44 :                     i = index_of_allowed_sasl_mech(conn, mech);
    1609          44 :                     if (i >= 0)
    1610           2 :                         goto duplicate;
    1611             : 
    1612          42 :                     i = index_of_allowed_sasl_mech(conn, NULL);
    1613          42 :                     if (i < 0)
    1614             :                     {
    1615             :                         /* Should not happen; the pointer list is corrupted. */
    1616             :                         Assert(false);
    1617             : 
    1618           0 :                         conn->status = CONNECTION_BAD;
    1619           0 :                         libpq_append_conn_error(conn,
    1620             :                                                 "internal error: no space in allowed_sasl_mechs");
    1621           0 :                         free(part);
    1622           0 :                         return false;
    1623             :                     }
    1624             : 
    1625          42 :                     conn->allowed_sasl_mechs[i] = mech;
    1626             :                 }
    1627             :             }
    1628             :             else
    1629             :             {
    1630             :                 /* Update the method bitmask. */
    1631             :                 Assert(bits);
    1632             : 
    1633          80 :                 if (negated)
    1634             :                 {
    1635          34 :                     if ((conn->allowed_auth_methods & bits) == 0)
    1636           2 :                         goto duplicate;
    1637             : 
    1638          32 :                     conn->allowed_auth_methods &= ~bits;
    1639             :                 }
    1640             :                 else
    1641             :                 {
    1642          46 :                     if ((conn->allowed_auth_methods & bits) == bits)
    1643           2 :                         goto duplicate;
    1644             : 
    1645          44 :                     conn->allowed_auth_methods |= bits;
    1646             :                 }
    1647             :             }
    1648             : 
    1649         134 :             free(part);
    1650         134 :             continue;
    1651             : 
    1652          12 :     duplicate:
    1653             : 
    1654             :             /*
    1655             :              * A duplicated method probably indicates a typo in a setting
    1656             :              * where typos are extremely risky.
    1657             :              */
    1658          12 :             conn->status = CONNECTION_BAD;
    1659          12 :             libpq_append_conn_error(conn, "require_auth method \"%s\" is specified more than once",
    1660             :                                     part);
    1661             : 
    1662          12 :             free(part);
    1663          12 :             return false;
    1664             :         }
    1665             : 
    1666             :         /*
    1667             :          * Finally, allow SASL authentication requests if (and only if) we've
    1668             :          * allowed any mechanisms.
    1669             :          */
    1670             :         {
    1671         102 :             bool        allowed = false;
    1672         102 :             const uint32 sasl_bits =
    1673             :                 (1 << AUTH_REQ_SASL)
    1674             :                 | (1 << AUTH_REQ_SASL_CONT)
    1675             :                 | (1 << AUTH_REQ_SASL_FIN);
    1676             : 
    1677         180 :             for (i = 0; i < lengthof(conn->allowed_sasl_mechs); i++)
    1678             :             {
    1679         148 :                 if (conn->allowed_sasl_mechs[i])
    1680             :                 {
    1681          70 :                     allowed = true;
    1682          70 :                     break;
    1683             :                 }
    1684             :             }
    1685             : 
    1686             :             /*
    1687             :              * For the standard case, add the SASL bits to the (default-empty)
    1688             :              * set if needed. For the negated case, remove them.
    1689             :              */
    1690         102 :             if (!negated && allowed)
    1691          38 :                 conn->allowed_auth_methods |= sasl_bits;
    1692          64 :             else if (negated && !allowed)
    1693           0 :                 conn->allowed_auth_methods &= ~sasl_bits;
    1694             :         }
    1695             :     }
    1696             : 
    1697             :     /*
    1698             :      * validate channel_binding option
    1699             :      */
    1700       28468 :     if (conn->channel_binding)
    1701             :     {
    1702       28468 :         if (strcmp(conn->channel_binding, "disable") != 0
    1703       28464 :             && strcmp(conn->channel_binding, "prefer") != 0
    1704          18 :             && strcmp(conn->channel_binding, "require") != 0)
    1705             :         {
    1706           2 :             conn->status = CONNECTION_BAD;
    1707           2 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1708             :                                     "channel_binding", conn->channel_binding);
    1709           2 :             return false;
    1710             :         }
    1711             :     }
    1712             :     else
    1713             :     {
    1714           0 :         conn->channel_binding = strdup(DefaultChannelBinding);
    1715           0 :         if (!conn->channel_binding)
    1716           0 :             goto oom_error;
    1717             :     }
    1718             : 
    1719             : #ifndef USE_SSL
    1720             : 
    1721             :     /*
    1722             :      * sslrootcert=system is not supported. Since setting this changes the
    1723             :      * default sslmode, check this _before_ we validate sslmode, to avoid
    1724             :      * confusing the user with errors for an option they may not have set.
    1725             :      */
    1726             :     if (conn->sslrootcert
    1727             :         && strcmp(conn->sslrootcert, "system") == 0)
    1728             :     {
    1729             :         conn->status = CONNECTION_BAD;
    1730             :         libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
    1731             :                                 "sslrootcert", conn->sslrootcert);
    1732             :         return false;
    1733             :     }
    1734             : #endif
    1735             : 
    1736             :     /*
    1737             :      * validate sslmode option
    1738             :      */
    1739       28466 :     if (conn->sslmode)
    1740             :     {
    1741       28466 :         if (strcmp(conn->sslmode, "disable") != 0
    1742       28422 :             && strcmp(conn->sslmode, "allow") != 0
    1743       28398 :             && strcmp(conn->sslmode, "prefer") != 0
    1744         254 :             && strcmp(conn->sslmode, "require") != 0
    1745         112 :             && strcmp(conn->sslmode, "verify-ca") != 0
    1746          78 :             && strcmp(conn->sslmode, "verify-full") != 0)
    1747             :         {
    1748           0 :             conn->status = CONNECTION_BAD;
    1749           0 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1750             :                                     "sslmode", conn->sslmode);
    1751           0 :             return false;
    1752             :         }
    1753             : 
    1754             : #ifndef USE_SSL
    1755             :         switch (conn->sslmode[0])
    1756             :         {
    1757             :             case 'a':           /* "allow" */
    1758             :             case 'p':           /* "prefer" */
    1759             : 
    1760             :                 /*
    1761             :                  * warn user that an SSL connection will never be negotiated
    1762             :                  * since SSL was not compiled in?
    1763             :                  */
    1764             :                 break;
    1765             : 
    1766             :             case 'r':           /* "require" */
    1767             :             case 'v':           /* "verify-ca" or "verify-full" */
    1768             :                 conn->status = CONNECTION_BAD;
    1769             :                 libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
    1770             :                                         "sslmode", conn->sslmode);
    1771             :                 return false;
    1772             :         }
    1773             : #endif
    1774             :     }
    1775             :     else
    1776             :     {
    1777           0 :         conn->sslmode = strdup(DefaultSSLMode);
    1778           0 :         if (!conn->sslmode)
    1779           0 :             goto oom_error;
    1780             :     }
    1781             : 
    1782             :     /*
    1783             :      * validate sslnegotiation option, default is "postgres" for the postgres
    1784             :      * style negotiated connection with an extra round trip but more options.
    1785             :      */
    1786       28466 :     if (conn->sslnegotiation)
    1787             :     {
    1788       28466 :         if (strcmp(conn->sslnegotiation, "postgres") != 0
    1789          48 :             && strcmp(conn->sslnegotiation, "direct") != 0)
    1790             :         {
    1791           0 :             conn->status = CONNECTION_BAD;
    1792           0 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1793             :                                     "sslnegotiation", conn->sslnegotiation);
    1794           0 :             return false;
    1795             :         }
    1796             : 
    1797             : #ifndef USE_SSL
    1798             :         if (conn->sslnegotiation[0] != 'p')
    1799             :         {
    1800             :             conn->status = CONNECTION_BAD;
    1801             :             libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
    1802             :                                     "sslnegotiation", conn->sslnegotiation);
    1803             :             return false;
    1804             :         }
    1805             : #endif
    1806             : 
    1807             :         /*
    1808             :          * Don't allow direct SSL negotiation with sslmode='prefer', because
    1809             :          * that poses a risk of unintentional fallback to plaintext connection
    1810             :          * when connecting to a pre-v17 server that does not support direct
    1811             :          * SSL connections. To keep things simple, don't allow it with
    1812             :          * sslmode='allow' or sslmode='disable' either. If a user goes through
    1813             :          * the trouble of setting sslnegotiation='direct', they probably
    1814             :          * intend to use SSL, and sslmode=disable or allow is probably a user
    1815             :          * user mistake anyway.
    1816             :          */
    1817       28466 :         if (conn->sslnegotiation[0] == 'd' &&
    1818          48 :             conn->sslmode[0] != 'r' && conn->sslmode[0] != 'v')
    1819             :         {
    1820          36 :             conn->status = CONNECTION_BAD;
    1821          36 :             libpq_append_conn_error(conn, "weak sslmode \"%s\" may not be used with sslnegotiation=direct (use \"require\", \"verify-ca\", or \"verify-full\")",
    1822             :                                     conn->sslmode);
    1823          36 :             return false;
    1824             :         }
    1825             :     }
    1826             :     else
    1827             :     {
    1828           0 :         conn->sslnegotiation = strdup(DefaultSSLNegotiation);
    1829           0 :         if (!conn->sslnegotiation)
    1830           0 :             goto oom_error;
    1831             :     }
    1832             : 
    1833             : #ifdef USE_SSL
    1834             : 
    1835             :     /*
    1836             :      * If sslrootcert=system, make sure our chosen sslmode is compatible.
    1837             :      */
    1838       28430 :     if (conn->sslrootcert
    1839         242 :         && strcmp(conn->sslrootcert, "system") == 0
    1840           8 :         && strcmp(conn->sslmode, "verify-full") != 0)
    1841             :     {
    1842           2 :         conn->status = CONNECTION_BAD;
    1843           2 :         libpq_append_conn_error(conn, "weak sslmode \"%s\" may not be used with sslrootcert=system (use \"verify-full\")",
    1844             :                                 conn->sslmode);
    1845           2 :         return false;
    1846             :     }
    1847             : #endif
    1848             : 
    1849             :     /*
    1850             :      * Validate TLS protocol versions for ssl_min_protocol_version and
    1851             :      * ssl_max_protocol_version.
    1852             :      */
    1853       28428 :     if (!sslVerifyProtocolVersion(conn->ssl_min_protocol_version))
    1854             :     {
    1855           2 :         conn->status = CONNECTION_BAD;
    1856           2 :         libpq_append_conn_error(conn, "invalid \"%s\" value: \"%s\"",
    1857             :                                 "ssl_min_protocol_version",
    1858             :                                 conn->ssl_min_protocol_version);
    1859           2 :         return false;
    1860             :     }
    1861       28426 :     if (!sslVerifyProtocolVersion(conn->ssl_max_protocol_version))
    1862             :     {
    1863           2 :         conn->status = CONNECTION_BAD;
    1864           2 :         libpq_append_conn_error(conn, "invalid \"%s\" value: \"%s\"",
    1865             :                                 "ssl_max_protocol_version",
    1866             :                                 conn->ssl_max_protocol_version);
    1867           2 :         return false;
    1868             :     }
    1869             : 
    1870             :     /*
    1871             :      * Check if the range of SSL protocols defined is correct.  This is done
    1872             :      * at this early step because this is independent of the SSL
    1873             :      * implementation used, and this avoids unnecessary cycles with an
    1874             :      * already-built SSL context when the connection is being established, as
    1875             :      * it would be doomed anyway.
    1876             :      */
    1877       28424 :     if (!sslVerifyProtocolRange(conn->ssl_min_protocol_version,
    1878       28424 :                                 conn->ssl_max_protocol_version))
    1879             :     {
    1880           2 :         conn->status = CONNECTION_BAD;
    1881           2 :         libpq_append_conn_error(conn, "invalid SSL protocol version range");
    1882           2 :         return false;
    1883             :     }
    1884             : 
    1885             :     /*
    1886             :      * validate sslcertmode option
    1887             :      */
    1888       28422 :     if (conn->sslcertmode)
    1889             :     {
    1890         366 :         if (strcmp(conn->sslcertmode, "disable") != 0 &&
    1891         360 :             strcmp(conn->sslcertmode, "allow") != 0 &&
    1892           6 :             strcmp(conn->sslcertmode, "require") != 0)
    1893             :         {
    1894           0 :             conn->status = CONNECTION_BAD;
    1895           0 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1896             :                                     "sslcertmode", conn->sslcertmode);
    1897           0 :             return false;
    1898             :         }
    1899             : #ifndef USE_SSL
    1900             :         if (strcmp(conn->sslcertmode, "require") == 0)
    1901             :         {
    1902             :             conn->status = CONNECTION_BAD;
    1903             :             libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
    1904             :                                     "sslcertmode", conn->sslcertmode);
    1905             :             return false;
    1906             :         }
    1907             : #endif
    1908             : #ifndef HAVE_SSL_CTX_SET_CERT_CB
    1909             : 
    1910             :         /*
    1911             :          * Without a certificate callback, the current implementation can't
    1912             :          * figure out if a certificate was actually requested, so "require" is
    1913             :          * useless.
    1914             :          */
    1915             :         if (strcmp(conn->sslcertmode, "require") == 0)
    1916             :         {
    1917             :             conn->status = CONNECTION_BAD;
    1918             :             libpq_append_conn_error(conn, "%s value \"%s\" is not supported (check OpenSSL version)",
    1919             :                                     "sslcertmode", conn->sslcertmode);
    1920             :             return false;
    1921             :         }
    1922             : #endif
    1923             :     }
    1924             :     else
    1925             :     {
    1926       28056 :         conn->sslcertmode = strdup(DefaultSSLCertMode);
    1927       28056 :         if (!conn->sslcertmode)
    1928           0 :             goto oom_error;
    1929             :     }
    1930             : 
    1931             :     /*
    1932             :      * validate gssencmode option
    1933             :      */
    1934       28422 :     if (conn->gssencmode)
    1935             :     {
    1936       28422 :         if (strcmp(conn->gssencmode, "disable") != 0 &&
    1937          24 :             strcmp(conn->gssencmode, "prefer") != 0 &&
    1938          12 :             strcmp(conn->gssencmode, "require") != 0)
    1939             :         {
    1940           0 :             conn->status = CONNECTION_BAD;
    1941           0 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"", "gssencmode", conn->gssencmode);
    1942           0 :             return false;
    1943             :         }
    1944             : #ifndef ENABLE_GSS
    1945       28422 :         if (strcmp(conn->gssencmode, "require") == 0)
    1946             :         {
    1947          12 :             conn->status = CONNECTION_BAD;
    1948          12 :             libpq_append_conn_error(conn, "gssencmode value \"%s\" invalid when GSSAPI support is not compiled in",
    1949             :                                     conn->gssencmode);
    1950          12 :             return false;
    1951             :         }
    1952             : #endif
    1953             :     }
    1954             :     else
    1955             :     {
    1956           0 :         conn->gssencmode = strdup(DefaultGSSMode);
    1957           0 :         if (!conn->gssencmode)
    1958           0 :             goto oom_error;
    1959             :     }
    1960             : 
    1961             :     /*
    1962             :      * validate target_session_attrs option, and set target_server_type
    1963             :      */
    1964       28410 :     if (conn->target_session_attrs)
    1965             :     {
    1966       28410 :         if (strcmp(conn->target_session_attrs, "any") == 0)
    1967       28380 :             conn->target_server_type = SERVER_TYPE_ANY;
    1968          30 :         else if (strcmp(conn->target_session_attrs, "read-write") == 0)
    1969           6 :             conn->target_server_type = SERVER_TYPE_READ_WRITE;
    1970          24 :         else if (strcmp(conn->target_session_attrs, "read-only") == 0)
    1971           6 :             conn->target_server_type = SERVER_TYPE_READ_ONLY;
    1972          18 :         else if (strcmp(conn->target_session_attrs, "primary") == 0)
    1973           6 :             conn->target_server_type = SERVER_TYPE_PRIMARY;
    1974          12 :         else if (strcmp(conn->target_session_attrs, "standby") == 0)
    1975           6 :             conn->target_server_type = SERVER_TYPE_STANDBY;
    1976           6 :         else if (strcmp(conn->target_session_attrs, "prefer-standby") == 0)
    1977           6 :             conn->target_server_type = SERVER_TYPE_PREFER_STANDBY;
    1978             :         else
    1979             :         {
    1980           0 :             conn->status = CONNECTION_BAD;
    1981           0 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1982             :                                     "target_session_attrs",
    1983             :                                     conn->target_session_attrs);
    1984           0 :             return false;
    1985             :         }
    1986             :     }
    1987             :     else
    1988           0 :         conn->target_server_type = SERVER_TYPE_ANY;
    1989             : 
    1990       28410 :     if (conn->scram_client_key)
    1991             :     {
    1992             :         int         len;
    1993             : 
    1994          16 :         len = pg_b64_dec_len(strlen(conn->scram_client_key));
    1995          16 :         conn->scram_client_key_binary = malloc(len);
    1996          16 :         if (!conn->scram_client_key_binary)
    1997           0 :             goto oom_error;
    1998          16 :         len = pg_b64_decode(conn->scram_client_key, strlen(conn->scram_client_key),
    1999          16 :                             conn->scram_client_key_binary, len);
    2000          16 :         if (len < 0)
    2001             :         {
    2002           0 :             libpq_append_conn_error(conn, "invalid SCRAM client key");
    2003           0 :             free(conn->scram_client_key_binary);
    2004           0 :             return false;
    2005             :         }
    2006          16 :         if (len != SCRAM_MAX_KEY_LEN)
    2007             :         {
    2008           0 :             libpq_append_conn_error(conn, "invalid SCRAM client key length: %d", len);
    2009           0 :             free(conn->scram_client_key_binary);
    2010           0 :             return false;
    2011             :         }
    2012          16 :         conn->scram_client_key_len = len;
    2013             :     }
    2014             : 
    2015       28410 :     if (conn->scram_server_key)
    2016             :     {
    2017             :         int         len;
    2018             : 
    2019          16 :         len = pg_b64_dec_len(strlen(conn->scram_server_key));
    2020          16 :         conn->scram_server_key_binary = malloc(len);
    2021          16 :         if (!conn->scram_server_key_binary)
    2022           0 :             goto oom_error;
    2023          16 :         len = pg_b64_decode(conn->scram_server_key, strlen(conn->scram_server_key),
    2024          16 :                             conn->scram_server_key_binary, len);
    2025          16 :         if (len < 0)
    2026             :         {
    2027           0 :             libpq_append_conn_error(conn, "invalid SCRAM server key");
    2028           0 :             free(conn->scram_server_key_binary);
    2029           0 :             return false;
    2030             :         }
    2031          16 :         if (len != SCRAM_MAX_KEY_LEN)
    2032             :         {
    2033           0 :             libpq_append_conn_error(conn, "invalid SCRAM server key length: %d", len);
    2034           0 :             free(conn->scram_server_key_binary);
    2035           0 :             return false;
    2036             :         }
    2037          16 :         conn->scram_server_key_len = len;
    2038             :     }
    2039             : 
    2040             :     /*
    2041             :      * validate load_balance_hosts option, and set load_balance_type
    2042             :      */
    2043       28410 :     if (conn->load_balance_hosts)
    2044             :     {
    2045       28410 :         if (strcmp(conn->load_balance_hosts, "disable") == 0)
    2046       28298 :             conn->load_balance_type = LOAD_BALANCE_DISABLE;
    2047         112 :         else if (strcmp(conn->load_balance_hosts, "random") == 0)
    2048         110 :             conn->load_balance_type = LOAD_BALANCE_RANDOM;
    2049             :         else
    2050             :         {
    2051           2 :             conn->status = CONNECTION_BAD;
    2052           2 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    2053             :                                     "load_balance_hosts",
    2054             :                                     conn->load_balance_hosts);
    2055           2 :             return false;
    2056             :         }
    2057             :     }
    2058             :     else
    2059           0 :         conn->load_balance_type = LOAD_BALANCE_DISABLE;
    2060             : 
    2061       28408 :     if (conn->load_balance_type == LOAD_BALANCE_RANDOM)
    2062             :     {
    2063         110 :         libpq_prng_init(conn);
    2064             : 
    2065             :         /*
    2066             :          * This is the "inside-out" variant of the Fisher-Yates shuffle
    2067             :          * algorithm. Notionally, we append each new value to the array and
    2068             :          * then swap it with a randomly-chosen array element (possibly
    2069             :          * including itself, else we fail to generate permutations with the
    2070             :          * last integer last).  The swap step can be optimized by combining it
    2071             :          * with the insertion.
    2072             :          */
    2073         330 :         for (i = 1; i < conn->nconnhost; i++)
    2074             :         {
    2075         220 :             int         j = pg_prng_uint64_range(&conn->prng_state, 0, i);
    2076         220 :             pg_conn_host temp = conn->connhost[j];
    2077             : 
    2078         220 :             conn->connhost[j] = conn->connhost[i];
    2079         220 :             conn->connhost[i] = temp;
    2080             :         }
    2081             :     }
    2082             : 
    2083             :     /*
    2084             :      * Resolve special "auto" client_encoding from the locale
    2085             :      */
    2086       28408 :     if (conn->client_encoding_initial &&
    2087        1590 :         strcmp(conn->client_encoding_initial, "auto") == 0)
    2088             :     {
    2089           4 :         free(conn->client_encoding_initial);
    2090           4 :         conn->client_encoding_initial = strdup(pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true)));
    2091           4 :         if (!conn->client_encoding_initial)
    2092           0 :             goto oom_error;
    2093             :     }
    2094             : 
    2095             :     /*
    2096             :      * Only if we get this far is it appropriate to try to connect. (We need a
    2097             :      * state flag, rather than just the boolean result of this function, in
    2098             :      * case someone tries to PQreset() the PGconn.)
    2099             :      */
    2100       28408 :     conn->options_valid = true;
    2101             : 
    2102       28408 :     return true;
    2103             : 
    2104           0 : oom_error:
    2105           0 :     conn->status = CONNECTION_BAD;
    2106           0 :     libpq_append_conn_error(conn, "out of memory");
    2107           0 :     return false;
    2108             : }
    2109             : 
    2110             : /*
    2111             :  *      PQconndefaults
    2112             :  *
    2113             :  * Construct a default connection options array, which identifies all the
    2114             :  * available options and shows any default values that are available from the
    2115             :  * environment etc.  On error (eg out of memory), NULL is returned.
    2116             :  *
    2117             :  * Using this function, an application may determine all possible options
    2118             :  * and their current default values.
    2119             :  *
    2120             :  * NOTE: as of PostgreSQL 7.0, the returned array is dynamically allocated
    2121             :  * and should be freed when no longer needed via PQconninfoFree().  (In prior
    2122             :  * versions, the returned array was static, but that's not thread-safe.)
    2123             :  * Pre-7.0 applications that use this function will see a small memory leak
    2124             :  * until they are updated to call PQconninfoFree.
    2125             :  */
    2126             : PQconninfoOption *
    2127         208 : PQconndefaults(void)
    2128             : {
    2129             :     PQExpBufferData errorBuf;
    2130             :     PQconninfoOption *connOptions;
    2131             : 
    2132             :     /* We don't actually report any errors here, but callees want a buffer */
    2133         208 :     initPQExpBuffer(&errorBuf);
    2134         208 :     if (PQExpBufferDataBroken(errorBuf))
    2135           0 :         return NULL;            /* out of memory already :-( */
    2136             : 
    2137         208 :     connOptions = conninfo_init(&errorBuf);
    2138         208 :     if (connOptions != NULL)
    2139             :     {
    2140             :         /* pass NULL errorBuf to ignore errors */
    2141         208 :         if (!conninfo_add_defaults(connOptions, NULL))
    2142             :         {
    2143           0 :             PQconninfoFree(connOptions);
    2144           0 :             connOptions = NULL;
    2145             :         }
    2146             :     }
    2147             : 
    2148         208 :     termPQExpBuffer(&errorBuf);
    2149         208 :     return connOptions;
    2150             : }
    2151             : 
    2152             : /* ----------------
    2153             :  *      PQsetdbLogin
    2154             :  *
    2155             :  * establishes a connection to a postgres backend through the postmaster
    2156             :  * at the specified host and port.
    2157             :  *
    2158             :  * returns a PGconn* which is needed for all subsequent libpq calls
    2159             :  *
    2160             :  * if the status field of the connection returned is CONNECTION_BAD,
    2161             :  * then only the errorMessage is likely to be useful.
    2162             :  * ----------------
    2163             :  */
    2164             : PGconn *
    2165           0 : PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
    2166             :              const char *pgtty, const char *dbName, const char *login,
    2167             :              const char *pwd)
    2168             : {
    2169             :     PGconn     *conn;
    2170             : 
    2171             :     /*
    2172             :      * Allocate memory for the conn structure.  Note that we also expect this
    2173             :      * to initialize conn->errorMessage to empty.  All subsequent steps during
    2174             :      * connection initialization will only append to that buffer.
    2175             :      */
    2176           0 :     conn = pqMakeEmptyPGconn();
    2177           0 :     if (conn == NULL)
    2178           0 :         return NULL;
    2179             : 
    2180             :     /*
    2181             :      * If the dbName parameter contains what looks like a connection string,
    2182             :      * parse it into conn struct using connectOptions1.
    2183             :      */
    2184           0 :     if (dbName && recognized_connection_string(dbName))
    2185             :     {
    2186           0 :         if (!connectOptions1(conn, dbName))
    2187           0 :             return conn;
    2188             :     }
    2189             :     else
    2190             :     {
    2191             :         /*
    2192             :          * Old-style path: first, parse an empty conninfo string in order to
    2193             :          * set up the same defaults that PQconnectdb() would use.
    2194             :          */
    2195           0 :         if (!connectOptions1(conn, ""))
    2196           0 :             return conn;
    2197             : 
    2198             :         /* Insert dbName parameter value into struct */
    2199           0 :         if (dbName && dbName[0] != '\0')
    2200             :         {
    2201           0 :             free(conn->dbName);
    2202           0 :             conn->dbName = strdup(dbName);
    2203           0 :             if (!conn->dbName)
    2204           0 :                 goto oom_error;
    2205             :         }
    2206             :     }
    2207             : 
    2208             :     /*
    2209             :      * Insert remaining parameters into struct, overriding defaults (as well
    2210             :      * as any conflicting data from dbName taken as a conninfo).
    2211             :      */
    2212           0 :     if (pghost && pghost[0] != '\0')
    2213             :     {
    2214           0 :         free(conn->pghost);
    2215           0 :         conn->pghost = strdup(pghost);
    2216           0 :         if (!conn->pghost)
    2217           0 :             goto oom_error;
    2218             :     }
    2219             : 
    2220           0 :     if (pgport && pgport[0] != '\0')
    2221             :     {
    2222           0 :         free(conn->pgport);
    2223           0 :         conn->pgport = strdup(pgport);
    2224           0 :         if (!conn->pgport)
    2225           0 :             goto oom_error;
    2226             :     }
    2227             : 
    2228           0 :     if (pgoptions && pgoptions[0] != '\0')
    2229             :     {
    2230           0 :         free(conn->pgoptions);
    2231           0 :         conn->pgoptions = strdup(pgoptions);
    2232           0 :         if (!conn->pgoptions)
    2233           0 :             goto oom_error;
    2234             :     }
    2235             : 
    2236           0 :     if (login && login[0] != '\0')
    2237             :     {
    2238           0 :         free(conn->pguser);
    2239           0 :         conn->pguser = strdup(login);
    2240           0 :         if (!conn->pguser)
    2241           0 :             goto oom_error;
    2242             :     }
    2243             : 
    2244           0 :     if (pwd && pwd[0] != '\0')
    2245             :     {
    2246           0 :         free(conn->pgpass);
    2247           0 :         conn->pgpass = strdup(pwd);
    2248           0 :         if (!conn->pgpass)
    2249           0 :             goto oom_error;
    2250             :     }
    2251             : 
    2252             :     /*
    2253             :      * Compute derived options
    2254             :      */
    2255           0 :     if (!pqConnectOptions2(conn))
    2256           0 :         return conn;
    2257             : 
    2258             :     /*
    2259             :      * Connect to the database
    2260             :      */
    2261           0 :     if (pqConnectDBStart(conn))
    2262           0 :         (void) pqConnectDBComplete(conn);
    2263             : 
    2264           0 :     return conn;
    2265             : 
    2266           0 : oom_error:
    2267           0 :     conn->status = CONNECTION_BAD;
    2268           0 :     libpq_append_conn_error(conn, "out of memory");
    2269           0 :     return conn;
    2270             : }
    2271             : 
    2272             : 
    2273             : /* ----------
    2274             :  * connectNoDelay -
    2275             :  * Sets the TCP_NODELAY socket option.
    2276             :  * Returns 1 if successful, 0 if not.
    2277             :  * ----------
    2278             :  */
    2279             : static int
    2280         590 : connectNoDelay(PGconn *conn)
    2281             : {
    2282             : #ifdef  TCP_NODELAY
    2283         590 :     int         on = 1;
    2284             : 
    2285         590 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
    2286             :                    (char *) &on,
    2287             :                    sizeof(on)) < 0)
    2288             :     {
    2289             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    2290             : 
    2291           0 :         libpq_append_conn_error(conn, "could not set socket to TCP no delay mode: %s",
    2292           0 :                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2293           0 :         return 0;
    2294             :     }
    2295             : #endif
    2296             : 
    2297         590 :     return 1;
    2298             : }
    2299             : 
    2300             : /* ----------
    2301             :  * Write currently connected IP address into host_addr (of len host_addr_len).
    2302             :  * If unable to, set it to the empty string.
    2303             :  * ----------
    2304             :  */
    2305             : static void
    2306       28454 : getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
    2307             : {
    2308       28454 :     struct sockaddr_storage *addr = &conn->raddr.addr;
    2309             : 
    2310       28454 :     if (addr->ss_family == AF_INET)
    2311             :     {
    2312         300 :         if (pg_inet_net_ntop(AF_INET,
    2313         300 :                              &((struct sockaddr_in *) addr)->sin_addr.s_addr,
    2314             :                              32,
    2315             :                              host_addr, host_addr_len) == NULL)
    2316           0 :             host_addr[0] = '\0';
    2317             :     }
    2318       28154 :     else if (addr->ss_family == AF_INET6)
    2319             :     {
    2320         290 :         if (pg_inet_net_ntop(AF_INET6,
    2321         290 :                              &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
    2322             :                              128,
    2323             :                              host_addr, host_addr_len) == NULL)
    2324           0 :             host_addr[0] = '\0';
    2325             :     }
    2326             :     else
    2327       27864 :         host_addr[0] = '\0';
    2328       28454 : }
    2329             : 
    2330             : /*
    2331             :  * emitHostIdentityInfo -
    2332             :  * Speculatively append "connection to server so-and-so failed: " to
    2333             :  * conn->errorMessage once we've identified the current connection target
    2334             :  * address.  This ensures that any subsequent error message will be properly
    2335             :  * attributed to the server we couldn't connect to.  conn->raddr must be
    2336             :  * valid, and the result of getHostaddr() must be supplied.
    2337             :  */
    2338             : static void
    2339       28454 : emitHostIdentityInfo(PGconn *conn, const char *host_addr)
    2340             : {
    2341       28454 :     if (conn->raddr.addr.ss_family == AF_UNIX)
    2342             :     {
    2343             :         char        service[NI_MAXHOST];
    2344             : 
    2345       27864 :         pg_getnameinfo_all(&conn->raddr.addr, conn->raddr.salen,
    2346             :                            NULL, 0,
    2347             :                            service, sizeof(service),
    2348             :                            NI_NUMERICSERV);
    2349       27864 :         appendPQExpBuffer(&conn->errorMessage,
    2350       27864 :                           libpq_gettext("connection to server on socket \"%s\" failed: "),
    2351             :                           service);
    2352             :     }
    2353             :     else
    2354             :     {
    2355             :         const char *displayed_host;
    2356             :         const char *displayed_port;
    2357             : 
    2358             :         /* To which host and port were we actually connecting? */
    2359         590 :         if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
    2360         296 :             displayed_host = conn->connhost[conn->whichhost].hostaddr;
    2361             :         else
    2362         294 :             displayed_host = conn->connhost[conn->whichhost].host;
    2363         590 :         displayed_port = conn->connhost[conn->whichhost].port;
    2364         590 :         if (displayed_port == NULL || displayed_port[0] == '\0')
    2365           0 :             displayed_port = DEF_PGPORT_STR;
    2366             : 
    2367             :         /*
    2368             :          * If the user did not supply an IP address using 'hostaddr', and
    2369             :          * 'host' was missing or does not match our lookup, display the
    2370             :          * looked-up IP address.
    2371             :          */
    2372         590 :         if (conn->connhost[conn->whichhost].type != CHT_HOST_ADDRESS &&
    2373         294 :             host_addr[0] &&
    2374         294 :             strcmp(displayed_host, host_addr) != 0)
    2375         292 :             appendPQExpBuffer(&conn->errorMessage,
    2376         292 :                               libpq_gettext("connection to server at \"%s\" (%s), port %s failed: "),
    2377             :                               displayed_host, host_addr,
    2378             :                               displayed_port);
    2379             :         else
    2380         298 :             appendPQExpBuffer(&conn->errorMessage,
    2381         298 :                               libpq_gettext("connection to server at \"%s\", port %s failed: "),
    2382             :                               displayed_host,
    2383             :                               displayed_port);
    2384             :     }
    2385       28454 : }
    2386             : 
    2387             : /* ----------
    2388             :  * connectFailureMessage -
    2389             :  * create a friendly error message on connection failure,
    2390             :  * using the given errno value.  Use this for error cases that
    2391             :  * imply that there's no server there.
    2392             :  * ----------
    2393             :  */
    2394             : static void
    2395         460 : connectFailureMessage(PGconn *conn, int errorno)
    2396             : {
    2397             :     char        sebuf[PG_STRERROR_R_BUFLEN];
    2398             : 
    2399         460 :     appendPQExpBuffer(&conn->errorMessage,
    2400             :                       "%s\n",
    2401             :                       SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)));
    2402             : 
    2403         460 :     if (conn->raddr.addr.ss_family == AF_UNIX)
    2404         454 :         libpq_append_conn_error(conn, "\tIs the server running locally and accepting connections on that socket?");
    2405             :     else
    2406           6 :         libpq_append_conn_error(conn, "\tIs the server running on that host and accepting TCP/IP connections?");
    2407         460 : }
    2408             : 
    2409             : /*
    2410             :  * Should we use keepalives?  Returns 1 if yes, 0 if no, and -1 if
    2411             :  * conn->keepalives is set to a value which is not parseable as an
    2412             :  * integer.
    2413             :  */
    2414             : static int
    2415         590 : useKeepalives(PGconn *conn)
    2416             : {
    2417             :     int         val;
    2418             : 
    2419         590 :     if (conn->keepalives == NULL)
    2420         590 :         return 1;
    2421             : 
    2422           0 :     if (!pqParseIntParam(conn->keepalives, &val, conn, "keepalives"))
    2423           0 :         return -1;
    2424             : 
    2425           0 :     return val != 0 ? 1 : 0;
    2426             : }
    2427             : 
    2428             : #ifndef WIN32
    2429             : /*
    2430             :  * Set the keepalive idle timer.
    2431             :  */
    2432             : static int
    2433         590 : setKeepalivesIdle(PGconn *conn)
    2434             : {
    2435             :     int         idle;
    2436             : 
    2437         590 :     if (conn->keepalives_idle == NULL)
    2438         590 :         return 1;
    2439             : 
    2440           0 :     if (!pqParseIntParam(conn->keepalives_idle, &idle, conn,
    2441             :                          "keepalives_idle"))
    2442           0 :         return 0;
    2443           0 :     if (idle < 0)
    2444           0 :         idle = 0;
    2445             : 
    2446             : #ifdef PG_TCP_KEEPALIVE_IDLE
    2447           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
    2448             :                    (char *) &idle, sizeof(idle)) < 0)
    2449             :     {
    2450             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    2451             : 
    2452           0 :         libpq_append_conn_error(conn, "%s(%s) failed: %s",
    2453             :                                 "setsockopt",
    2454             :                                 PG_TCP_KEEPALIVE_IDLE_STR,
    2455           0 :                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2456           0 :         return 0;
    2457             :     }
    2458             : #endif
    2459             : 
    2460           0 :     return 1;
    2461             : }
    2462             : 
    2463             : /*
    2464             :  * Set the keepalive interval.
    2465             :  */
    2466             : static int
    2467         590 : setKeepalivesInterval(PGconn *conn)
    2468             : {
    2469             :     int         interval;
    2470             : 
    2471         590 :     if (conn->keepalives_interval == NULL)
    2472         590 :         return 1;
    2473             : 
    2474           0 :     if (!pqParseIntParam(conn->keepalives_interval, &interval, conn,
    2475             :                          "keepalives_interval"))
    2476           0 :         return 0;
    2477           0 :     if (interval < 0)
    2478           0 :         interval = 0;
    2479             : 
    2480             : #ifdef TCP_KEEPINTVL
    2481           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPINTVL,
    2482             :                    (char *) &interval, sizeof(interval)) < 0)
    2483             :     {
    2484             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    2485             : 
    2486           0 :         libpq_append_conn_error(conn, "%s(%s) failed: %s",
    2487             :                                 "setsockopt",
    2488             :                                 "TCP_KEEPINTVL",
    2489           0 :                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2490           0 :         return 0;
    2491             :     }
    2492             : #endif
    2493             : 
    2494           0 :     return 1;
    2495             : }
    2496             : 
    2497             : /*
    2498             :  * Set the count of lost keepalive packets that will trigger a connection
    2499             :  * break.
    2500             :  */
    2501             : static int
    2502         590 : setKeepalivesCount(PGconn *conn)
    2503             : {
    2504             :     int         count;
    2505             : 
    2506         590 :     if (conn->keepalives_count == NULL)
    2507         590 :         return 1;
    2508             : 
    2509           0 :     if (!pqParseIntParam(conn->keepalives_count, &count, conn,
    2510             :                          "keepalives_count"))
    2511           0 :         return 0;
    2512           0 :     if (count < 0)
    2513           0 :         count = 0;
    2514             : 
    2515             : #ifdef TCP_KEEPCNT
    2516           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPCNT,
    2517             :                    (char *) &count, sizeof(count)) < 0)
    2518             :     {
    2519             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    2520             : 
    2521           0 :         libpq_append_conn_error(conn, "%s(%s) failed: %s",
    2522             :                                 "setsockopt",
    2523             :                                 "TCP_KEEPCNT",
    2524           0 :                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2525           0 :         return 0;
    2526             :     }
    2527             : #endif
    2528             : 
    2529           0 :     return 1;
    2530             : }
    2531             : #else                           /* WIN32 */
    2532             : #ifdef SIO_KEEPALIVE_VALS
    2533             : /*
    2534             :  * Enable keepalives and set the keepalive values on Win32,
    2535             :  * where they are always set in one batch.
    2536             :  *
    2537             :  * CAUTION: This needs to be signal safe, since it's used by PQcancel.
    2538             :  */
    2539             : int
    2540             : pqSetKeepalivesWin32(pgsocket sock, int idle, int interval)
    2541             : {
    2542             :     struct tcp_keepalive ka;
    2543             :     DWORD       retsize;
    2544             : 
    2545             :     if (idle <= 0)
    2546             :         idle = 2 * 60 * 60;     /* 2 hours = default */
    2547             :     if (interval <= 0)
    2548             :         interval = 1;           /* 1 second = default */
    2549             : 
    2550             :     ka.onoff = 1;
    2551             :     ka.keepalivetime = idle * 1000;
    2552             :     ka.keepaliveinterval = interval * 1000;
    2553             : 
    2554             :     if (WSAIoctl(sock,
    2555             :                  SIO_KEEPALIVE_VALS,
    2556             :                  (LPVOID) &ka,
    2557             :                  sizeof(ka),
    2558             :                  NULL,
    2559             :                  0,
    2560             :                  &retsize,
    2561             :                  NULL,
    2562             :                  NULL)
    2563             :         != 0)
    2564             :         return 0;
    2565             :     return 1;
    2566             : }
    2567             : 
    2568             : static int
    2569             : prepKeepalivesWin32(PGconn *conn)
    2570             : {
    2571             :     int         idle = -1;
    2572             :     int         interval = -1;
    2573             : 
    2574             :     if (conn->keepalives_idle &&
    2575             :         !pqParseIntParam(conn->keepalives_idle, &idle, conn,
    2576             :                          "keepalives_idle"))
    2577             :         return 0;
    2578             :     if (conn->keepalives_interval &&
    2579             :         !pqParseIntParam(conn->keepalives_interval, &interval, conn,
    2580             :                          "keepalives_interval"))
    2581             :         return 0;
    2582             : 
    2583             :     if (!pqSetKeepalivesWin32(conn->sock, idle, interval))
    2584             :     {
    2585             :         libpq_append_conn_error(conn, "%s(%s) failed: error code %d",
    2586             :                                 "WSAIoctl", "SIO_KEEPALIVE_VALS",
    2587             :                                 WSAGetLastError());
    2588             :         return 0;
    2589             :     }
    2590             :     return 1;
    2591             : }
    2592             : #endif                          /* SIO_KEEPALIVE_VALS */
    2593             : #endif                          /* WIN32 */
    2594             : 
    2595             : /*
    2596             :  * Set the TCP user timeout.
    2597             :  */
    2598             : static int
    2599         590 : setTCPUserTimeout(PGconn *conn)
    2600             : {
    2601             :     int         timeout;
    2602             : 
    2603         590 :     if (conn->pgtcp_user_timeout == NULL)
    2604         590 :         return 1;
    2605             : 
    2606           0 :     if (!pqParseIntParam(conn->pgtcp_user_timeout, &timeout, conn,
    2607             :                          "tcp_user_timeout"))
    2608           0 :         return 0;
    2609             : 
    2610           0 :     if (timeout < 0)
    2611           0 :         timeout = 0;
    2612             : 
    2613             : #ifdef TCP_USER_TIMEOUT
    2614           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_USER_TIMEOUT,
    2615             :                    (char *) &timeout, sizeof(timeout)) < 0)
    2616             :     {
    2617             :         char        sebuf[256];
    2618             : 
    2619           0 :         libpq_append_conn_error(conn, "%s(%s) failed: %s",
    2620             :                                 "setsockopt",
    2621             :                                 "TCP_USER_TIMEOUT",
    2622           0 :                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2623           0 :         return 0;
    2624             :     }
    2625             : #endif
    2626             : 
    2627           0 :     return 1;
    2628             : }
    2629             : 
    2630             : /* ----------
    2631             :  * pqConnectDBStart -
    2632             :  *      Begin the process of making a connection to the backend.
    2633             :  *
    2634             :  * Returns 1 if successful, 0 if not.
    2635             :  * ----------
    2636             :  */
    2637             : int
    2638       28410 : pqConnectDBStart(PGconn *conn)
    2639             : {
    2640       28410 :     if (!conn)
    2641           0 :         return 0;
    2642             : 
    2643       28410 :     if (!conn->options_valid)
    2644           0 :         goto connect_errReturn;
    2645             : 
    2646             :     /*
    2647             :      * Check for bad linking to backend-internal versions of src/common
    2648             :      * functions (see comments in link-canary.c for the reason we need this).
    2649             :      * Nobody but developers should see this message, so we don't bother
    2650             :      * translating it.
    2651             :      */
    2652       28410 :     if (!pg_link_canary_is_frontend())
    2653             :     {
    2654           0 :         appendPQExpBufferStr(&conn->errorMessage,
    2655             :                              "libpq is incorrectly linked to backend functions\n");
    2656           0 :         goto connect_errReturn;
    2657             :     }
    2658             : 
    2659             :     /* Ensure our buffers are empty */
    2660       28410 :     conn->inStart = conn->inCursor = conn->inEnd = 0;
    2661       28410 :     conn->outCount = 0;
    2662             : 
    2663             :     /*
    2664             :      * Set up to try to connect to the first host.  (Setting whichhost = -1 is
    2665             :      * a bit of a cheat, but PQconnectPoll will advance it to 0 before
    2666             :      * anything else looks at it.)
    2667             :      *
    2668             :      * Cancel requests are special though, they should only try one host and
    2669             :      * address, and these fields have already been set up in PQcancelCreate,
    2670             :      * so leave these fields alone for cancel requests.
    2671             :      */
    2672       28410 :     if (!conn->cancelRequest)
    2673             :     {
    2674       28398 :         conn->whichhost = -1;
    2675       28398 :         conn->try_next_host = true;
    2676       28398 :         conn->try_next_addr = false;
    2677             :     }
    2678             : 
    2679       28410 :     conn->status = CONNECTION_NEEDED;
    2680             : 
    2681             :     /* Also reset the target_server_type state if needed */
    2682       28410 :     if (conn->target_server_type == SERVER_TYPE_PREFER_STANDBY_PASS2)
    2683           0 :         conn->target_server_type = SERVER_TYPE_PREFER_STANDBY;
    2684             : 
    2685             :     /*
    2686             :      * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
    2687             :      * so that it can easily be re-executed if needed again during the
    2688             :      * asynchronous startup process.  However, we must run it once here,
    2689             :      * because callers expect a success return from this routine to mean that
    2690             :      * we are in PGRES_POLLING_WRITING connection state.
    2691             :      */
    2692       28410 :     if (PQconnectPoll(conn) == PGRES_POLLING_WRITING)
    2693       27970 :         return 1;
    2694             : 
    2695         440 : connect_errReturn:
    2696             : 
    2697             :     /*
    2698             :      * If we managed to open a socket, close it immediately rather than
    2699             :      * waiting till PQfinish.  (The application cannot have gotten the socket
    2700             :      * from PQsocket yet, so this doesn't risk breaking anything.)
    2701             :      */
    2702         440 :     pqDropConnection(conn, true);
    2703         440 :     conn->status = CONNECTION_BAD;
    2704         440 :     return 0;
    2705             : }
    2706             : 
    2707             : 
    2708             : /*
    2709             :  *      pqConnectDBComplete
    2710             :  *
    2711             :  * Block and complete a connection.
    2712             :  *
    2713             :  * Returns 1 on success, 0 on failure.
    2714             :  */
    2715             : int
    2716       25438 : pqConnectDBComplete(PGconn *conn)
    2717             : {
    2718       25438 :     PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
    2719       25438 :     pg_usec_time_t end_time = -1;
    2720       25438 :     int         timeout = 0;
    2721       25438 :     int         last_whichhost = -2;    /* certainly different from whichhost */
    2722       25438 :     int         last_whichaddr = -2;    /* certainly different from whichaddr */
    2723             : 
    2724       25438 :     if (conn == NULL || conn->status == CONNECTION_BAD)
    2725           0 :         return 0;
    2726             : 
    2727             :     /*
    2728             :      * Set up a time limit, if connect_timeout is greater than zero.
    2729             :      */
    2730       25438 :     if (conn->connect_timeout != NULL)
    2731             :     {
    2732           8 :         if (!pqParseIntParam(conn->connect_timeout, &timeout, conn,
    2733             :                              "connect_timeout"))
    2734             :         {
    2735             :             /* mark the connection as bad to report the parsing failure */
    2736           0 :             conn->status = CONNECTION_BAD;
    2737           0 :             return 0;
    2738             :         }
    2739             :     }
    2740             : 
    2741             :     for (;;)
    2742       53062 :     {
    2743       78500 :         int         ret = 0;
    2744             : 
    2745             :         /*
    2746             :          * (Re)start the connect_timeout timer if it's active and we are
    2747             :          * considering a different host than we were last time through.  If
    2748             :          * we've already succeeded, though, needn't recalculate.
    2749             :          */
    2750       78500 :         if (flag != PGRES_POLLING_OK &&
    2751       53540 :             timeout > 0 &&
    2752          28 :             (conn->whichhost != last_whichhost ||
    2753          20 :              conn->whichaddr != last_whichaddr))
    2754             :         {
    2755           8 :             end_time = PQgetCurrentTimeUSec() + (pg_usec_time_t) timeout * 1000000;
    2756           8 :             last_whichhost = conn->whichhost;
    2757           8 :             last_whichaddr = conn->whichaddr;
    2758             :         }
    2759             : 
    2760             :         /*
    2761             :          * Wait, if necessary.  Note that the initial state (just after
    2762             :          * PQconnectStart) is to wait for the socket to select for writing.
    2763             :          */
    2764       78500 :         switch (flag)
    2765             :         {
    2766       24960 :             case PGRES_POLLING_OK:
    2767       24960 :                 return 1;       /* success! */
    2768             : 
    2769       26508 :             case PGRES_POLLING_READING:
    2770       26508 :                 ret = pqWaitTimed(1, 0, conn, end_time);
    2771       26508 :                 if (ret == -1)
    2772             :                 {
    2773             :                     /* hard failure, eg select() problem, aborts everything */
    2774           0 :                     conn->status = CONNECTION_BAD;
    2775           0 :                     return 0;
    2776             :                 }
    2777       26508 :                 break;
    2778             : 
    2779       26554 :             case PGRES_POLLING_WRITING:
    2780       26554 :                 ret = pqWaitTimed(0, 1, conn, end_time);
    2781       26554 :                 if (ret == -1)
    2782             :                 {
    2783             :                     /* hard failure, eg select() problem, aborts everything */
    2784           0 :                     conn->status = CONNECTION_BAD;
    2785           0 :                     return 0;
    2786             :                 }
    2787       26554 :                 break;
    2788             : 
    2789         478 :             default:
    2790             :                 /* Just in case we failed to set it in PQconnectPoll */
    2791         478 :                 conn->status = CONNECTION_BAD;
    2792         478 :                 return 0;
    2793             :         }
    2794             : 
    2795       53062 :         if (ret == 1)           /* connect_timeout elapsed */
    2796             :         {
    2797             :             /*
    2798             :              * Give up on current server/address, try the next one.
    2799             :              */
    2800           0 :             conn->try_next_addr = true;
    2801           0 :             conn->status = CONNECTION_NEEDED;
    2802             :         }
    2803             : 
    2804             :         /*
    2805             :          * Now try to advance the state machine.
    2806             :          */
    2807       53062 :         if (conn->cancelRequest)
    2808           4 :             flag = PQcancelPoll((PGcancelConn *) conn);
    2809             :         else
    2810       53058 :             flag = PQconnectPoll(conn);
    2811             :     }
    2812             : }
    2813             : 
    2814             : /* ----------------
    2815             :  *      PQconnectPoll
    2816             :  *
    2817             :  * Poll an asynchronous connection.
    2818             :  *
    2819             :  * Returns a PostgresPollingStatusType.
    2820             :  * Before calling this function, use select(2) to determine when data
    2821             :  * has arrived..
    2822             :  *
    2823             :  * You must call PQfinish whether or not this fails.
    2824             :  *
    2825             :  * This function and PQconnectStart are intended to allow connections to be
    2826             :  * made without blocking the execution of your program on remote I/O. However,
    2827             :  * there are a number of caveats:
    2828             :  *
    2829             :  *   o  If you call PQtrace, ensure that the stream object into which you trace
    2830             :  *      will not block.
    2831             :  *   o  If you do not supply an IP address for the remote host (i.e. you
    2832             :  *      supply a host name instead) then PQconnectStart will block on
    2833             :  *      getaddrinfo.  You will be fine if using Unix sockets (i.e. by
    2834             :  *      supplying neither a host name nor a host address).
    2835             :  *   o  If your backend wants to use Kerberos authentication then you must
    2836             :  *      supply both a host name and a host address, otherwise this function
    2837             :  *      may block on gethostname.
    2838             :  *
    2839             :  * ----------------
    2840             :  */
    2841             : PostgresPollingStatusType
    2842       86548 : PQconnectPoll(PGconn *conn)
    2843             : {
    2844       86548 :     bool        reset_connection_state_machine = false;
    2845       86548 :     bool        need_new_connection = false;
    2846             :     PGresult   *res;
    2847             :     char        sebuf[PG_STRERROR_R_BUFLEN];
    2848             :     int         optval;
    2849             : 
    2850       86548 :     if (conn == NULL)
    2851           0 :         return PGRES_POLLING_FAILED;
    2852             : 
    2853             :     /* Get the new data */
    2854       86548 :     switch (conn->status)
    2855             :     {
    2856             :             /*
    2857             :              * We really shouldn't have been polled in these two cases, but we
    2858             :              * can handle it.
    2859             :              */
    2860           0 :         case CONNECTION_BAD:
    2861           0 :             return PGRES_POLLING_FAILED;
    2862           0 :         case CONNECTION_OK:
    2863           0 :             return PGRES_POLLING_OK;
    2864             : 
    2865             :             /* These are reading states */
    2866       28252 :         case CONNECTION_AWAITING_RESPONSE:
    2867             :         case CONNECTION_AUTH_OK:
    2868             :         case CONNECTION_CHECK_WRITABLE:
    2869             :         case CONNECTION_CONSUME:
    2870             :         case CONNECTION_CHECK_STANDBY:
    2871             :             {
    2872             :                 /* Load waiting data */
    2873       28252 :                 int         n = pqReadData(conn);
    2874             : 
    2875       28252 :                 if (n < 0)
    2876          32 :                     goto error_return;
    2877       28220 :                 if (n == 0)
    2878           2 :                     return PGRES_POLLING_READING;
    2879             : 
    2880       28218 :                 break;
    2881             :             }
    2882             : 
    2883             :             /* These are writing states, so we just proceed. */
    2884       29074 :         case CONNECTION_STARTED:
    2885             :         case CONNECTION_MADE:
    2886       29074 :             break;
    2887             : 
    2888             :             /* Special cases: proceed without waiting. */
    2889       29222 :         case CONNECTION_SSL_STARTUP:
    2890             :         case CONNECTION_NEEDED:
    2891             :         case CONNECTION_GSS_STARTUP:
    2892             :         case CONNECTION_CHECK_TARGET:
    2893             :         case CONNECTION_AUTHENTICATING:
    2894       29222 :             break;
    2895             : 
    2896           0 :         default:
    2897           0 :             libpq_append_conn_error(conn, "invalid connection state, probably indicative of memory corruption");
    2898           0 :             goto error_return;
    2899             :     }
    2900             : 
    2901             : 
    2902       86514 : keep_going:                     /* We will come back to here until there is
    2903             :                                  * nothing left to do. */
    2904             : 
    2905             :     /* Time to advance to next address, or next host if no more addresses? */
    2906      170458 :     if (conn->try_next_addr)
    2907             :     {
    2908         460 :         if (conn->whichaddr < conn->naddr)
    2909             :         {
    2910         460 :             conn->whichaddr++;
    2911         460 :             reset_connection_state_machine = true;
    2912             :         }
    2913             :         else
    2914           0 :             conn->try_next_host = true;
    2915         460 :         conn->try_next_addr = false;
    2916             :     }
    2917             : 
    2918             :     /* Time to advance to next connhost[] entry? */
    2919      170458 :     if (conn->try_next_host)
    2920             :     {
    2921             :         pg_conn_host *ch;
    2922             :         struct addrinfo hint;
    2923             :         struct addrinfo *addrlist;
    2924             :         int         thisport;
    2925             :         int         ret;
    2926             :         char        portstr[MAXPGPATH];
    2927             : 
    2928       29124 :         if (conn->whichhost + 1 < conn->nconnhost)
    2929       28438 :             conn->whichhost++;
    2930             :         else
    2931             :         {
    2932             :             /*
    2933             :              * Oops, no more hosts.
    2934             :              *
    2935             :              * If we are trying to connect in "prefer-standby" mode, then drop
    2936             :              * the standby requirement and start over. Don't do this for
    2937             :              * cancel requests though, since we are certain the list of
    2938             :              * servers won't change as the target_server_type option is not
    2939             :              * applicable to those connections.
    2940             :              *
    2941             :              * Otherwise, an appropriate error message is already set up, so
    2942             :              * we just need to set the right status.
    2943             :              */
    2944         686 :             if (conn->target_server_type == SERVER_TYPE_PREFER_STANDBY &&
    2945           2 :                 conn->nconnhost > 0 &&
    2946           2 :                 !conn->cancelRequest)
    2947             :             {
    2948           2 :                 conn->target_server_type = SERVER_TYPE_PREFER_STANDBY_PASS2;
    2949           2 :                 conn->whichhost = 0;
    2950             :             }
    2951             :             else
    2952         684 :                 goto error_return;
    2953             :         }
    2954             : 
    2955             :         /* Drop any address info for previous host */
    2956       28440 :         release_conn_addrinfo(conn);
    2957             : 
    2958             :         /*
    2959             :          * Look up info for the new host.  On failure, log the problem in
    2960             :          * conn->errorMessage, then loop around to try the next host.  (Note
    2961             :          * we don't clear try_next_host until we've succeeded.)
    2962             :          */
    2963       28440 :         ch = &conn->connhost[conn->whichhost];
    2964             : 
    2965             :         /* Initialize hint structure */
    2966      199080 :         MemSet(&hint, 0, sizeof(hint));
    2967       28440 :         hint.ai_socktype = SOCK_STREAM;
    2968       28440 :         hint.ai_family = AF_UNSPEC;
    2969             : 
    2970             :         /* Figure out the port number we're going to use. */
    2971       28440 :         if (ch->port == NULL || ch->port[0] == '\0')
    2972           0 :             thisport = DEF_PGPORT;
    2973             :         else
    2974             :         {
    2975       28440 :             if (!pqParseIntParam(ch->port, &thisport, conn, "port"))
    2976           0 :                 goto error_return;
    2977             : 
    2978       28440 :             if (thisport < 1 || thisport > 65535)
    2979             :             {
    2980           6 :                 libpq_append_conn_error(conn, "invalid port number: \"%s\"", ch->port);
    2981           6 :                 goto keep_going;
    2982             :             }
    2983             :         }
    2984       28434 :         snprintf(portstr, sizeof(portstr), "%d", thisport);
    2985             : 
    2986             :         /* Use pg_getaddrinfo_all() to resolve the address */
    2987       28434 :         switch (ch->type)
    2988             :         {
    2989         292 :             case CHT_HOST_NAME:
    2990         292 :                 ret = pg_getaddrinfo_all(ch->host, portstr, &hint,
    2991             :                                          &addrlist);
    2992         292 :                 if (ret || !addrlist)
    2993             :                 {
    2994           0 :                     libpq_append_conn_error(conn, "could not translate host name \"%s\" to address: %s",
    2995             :                                             ch->host, gai_strerror(ret));
    2996           0 :                     goto keep_going;
    2997             :                 }
    2998         292 :                 break;
    2999             : 
    3000         290 :             case CHT_HOST_ADDRESS:
    3001         290 :                 hint.ai_flags = AI_NUMERICHOST;
    3002         290 :                 ret = pg_getaddrinfo_all(ch->hostaddr, portstr, &hint,
    3003             :                                          &addrlist);
    3004         290 :                 if (ret || !addrlist)
    3005             :                 {
    3006           0 :                     libpq_append_conn_error(conn, "could not parse network address \"%s\": %s",
    3007             :                                             ch->hostaddr, gai_strerror(ret));
    3008           0 :                     goto keep_going;
    3009             :                 }
    3010         290 :                 break;
    3011             : 
    3012       27852 :             case CHT_UNIX_SOCKET:
    3013       27852 :                 hint.ai_family = AF_UNIX;
    3014       27852 :                 UNIXSOCK_PATH(portstr, thisport, ch->host);
    3015       27852 :                 if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
    3016             :                 {
    3017           0 :                     libpq_append_conn_error(conn, "Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
    3018             :                                             portstr,
    3019             :                                             (int) (UNIXSOCK_PATH_BUFLEN - 1));
    3020           0 :                     goto keep_going;
    3021             :                 }
    3022             : 
    3023             :                 /*
    3024             :                  * NULL hostname tells pg_getaddrinfo_all to parse the service
    3025             :                  * name as a Unix-domain socket path.
    3026             :                  */
    3027       27852 :                 ret = pg_getaddrinfo_all(NULL, portstr, &hint,
    3028             :                                          &addrlist);
    3029       27852 :                 if (ret || !addrlist)
    3030             :                 {
    3031           0 :                     libpq_append_conn_error(conn, "could not translate Unix-domain socket path \"%s\" to address: %s",
    3032             :                                             portstr, gai_strerror(ret));
    3033           0 :                     goto keep_going;
    3034             :                 }
    3035       27852 :                 break;
    3036             :         }
    3037             : 
    3038             :         /*
    3039             :          * Store a copy of the addrlist in private memory so we can perform
    3040             :          * randomization for load balancing.
    3041             :          */
    3042       28434 :         ret = store_conn_addrinfo(conn, addrlist);
    3043       28434 :         pg_freeaddrinfo_all(hint.ai_family, addrlist);
    3044       28434 :         if (ret)
    3045           0 :             goto error_return;  /* message already logged */
    3046             : 
    3047             :         /*
    3048             :          * If random load balancing is enabled we shuffle the addresses.
    3049             :          */
    3050       28434 :         if (conn->load_balance_type == LOAD_BALANCE_RANDOM)
    3051             :         {
    3052             :             /*
    3053             :              * This is the "inside-out" variant of the Fisher-Yates shuffle
    3054             :              * algorithm. Notionally, we append each new value to the array
    3055             :              * and then swap it with a randomly-chosen array element (possibly
    3056             :              * including itself, else we fail to generate permutations with
    3057             :              * the last integer last).  The swap step can be optimized by
    3058             :              * combining it with the insertion.
    3059             :              *
    3060             :              * We don't need to initialize conn->prng_state here, because that
    3061             :              * already happened in pqConnectOptions2.
    3062             :              */
    3063         126 :             for (int i = 1; i < conn->naddr; i++)
    3064             :             {
    3065           0 :                 int         j = pg_prng_uint64_range(&conn->prng_state, 0, i);
    3066           0 :                 AddrInfo    temp = conn->addr[j];
    3067             : 
    3068           0 :                 conn->addr[j] = conn->addr[i];
    3069           0 :                 conn->addr[i] = temp;
    3070             :             }
    3071             :         }
    3072             : 
    3073       28434 :         reset_connection_state_machine = true;
    3074       28434 :         conn->try_next_host = false;
    3075             :     }
    3076             : 
    3077             :     /* Reset connection state machine? */
    3078      169768 :     if (reset_connection_state_machine)
    3079             :     {
    3080             :         /*
    3081             :          * (Re) initialize our connection control variables for a set of
    3082             :          * connection attempts to a single server address.  These variables
    3083             :          * must persist across individual connection attempts, but we must
    3084             :          * reset them when we start to consider a new server.
    3085             :          */
    3086       28894 :         conn->pversion = PG_PROTOCOL(3, 0);
    3087       28894 :         conn->send_appname = true;
    3088       28894 :         conn->failed_enc_methods = 0;
    3089       28894 :         conn->current_enc_method = 0;
    3090       28894 :         conn->allowed_enc_methods = 0;
    3091       28894 :         reset_connection_state_machine = false;
    3092       28894 :         need_new_connection = true;
    3093             :     }
    3094             : 
    3095             :     /* Force a new connection (perhaps to the same server as before)? */
    3096      169768 :     if (need_new_connection)
    3097             :     {
    3098             :         /* Drop any existing connection */
    3099       28900 :         pqDropConnection(conn, true);
    3100             : 
    3101             :         /* Reset all state obtained from old server */
    3102       28900 :         pqDropServerData(conn);
    3103             : 
    3104             :         /* Drop any PGresult we might have, too */
    3105       28900 :         conn->asyncStatus = PGASYNC_IDLE;
    3106       28900 :         conn->xactStatus = PQTRANS_IDLE;
    3107       28900 :         conn->pipelineStatus = PQ_PIPELINE_OFF;
    3108       28900 :         pqClearAsyncResult(conn);
    3109             : 
    3110             :         /* Reset conn->status to put the state machine in the right state */
    3111       28900 :         conn->status = CONNECTION_NEEDED;
    3112             : 
    3113       28900 :         need_new_connection = false;
    3114             :     }
    3115             : 
    3116             :     /*
    3117             :      * Decide what to do next, if server rejects SSL or GSS negotiation, but
    3118             :      * the connection is still valid.  If there are no options left, error out
    3119             :      * with 'msg'.
    3120             :      */
    3121             : #define ENCRYPTION_NEGOTIATION_FAILED(msg) \
    3122             :     do { \
    3123             :         switch (encryption_negotiation_failed(conn)) \
    3124             :         { \
    3125             :             case 0: \
    3126             :                 libpq_append_conn_error(conn, (msg)); \
    3127             :                 goto error_return; \
    3128             :             case 1: \
    3129             :                 conn->status = CONNECTION_MADE; \
    3130             :                 return PGRES_POLLING_WRITING; \
    3131             :             case 2: \
    3132             :                 need_new_connection = true; \
    3133             :                 goto keep_going; \
    3134             :         } \
    3135             :     } while(0);
    3136             : 
    3137             :     /*
    3138             :      * Decide what to do next, if connection fails.  If there are no options
    3139             :      * left, return with an error.  The error message has already been written
    3140             :      * to the connection's error buffer.
    3141             :      */
    3142             : #define CONNECTION_FAILED() \
    3143             :     do { \
    3144             :         if (connection_failed(conn)) \
    3145             :         { \
    3146             :             need_new_connection = true; \
    3147             :             goto keep_going; \
    3148             :         } \
    3149             :         else \
    3150             :             goto error_return; \
    3151             :     } while(0);
    3152             : 
    3153             :     /* Now try to advance the state machine for this connection */
    3154      169768 :     switch (conn->status)
    3155             :     {
    3156       28912 :         case CONNECTION_NEEDED:
    3157             :             {
    3158             :                 /*
    3159             :                  * Try to initiate a connection to one of the addresses
    3160             :                  * returned by pg_getaddrinfo_all().  conn->whichaddr is the
    3161             :                  * next one to try.
    3162             :                  *
    3163             :                  * The extra level of braces here is historical.  It's not
    3164             :                  * worth reindenting this whole switch case to remove 'em.
    3165             :                  */
    3166             :                 {
    3167             :                     char        host_addr[NI_MAXHOST];
    3168             :                     int         sock_type;
    3169             :                     AddrInfo   *addr_cur;
    3170             : 
    3171             :                     /*
    3172             :                      * Advance to next possible host, if we've tried all of
    3173             :                      * the addresses for the current host.
    3174             :                      */
    3175       28912 :                     if (conn->whichaddr == conn->naddr)
    3176             :                     {
    3177         458 :                         conn->try_next_host = true;
    3178       28322 :                         goto keep_going;
    3179             :                     }
    3180       28454 :                     addr_cur = &conn->addr[conn->whichaddr];
    3181             : 
    3182             :                     /* Remember current address for possible use later */
    3183       28454 :                     memcpy(&conn->raddr, &addr_cur->addr, sizeof(SockAddr));
    3184             : 
    3185             : #ifdef ENABLE_GSS
    3186             : 
    3187             :                     /*
    3188             :                      * Before establishing the connection, check if it's
    3189             :                      * doomed to fail because gssencmode='require' but GSSAPI
    3190             :                      * is not available.
    3191             :                      */
    3192             :                     if (conn->gssencmode[0] == 'r')
    3193             :                     {
    3194             :                         if (conn->raddr.addr.ss_family == AF_UNIX)
    3195             :                         {
    3196             :                             libpq_append_conn_error(conn,
    3197             :                                                     "GSSAPI encryption required but it is not supported over a local socket");
    3198             :                             goto error_return;
    3199             :                         }
    3200             :                         if (conn->gcred == GSS_C_NO_CREDENTIAL)
    3201             :                         {
    3202             :                             if (!pg_GSS_have_cred_cache(&conn->gcred))
    3203             :                             {
    3204             :                                 libpq_append_conn_error(conn,
    3205             :                                                         "GSSAPI encryption required but no credential cache");
    3206             :                                 goto error_return;
    3207             :                             }
    3208             :                         }
    3209             :                     }
    3210             : #endif
    3211             : 
    3212             :                     /*
    3213             :                      * Choose the encryption method to try first.  Do this
    3214             :                      * before establishing the connection, so that if none of
    3215             :                      * the modes allowed by the connections options are
    3216             :                      * available, we can error out before establishing the
    3217             :                      * connection.
    3218             :                      */
    3219       28454 :                     if (!init_allowed_encryption_methods(conn))
    3220           0 :                         goto error_return;
    3221             : 
    3222             :                     /*
    3223             :                      * Set connip, too.  Note we purposely ignore strdup
    3224             :                      * failure; not a big problem if it fails.
    3225             :                      */
    3226       28454 :                     if (conn->connip != NULL)
    3227             :                     {
    3228           8 :                         free(conn->connip);
    3229           8 :                         conn->connip = NULL;
    3230             :                     }
    3231       28454 :                     getHostaddr(conn, host_addr, NI_MAXHOST);
    3232       28454 :                     if (host_addr[0])
    3233         590 :                         conn->connip = strdup(host_addr);
    3234             : 
    3235             :                     /* Try to create the socket */
    3236       28454 :                     sock_type = SOCK_STREAM;
    3237             : #ifdef SOCK_CLOEXEC
    3238             : 
    3239             :                     /*
    3240             :                      * Atomically mark close-on-exec, if possible on this
    3241             :                      * platform, so that there isn't a window where a
    3242             :                      * subprogram executed by another thread inherits the
    3243             :                      * socket.  See fallback code below.
    3244             :                      */
    3245       28454 :                     sock_type |= SOCK_CLOEXEC;
    3246             : #endif
    3247             : #ifdef SOCK_NONBLOCK
    3248             : 
    3249             :                     /*
    3250             :                      * We might as well skip a system call for nonblocking
    3251             :                      * mode too, if we can.
    3252             :                      */
    3253       28454 :                     sock_type |= SOCK_NONBLOCK;
    3254             : #endif
    3255       28454 :                     conn->sock = socket(addr_cur->family, sock_type, 0);
    3256       28454 :                     if (conn->sock == PGINVALID_SOCKET)
    3257             :                     {
    3258           0 :                         int         errorno = SOCK_ERRNO;
    3259             : 
    3260             :                         /*
    3261             :                          * Silently ignore socket() failure if we have more
    3262             :                          * addresses to try; this reduces useless chatter in
    3263             :                          * cases where the address list includes both IPv4 and
    3264             :                          * IPv6 but kernel only accepts one family.
    3265             :                          */
    3266           0 :                         if (conn->whichaddr < conn->naddr ||
    3267           0 :                             conn->whichhost + 1 < conn->nconnhost)
    3268             :                         {
    3269           0 :                             conn->try_next_addr = true;
    3270           0 :                             goto keep_going;
    3271             :                         }
    3272           0 :                         emitHostIdentityInfo(conn, host_addr);
    3273           0 :                         libpq_append_conn_error(conn, "could not create socket: %s",
    3274             :                                                 SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)));
    3275           0 :                         goto error_return;
    3276             :                     }
    3277             : 
    3278             :                     /*
    3279             :                      * Once we've identified a target address, all errors
    3280             :                      * except the preceding socket()-failure case should be
    3281             :                      * prefixed with host-identity information.  (If the
    3282             :                      * connection succeeds, the contents of conn->errorMessage
    3283             :                      * won't matter, so this is harmless.)
    3284             :                      */
    3285       28454 :                     emitHostIdentityInfo(conn, host_addr);
    3286             : 
    3287             :                     /*
    3288             :                      * Select socket options: no delay of outgoing data for
    3289             :                      * TCP sockets, nonblock mode, close-on-exec.  Try the
    3290             :                      * next address if any of this fails.
    3291             :                      */
    3292       28454 :                     if (addr_cur->family != AF_UNIX)
    3293             :                     {
    3294         590 :                         if (!connectNoDelay(conn))
    3295             :                         {
    3296             :                             /* error message already created */
    3297           0 :                             conn->try_next_addr = true;
    3298           0 :                             goto keep_going;
    3299             :                         }
    3300             :                     }
    3301             : #ifndef SOCK_NONBLOCK
    3302             :                     if (!pg_set_noblock(conn->sock))
    3303             :                     {
    3304             :                         libpq_append_conn_error(conn, "could not set socket to nonblocking mode: %s",
    3305             :                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3306             :                         conn->try_next_addr = true;
    3307             :                         goto keep_going;
    3308             :                     }
    3309             : #endif
    3310             : 
    3311             : #ifndef SOCK_CLOEXEC
    3312             : #ifdef F_SETFD
    3313             :                     if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
    3314             :                     {
    3315             :                         libpq_append_conn_error(conn, "could not set socket to close-on-exec mode: %s",
    3316             :                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3317             :                         conn->try_next_addr = true;
    3318             :                         goto keep_going;
    3319             :                     }
    3320             : #endif                          /* F_SETFD */
    3321             : #endif
    3322             : 
    3323       28454 :                     if (addr_cur->family != AF_UNIX)
    3324             :                     {
    3325             : #ifndef WIN32
    3326         590 :                         int         on = 1;
    3327             : #endif
    3328         590 :                         int         usekeepalives = useKeepalives(conn);
    3329         590 :                         int         err = 0;
    3330             : 
    3331         590 :                         if (usekeepalives < 0)
    3332             :                         {
    3333             :                             /* error is already reported */
    3334           0 :                             err = 1;
    3335             :                         }
    3336         590 :                         else if (usekeepalives == 0)
    3337             :                         {
    3338             :                             /* Do nothing */
    3339             :                         }
    3340             : #ifndef WIN32
    3341         590 :                         else if (setsockopt(conn->sock,
    3342             :                                             SOL_SOCKET, SO_KEEPALIVE,
    3343             :                                             (char *) &on, sizeof(on)) < 0)
    3344             :                         {
    3345           0 :                             libpq_append_conn_error(conn, "%s(%s) failed: %s",
    3346             :                                                     "setsockopt",
    3347             :                                                     "SO_KEEPALIVE",
    3348           0 :                                                     SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3349           0 :                             err = 1;
    3350             :                         }
    3351         590 :                         else if (!setKeepalivesIdle(conn)
    3352         590 :                                  || !setKeepalivesInterval(conn)
    3353         590 :                                  || !setKeepalivesCount(conn))
    3354           0 :                             err = 1;
    3355             : #else                           /* WIN32 */
    3356             : #ifdef SIO_KEEPALIVE_VALS
    3357             :                         else if (!prepKeepalivesWin32(conn))
    3358             :                             err = 1;
    3359             : #endif                          /* SIO_KEEPALIVE_VALS */
    3360             : #endif                          /* WIN32 */
    3361         590 :                         else if (!setTCPUserTimeout(conn))
    3362           0 :                             err = 1;
    3363             : 
    3364         590 :                         if (err)
    3365             :                         {
    3366           0 :                             conn->try_next_addr = true;
    3367           0 :                             goto keep_going;
    3368             :                         }
    3369             :                     }
    3370             : 
    3371             :                     /*----------
    3372             :                      * We have three methods of blocking SIGPIPE during
    3373             :                      * send() calls to this socket:
    3374             :                      *
    3375             :                      *  - setsockopt(sock, SO_NOSIGPIPE)
    3376             :                      *  - send(sock, ..., MSG_NOSIGNAL)
    3377             :                      *  - setting the signal mask to SIG_IGN during send()
    3378             :                      *
    3379             :                      * The third method requires three syscalls per send,
    3380             :                      * so we prefer either of the first two, but they are
    3381             :                      * less portable.  The state is tracked in the following
    3382             :                      * members of PGconn:
    3383             :                      *
    3384             :                      * conn->sigpipe_so      - we have set up SO_NOSIGPIPE
    3385             :                      * conn->sigpipe_flag    - we're specifying MSG_NOSIGNAL
    3386             :                      *
    3387             :                      * If we can use SO_NOSIGPIPE, then set sigpipe_so here
    3388             :                      * and we're done.  Otherwise, set sigpipe_flag so that
    3389             :                      * we will try MSG_NOSIGNAL on sends.  If we get an error
    3390             :                      * with MSG_NOSIGNAL, we'll clear that flag and revert to
    3391             :                      * signal masking.
    3392             :                      *----------
    3393             :                      */
    3394       28454 :                     conn->sigpipe_so = false;
    3395             : #ifdef MSG_NOSIGNAL
    3396       28454 :                     conn->sigpipe_flag = true;
    3397             : #else
    3398             :                     conn->sigpipe_flag = false;
    3399             : #endif                          /* MSG_NOSIGNAL */
    3400             : 
    3401             : #ifdef SO_NOSIGPIPE
    3402             :                     optval = 1;
    3403             :                     if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE,
    3404             :                                    (char *) &optval, sizeof(optval)) == 0)
    3405             :                     {
    3406             :                         conn->sigpipe_so = true;
    3407             :                         conn->sigpipe_flag = false;
    3408             :                     }
    3409             : #endif                          /* SO_NOSIGPIPE */
    3410             : 
    3411             :                     /*
    3412             :                      * Start/make connection.  This should not block, since we
    3413             :                      * are in nonblock mode.  If it does, well, too bad.
    3414             :                      */
    3415       28454 :                     if (connect(conn->sock, (struct sockaddr *) &addr_cur->addr.addr,
    3416             :                                 addr_cur->addr.salen) < 0)
    3417             :                     {
    3418        1044 :                         if (SOCK_ERRNO == EINPROGRESS ||
    3419             : #ifdef WIN32
    3420             :                             SOCK_ERRNO == EWOULDBLOCK ||
    3421             : #endif
    3422         454 :                             SOCK_ERRNO == EINTR)
    3423             :                         {
    3424             :                             /*
    3425             :                              * This is fine - we're in non-blocking mode, and
    3426             :                              * the connection is in progress.  Tell caller to
    3427             :                              * wait for write-ready on socket.
    3428             :                              */
    3429         590 :                             conn->status = CONNECTION_STARTED;
    3430         590 :                             return PGRES_POLLING_WRITING;
    3431             :                         }
    3432             :                         /* otherwise, trouble */
    3433             :                     }
    3434             :                     else
    3435             :                     {
    3436             :                         /*
    3437             :                          * Hm, we're connected already --- seems the "nonblock
    3438             :                          * connection" wasn't.  Advance the state machine and
    3439             :                          * go do the next stuff.
    3440             :                          */
    3441       27410 :                         conn->status = CONNECTION_STARTED;
    3442       27410 :                         goto keep_going;
    3443             :                     }
    3444             : 
    3445             :                     /*
    3446             :                      * This connection failed.  Add the error report to
    3447             :                      * conn->errorMessage, then try the next address if any.
    3448             :                      */
    3449         454 :                     connectFailureMessage(conn, SOCK_ERRNO);
    3450         454 :                     conn->try_next_addr = true;
    3451         454 :                     goto keep_going;
    3452             :                 }
    3453             :             }
    3454             : 
    3455       28000 :         case CONNECTION_STARTED:
    3456             :             {
    3457       28000 :                 socklen_t   optlen = sizeof(optval);
    3458             : 
    3459             :                 /*
    3460             :                  * Write ready, since we've made it here, so the connection
    3461             :                  * has been made ... or has failed.
    3462             :                  */
    3463             : 
    3464             :                 /*
    3465             :                  * Now check (using getsockopt) that there is not an error
    3466             :                  * state waiting for us on the socket.
    3467             :                  */
    3468             : 
    3469       28000 :                 if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
    3470             :                                (char *) &optval, &optlen) == -1)
    3471             :                 {
    3472           0 :                     libpq_append_conn_error(conn, "could not get socket error status: %s",
    3473           0 :                                             SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3474           0 :                     goto error_return;
    3475             :                 }
    3476       28000 :                 else if (optval != 0)
    3477             :                 {
    3478             :                     /*
    3479             :                      * When using a nonblocking connect, we will typically see
    3480             :                      * connect failures at this point, so provide a friendly
    3481             :                      * error message.
    3482             :                      */
    3483           6 :                     connectFailureMessage(conn, optval);
    3484             : 
    3485             :                     /*
    3486             :                      * Try the next address if any, just as in the case where
    3487             :                      * connect() returned failure immediately.
    3488             :                      */
    3489           6 :                     conn->try_next_addr = true;
    3490           6 :                     goto keep_going;
    3491             :                 }
    3492             : 
    3493             :                 /* Fill in the client address */
    3494       27994 :                 conn->laddr.salen = sizeof(conn->laddr.addr);
    3495       27994 :                 if (getsockname(conn->sock,
    3496       27994 :                                 (struct sockaddr *) &conn->laddr.addr,
    3497             :                                 &conn->laddr.salen) < 0)
    3498             :                 {
    3499           0 :                     libpq_append_conn_error(conn, "could not get client address from socket: %s",
    3500           0 :                                             SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3501           0 :                     goto error_return;
    3502             :                 }
    3503             : 
    3504             :                 /*
    3505             :                  * Implement requirepeer check, if requested and it's a
    3506             :                  * Unix-domain socket.
    3507             :                  */
    3508       27994 :                 if (conn->requirepeer && conn->requirepeer[0] &&
    3509           0 :                     conn->raddr.addr.ss_family == AF_UNIX)
    3510             :                 {
    3511             : #ifndef WIN32
    3512             :                     char       *remote_username;
    3513             : #endif
    3514             :                     uid_t       uid;
    3515             :                     gid_t       gid;
    3516             : 
    3517           0 :                     errno = 0;
    3518           0 :                     if (getpeereid(conn->sock, &uid, &gid) != 0)
    3519             :                     {
    3520             :                         /*
    3521             :                          * Provide special error message if getpeereid is a
    3522             :                          * stub
    3523             :                          */
    3524           0 :                         if (errno == ENOSYS)
    3525           0 :                             libpq_append_conn_error(conn, "requirepeer parameter is not supported on this platform");
    3526             :                         else
    3527           0 :                             libpq_append_conn_error(conn, "could not get peer credentials: %s",
    3528           0 :                                                     strerror_r(errno, sebuf, sizeof(sebuf)));
    3529           0 :                         goto error_return;
    3530             :                     }
    3531             : 
    3532             : #ifndef WIN32
    3533           0 :                     remote_username = pg_fe_getusername(uid,
    3534             :                                                         &conn->errorMessage);
    3535           0 :                     if (remote_username == NULL)
    3536           0 :                         goto error_return;  /* message already logged */
    3537             : 
    3538           0 :                     if (strcmp(remote_username, conn->requirepeer) != 0)
    3539             :                     {
    3540           0 :                         libpq_append_conn_error(conn, "requirepeer specifies \"%s\", but actual peer user name is \"%s\"",
    3541             :                                                 conn->requirepeer, remote_username);
    3542           0 :                         free(remote_username);
    3543           0 :                         goto error_return;
    3544             :                     }
    3545           0 :                     free(remote_username);
    3546             : #else                           /* WIN32 */
    3547             :                     /* should have failed with ENOSYS above */
    3548             :                     Assert(false);
    3549             : #endif                          /* WIN32 */
    3550             :                 }
    3551             : 
    3552             :                 /*
    3553             :                  * Make sure we can write before advancing to next step.
    3554             :                  */
    3555       27994 :                 conn->status = CONNECTION_MADE;
    3556       27994 :                 return PGRES_POLLING_WRITING;
    3557             :             }
    3558             : 
    3559       28484 :         case CONNECTION_MADE:
    3560             :             {
    3561             :                 char       *startpacket;
    3562             :                 int         packetlen;
    3563             : 
    3564             : #ifdef ENABLE_GSS
    3565             : 
    3566             :                 /*
    3567             :                  * If GSSAPI encryption is enabled, send a packet to the
    3568             :                  * server asking for GSSAPI Encryption and proceed with GSSAPI
    3569             :                  * handshake.  We will come back here after GSSAPI encryption
    3570             :                  * has been established, with conn->gctx set.
    3571             :                  */
    3572             :                 if (conn->current_enc_method == ENC_GSSAPI && !conn->gctx)
    3573             :                 {
    3574             :                     ProtocolVersion pv = pg_hton32(NEGOTIATE_GSS_CODE);
    3575             : 
    3576             :                     if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
    3577             :                     {
    3578             :                         libpq_append_conn_error(conn, "could not send GSSAPI negotiation packet: %s",
    3579             :                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3580             :                         goto error_return;
    3581             :                     }
    3582             : 
    3583             :                     /* Ok, wait for response */
    3584             :                     conn->status = CONNECTION_GSS_STARTUP;
    3585             :                     return PGRES_POLLING_READING;
    3586             :                 }
    3587             : #endif
    3588             : 
    3589             : #ifdef USE_SSL
    3590             : 
    3591             :                 /*
    3592             :                  * If SSL is enabled, start the SSL negotiation. We will come
    3593             :                  * back here after SSL encryption has been established, with
    3594             :                  * ssl_in_use set.
    3595             :                  */
    3596       28484 :                 if (conn->current_enc_method == ENC_SSL && !conn->ssl_in_use)
    3597             :                 {
    3598             :                     /*
    3599             :                      * If traditional postgres SSL negotiation is used, send
    3600             :                      * the SSL request.  In direct negotiation, jump straight
    3601             :                      * into the SSL handshake.
    3602             :                      */
    3603         558 :                     if (conn->sslnegotiation[0] == 'p')
    3604             :                     {
    3605             :                         ProtocolVersion pv;
    3606             : 
    3607             :                         /*
    3608             :                          * Send the SSL request packet.
    3609             :                          *
    3610             :                          * Theoretically, this could block, but it really
    3611             :                          * shouldn't since we only got here if the socket is
    3612             :                          * write-ready.
    3613             :                          */
    3614         548 :                         pv = pg_hton32(NEGOTIATE_SSL_CODE);
    3615         548 :                         if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
    3616             :                         {
    3617           0 :                             libpq_append_conn_error(conn, "could not send SSL negotiation packet: %s",
    3618           0 :                                                     SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3619           0 :                             goto error_return;
    3620             :                         }
    3621             :                         /* Ok, wait for response */
    3622         548 :                         conn->status = CONNECTION_SSL_STARTUP;
    3623         548 :                         return PGRES_POLLING_READING;
    3624             :                     }
    3625             :                     else
    3626             :                     {
    3627             :                         Assert(conn->sslnegotiation[0] == 'd');
    3628          10 :                         conn->status = CONNECTION_SSL_STARTUP;
    3629          10 :                         return PGRES_POLLING_WRITING;
    3630             :                     }
    3631             :                 }
    3632             : #endif                          /* USE_SSL */
    3633             : 
    3634             :                 /*
    3635             :                  * For cancel requests this is as far as we need to go in the
    3636             :                  * connection establishment. Now we can actually send our
    3637             :                  * cancellation request.
    3638             :                  */
    3639       27926 :                 if (conn->cancelRequest)
    3640             :                 {
    3641             :                     CancelRequestPacket cancelpacket;
    3642             : 
    3643          12 :                     packetlen = sizeof(cancelpacket);
    3644          12 :                     cancelpacket.cancelRequestCode = (MsgType) pg_hton32(CANCEL_REQUEST_CODE);
    3645          12 :                     cancelpacket.backendPID = pg_hton32(conn->be_pid);
    3646          12 :                     cancelpacket.cancelAuthCode = pg_hton32(conn->be_key);
    3647          12 :                     if (pqPacketSend(conn, 0, &cancelpacket, packetlen) != STATUS_OK)
    3648             :                     {
    3649           0 :                         libpq_append_conn_error(conn, "could not send cancel packet: %s",
    3650           0 :                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3651           0 :                         goto error_return;
    3652             :                     }
    3653          12 :                     conn->status = CONNECTION_AWAITING_RESPONSE;
    3654          12 :                     return PGRES_POLLING_READING;
    3655             :                 }
    3656             : 
    3657             :                 /*
    3658             :                  * We have now established encryption, or we are happy to
    3659             :                  * proceed without.
    3660             :                  */
    3661             : 
    3662             :                 /* Build the startup packet. */
    3663       27914 :                 startpacket = pqBuildStartupPacket3(conn, &packetlen,
    3664             :                                                     EnvironmentOptions);
    3665       27914 :                 if (!startpacket)
    3666             :                 {
    3667           0 :                     libpq_append_conn_error(conn, "out of memory");
    3668           0 :                     goto error_return;
    3669             :                 }
    3670             : 
    3671             :                 /*
    3672             :                  * Send the startup packet.
    3673             :                  *
    3674             :                  * Theoretically, this could block, but it really shouldn't
    3675             :                  * since we only got here if the socket is write-ready.
    3676             :                  */
    3677       27914 :                 if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
    3678             :                 {
    3679           0 :                     libpq_append_conn_error(conn, "could not send startup packet: %s",
    3680           0 :                                             SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3681           0 :                     free(startpacket);
    3682           0 :                     goto error_return;
    3683             :                 }
    3684             : 
    3685       27914 :                 free(startpacket);
    3686             : 
    3687       27914 :                 conn->status = CONNECTION_AWAITING_RESPONSE;
    3688       27914 :                 return PGRES_POLLING_READING;
    3689             :             }
    3690             : 
    3691             :             /*
    3692             :              * Handle SSL negotiation: wait for postmaster messages and
    3693             :              * respond as necessary.
    3694             :              */
    3695         812 :         case CONNECTION_SSL_STARTUP:
    3696             :             {
    3697             : #ifdef USE_SSL
    3698             :                 PostgresPollingStatusType pollres;
    3699             : 
    3700             :                 /*
    3701             :                  * On first time through with traditional SSL negotiation, get
    3702             :                  * the postmaster's response to our SSLRequest packet. With
    3703             :                  * sslnegotiation='direct', go straight to initiating SSL.
    3704             :                  */
    3705         812 :                 if (!conn->ssl_in_use && conn->sslnegotiation[0] == 'p')
    3706             :                 {
    3707             :                     /*
    3708             :                      * We use pqReadData here since it has the logic to
    3709             :                      * distinguish no-data-yet from connection closure. Since
    3710             :                      * conn->ssl isn't set, a plain recv() will occur.
    3711             :                      */
    3712             :                     char        SSLok;
    3713             :                     int         rdresult;
    3714             : 
    3715         548 :                     rdresult = pqReadData(conn);
    3716         548 :                     if (rdresult < 0)
    3717             :                     {
    3718             :                         /* errorMessage is already filled in */
    3719           8 :                         goto error_return;
    3720             :                     }
    3721         548 :                     if (rdresult == 0)
    3722             :                     {
    3723             :                         /* caller failed to wait for data */
    3724         292 :                         return PGRES_POLLING_READING;
    3725             :                     }
    3726         548 :                     if (pqGetc(&SSLok, conn) < 0)
    3727             :                     {
    3728             :                         /* should not happen really */
    3729           0 :                         return PGRES_POLLING_READING;
    3730             :                     }
    3731         548 :                     if (SSLok == 'S')
    3732             :                     {
    3733         248 :                         if (conn->Pfdebug)
    3734           0 :                             pqTraceOutputCharResponse(conn, "SSLResponse",
    3735             :                                                       SSLok);
    3736             :                         /* mark byte consumed */
    3737         248 :                         conn->inStart = conn->inCursor;
    3738             :                     }
    3739         300 :                     else if (SSLok == 'N')
    3740             :                     {
    3741         296 :                         if (conn->Pfdebug)
    3742           0 :                             pqTraceOutputCharResponse(conn, "SSLResponse",
    3743             :                                                       SSLok);
    3744             :                         /* mark byte consumed */
    3745         296 :                         conn->inStart = conn->inCursor;
    3746             : 
    3747             :                         /*
    3748             :                          * The connection is still valid, so if it's OK to
    3749             :                          * continue without SSL, we can proceed using this
    3750             :                          * connection.  Otherwise return with an error.
    3751             :                          */
    3752         592 :                         ENCRYPTION_NEGOTIATION_FAILED(libpq_gettext("server does not support SSL, but SSL was required"));
    3753             :                     }
    3754           4 :                     else if (SSLok == 'E')
    3755             :                     {
    3756             :                         /*
    3757             :                          * Server failure of some sort, such as failure to
    3758             :                          * fork a backend process.  Don't bother retrieving
    3759             :                          * the error message; we should not trust it as the
    3760             :                          * server has not been authenticated yet.
    3761             :                          */
    3762           4 :                         libpq_append_conn_error(conn, "server sent an error response during SSL exchange");
    3763           4 :                         goto error_return;
    3764             :                     }
    3765             :                     else
    3766             :                     {
    3767           0 :                         libpq_append_conn_error(conn, "received invalid response to SSL negotiation: %c",
    3768             :                                                 SSLok);
    3769           0 :                         goto error_return;
    3770             :                     }
    3771             :                 }
    3772             : 
    3773             :                 /*
    3774             :                  * Begin or continue the SSL negotiation process.
    3775             :                  */
    3776         512 :                 pollres = pqsecure_open_client(conn);
    3777         512 :                 if (pollres == PGRES_POLLING_OK)
    3778             :                 {
    3779             :                     /*
    3780             :                      * At this point we should have no data already buffered.
    3781             :                      * If we do, it was received before we performed the SSL
    3782             :                      * handshake, so it wasn't encrypted and indeed may have
    3783             :                      * been injected by a man-in-the-middle.
    3784             :                      */
    3785         200 :                     if (conn->inCursor != conn->inEnd)
    3786             :                     {
    3787           0 :                         libpq_append_conn_error(conn, "received unencrypted data after SSL response");
    3788           0 :                         goto error_return;
    3789             :                     }
    3790             : 
    3791             :                     /* SSL handshake done, ready to send startup packet */
    3792         200 :                     conn->status = CONNECTION_MADE;
    3793         200 :                     return PGRES_POLLING_WRITING;
    3794             :                 }
    3795         312 :                 if (pollres == PGRES_POLLING_FAILED)
    3796             :                 {
    3797             :                     /*
    3798             :                      * SSL handshake failed.  We will retry with a plaintext
    3799             :                      * connection, if permitted by sslmode.
    3800             :                      */
    3801          58 :                     CONNECTION_FAILED();
    3802             :                 }
    3803             :                 /* Else, return POLLING_READING or POLLING_WRITING status */
    3804         254 :                 return pollres;
    3805             : #else                           /* !USE_SSL */
    3806             :                 /* can't get here */
    3807             :                 goto error_return;
    3808             : #endif                          /* USE_SSL */
    3809             :             }
    3810             : 
    3811           0 :         case CONNECTION_GSS_STARTUP:
    3812             :             {
    3813             : #ifdef ENABLE_GSS
    3814             :                 PostgresPollingStatusType pollres;
    3815             : 
    3816             :                 /*
    3817             :                  * If we haven't yet, get the postmaster's response to our
    3818             :                  * negotiation packet
    3819             :                  */
    3820             :                 if (!conn->gctx)
    3821             :                 {
    3822             :                     char        gss_ok;
    3823             :                     int         rdresult = pqReadData(conn);
    3824             : 
    3825             :                     if (rdresult < 0)
    3826             :                         /* pqReadData fills in error message */
    3827             :                         goto error_return;
    3828             :                     else if (rdresult == 0)
    3829             :                         /* caller failed to wait for data */
    3830             :                         return PGRES_POLLING_READING;
    3831             :                     if (pqGetc(&gss_ok, conn) < 0)
    3832             :                         /* shouldn't happen... */
    3833             :                         return PGRES_POLLING_READING;
    3834             : 
    3835             :                     if (gss_ok == 'E')
    3836             :                     {
    3837             :                         /*
    3838             :                          * Server failure of some sort, possibly protocol
    3839             :                          * version support failure.  Don't bother retrieving
    3840             :                          * the error message; we should not trust it anyway as
    3841             :                          * the server has not authenticated yet.
    3842             :                          *
    3843             :                          * Note that unlike on an error response to
    3844             :                          * SSLRequest, we allow falling back to SSL or
    3845             :                          * plaintext connection here.  GSS support was
    3846             :                          * introduced in PostgreSQL version 12, so an error
    3847             :                          * response might mean that we are connecting to a
    3848             :                          * pre-v12 server.
    3849             :                          */
    3850             :                         libpq_append_conn_error(conn, "server sent an error response during GSS encryption exchange");
    3851             :                         CONNECTION_FAILED();
    3852             :                     }
    3853             : 
    3854             :                     /* mark byte consumed */
    3855             :                     conn->inStart = conn->inCursor;
    3856             : 
    3857             :                     if (gss_ok == 'N')
    3858             :                     {
    3859             :                         if (conn->Pfdebug)
    3860             :                             pqTraceOutputCharResponse(conn, "GSSENCResponse",
    3861             :                                                       gss_ok);
    3862             : 
    3863             :                         /*
    3864             :                          * The connection is still valid, so if it's OK to
    3865             :                          * continue without GSS, we can proceed using this
    3866             :                          * connection.  Otherwise return with an error.
    3867             :                          */
    3868             :                         ENCRYPTION_NEGOTIATION_FAILED(libpq_gettext("server doesn't support GSSAPI encryption, but it was required"));
    3869             :                     }
    3870             :                     else if (gss_ok != 'G')
    3871             :                     {
    3872             :                         libpq_append_conn_error(conn, "received invalid response to GSSAPI negotiation: %c",
    3873             :                                                 gss_ok);
    3874             :                         goto error_return;
    3875             :                     }
    3876             : 
    3877             :                     if (conn->Pfdebug)
    3878             :                         pqTraceOutputCharResponse(conn, "GSSENCResponse",
    3879             :                                                   gss_ok);
    3880             :                 }
    3881             : 
    3882             :                 /* Begin or continue GSSAPI negotiation */
    3883             :                 pollres = pqsecure_open_gss(conn);
    3884             :                 if (pollres == PGRES_POLLING_OK)
    3885             :                 {
    3886             :                     /*
    3887             :                      * At this point we should have no data already buffered.
    3888             :                      * If we do, it was received before we performed the GSS
    3889             :                      * handshake, so it wasn't encrypted and indeed may have
    3890             :                      * been injected by a man-in-the-middle.
    3891             :                      */
    3892             :                     if (conn->inCursor != conn->inEnd)
    3893             :                     {
    3894             :                         libpq_append_conn_error(conn, "received unencrypted data after GSSAPI encryption response");
    3895             :                         goto error_return;
    3896             :                     }
    3897             : 
    3898             :                     /* All set for startup packet */
    3899             :                     conn->status = CONNECTION_MADE;
    3900             :                     return PGRES_POLLING_WRITING;
    3901             :                 }
    3902             :                 else if (pollres == PGRES_POLLING_FAILED)
    3903             :                 {
    3904             :                     /*
    3905             :                      * GSS handshake failed.  We will retry with an SSL or
    3906             :                      * plaintext connection, if permitted by the options.
    3907             :                      */
    3908             :                     CONNECTION_FAILED();
    3909             :                 }
    3910             :                 /* Else, return POLLING_READING or POLLING_WRITING status */
    3911             :                 return pollres;
    3912             : #else                           /* !ENABLE_GSS */
    3913             :                 /* unreachable */
    3914           0 :                 goto error_return;
    3915             : #endif                          /* ENABLE_GSS */
    3916             :             }
    3917             : 
    3918             :             /*
    3919             :              * Handle authentication exchange: wait for postmaster messages
    3920             :              * and respond as necessary.
    3921             :              */
    3922       28624 :         case CONNECTION_AWAITING_RESPONSE:
    3923             :             {
    3924             :                 char        beresp;
    3925             :                 int         msgLength;
    3926             :                 int         avail;
    3927             :                 AuthRequest areq;
    3928             :                 int         res;
    3929             :                 bool        async;
    3930             : 
    3931             :                 /*
    3932             :                  * Scan the message from current point (note that if we find
    3933             :                  * the message is incomplete, we will return without advancing
    3934             :                  * inStart, and resume here next time).
    3935             :                  */
    3936       28624 :                 conn->inCursor = conn->inStart;
    3937             : 
    3938             :                 /* Read type byte */
    3939       28624 :                 if (pqGetc(&beresp, conn))
    3940             :                 {
    3941             :                     /* We'll come back when there is more data */
    3942         324 :                     return PGRES_POLLING_READING;
    3943             :                 }
    3944             : 
    3945             :                 /*
    3946             :                  * Validate message type: we expect only an authentication
    3947             :                  * request, NegotiateProtocolVersion, or an error here.
    3948             :                  * Anything else probably means it's not Postgres on the other
    3949             :                  * end at all.
    3950             :                  */
    3951       28300 :                 if (beresp != PqMsg_AuthenticationRequest &&
    3952         328 :                     beresp != PqMsg_ErrorResponse &&
    3953           0 :                     beresp != PqMsg_NegotiateProtocolVersion)
    3954             :                 {
    3955           0 :                     libpq_append_conn_error(conn, "expected authentication request from server, but received %c",
    3956             :                                             beresp);
    3957         156 :                     goto error_return;
    3958             :                 }
    3959             : 
    3960             :                 /* Read message length word */
    3961       28300 :                 if (pqGetInt(&msgLength, 4, conn))
    3962             :                 {
    3963             :                     /* We'll come back when there is more data */
    3964           0 :                     return PGRES_POLLING_READING;
    3965             :                 }
    3966             : 
    3967             :                 /*
    3968             :                  * Try to validate message length before using it.
    3969             :                  *
    3970             :                  * Authentication requests can't be very large, although GSS
    3971             :                  * auth requests may not be that small.  Same for
    3972             :                  * NegotiateProtocolVersion.
    3973             :                  *
    3974             :                  * Errors can be a little larger, but not huge.  If we see a
    3975             :                  * large apparent length in an error, it means we're really
    3976             :                  * talking to a pre-3.0-protocol server; cope.  (Before
    3977             :                  * version 14, the server also used the old protocol for
    3978             :                  * errors that happened before processing the startup packet.)
    3979             :                  */
    3980       28300 :                 if (beresp == PqMsg_AuthenticationRequest &&
    3981       27972 :                     (msgLength < 8 || msgLength > 2000))
    3982             :                 {
    3983           0 :                     libpq_append_conn_error(conn, "received invalid authentication request");
    3984           0 :                     goto error_return;
    3985             :                 }
    3986       28300 :                 if (beresp == PqMsg_NegotiateProtocolVersion &&
    3987           0 :                     (msgLength < 8 || msgLength > 2000))
    3988             :                 {
    3989           0 :                     libpq_append_conn_error(conn, "received invalid protocol negotiation message");
    3990           0 :                     goto error_return;
    3991             :                 }
    3992             : 
    3993             : #define MAX_ERRLEN 30000
    3994       28300 :                 if (beresp == PqMsg_ErrorResponse &&
    3995         328 :                     (msgLength < 8 || msgLength > MAX_ERRLEN))
    3996             :                 {
    3997             :                     /* Handle error from a pre-3.0 server */
    3998           0 :                     conn->inCursor = conn->inStart + 1; /* reread data */
    3999           0 :                     if (pqGets_append(&conn->errorMessage, conn))
    4000             :                     {
    4001             :                         /*
    4002             :                          * We may not have authenticated the server yet, so
    4003             :                          * don't let the buffer grow forever.
    4004             :                          */
    4005           0 :                         avail = conn->inEnd - conn->inCursor;
    4006           0 :                         if (avail > MAX_ERRLEN)
    4007             :                         {
    4008           0 :                             libpq_append_conn_error(conn, "received invalid error message");
    4009           0 :                             goto error_return;
    4010             :                         }
    4011             : 
    4012             :                         /* We'll come back when there is more data */
    4013           0 :                         return PGRES_POLLING_READING;
    4014             :                     }
    4015             :                     /* OK, we read the message; mark data consumed */
    4016           0 :                     pqParseDone(conn, conn->inCursor);
    4017             : 
    4018             :                     /*
    4019             :                      * Before 7.2, the postmaster didn't always end its
    4020             :                      * messages with a newline, so add one if needed to
    4021             :                      * conform to libpq conventions.
    4022             :                      */
    4023           0 :                     if (conn->errorMessage.len == 0 ||
    4024           0 :                         conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
    4025             :                     {
    4026           0 :                         appendPQExpBufferChar(&conn->errorMessage, '\n');
    4027             :                     }
    4028             : 
    4029           0 :                     goto error_return;
    4030             :                 }
    4031             : #undef MAX_ERRLEN
    4032             : 
    4033             :                 /*
    4034             :                  * Can't process if message body isn't all here yet.
    4035             :                  *
    4036             :                  * After this check passes, any further EOF during parsing
    4037             :                  * implies that the server sent a bad/truncated message.
    4038             :                  * Reading more bytes won't help in that case, so don't return
    4039             :                  * PGRES_POLLING_READING after this point.
    4040             :                  */
    4041       28300 :                 msgLength -= 4;
    4042       28300 :                 avail = conn->inEnd - conn->inCursor;
    4043       28300 :                 if (avail < msgLength)
    4044             :                 {
    4045             :                     /*
    4046             :                      * Before returning, try to enlarge the input buffer if
    4047             :                      * needed to hold the whole message; see notes in
    4048             :                      * pqParseInput3.
    4049             :                      */
    4050           0 :                     if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
    4051             :                                              conn))
    4052           0 :                         goto error_return;
    4053             :                     /* We'll come back when there is more data */
    4054           0 :                     return PGRES_POLLING_READING;
    4055             :                 }
    4056             : 
    4057             :                 /* Handle errors. */
    4058       28300 :                 if (beresp == PqMsg_ErrorResponse)
    4059             :                 {
    4060         328 :                     if (pqGetErrorNotice3(conn, true))
    4061             :                     {
    4062           0 :                         libpq_append_conn_error(conn, "received invalid error message");
    4063           0 :                         goto error_return;
    4064             :                     }
    4065             :                     /* OK, we read the message; mark data consumed */
    4066         328 :                     pqParseDone(conn, conn->inCursor);
    4067             : 
    4068             :                     /*
    4069             :                      * If error is "cannot connect now", try the next host if
    4070             :                      * any (but we don't want to consider additional addresses
    4071             :                      * for this host, nor is there much point in changing SSL
    4072             :                      * or GSS mode).  This is helpful when dealing with
    4073             :                      * standby servers that might not be in hot-standby state.
    4074             :                      */
    4075         328 :                     if (strcmp(conn->last_sqlstate,
    4076             :                                ERRCODE_CANNOT_CONNECT_NOW) == 0)
    4077             :                     {
    4078         232 :                         conn->try_next_host = true;
    4079       28144 :                         goto keep_going;
    4080             :                     }
    4081             : 
    4082             :                     /* Check to see if we should mention pgpassfile */
    4083          96 :                     pgpassfileWarning(conn);
    4084             : 
    4085          96 :                     CONNECTION_FAILED();
    4086             :                 }
    4087       27972 :                 else if (beresp == PqMsg_NegotiateProtocolVersion)
    4088             :                 {
    4089           0 :                     if (pqGetNegotiateProtocolVersion3(conn))
    4090             :                     {
    4091           0 :                         libpq_append_conn_error(conn, "received invalid protocol negotiation message");
    4092           0 :                         goto error_return;
    4093             :                     }
    4094             :                     /* OK, we read the message; mark data consumed */
    4095           0 :                     pqParseDone(conn, conn->inCursor);
    4096           0 :                     goto error_return;
    4097             :                 }
    4098             : 
    4099             :                 /* It is an authentication request. */
    4100       27972 :                 conn->auth_req_received = true;
    4101             : 
    4102             :                 /* Get the type of request. */
    4103       27972 :                 if (pqGetInt((int *) &areq, 4, conn))
    4104             :                 {
    4105             :                     /* can't happen because we checked the length already */
    4106           0 :                     libpq_append_conn_error(conn, "received invalid authentication request");
    4107           0 :                     goto error_return;
    4108             :                 }
    4109       27972 :                 msgLength -= 4;
    4110             : 
    4111             :                 /*
    4112             :                  * Process the rest of the authentication request message, and
    4113             :                  * respond to it if necessary.
    4114             :                  *
    4115             :                  * Note that conn->pghost must be non-NULL if we are going to
    4116             :                  * avoid the Kerberos code doing a hostname look-up.
    4117             :                  */
    4118       27972 :                 res = pg_fe_sendauth(areq, msgLength, conn, &async);
    4119             : 
    4120       27972 :                 if (async && (res == STATUS_OK))
    4121             :                 {
    4122             :                     /*
    4123             :                      * We'll come back later once we're ready to respond.
    4124             :                      * Don't consume the request yet.
    4125             :                      */
    4126           0 :                     conn->status = CONNECTION_AUTHENTICATING;
    4127           0 :                     goto keep_going;
    4128             :                 }
    4129             : 
    4130             :                 /*
    4131             :                  * OK, we have processed the message; mark data consumed.  We
    4132             :                  * don't call pqParseDone here because we already traced this
    4133             :                  * message inside pg_fe_sendauth.
    4134             :                  */
    4135       27972 :                 conn->inStart = conn->inCursor;
    4136             : 
    4137       27972 :                 if (res != STATUS_OK)
    4138             :                 {
    4139             :                     /*
    4140             :                      * OAuth connections may perform two-step discovery, where
    4141             :                      * the first connection is a dummy.
    4142             :                      */
    4143          64 :                     if (conn->sasl == &pg_oauth_mech && conn->oauth_want_retry)
    4144             :                     {
    4145           0 :                         need_new_connection = true;
    4146           0 :                         goto keep_going;
    4147             :                     }
    4148             : 
    4149          64 :                     goto error_return;
    4150             :                 }
    4151             : 
    4152             :                 /*
    4153             :                  * Just make sure that any data sent by pg_fe_sendauth is
    4154             :                  * flushed out.  Although this theoretically could block, it
    4155             :                  * really shouldn't since we don't send large auth responses.
    4156             :                  */
    4157       27908 :                 if (pqFlush(conn))
    4158           0 :                     goto error_return;
    4159             : 
    4160       27908 :                 if (areq == AUTH_REQ_OK)
    4161             :                 {
    4162             :                     /* We are done with authentication exchange */
    4163       27476 :                     conn->status = CONNECTION_AUTH_OK;
    4164             : 
    4165             :                     /*
    4166             :                      * Set asyncStatus so that PQgetResult will think that
    4167             :                      * what comes back next is the result of a query.  See
    4168             :                      * below.
    4169             :                      */
    4170       27476 :                     conn->asyncStatus = PGASYNC_BUSY;
    4171             :                 }
    4172             : 
    4173             :                 /* Look to see if we have more data yet. */
    4174       27908 :                 goto keep_going;
    4175             :             }
    4176             : 
    4177           0 :         case CONNECTION_AUTHENTICATING:
    4178             :             {
    4179             :                 PostgresPollingStatusType status;
    4180             : 
    4181           0 :                 if (!conn->async_auth || !conn->cleanup_async_auth)
    4182             :                 {
    4183             :                     /* programmer error; should not happen */
    4184           0 :                     libpq_append_conn_error(conn,
    4185             :                                             "internal error: async authentication has no handler");
    4186           0 :                     goto error_return;
    4187             :                 }
    4188             : 
    4189             :                 /* Drive some external authentication work. */
    4190           0 :                 status = conn->async_auth(conn);
    4191             : 
    4192           0 :                 if (status == PGRES_POLLING_FAILED)
    4193           0 :                     goto error_return;
    4194             : 
    4195           0 :                 if (status == PGRES_POLLING_OK)
    4196             :                 {
    4197             :                     /* Done. Tear down the async implementation. */
    4198           0 :                     conn->cleanup_async_auth(conn);
    4199           0 :                     conn->cleanup_async_auth = NULL;
    4200             : 
    4201             :                     /*
    4202             :                      * Cleanup must unset altsock, both as an indication that
    4203             :                      * it's been released, and to stop pqSocketCheck from
    4204             :                      * looking at the wrong socket after async auth is done.
    4205             :                      */
    4206           0 :                     if (conn->altsock != PGINVALID_SOCKET)
    4207             :                     {
    4208             :                         Assert(false);
    4209           0 :                         libpq_append_conn_error(conn,
    4210             :                                                 "internal error: async cleanup did not release polling socket");
    4211           0 :                         goto error_return;
    4212             :                     }
    4213             : 
    4214             :                     /*
    4215             :                      * Reenter the authentication exchange with the server. We
    4216             :                      * didn't consume the message that started external
    4217             :                      * authentication, so it'll be reprocessed as if we just
    4218             :                      * received it.
    4219             :                      */
    4220           0 :                     conn->status = CONNECTION_AWAITING_RESPONSE;
    4221             : 
    4222           0 :                     goto keep_going;
    4223             :                 }
    4224             : 
    4225             :                 /*
    4226             :                  * Caller needs to poll some more. conn->async_auth() should
    4227             :                  * have assigned an altsock to poll on.
    4228             :                  */
    4229           0 :                 if (conn->altsock == PGINVALID_SOCKET)
    4230             :                 {
    4231             :                     Assert(false);
    4232           0 :                     libpq_append_conn_error(conn,
    4233             :                                             "internal error: async authentication did not set a socket for polling");
    4234           0 :                     goto error_return;
    4235             :                 }
    4236             : 
    4237           0 :                 return status;
    4238             :             }
    4239             : 
    4240       27502 :         case CONNECTION_AUTH_OK:
    4241             :             {
    4242             :                 /*
    4243             :                  * Now we expect to hear from the backend. A ReadyForQuery
    4244             :                  * message indicates that startup is successful, but we might
    4245             :                  * also get an Error message indicating failure. (Notice
    4246             :                  * messages indicating nonfatal warnings are also allowed by
    4247             :                  * the protocol, as are ParameterStatus and BackendKeyData
    4248             :                  * messages.) Easiest way to handle this is to let
    4249             :                  * PQgetResult() read the messages. We just have to fake it
    4250             :                  * out about the state of the connection, by setting
    4251             :                  * asyncStatus = PGASYNC_BUSY (done above).
    4252             :                  */
    4253             : 
    4254       27502 :                 if (PQisBusy(conn))
    4255          26 :                     return PGRES_POLLING_READING;
    4256             : 
    4257       27476 :                 res = PQgetResult(conn);
    4258             : 
    4259             :                 /*
    4260             :                  * NULL return indicating we have gone to IDLE state is
    4261             :                  * expected
    4262             :                  */
    4263       27476 :                 if (res)
    4264             :                 {
    4265          42 :                     if (res->resultStatus != PGRES_FATAL_ERROR)
    4266           0 :                         libpq_append_conn_error(conn, "unexpected message from server during startup");
    4267          42 :                     else if (conn->send_appname &&
    4268          42 :                              (conn->appname || conn->fbappname))
    4269             :                     {
    4270             :                         /*
    4271             :                          * If we tried to send application_name, check to see
    4272             :                          * if the error is about that --- pre-9.0 servers will
    4273             :                          * reject it at this stage of the process.  If so,
    4274             :                          * close the connection and retry without sending
    4275             :                          * application_name.  We could possibly get a false
    4276             :                          * SQLSTATE match here and retry uselessly, but there
    4277             :                          * seems no great harm in that; we'll just get the
    4278             :                          * same error again if it's unrelated.
    4279             :                          */
    4280             :                         const char *sqlstate;
    4281             : 
    4282          42 :                         sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
    4283          42 :                         if (sqlstate &&
    4284          42 :                             strcmp(sqlstate, ERRCODE_APPNAME_UNKNOWN) == 0)
    4285             :                         {
    4286           0 :                             PQclear(res);
    4287           0 :                             conn->send_appname = false;
    4288           0 :                             need_new_connection = true;
    4289           0 :                             goto keep_going;
    4290             :                         }
    4291             :                     }
    4292             : 
    4293             :                     /*
    4294             :                      * if the resultStatus is FATAL, then conn->errorMessage
    4295             :                      * already has a copy of the error; needn't copy it back.
    4296             :                      * But add a newline if it's not there already, since
    4297             :                      * postmaster error messages may not have one.
    4298             :                      */
    4299          42 :                     if (conn->errorMessage.len <= 0 ||
    4300          42 :                         conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
    4301           0 :                         appendPQExpBufferChar(&conn->errorMessage, '\n');
    4302          42 :                     PQclear(res);
    4303          42 :                     goto error_return;
    4304             :                 }
    4305             : 
    4306             :                 /* Almost there now ... */
    4307       27434 :                 conn->status = CONNECTION_CHECK_TARGET;
    4308       27434 :                 goto keep_going;
    4309             :             }
    4310             : 
    4311       27434 :         case CONNECTION_CHECK_TARGET:
    4312             :             {
    4313             :                 /*
    4314             :                  * If a read-write, read-only, primary, or standby connection
    4315             :                  * is required, see if we have one.
    4316             :                  */
    4317       27434 :                 if (conn->target_server_type == SERVER_TYPE_READ_WRITE ||
    4318       27424 :                     conn->target_server_type == SERVER_TYPE_READ_ONLY)
    4319           8 :                 {
    4320             :                     bool        read_only_server;
    4321             : 
    4322             :                     /*
    4323             :                      * If the server didn't report
    4324             :                      * "default_transaction_read_only" or "in_hot_standby" at
    4325             :                      * startup, we must determine its state by sending the
    4326             :                      * query "SHOW transaction_read_only".  This GUC exists in
    4327             :                      * all server versions that support 3.0 protocol.
    4328             :                      */
    4329          20 :                     if (conn->default_transaction_read_only == PG_BOOL_UNKNOWN ||
    4330          20 :                         conn->in_hot_standby == PG_BOOL_UNKNOWN)
    4331             :                     {
    4332             :                         /*
    4333             :                          * We use PQsendQueryContinue so that
    4334             :                          * conn->errorMessage does not get cleared.  We need
    4335             :                          * to preserve any error messages related to previous
    4336             :                          * hosts we have tried and failed to connect to.
    4337             :                          */
    4338           0 :                         conn->status = CONNECTION_OK;
    4339           0 :                         if (!PQsendQueryContinue(conn,
    4340             :                                                  "SHOW transaction_read_only"))
    4341           0 :                             goto error_return;
    4342             :                         /* We'll return to this state when we have the answer */
    4343           0 :                         conn->status = CONNECTION_CHECK_WRITABLE;
    4344           0 :                         return PGRES_POLLING_READING;
    4345             :                     }
    4346             : 
    4347             :                     /* OK, we can make the test */
    4348          20 :                     read_only_server =
    4349          40 :                         (conn->default_transaction_read_only == PG_BOOL_YES ||
    4350          20 :                          conn->in_hot_standby == PG_BOOL_YES);
    4351             : 
    4352          20 :                     if ((conn->target_server_type == SERVER_TYPE_READ_WRITE) ?
    4353             :                         read_only_server : !read_only_server)
    4354             :                     {
    4355             :                         /* Wrong server state, reject and try the next host */
    4356          12 :                         if (conn->target_server_type == SERVER_TYPE_READ_WRITE)
    4357           6 :                             libpq_append_conn_error(conn, "session is read-only");
    4358             :                         else
    4359           6 :                             libpq_append_conn_error(conn, "session is not read-only");
    4360             : 
    4361             :                         /* Close connection politely. */
    4362          12 :                         conn->status = CONNECTION_OK;
    4363          12 :                         sendTerminateConn(conn);
    4364             : 
    4365             :                         /*
    4366             :                          * Try next host if any, but we don't want to consider
    4367             :                          * additional addresses for this host.
    4368             :                          */
    4369          12 :                         conn->try_next_host = true;
    4370          12 :                         goto keep_going;
    4371             :                     }
    4372             :                 }
    4373       27414 :                 else if (conn->target_server_type == SERVER_TYPE_PRIMARY ||
    4374       27404 :                          conn->target_server_type == SERVER_TYPE_STANDBY ||
    4375       27394 :                          conn->target_server_type == SERVER_TYPE_PREFER_STANDBY)
    4376             :                 {
    4377             :                     /*
    4378             :                      * If the server didn't report "in_hot_standby" at
    4379             :                      * startup, we must determine its state by sending the
    4380             :                      * query "SELECT pg_catalog.pg_is_in_recovery()".  Servers
    4381             :                      * before 9.0 don't have that function, but by the same
    4382             :                      * token they don't have any standby mode, so we may just
    4383             :                      * assume the result.
    4384             :                      */
    4385          30 :                     if (conn->sversion < 90000)
    4386           0 :                         conn->in_hot_standby = PG_BOOL_NO;
    4387             : 
    4388          30 :                     if (conn->in_hot_standby == PG_BOOL_UNKNOWN)
    4389             :                     {
    4390             :                         /*
    4391             :                          * We use PQsendQueryContinue so that
    4392             :                          * conn->errorMessage does not get cleared.  We need
    4393             :                          * to preserve any error messages related to previous
    4394             :                          * hosts we have tried and failed to connect to.
    4395             :                          */
    4396           0 :                         conn->status = CONNECTION_OK;
    4397           0 :                         if (!PQsendQueryContinue(conn,
    4398             :                                                  "SELECT pg_catalog.pg_is_in_recovery()"))
    4399           0 :                             goto error_return;
    4400             :                         /* We'll return to this state when we have the answer */
    4401           0 :                         conn->status = CONNECTION_CHECK_STANDBY;
    4402           0 :                         return PGRES_POLLING_READING;
    4403             :                     }
    4404             : 
    4405             :                     /* OK, we can make the test */
    4406          60 :                     if ((conn->target_server_type == SERVER_TYPE_PRIMARY) ?
    4407          10 :                         (conn->in_hot_standby == PG_BOOL_YES) :
    4408          20 :                         (conn->in_hot_standby == PG_BOOL_NO))
    4409             :                     {
    4410             :                         /* Wrong server state, reject and try the next host */
    4411          18 :                         if (conn->target_server_type == SERVER_TYPE_PRIMARY)
    4412           6 :                             libpq_append_conn_error(conn, "server is in hot standby mode");
    4413             :                         else
    4414          12 :                             libpq_append_conn_error(conn, "server is not in hot standby mode");
    4415             : 
    4416             :                         /* Close connection politely. */
    4417          18 :                         conn->status = CONNECTION_OK;
    4418          18 :                         sendTerminateConn(conn);
    4419             : 
    4420             :                         /*
    4421             :                          * Try next host if any, but we don't want to consider
    4422             :                          * additional addresses for this host.
    4423             :                          */
    4424          18 :                         conn->try_next_host = true;
    4425          18 :                         goto keep_going;
    4426             :                     }
    4427             :                 }
    4428             : 
    4429             :                 /* Don't hold onto any OAuth tokens longer than necessary. */
    4430       27404 :                 pqClearOAuthToken(conn);
    4431             : 
    4432             :                 /*
    4433             :                  * For non cancel requests we can release the address list
    4434             :                  * now. For cancel requests we never actually resolve
    4435             :                  * addresses and instead the addrinfo exists for the lifetime
    4436             :                  * of the connection.
    4437             :                  */
    4438       27404 :                 if (!conn->cancelRequest)
    4439       27404 :                     release_conn_addrinfo(conn);
    4440             : 
    4441             :                 /*
    4442             :                  * Contents of conn->errorMessage are no longer interesting
    4443             :                  * (and it seems some clients expect it to be empty after a
    4444             :                  * successful connection).
    4445             :                  */
    4446       27404 :                 pqClearConnErrorState(conn);
    4447             : 
    4448             :                 /* We are open for business! */
    4449       27404 :                 conn->status = CONNECTION_OK;
    4450       27404 :                 return PGRES_POLLING_OK;
    4451             :             }
    4452             : 
    4453           0 :         case CONNECTION_CONSUME:
    4454             :             {
    4455             :                 /*
    4456             :                  * This state just makes sure the connection is idle after
    4457             :                  * we've obtained the result of a SHOW or SELECT query.  Once
    4458             :                  * we're clear, return to CONNECTION_CHECK_TARGET state to
    4459             :                  * decide what to do next.  We must transiently set status =
    4460             :                  * CONNECTION_OK in order to use the result-consuming
    4461             :                  * subroutines.
    4462             :                  */
    4463           0 :                 conn->status = CONNECTION_OK;
    4464           0 :                 if (!PQconsumeInput(conn))
    4465           0 :                     goto error_return;
    4466             : 
    4467           0 :                 if (PQisBusy(conn))
    4468             :                 {
    4469           0 :                     conn->status = CONNECTION_CONSUME;
    4470           0 :                     return PGRES_POLLING_READING;
    4471             :                 }
    4472             : 
    4473             :                 /* Call PQgetResult() again until we get a NULL result */
    4474           0 :                 res = PQgetResult(conn);
    4475           0 :                 if (res != NULL)
    4476             :                 {
    4477           0 :                     PQclear(res);
    4478           0 :                     conn->status = CONNECTION_CONSUME;
    4479           0 :                     return PGRES_POLLING_READING;
    4480             :                 }
    4481             : 
    4482           0 :                 conn->status = CONNECTION_CHECK_TARGET;
    4483           0 :                 goto keep_going;
    4484             :             }
    4485             : 
    4486           0 :         case CONNECTION_CHECK_WRITABLE:
    4487             :             {
    4488             :                 /*
    4489             :                  * Waiting for result of "SHOW transaction_read_only".  We
    4490             :                  * must transiently set status = CONNECTION_OK in order to use
    4491             :                  * the result-consuming subroutines.
    4492             :                  */
    4493           0 :                 conn->status = CONNECTION_OK;
    4494           0 :                 if (!PQconsumeInput(conn))
    4495           0 :                     goto error_return;
    4496             : 
    4497           0 :                 if (PQisBusy(conn))
    4498             :                 {
    4499           0 :                     conn->status = CONNECTION_CHECK_WRITABLE;
    4500           0 :                     return PGRES_POLLING_READING;
    4501             :                 }
    4502             : 
    4503           0 :                 res = PQgetResult(conn);
    4504           0 :                 if (res && PQresultStatus(res) == PGRES_TUPLES_OK &&
    4505           0 :                     PQntuples(res) == 1)
    4506             :                 {
    4507           0 :                     char       *val = PQgetvalue(res, 0, 0);
    4508             : 
    4509             :                     /*
    4510             :                      * "transaction_read_only = on" proves that at least one
    4511             :                      * of default_transaction_read_only and in_hot_standby is
    4512             :                      * on, but we don't actually know which.  We don't care
    4513             :                      * though for the purpose of identifying a read-only
    4514             :                      * session, so satisfy the CONNECTION_CHECK_TARGET code by
    4515             :                      * claiming they are both on.  On the other hand, if it's
    4516             :                      * a read-write session, they are certainly both off.
    4517             :                      */
    4518           0 :                     if (strncmp(val, "on", 2) == 0)
    4519             :                     {
    4520           0 :                         conn->default_transaction_read_only = PG_BOOL_YES;
    4521           0 :                         conn->in_hot_standby = PG_BOOL_YES;
    4522             :                     }
    4523             :                     else
    4524             :                     {
    4525           0 :                         conn->default_transaction_read_only = PG_BOOL_NO;
    4526           0 :                         conn->in_hot_standby = PG_BOOL_NO;
    4527             :                     }
    4528           0 :                     PQclear(res);
    4529             : 
    4530             :                     /* Finish reading messages before continuing */
    4531           0 :                     conn->status = CONNECTION_CONSUME;
    4532           0 :                     goto keep_going;
    4533             :                 }
    4534             : 
    4535             :                 /* Something went wrong with "SHOW transaction_read_only". */
    4536           0 :                 PQclear(res);
    4537             : 
    4538             :                 /* Append error report to conn->errorMessage. */
    4539           0 :                 libpq_append_conn_error(conn, "\"%s\" failed",
    4540             :                                         "SHOW transaction_read_only");
    4541             : 
    4542             :                 /* Close connection politely. */
    4543           0 :                 conn->status = CONNECTION_OK;
    4544           0 :                 sendTerminateConn(conn);
    4545             : 
    4546             :                 /* Try next host. */
    4547           0 :                 conn->try_next_host = true;
    4548           0 :                 goto keep_going;
    4549             :             }
    4550             : 
    4551           0 :         case CONNECTION_CHECK_STANDBY:
    4552             :             {
    4553             :                 /*
    4554             :                  * Waiting for result of "SELECT pg_is_in_recovery()".  We
    4555             :                  * must transiently set status = CONNECTION_OK in order to use
    4556             :                  * the result-consuming subroutines.
    4557             :                  */
    4558           0 :                 conn->status = CONNECTION_OK;
    4559           0 :                 if (!PQconsumeInput(conn))
    4560           0 :                     goto error_return;
    4561             : 
    4562           0 :                 if (PQisBusy(conn))
    4563             :                 {
    4564           0 :                     conn->status = CONNECTION_CHECK_STANDBY;
    4565           0 :                     return PGRES_POLLING_READING;
    4566             :                 }
    4567             : 
    4568           0 :                 res = PQgetResult(conn);
    4569           0 :                 if (res && PQresultStatus(res) == PGRES_TUPLES_OK &&
    4570           0 :                     PQntuples(res) == 1)
    4571             :                 {
    4572           0 :                     char       *val = PQgetvalue(res, 0, 0);
    4573             : 
    4574           0 :                     if (strncmp(val, "t", 1) == 0)
    4575           0 :                         conn->in_hot_standby = PG_BOOL_YES;
    4576             :                     else
    4577           0 :                         conn->in_hot_standby = PG_BOOL_NO;
    4578           0 :                     PQclear(res);
    4579             : 
    4580             :                     /* Finish reading messages before continuing */
    4581           0 :                     conn->status = CONNECTION_CONSUME;
    4582           0 :                     goto keep_going;
    4583             :                 }
    4584             : 
    4585             :                 /* Something went wrong with "SELECT pg_is_in_recovery()". */
    4586           0 :                 PQclear(res);
    4587             : 
    4588             :                 /* Append error report to conn->errorMessage. */
    4589           0 :                 libpq_append_conn_error(conn, "\"%s\" failed",
    4590             :                                         "SELECT pg_is_in_recovery()");
    4591             : 
    4592             :                 /* Close connection politely. */
    4593           0 :                 conn->status = CONNECTION_OK;
    4594           0 :                 sendTerminateConn(conn);
    4595             : 
    4596             :                 /* Try next host. */
    4597           0 :                 conn->try_next_host = true;
    4598           0 :                 goto keep_going;
    4599             :             }
    4600             : 
    4601           0 :         default:
    4602           0 :             libpq_append_conn_error(conn,
    4603             :                                     "invalid connection state %d, probably indicative of memory corruption",
    4604           0 :                                     conn->status);
    4605           0 :             goto error_return;
    4606             :     }
    4607             : 
    4608             :     /* Unreachable */
    4609             : 
    4610         978 : error_return:
    4611             : 
    4612             :     /*
    4613             :      * We used to close the socket at this point, but that makes it awkward
    4614             :      * for those above us if they wish to remove this socket from their own
    4615             :      * records (an fd_set for example).  We'll just have this socket closed
    4616             :      * when PQfinish is called (which is compulsory even after an error, since
    4617             :      * the connection structure must be freed).
    4618             :      */
    4619         978 :     conn->status = CONNECTION_BAD;
    4620         978 :     return PGRES_POLLING_FAILED;
    4621             : }
    4622             : 
    4623             : /*
    4624             :  * Initialize the state machine for negotiating encryption
    4625             :  */
    4626             : static bool
    4627       28454 : init_allowed_encryption_methods(PGconn *conn)
    4628             : {
    4629       28454 :     if (conn->raddr.addr.ss_family == AF_UNIX)
    4630             :     {
    4631             :         /* Don't request SSL or GSSAPI over Unix sockets */
    4632       27864 :         conn->allowed_enc_methods &= ~(ENC_SSL | ENC_GSSAPI);
    4633             : 
    4634             :         /*
    4635             :          * XXX: we probably should not do this. sslmode=require works
    4636             :          * differently
    4637             :          */
    4638       27864 :         if (conn->gssencmode[0] == 'r')
    4639             :         {
    4640           0 :             libpq_append_conn_error(conn,
    4641             :                                     "GSSAPI encryption required but it is not supported over a local socket");
    4642           0 :             conn->allowed_enc_methods = 0;
    4643           0 :             conn->current_enc_method = ENC_ERROR;
    4644           0 :             return false;
    4645             :         }
    4646             : 
    4647       27864 :         conn->allowed_enc_methods = ENC_PLAINTEXT;
    4648       27864 :         conn->current_enc_method = ENC_PLAINTEXT;
    4649       27864 :         return true;
    4650             :     }
    4651             : 
    4652             :     /* initialize based on sslmode and gssencmode */
    4653         590 :     conn->allowed_enc_methods = 0;
    4654             : 
    4655             : #ifdef USE_SSL
    4656             :     /* sslmode anything but 'disable', and GSSAPI not required */
    4657         590 :     if (conn->sslmode[0] != 'd' && conn->gssencmode[0] != 'r')
    4658             :     {
    4659         578 :         conn->allowed_enc_methods |= ENC_SSL;
    4660             :     }
    4661             : #endif
    4662             : 
    4663             : #ifdef ENABLE_GSS
    4664             :     if (conn->gssencmode[0] != 'd')
    4665             :         conn->allowed_enc_methods |= ENC_GSSAPI;
    4666             : #endif
    4667             : 
    4668         590 :     if ((conn->sslmode[0] == 'd' || conn->sslmode[0] == 'p' || conn->sslmode[0] == 'a') &&
    4669         348 :         (conn->gssencmode[0] == 'd' || conn->gssencmode[0] == 'p'))
    4670             :     {
    4671         348 :         conn->allowed_enc_methods |= ENC_PLAINTEXT;
    4672             :     }
    4673             : 
    4674         590 :     return select_next_encryption_method(conn, false);
    4675             : }
    4676             : 
    4677             : /*
    4678             :  * Out-of-line portion of the ENCRYPTION_NEGOTIATION_FAILED() macro in the
    4679             :  * PQconnectPoll state machine.
    4680             :  *
    4681             :  * Return value:
    4682             :  *  0: connection failed and we are out of encryption methods to try. return an error
    4683             :  *  1: Retry with next connection method. The TCP connection is still valid and in
    4684             :  *     known state, so we can proceed with the negotiating next method without
    4685             :  *     reconnecting.
    4686             :  *  2: Disconnect, and retry with next connection method.
    4687             :  *
    4688             :  * conn->current_enc_method is updated to the next method to try.
    4689             :  */
    4690             : #if defined(USE_SSL) || defined(ENABLE_GSS)
    4691             : static int
    4692         296 : encryption_negotiation_failed(PGconn *conn)
    4693             : {
    4694             :     Assert((conn->failed_enc_methods & conn->current_enc_method) == 0);
    4695         296 :     conn->failed_enc_methods |= conn->current_enc_method;
    4696             : 
    4697         296 :     if (select_next_encryption_method(conn, true))
    4698             :     {
    4699             :         /* An existing connection cannot be reused for direct SSL */
    4700         292 :         if (conn->current_enc_method == ENC_SSL && conn->sslnegotiation[0] == 'd')
    4701           0 :             return 2;
    4702             :         else
    4703         292 :             return 1;
    4704             :     }
    4705             :     else
    4706           4 :         return 0;
    4707             : }
    4708             : #endif
    4709             : 
    4710             : /*
    4711             :  * Out-of-line portion of the CONNECTION_FAILED() macro
    4712             :  *
    4713             :  * Returns true, if we should reconnect and retry with a different encryption
    4714             :  * method.  conn->current_enc_method is updated to the next method to try.
    4715             :  */
    4716             : static bool
    4717         154 : connection_failed(PGconn *conn)
    4718             : {
    4719             :     Assert((conn->failed_enc_methods & conn->current_enc_method) == 0);
    4720         154 :     conn->failed_enc_methods |= conn->current_enc_method;
    4721             : 
    4722         154 :     return select_next_encryption_method(conn, false);
    4723             : }
    4724             : 
    4725             : /*
    4726             :  * Choose the next encryption method to try. If this is a retry,
    4727             :  * conn->failed_enc_methods has already been updated. The function sets
    4728             :  * conn->current_enc_method to the next method to try. Returns false if no
    4729             :  * encryption methods remain.
    4730             :  */
    4731             : static bool
    4732        1040 : select_next_encryption_method(PGconn *conn, bool have_valid_connection)
    4733             : {
    4734             :     int         remaining_methods;
    4735             : 
    4736             : #define SELECT_NEXT_METHOD(method) \
    4737             :     do { \
    4738             :         if ((remaining_methods & method) != 0) \
    4739             :         { \
    4740             :             conn->current_enc_method = method; \
    4741             :             return true; \
    4742             :         } \
    4743             :     } while (false)
    4744             : 
    4745        1040 :     remaining_methods = conn->allowed_enc_methods & ~conn->failed_enc_methods;
    4746             : 
    4747             :     /*
    4748             :      * Try GSSAPI before SSL
    4749             :      */
    4750             : #ifdef ENABLE_GSS
    4751             :     if ((remaining_methods & ENC_GSSAPI) != 0)
    4752             :     {
    4753             :         /*
    4754             :          * If GSSAPI encryption is enabled, then call pg_GSS_have_cred_cache()
    4755             :          * which will return true if we can acquire credentials (and give us a
    4756             :          * handle to use in conn->gcred), and then send a packet to the server
    4757             :          * asking for GSSAPI Encryption (and skip past SSL negotiation and
    4758             :          * regular startup below).
    4759             :          */
    4760             :         if (!conn->gctx)
    4761             :         {
    4762             :             if (!pg_GSS_have_cred_cache(&conn->gcred))
    4763             :             {
    4764             :                 conn->allowed_enc_methods &= ~ENC_GSSAPI;
    4765             :                 remaining_methods &= ~ENC_GSSAPI;
    4766             : 
    4767             :                 if (conn->gssencmode[0] == 'r')
    4768             :                 {
    4769             :                     libpq_append_conn_error(conn,
    4770             :                                             "GSSAPI encryption required but no credential cache");
    4771             :                 }
    4772             :             }
    4773             :         }
    4774             :     }
    4775             : 
    4776             :     SELECT_NEXT_METHOD(ENC_GSSAPI);
    4777             : #endif
    4778             : 
    4779             :     /*
    4780             :      * The order between SSL encryption and plaintext depends on sslmode. With
    4781             :      * sslmode=allow, try plaintext connection before SSL. With
    4782             :      * sslmode=prefer, it's the other way round. With other modes, we only try
    4783             :      * plaintext or SSL connections so the order they're listed here doesn't
    4784             :      * matter.
    4785             :      */
    4786        1040 :     if (conn->sslmode[0] == 'a')
    4787          14 :         SELECT_NEXT_METHOD(ENC_PLAINTEXT);
    4788             : 
    4789        1030 :     SELECT_NEXT_METHOD(ENC_SSL);
    4790             : 
    4791         464 :     if (conn->sslmode[0] != 'a')
    4792         464 :         SELECT_NEXT_METHOD(ENC_PLAINTEXT);
    4793             : 
    4794             :     /* No more options */
    4795         152 :     conn->current_enc_method = ENC_ERROR;
    4796         152 :     return false;
    4797             : #undef SELECT_NEXT_METHOD
    4798             : }
    4799             : 
    4800             : /*
    4801             :  * internal_ping
    4802             :  *      Determine if a server is running and if we can connect to it.
    4803             :  *
    4804             :  * The argument is a connection that's been started, but not completed.
    4805             :  */
    4806             : static PGPing
    4807         672 : internal_ping(PGconn *conn)
    4808             : {
    4809             :     /* Say "no attempt" if we never got to PQconnectPoll */
    4810         672 :     if (!conn || !conn->options_valid)
    4811           0 :         return PQPING_NO_ATTEMPT;
    4812             : 
    4813             :     /* Attempt to complete the connection */
    4814         672 :     if (conn->status != CONNECTION_BAD)
    4815         374 :         (void) pqConnectDBComplete(conn);
    4816             : 
    4817             :     /* Definitely OK if we succeeded */
    4818         672 :     if (conn->status != CONNECTION_BAD)
    4819         182 :         return PQPING_OK;
    4820             : 
    4821             :     /*
    4822             :      * Here begins the interesting part of "ping": determine the cause of the
    4823             :      * failure in sufficient detail to decide what to return.  We do not want
    4824             :      * to report that the server is not up just because we didn't have a valid
    4825             :      * password, for example.  In fact, any sort of authentication request
    4826             :      * implies the server is up.  (We need this check since the libpq side of
    4827             :      * things might have pulled the plug on the connection before getting an
    4828             :      * error as such from the postmaster.)
    4829             :      */
    4830         490 :     if (conn->auth_req_received)
    4831           0 :         return PQPING_OK;
    4832             : 
    4833             :     /*
    4834             :      * If we failed to get any ERROR response from the postmaster, report
    4835             :      * PQPING_NO_RESPONSE.  This result could be somewhat misleading for a
    4836             :      * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
    4837             :      * out of support.  Another corner case where the server could return a
    4838             :      * failure without a SQLSTATE is fork failure, but PQPING_NO_RESPONSE
    4839             :      * isn't totally unreasonable for that anyway.  We expect that every other
    4840             :      * failure case in a modern server will produce a report with a SQLSTATE.
    4841             :      *
    4842             :      * NOTE: whenever we get around to making libpq generate SQLSTATEs for
    4843             :      * client-side errors, we should either not store those into
    4844             :      * last_sqlstate, or add an extra flag so we can tell client-side errors
    4845             :      * apart from server-side ones.
    4846             :      */
    4847         490 :     if (strlen(conn->last_sqlstate) != 5)
    4848         300 :         return PQPING_NO_RESPONSE;
    4849             : 
    4850             :     /*
    4851             :      * Report PQPING_REJECT if server says it's not accepting connections.
    4852             :      */
    4853         190 :     if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
    4854         190 :         return PQPING_REJECT;
    4855             : 
    4856             :     /*
    4857             :      * Any other SQLSTATE can be taken to indicate that the server is up.
    4858             :      * Presumably it didn't like our username, password, or database name; or
    4859             :      * perhaps it had some transient failure, but that should not be taken as
    4860             :      * meaning "it's down".
    4861             :      */
    4862           0 :     return PQPING_OK;
    4863             : }
    4864             : 
    4865             : 
    4866             : /*
    4867             :  * pqMakeEmptyPGconn
    4868             :  *   - create a PGconn data structure with (as yet) no interesting data
    4869             :  */
    4870             : PGconn *
    4871       28500 : pqMakeEmptyPGconn(void)
    4872             : {
    4873             :     PGconn     *conn;
    4874             : 
    4875             : #ifdef WIN32
    4876             : 
    4877             :     /*
    4878             :      * Make sure socket support is up and running in this process.
    4879             :      *
    4880             :      * Note: the Windows documentation says that we should eventually do a
    4881             :      * matching WSACleanup() call, but experience suggests that that is at
    4882             :      * least as likely to cause problems as fix them.  So we don't.
    4883             :      */
    4884             :     static bool wsastartup_done = false;
    4885             : 
    4886             :     if (!wsastartup_done)
    4887             :     {
    4888             :         WSADATA     wsaData;
    4889             : 
    4890             :         if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    4891             :             return NULL;
    4892             :         wsastartup_done = true;
    4893             :     }
    4894             : 
    4895             :     /* Forget any earlier error */
    4896             :     WSASetLastError(0);
    4897             : #endif                          /* WIN32 */
    4898             : 
    4899       28500 :     conn = (PGconn *) malloc(sizeof(PGconn));
    4900       28500 :     if (conn == NULL)
    4901           0 :         return conn;
    4902             : 
    4903             :     /* Zero all pointers and booleans */
    4904       28500 :     MemSet(conn, 0, sizeof(PGconn));
    4905             : 
    4906             :     /* install default notice hooks */
    4907       28500 :     conn->noticeHooks.noticeRec = defaultNoticeReceiver;
    4908       28500 :     conn->noticeHooks.noticeProc = defaultNoticeProcessor;
    4909             : 
    4910       28500 :     conn->status = CONNECTION_BAD;
    4911       28500 :     conn->asyncStatus = PGASYNC_IDLE;
    4912       28500 :     conn->pipelineStatus = PQ_PIPELINE_OFF;
    4913       28500 :     conn->xactStatus = PQTRANS_IDLE;
    4914       28500 :     conn->options_valid = false;
    4915       28500 :     conn->nonblocking = false;
    4916       28500 :     conn->client_encoding = PG_SQL_ASCII;
    4917       28500 :     conn->std_strings = false;   /* unless server says differently */
    4918       28500 :     conn->default_transaction_read_only = PG_BOOL_UNKNOWN;
    4919       28500 :     conn->in_hot_standby = PG_BOOL_UNKNOWN;
    4920       28500 :     conn->scram_sha_256_iterations = SCRAM_SHA_256_DEFAULT_ITERATIONS;
    4921       28500 :     conn->verbosity = PQERRORS_DEFAULT;
    4922       28500 :     conn->show_context = PQSHOW_CONTEXT_ERRORS;
    4923       28500 :     conn->sock = PGINVALID_SOCKET;
    4924       28500 :     conn->altsock = PGINVALID_SOCKET;
    4925       28500 :     conn->Pfdebug = NULL;
    4926             : 
    4927             :     /*
    4928             :      * We try to send at least 8K at a time, which is the usual size of pipe
    4929             :      * buffers on Unix systems.  That way, when we are sending a large amount
    4930             :      * of data, we avoid incurring extra kernel context swaps for partial
    4931             :      * bufferloads.  The output buffer is initially made 16K in size, and we
    4932             :      * try to dump it after accumulating 8K.
    4933             :      *
    4934             :      * With the same goal of minimizing context swaps, the input buffer will
    4935             :      * be enlarged anytime it has less than 8K free, so we initially allocate
    4936             :      * twice that.
    4937             :      */
    4938       28500 :     conn->inBufSize = 16 * 1024;
    4939       28500 :     conn->inBuffer = (char *) malloc(conn->inBufSize);
    4940       28500 :     conn->outBufSize = 16 * 1024;
    4941       28500 :     conn->outBuffer = (char *) malloc(conn->outBufSize);
    4942       28500 :     conn->rowBufLen = 32;
    4943       28500 :     conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
    4944       28500 :     initPQExpBuffer(&conn->errorMessage);
    4945       28500 :     initPQExpBuffer(&conn->workBuffer);
    4946             : 
    4947       28500 :     if (conn->inBuffer == NULL ||
    4948       28500 :         conn->outBuffer == NULL ||
    4949       28500 :         conn->rowBuf == NULL ||
    4950       28500 :         PQExpBufferBroken(&conn->errorMessage) ||
    4951       28500 :         PQExpBufferBroken(&conn->workBuffer))
    4952             :     {
    4953             :         /* out of memory already :-( */
    4954           0 :         freePGconn(conn);
    4955           0 :         conn = NULL;
    4956             :     }
    4957             : 
    4958       28500 :     return conn;
    4959             : }
    4960             : 
    4961             : /*
    4962             :  * freePGconn
    4963             :  *   - free an idle (closed) PGconn data structure
    4964             :  *
    4965             :  * NOTE: this should not overlap any functionality with pqClosePGconn().
    4966             :  * Clearing/resetting of transient state belongs there; what we do here is
    4967             :  * release data that is to be held for the life of the PGconn structure.
    4968             :  * If a value ought to be cleared/freed during PQreset(), do it there not here.
    4969             :  */
    4970             : static void
    4971       28088 : freePGconn(PGconn *conn)
    4972             : {
    4973             :     /* let any event procs clean up their state data */
    4974       28088 :     for (int i = 0; i < conn->nEvents; i++)
    4975             :     {
    4976             :         PGEventConnDestroy evt;
    4977             : 
    4978           0 :         evt.conn = conn;
    4979           0 :         (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
    4980           0 :                                     conn->events[i].passThrough);
    4981           0 :         free(conn->events[i].name);
    4982             :     }
    4983             : 
    4984       28088 :     release_conn_addrinfo(conn);
    4985       28088 :     pqReleaseConnHosts(conn);
    4986             : 
    4987       28088 :     free(conn->client_encoding_initial);
    4988       28088 :     free(conn->events);
    4989       28088 :     free(conn->pghost);
    4990       28088 :     free(conn->pghostaddr);
    4991       28088 :     free(conn->pgport);
    4992       28088 :     free(conn->connect_timeout);
    4993       28088 :     free(conn->pgtcp_user_timeout);
    4994       28088 :     free(conn->pgoptions);
    4995       28088 :     free(conn->appname);
    4996       28088 :     free(conn->fbappname);
    4997       28088 :     free(conn->dbName);
    4998       28088 :     free(conn->replication);
    4999       28088 :     free(conn->pguser);
    5000       28088 :     if (conn->pgpass)
    5001             :     {
    5002         452 :         explicit_bzero(conn->pgpass, strlen(conn->pgpass));
    5003         452 :         free(conn->pgpass);
    5004             :     }
    5005       28088 :     free(conn->pgpassfile);
    5006       28088 :     free(conn->channel_binding);
    5007       28088 :     free(conn->keepalives);
    5008       28088 :     free(conn->keepalives_idle);
    5009       28088 :     free(conn->keepalives_interval);
    5010       28088 :     free(conn->keepalives_count);
    5011       28088 :     free(conn->sslmode);
    5012       28088 :     free(conn->sslnegotiation);
    5013       28088 :     free(conn->sslcert);
    5014       28088 :     free(conn->sslkey);
    5015       28088 :     if (conn->sslpassword)
    5016             :     {
    5017           6 :         explicit_bzero(conn->sslpassword, strlen(conn->sslpassword));
    5018           6 :         free(conn->sslpassword);
    5019             :     }
    5020       28088 :     free(conn->sslcertmode);
    5021       28088 :     free(conn->sslrootcert);
    5022       28088 :     free(conn->sslcrl);
    5023       28088 :     free(conn->sslcrldir);
    5024       28088 :     free(conn->sslcompression);
    5025       28088 :     free(conn->sslsni);
    5026       28088 :     free(conn->requirepeer);
    5027       28088 :     free(conn->require_auth);
    5028       28088 :     free(conn->ssl_min_protocol_version);
    5029       28088 :     free(conn->ssl_max_protocol_version);
    5030       28088 :     free(conn->gssencmode);
    5031       28088 :     free(conn->krbsrvname);
    5032       28088 :     free(conn->gsslib);
    5033       28088 :     free(conn->gssdelegation);
    5034       28088 :     free(conn->connip);
    5035             :     /* Note that conn->Pfdebug is not ours to close or free */
    5036       28088 :     free(conn->write_err_msg);
    5037       28088 :     free(conn->inBuffer);
    5038       28088 :     free(conn->outBuffer);
    5039       28088 :     free(conn->rowBuf);
    5040       28088 :     free(conn->target_session_attrs);
    5041       28088 :     free(conn->load_balance_hosts);
    5042       28088 :     free(conn->scram_client_key);
    5043       28088 :     free(conn->scram_server_key);
    5044       28088 :     free(conn->oauth_issuer);
    5045       28088 :     free(conn->oauth_issuer_id);
    5046       28088 :     free(conn->oauth_discovery_uri);
    5047       28088 :     free(conn->oauth_client_id);
    5048       28088 :     free(conn->oauth_client_secret);
    5049       28088 :     free(conn->oauth_scope);
    5050       28088 :     termPQExpBuffer(&conn->errorMessage);
    5051       28088 :     termPQExpBuffer(&conn->workBuffer);
    5052             : 
    5053       28088 :     free(conn);
    5054       28088 : }
    5055             : 
    5056             : /*
    5057             :  * pqReleaseConnHosts
    5058             :  *   - Free the host list in the PGconn.
    5059             :  */
    5060             : void
    5061       28098 : pqReleaseConnHosts(PGconn *conn)
    5062             : {
    5063       28098 :     if (conn->connhost)
    5064             :     {
    5065       56434 :         for (int i = 0; i < conn->nconnhost; ++i)
    5066             :         {
    5067       28350 :             free(conn->connhost[i].host);
    5068       28350 :             free(conn->connhost[i].hostaddr);
    5069       28350 :             free(conn->connhost[i].port);
    5070       28350 :             if (conn->connhost[i].password != NULL)
    5071             :             {
    5072          14 :                 explicit_bzero(conn->connhost[i].password,
    5073          14 :                                strlen(conn->connhost[i].password));
    5074          14 :                 free(conn->connhost[i].password);
    5075             :             }
    5076             :         }
    5077       28084 :         free(conn->connhost);
    5078             :     }
    5079       28098 : }
    5080             : 
    5081             : /*
    5082             :  * store_conn_addrinfo
    5083             :  *   - copy addrinfo to PGconn object
    5084             :  *
    5085             :  * Copies the addrinfos from addrlist to the PGconn object such that the
    5086             :  * addrinfos can be manipulated by libpq. Returns a positive integer on
    5087             :  * failure, otherwise zero.
    5088             :  */
    5089             : static int
    5090       28434 : store_conn_addrinfo(PGconn *conn, struct addrinfo *addrlist)
    5091             : {
    5092       28434 :     struct addrinfo *ai = addrlist;
    5093             : 
    5094       28434 :     conn->whichaddr = 0;
    5095             : 
    5096       28434 :     conn->naddr = 0;
    5097       57158 :     while (ai)
    5098             :     {
    5099       28724 :         ai = ai->ai_next;
    5100       28724 :         conn->naddr++;
    5101             :     }
    5102             : 
    5103       28434 :     conn->addr = calloc(conn->naddr, sizeof(AddrInfo));
    5104       28434 :     if (conn->addr == NULL)
    5105             :     {
    5106           0 :         libpq_append_conn_error(conn, "out of memory");
    5107           0 :         return 1;
    5108             :     }
    5109             : 
    5110       28434 :     ai = addrlist;
    5111       57158 :     for (int i = 0; i < conn->naddr; i++)
    5112             :     {
    5113       28724 :         conn->addr[i].family = ai->ai_family;
    5114             : 
    5115       28724 :         memcpy(&conn->addr[i].addr.addr, ai->ai_addr,
    5116       28724 :                ai->ai_addrlen);
    5117       28724 :         conn->addr[i].addr.salen = ai->ai_addrlen;
    5118       28724 :         ai = ai->ai_next;
    5119             :     }
    5120             : 
    5121       28434 :     return 0;
    5122             : }
    5123             : 
    5124             : /*
    5125             :  * release_conn_addrinfo
    5126             :  *   - Free any addrinfo list in the PGconn.
    5127             :  */
    5128             : static void
    5129      112010 : release_conn_addrinfo(PGconn *conn)
    5130             : {
    5131      112010 :     if (conn->addr)
    5132             :     {
    5133       28418 :         free(conn->addr);
    5134       28418 :         conn->addr = NULL;
    5135             :     }
    5136      112010 : }
    5137             : 
    5138             : /*
    5139             :  * sendTerminateConn
    5140             :  *   - Send a terminate message to backend.
    5141             :  */
    5142             : static void
    5143       28120 : sendTerminateConn(PGconn *conn)
    5144             : {
    5145             :     /*
    5146             :      * The Postgres cancellation protocol does not have a notion of a
    5147             :      * Terminate message, so don't send one.
    5148             :      */
    5149       28120 :     if (conn->cancelRequest)
    5150          12 :         return;
    5151             : 
    5152             :     /*
    5153             :      * Note that the protocol doesn't allow us to send Terminate messages
    5154             :      * during the startup phase.
    5155             :      */
    5156       28108 :     if (conn->sock != PGINVALID_SOCKET && conn->status == CONNECTION_OK)
    5157             :     {
    5158             :         /*
    5159             :          * Try to send "close connection" message to backend. Ignore any
    5160             :          * error.
    5161             :          */
    5162       26878 :         pqPutMsgStart(PqMsg_Terminate, conn);
    5163       26878 :         pqPutMsgEnd(conn);
    5164       26878 :         (void) pqFlush(conn);
    5165             :     }
    5166             : }
    5167             : 
    5168             : /*
    5169             :  * pqClosePGconn
    5170             :  *   - properly close a connection to the backend
    5171             :  *
    5172             :  * This should reset or release all transient state, but NOT the connection
    5173             :  * parameters.  On exit, the PGconn should be in condition to start a fresh
    5174             :  * connection with the same parameters (see PQreset()).
    5175             :  */
    5176             : void
    5177       28090 : pqClosePGconn(PGconn *conn)
    5178             : {
    5179             :     /*
    5180             :      * If possible, send Terminate message to close the connection politely.
    5181             :      */
    5182       28090 :     sendTerminateConn(conn);
    5183             : 
    5184             :     /*
    5185             :      * Must reset the blocking status so a possible reconnect will work.
    5186             :      *
    5187             :      * Don't call PQsetnonblocking() because it will fail if it's unable to
    5188             :      * flush the connection.
    5189             :      */
    5190       28090 :     conn->nonblocking = false;
    5191             : 
    5192             :     /*
    5193             :      * Close the connection, reset all transient state, flush I/O buffers.
    5194             :      * Note that this includes clearing conn's error state; we're no longer
    5195             :      * interested in any failures associated with the old connection, and we
    5196             :      * want a clean slate for any new connection attempt.
    5197             :      */
    5198       28090 :     pqDropConnection(conn, true);
    5199       28090 :     conn->status = CONNECTION_BAD;   /* Well, not really _bad_ - just absent */
    5200       28090 :     conn->asyncStatus = PGASYNC_IDLE;
    5201       28090 :     conn->xactStatus = PQTRANS_IDLE;
    5202       28090 :     conn->pipelineStatus = PQ_PIPELINE_OFF;
    5203       28090 :     pqClearOAuthToken(conn);
    5204       28090 :     pqClearAsyncResult(conn);   /* deallocate result */
    5205       28090 :     pqClearConnErrorState(conn);
    5206             : 
    5207             :     /*
    5208             :      * Release addrinfo, but since cancel requests never change their addrinfo
    5209             :      * we don't do that. Otherwise we would have to rebuild it during a
    5210             :      * PQcancelReset.
    5211             :      */
    5212       28090 :     if (!conn->cancelRequest)
    5213       28078 :         release_conn_addrinfo(conn);
    5214             : 
    5215             :     /* Reset all state obtained from server, too */
    5216       28090 :     pqDropServerData(conn);
    5217       28090 : }
    5218             : 
    5219             : /*
    5220             :  * PQfinish: properly close a connection to the backend. Also frees
    5221             :  * the PGconn data structure so it shouldn't be re-used after this.
    5222             :  */
    5223             : void
    5224       28088 : PQfinish(PGconn *conn)
    5225             : {
    5226       28088 :     if (conn)
    5227             :     {
    5228       28088 :         pqClosePGconn(conn);
    5229       28088 :         freePGconn(conn);
    5230             :     }
    5231       28088 : }
    5232             : 
    5233             : /*
    5234             :  * PQreset: resets the connection to the backend by closing the
    5235             :  * existing connection and creating a new one.
    5236             :  */
    5237             : void
    5238           0 : PQreset(PGconn *conn)
    5239             : {
    5240           0 :     if (conn)
    5241             :     {
    5242           0 :         pqClosePGconn(conn);
    5243             : 
    5244           0 :         if (pqConnectDBStart(conn) && pqConnectDBComplete(conn))
    5245             :         {
    5246             :             /*
    5247             :              * Notify event procs of successful reset.
    5248             :              */
    5249             :             int         i;
    5250             : 
    5251           0 :             for (i = 0; i < conn->nEvents; i++)
    5252             :             {
    5253             :                 PGEventConnReset evt;
    5254             : 
    5255           0 :                 evt.conn = conn;
    5256           0 :                 (void) conn->events[i].proc(PGEVT_CONNRESET, &evt,
    5257           0 :                                             conn->events[i].passThrough);
    5258             :             }
    5259             :         }
    5260             :     }
    5261           0 : }
    5262             : 
    5263             : 
    5264             : /*
    5265             :  * PQresetStart:
    5266             :  * resets the connection to the backend
    5267             :  * closes the existing connection and makes a new one
    5268             :  * Returns 1 on success, 0 on failure.
    5269             :  */
    5270             : int
    5271           0 : PQresetStart(PGconn *conn)
    5272             : {
    5273           0 :     if (conn)
    5274             :     {
    5275           0 :         pqClosePGconn(conn);
    5276             : 
    5277           0 :         return pqConnectDBStart(conn);
    5278             :     }
    5279             : 
    5280           0 :     return 0;
    5281             : }
    5282             : 
    5283             : 
    5284             : /*
    5285             :  * PQresetPoll:
    5286             :  * resets the connection to the backend
    5287             :  * closes the existing connection and makes a new one
    5288             :  */
    5289             : PostgresPollingStatusType
    5290           0 : PQresetPoll(PGconn *conn)
    5291             : {
    5292           0 :     if (conn)
    5293             :     {
    5294           0 :         PostgresPollingStatusType status = PQconnectPoll(conn);
    5295             : 
    5296           0 :         if (status == PGRES_POLLING_OK)
    5297             :         {
    5298             :             /*
    5299             :              * Notify event procs of successful reset.
    5300             :              */
    5301             :             int         i;
    5302             : 
    5303           0 :             for (i = 0; i < conn->nEvents; i++)
    5304             :             {
    5305             :                 PGEventConnReset evt;
    5306             : 
    5307           0 :                 evt.conn = conn;
    5308           0 :                 (void) conn->events[i].proc(PGEVT_CONNRESET, &evt,
    5309           0 :                                             conn->events[i].passThrough);
    5310             :             }
    5311             :         }
    5312             : 
    5313           0 :         return status;
    5314             :     }
    5315             : 
    5316           0 :     return PGRES_POLLING_FAILED;
    5317             : }
    5318             : 
    5319             : /*
    5320             :  * pqPacketSend() -- convenience routine to send a message to server.
    5321             :  *
    5322             :  * pack_type: the single-byte message type code.  (Pass zero for startup
    5323             :  * packets, which have no message type code.)
    5324             :  *
    5325             :  * buf, buf_len: contents of message.  The given length includes only what
    5326             :  * is in buf; the message type and message length fields are added here.
    5327             :  *
    5328             :  * RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
    5329             :  * SIDE_EFFECTS: may block.
    5330             :  */
    5331             : int
    5332       28678 : pqPacketSend(PGconn *conn, char pack_type,
    5333             :              const void *buf, size_t buf_len)
    5334             : {
    5335             :     /* Start the message. */
    5336       28678 :     if (pqPutMsgStart(pack_type, conn))
    5337           0 :         return STATUS_ERROR;
    5338             : 
    5339             :     /* Send the message body. */
    5340       28678 :     if (pqPutnchar(buf, buf_len, conn))
    5341           0 :         return STATUS_ERROR;
    5342             : 
    5343             :     /* Finish the message. */
    5344       28678 :     if (pqPutMsgEnd(conn))
    5345           0 :         return STATUS_ERROR;
    5346             : 
    5347             :     /* Flush to ensure backend gets it. */
    5348       28678 :     if (pqFlush(conn))
    5349           0 :         return STATUS_ERROR;
    5350             : 
    5351       28678 :     return STATUS_OK;
    5352             : }
    5353             : 
    5354             : #ifdef USE_LDAP
    5355             : 
    5356             : #define LDAP_URL    "ldap://"
    5357             : #define LDAP_DEF_PORT   389
    5358             : #define PGLDAP_TIMEOUT 2
    5359             : 
    5360             : #define ld_is_sp_tab(x) ((x) == ' ' || (x) == '\t')
    5361             : #define ld_is_nl_cr(x) ((x) == '\r' || (x) == '\n')
    5362             : 
    5363             : 
    5364             : /*
    5365             :  *      ldapServiceLookup
    5366             :  *
    5367             :  * Search the LDAP URL passed as first argument, treat the result as a
    5368             :  * string of connection options that are parsed and added to the array of
    5369             :  * options passed as second argument.
    5370             :  *
    5371             :  * LDAP URLs must conform to RFC 1959 without escape sequences.
    5372             :  *  ldap://host:port/dn?attributes?scope?filter?extensions
    5373             :  *
    5374             :  * Returns
    5375             :  *  0 if the lookup was successful,
    5376             :  *  1 if the connection to the LDAP server could be established but
    5377             :  *    the search was unsuccessful,
    5378             :  *  2 if a connection could not be established, and
    5379             :  *  3 if a fatal error occurred.
    5380             :  *
    5381             :  * An error message is appended to *errorMessage for return codes 1 and 3.
    5382             :  */
    5383             : static int
    5384           2 : ldapServiceLookup(const char *purl, PQconninfoOption *options,
    5385             :                   PQExpBuffer errorMessage)
    5386             : {
    5387           2 :     int         port = LDAP_DEF_PORT,
    5388             :                 scope,
    5389             :                 rc,
    5390             :                 size,
    5391             :                 state,
    5392             :                 oldstate,
    5393             :                 i;
    5394             : #ifndef WIN32
    5395             :     int         msgid;
    5396             : #endif
    5397             :     bool        found_keyword;
    5398             :     char       *url,
    5399             :                *hostname,
    5400             :                *portstr,
    5401             :                *endptr,
    5402             :                *dn,
    5403             :                *scopestr,
    5404             :                *filter,
    5405             :                *result,
    5406             :                *p,
    5407           2 :                *p1 = NULL,
    5408           2 :                *optname = NULL,
    5409           2 :                *optval = NULL;
    5410           2 :     char       *attrs[2] = {NULL, NULL};
    5411           2 :     LDAP       *ld = NULL;
    5412             :     LDAPMessage *res,
    5413             :                *entry;
    5414             :     struct berval **values;
    5415           2 :     LDAP_TIMEVAL time = {PGLDAP_TIMEOUT, 0};
    5416             : 
    5417           2 :     if ((url = strdup(purl)) == NULL)
    5418             :     {
    5419           0 :         libpq_append_error(errorMessage, "out of memory");
    5420           0 :         return 3;
    5421             :     }
    5422             : 
    5423             :     /*
    5424             :      * Parse URL components, check for correctness.  Basically, url has '\0'
    5425             :      * placed at component boundaries and variables are pointed at each
    5426             :      * component.
    5427             :      */
    5428             : 
    5429           2 :     if (pg_strncasecmp(url, LDAP_URL, strlen(LDAP_URL)) != 0)
    5430             :     {
    5431           0 :         libpq_append_error(errorMessage,
    5432             :                            "invalid LDAP URL \"%s\": scheme must be ldap://", purl);
    5433           0 :         free(url);
    5434           0 :         return 3;
    5435             :     }
    5436             : 
    5437             :     /* hostname */
    5438           2 :     hostname = url + strlen(LDAP_URL);
    5439           2 :     if (*hostname == '/')       /* no hostname? */
    5440           0 :         hostname = DefaultHost; /* the default */
    5441             : 
    5442             :     /* dn, "distinguished name" */
    5443           2 :     p = strchr(url + strlen(LDAP_URL), '/');
    5444           2 :     if (p == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    5445             :     {
    5446           0 :         libpq_append_error(errorMessage,
    5447             :                            "invalid LDAP URL \"%s\": missing distinguished name",
    5448             :                            purl);
    5449           0 :         free(url);
    5450           0 :         return 3;
    5451             :     }
    5452           2 :     *p = '\0';                  /* terminate hostname */
    5453           2 :     dn = p + 1;
    5454             : 
    5455             :     /* attribute */
    5456           2 :     if ((p = strchr(dn, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    5457             :     {
    5458           0 :         libpq_append_error(errorMessage,
    5459             :                            "invalid LDAP URL \"%s\": must have exactly one attribute",
    5460             :                            purl);
    5461           0 :         free(url);
    5462           0 :         return 3;
    5463             :     }
    5464           2 :     *p = '\0';
    5465           2 :     attrs[0] = p + 1;
    5466             : 
    5467             :     /* scope */
    5468           2 :     if ((p = strchr(attrs[0], '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    5469             :     {
    5470           0 :         libpq_append_error(errorMessage,
    5471             :                            "invalid LDAP URL \"%s\": must have search scope (base/one/sub)",
    5472             :                            purl);
    5473           0 :         free(url);
    5474           0 :         return 3;
    5475             :     }
    5476           2 :     *p = '\0';
    5477           2 :     scopestr = p + 1;
    5478             : 
    5479             :     /* filter */
    5480           2 :     if ((p = strchr(scopestr, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    5481             :     {
    5482           0 :         libpq_append_error(errorMessage,
    5483             :                            "invalid LDAP URL \"%s\": no filter",
    5484             :                            purl);
    5485           0 :         free(url);
    5486           0 :         return 3;
    5487             :     }
    5488           2 :     *p = '\0';
    5489           2 :     filter = p + 1;
    5490           2 :     if ((p = strchr(filter, '?')) != NULL)
    5491           0 :         *p = '\0';
    5492             : 
    5493             :     /* port number? */
    5494           2 :     if ((p1 = strchr(hostname, ':')) != NULL)
    5495             :     {
    5496             :         long        lport;
    5497             : 
    5498           2 :         *p1 = '\0';
    5499           2 :         portstr = p1 + 1;
    5500           2 :         errno = 0;
    5501           2 :         lport = strtol(portstr, &endptr, 10);
    5502           2 :         if (*portstr == '\0' || *endptr != '\0' || errno || lport < 0 || lport > 65535)
    5503             :         {
    5504           0 :             libpq_append_error(errorMessage,
    5505             :                                "invalid LDAP URL \"%s\": invalid port number",
    5506             :                                purl);
    5507           0 :             free(url);
    5508           0 :             return 3;
    5509             :         }
    5510           2 :         port = (int) lport;
    5511             :     }
    5512             : 
    5513             :     /* Allow only one attribute */
    5514           2 :     if (strchr(attrs[0], ',') != NULL)
    5515             :     {
    5516           0 :         libpq_append_error(errorMessage,
    5517             :                            "invalid LDAP URL \"%s\": must have exactly one attribute",
    5518             :                            purl);
    5519           0 :         free(url);
    5520           0 :         return 3;
    5521             :     }
    5522             : 
    5523             :     /* set scope */
    5524           2 :     if (pg_strcasecmp(scopestr, "base") == 0)
    5525           0 :         scope = LDAP_SCOPE_BASE;
    5526           2 :     else if (pg_strcasecmp(scopestr, "one") == 0)
    5527           2 :         scope = LDAP_SCOPE_ONELEVEL;
    5528           0 :     else if (pg_strcasecmp(scopestr, "sub") == 0)
    5529           0 :         scope = LDAP_SCOPE_SUBTREE;
    5530             :     else
    5531             :     {
    5532           0 :         libpq_append_error(errorMessage,
    5533             :                            "invalid LDAP URL \"%s\": must have search scope (base/one/sub)",
    5534             :                            purl);
    5535           0 :         free(url);
    5536           0 :         return 3;
    5537             :     }
    5538             : 
    5539             :     /* initialize LDAP structure */
    5540           2 :     if ((ld = ldap_init(hostname, port)) == NULL)
    5541             :     {
    5542           0 :         libpq_append_error(errorMessage, "could not create LDAP structure");
    5543           0 :         free(url);
    5544           0 :         return 3;
    5545             :     }
    5546             : 
    5547             :     /*
    5548             :      * Perform an explicit anonymous bind.
    5549             :      *
    5550             :      * LDAP does not require that an anonymous bind is performed explicitly,
    5551             :      * but we want to distinguish between the case where LDAP bind does not
    5552             :      * succeed within PGLDAP_TIMEOUT seconds (return 2 to continue parsing the
    5553             :      * service control file) and the case where querying the LDAP server fails
    5554             :      * (return 1 to end parsing).
    5555             :      *
    5556             :      * Unfortunately there is no way of setting a timeout that works for both
    5557             :      * Windows and OpenLDAP.
    5558             :      */
    5559             : #ifdef WIN32
    5560             :     /* the nonstandard ldap_connect function performs an anonymous bind */
    5561             :     if (ldap_connect(ld, &time) != LDAP_SUCCESS)
    5562             :     {
    5563             :         /* error or timeout in ldap_connect */
    5564             :         free(url);
    5565             :         ldap_unbind(ld);
    5566             :         return 2;
    5567             :     }
    5568             : #else                           /* !WIN32 */
    5569             :     /* in OpenLDAP, use the LDAP_OPT_NETWORK_TIMEOUT option */
    5570           2 :     if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
    5571             :     {
    5572           0 :         free(url);
    5573           0 :         ldap_unbind(ld);
    5574           0 :         return 3;
    5575             :     }
    5576             : 
    5577             :     /* anonymous bind */
    5578           2 :     if ((msgid = ldap_simple_bind(ld, NULL, NULL)) == -1)
    5579             :     {
    5580             :         /* error or network timeout */
    5581           2 :         free(url);
    5582           2 :         ldap_unbind(ld);
    5583           2 :         return 2;
    5584             :     }
    5585             : 
    5586             :     /* wait some time for the connection to succeed */
    5587           0 :     res = NULL;
    5588           0 :     if ((rc = ldap_result(ld, msgid, LDAP_MSG_ALL, &time, &res)) == -1 ||
    5589           0 :         res == NULL)
    5590             :     {
    5591             :         /* error or timeout */
    5592           0 :         if (res != NULL)
    5593           0 :             ldap_msgfree(res);
    5594           0 :         free(url);
    5595           0 :         ldap_unbind(ld);
    5596           0 :         return 2;
    5597             :     }
    5598           0 :     ldap_msgfree(res);
    5599             : 
    5600             :     /* reset timeout */
    5601           0 :     time.tv_sec = -1;
    5602           0 :     if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
    5603             :     {
    5604           0 :         free(url);
    5605           0 :         ldap_unbind(ld);
    5606           0 :         return 3;
    5607             :     }
    5608             : #endif                          /* WIN32 */
    5609             : 
    5610             :     /* search */
    5611           0 :     res = NULL;
    5612           0 :     if ((rc = ldap_search_st(ld, dn, scope, filter, attrs, 0, &time, &res))
    5613             :         != LDAP_SUCCESS)
    5614             :     {
    5615           0 :         if (res != NULL)
    5616           0 :             ldap_msgfree(res);
    5617           0 :         libpq_append_error(errorMessage, "lookup on LDAP server failed: %s", ldap_err2string(rc));
    5618           0 :         ldap_unbind(ld);
    5619           0 :         free(url);
    5620           0 :         return 1;
    5621             :     }
    5622             : 
    5623             :     /* complain if there was not exactly one result */
    5624           0 :     if ((rc = ldap_count_entries(ld, res)) != 1)
    5625             :     {
    5626           0 :         if (rc > 1)
    5627           0 :             libpq_append_error(errorMessage, "more than one entry found on LDAP lookup");
    5628             :         else
    5629           0 :             libpq_append_error(errorMessage, "no entry found on LDAP lookup");
    5630           0 :         ldap_msgfree(res);
    5631           0 :         ldap_unbind(ld);
    5632           0 :         free(url);
    5633           0 :         return 1;
    5634             :     }
    5635             : 
    5636             :     /* get entry */
    5637           0 :     if ((entry = ldap_first_entry(ld, res)) == NULL)
    5638             :     {
    5639             :         /* should never happen */
    5640           0 :         libpq_append_error(errorMessage, "no entry found on LDAP lookup");
    5641           0 :         ldap_msgfree(res);
    5642           0 :         ldap_unbind(ld);
    5643           0 :         free(url);
    5644           0 :         return 1;
    5645             :     }
    5646             : 
    5647             :     /* get values */
    5648           0 :     if ((values = ldap_get_values_len(ld, entry, attrs[0])) == NULL)
    5649             :     {
    5650           0 :         libpq_append_error(errorMessage, "attribute has no values on LDAP lookup");
    5651           0 :         ldap_msgfree(res);
    5652           0 :         ldap_unbind(ld);
    5653           0 :         free(url);
    5654           0 :         return 1;
    5655             :     }
    5656             : 
    5657           0 :     ldap_msgfree(res);
    5658           0 :     free(url);
    5659             : 
    5660           0 :     if (values[0] == NULL)
    5661             :     {
    5662           0 :         libpq_append_error(errorMessage, "attribute has no values on LDAP lookup");
    5663           0 :         ldap_value_free_len(values);
    5664           0 :         ldap_unbind(ld);
    5665           0 :         return 1;
    5666             :     }
    5667             : 
    5668             :     /* concatenate values into a single string with newline terminators */
    5669           0 :     size = 1;                   /* for the trailing null */
    5670           0 :     for (i = 0; values[i] != NULL; i++)
    5671           0 :         size += values[i]->bv_len + 1;
    5672           0 :     if ((result = malloc(size)) == NULL)
    5673             :     {
    5674           0 :         libpq_append_error(errorMessage, "out of memory");
    5675           0 :         ldap_value_free_len(values);
    5676           0 :         ldap_unbind(ld);
    5677           0 :         return 3;
    5678             :     }
    5679           0 :     p = result;
    5680           0 :     for (i = 0; values[i] != NULL; i++)
    5681             :     {
    5682           0 :         memcpy(p, values[i]->bv_val, values[i]->bv_len);
    5683           0 :         p += values[i]->bv_len;
    5684           0 :         *(p++) = '\n';
    5685             :     }
    5686           0 :     *p = '\0';
    5687             : 
    5688           0 :     ldap_value_free_len(values);
    5689           0 :     ldap_unbind(ld);
    5690             : 
    5691             :     /* parse result string */
    5692           0 :     oldstate = state = 0;
    5693           0 :     for (p = result; *p != '\0'; ++p)
    5694             :     {
    5695           0 :         switch (state)
    5696             :         {
    5697           0 :             case 0:             /* between entries */
    5698           0 :                 if (!ld_is_sp_tab(*p) && !ld_is_nl_cr(*p))
    5699             :                 {
    5700           0 :                     optname = p;
    5701           0 :                     state = 1;
    5702             :                 }
    5703           0 :                 break;
    5704           0 :             case 1:             /* in option name */
    5705           0 :                 if (ld_is_sp_tab(*p))
    5706             :                 {
    5707           0 :                     *p = '\0';
    5708           0 :                     state = 2;
    5709             :                 }
    5710           0 :                 else if (ld_is_nl_cr(*p))
    5711             :                 {
    5712           0 :                     libpq_append_error(errorMessage,
    5713             :                                        "missing \"=\" after \"%s\" in connection info string",
    5714             :                                        optname);
    5715           0 :                     free(result);
    5716           0 :                     return 3;
    5717             :                 }
    5718           0 :                 else if (*p == '=')
    5719             :                 {
    5720           0 :                     *p = '\0';
    5721           0 :                     state = 3;
    5722             :                 }
    5723           0 :                 break;
    5724           0 :             case 2:             /* after option name */
    5725           0 :                 if (*p == '=')
    5726             :                 {
    5727           0 :                     state = 3;
    5728             :                 }
    5729           0 :                 else if (!ld_is_sp_tab(*p))
    5730             :                 {
    5731           0 :                     libpq_append_error(errorMessage,
    5732             :                                        "missing \"=\" after \"%s\" in connection info string",
    5733             :                                        optname);
    5734           0 :                     free(result);
    5735           0 :                     return 3;
    5736             :                 }
    5737           0 :                 break;
    5738           0 :             case 3:             /* before option value */
    5739           0 :                 if (*p == '\'')
    5740             :                 {
    5741           0 :                     optval = p + 1;
    5742           0 :                     p1 = p + 1;
    5743           0 :                     state = 5;
    5744             :                 }
    5745           0 :                 else if (ld_is_nl_cr(*p))
    5746             :                 {
    5747           0 :                     optval = optname + strlen(optname); /* empty */
    5748           0 :                     state = 0;
    5749             :                 }
    5750           0 :                 else if (!ld_is_sp_tab(*p))
    5751             :                 {
    5752           0 :                     optval = p;
    5753           0 :                     state = 4;
    5754             :                 }
    5755           0 :                 break;
    5756           0 :             case 4:             /* in unquoted option value */
    5757           0 :                 if (ld_is_sp_tab(*p) || ld_is_nl_cr(*p))
    5758             :                 {
    5759           0 :                     *p = '\0';
    5760           0 :                     state = 0;
    5761             :                 }
    5762           0 :                 break;
    5763           0 :             case 5:             /* in quoted option value */
    5764           0 :                 if (*p == '\'')
    5765             :                 {
    5766           0 :                     *p1 = '\0';
    5767           0 :                     state = 0;
    5768             :                 }
    5769           0 :                 else if (*p == '\\')
    5770           0 :                     state = 6;
    5771             :                 else
    5772           0 :                     *(p1++) = *p;
    5773           0 :                 break;
    5774           0 :             case 6:             /* in quoted option value after escape */
    5775           0 :                 *(p1++) = *p;
    5776           0 :                 state = 5;
    5777           0 :                 break;
    5778             :         }
    5779             : 
    5780           0 :         if (state == 0 && oldstate != 0)
    5781             :         {
    5782           0 :             found_keyword = false;
    5783           0 :             for (i = 0; options[i].keyword; i++)
    5784             :             {
    5785           0 :                 if (strcmp(options[i].keyword, optname) == 0)
    5786             :                 {
    5787           0 :                     if (options[i].val == NULL)
    5788             :                     {
    5789           0 :                         options[i].val = strdup(optval);
    5790           0 :                         if (!options[i].val)
    5791             :                         {
    5792           0 :                             libpq_append_error(errorMessage, "out of memory");
    5793           0 :                             free(result);
    5794           0 :                             return 3;
    5795             :                         }
    5796             :                     }
    5797           0 :                     found_keyword = true;
    5798           0 :                     break;
    5799             :                 }
    5800             :             }
    5801           0 :             if (!found_keyword)
    5802             :             {
    5803           0 :                 libpq_append_error(errorMessage, "invalid connection option \"%s\"", optname);
    5804           0 :                 free(result);
    5805           0 :                 return 1;
    5806             :             }
    5807           0 :             optname = NULL;
    5808           0 :             optval = NULL;
    5809             :         }
    5810           0 :         oldstate = state;
    5811             :     }
    5812             : 
    5813           0 :     free(result);
    5814             : 
    5815           0 :     if (state == 5 || state == 6)
    5816             :     {
    5817           0 :         libpq_append_error(errorMessage,
    5818             :                            "unterminated quoted string in connection info string");
    5819           0 :         return 3;
    5820             :     }
    5821             : 
    5822           0 :     return 0;
    5823             : }
    5824             : 
    5825             : #endif                          /* USE_LDAP */
    5826             : 
    5827             : /*
    5828             :  * parseServiceInfo: if a service name has been given, look it up and absorb
    5829             :  * connection options from it into *options.
    5830             :  *
    5831             :  * Returns 0 on success, nonzero on failure.  On failure, if errorMessage
    5832             :  * isn't null, also store an error message there.  (Note: the only reason
    5833             :  * this function and related ones don't dump core on errorMessage == NULL
    5834             :  * is the undocumented fact that appendPQExpBuffer does nothing when passed
    5835             :  * a null PQExpBuffer pointer.)
    5836             :  */
    5837             : static int
    5838       28694 : parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
    5839             : {
    5840       28694 :     const char *service = conninfo_getval(options, "service");
    5841             :     char        serviceFile[MAXPGPATH];
    5842             :     char       *env;
    5843       28694 :     bool        group_found = false;
    5844             :     int         status;
    5845             :     struct stat stat_buf;
    5846             : 
    5847             :     /*
    5848             :      * We have to special-case the environment variable PGSERVICE here, since
    5849             :      * this is and should be called before inserting environment defaults for
    5850             :      * other connection options.
    5851             :      */
    5852       28694 :     if (service == NULL)
    5853       28678 :         service = getenv("PGSERVICE");
    5854             : 
    5855             :     /* If no service name given, nothing to do */
    5856       28694 :     if (service == NULL)
    5857       28670 :         return 0;
    5858             : 
    5859             :     /*
    5860             :      * Try PGSERVICEFILE if specified, else try ~/.pg_service.conf (if that
    5861             :      * exists).
    5862             :      */
    5863          24 :     if ((env = getenv("PGSERVICEFILE")) != NULL)
    5864          24 :         strlcpy(serviceFile, env, sizeof(serviceFile));
    5865             :     else
    5866             :     {
    5867             :         char        homedir[MAXPGPATH];
    5868             : 
    5869           0 :         if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
    5870           0 :             goto next_file;
    5871           0 :         snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
    5872           0 :         if (stat(serviceFile, &stat_buf) != 0)
    5873           0 :             goto next_file;
    5874             :     }
    5875             : 
    5876          24 :     status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
    5877          24 :     if (group_found || status != 0)
    5878          10 :         return status;
    5879             : 
    5880          14 : next_file:
    5881             : 
    5882             :     /*
    5883             :      * This could be used by any application so we can't use the binary
    5884             :      * location to find our config files.
    5885             :      */
    5886          28 :     snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
    5887          28 :              getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
    5888          14 :     if (stat(serviceFile, &stat_buf) != 0)
    5889           4 :         goto last_file;
    5890             : 
    5891          10 :     status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
    5892          10 :     if (status != 0)
    5893           0 :         return status;
    5894             : 
    5895          10 : last_file:
    5896          14 :     if (!group_found)
    5897             :     {
    5898           8 :         libpq_append_error(errorMessage, "definition of service \"%s\" not found", service);
    5899           8 :         return 3;
    5900             :     }
    5901             : 
    5902           6 :     return 0;
    5903             : }
    5904             : 
    5905             : static int
    5906          34 : parseServiceFile(const char *serviceFile,
    5907             :                  const char *service,
    5908             :                  PQconninfoOption *options,
    5909             :                  PQExpBuffer errorMessage,
    5910             :                  bool *group_found)
    5911             : {
    5912          34 :     int         result = 0,
    5913          34 :                 linenr = 0,
    5914             :                 i;
    5915             :     FILE       *f;
    5916             :     char       *line;
    5917             :     char        buf[1024];
    5918             : 
    5919          34 :     *group_found = false;
    5920             : 
    5921          34 :     f = fopen(serviceFile, "r");
    5922          34 :     if (f == NULL)
    5923             :     {
    5924           2 :         libpq_append_error(errorMessage, "service file \"%s\" not found", serviceFile);
    5925           2 :         return 1;
    5926             :     }
    5927             : 
    5928          66 :     while ((line = fgets(buf, sizeof(buf), f)) != NULL)
    5929             :     {
    5930             :         int         len;
    5931             : 
    5932          34 :         linenr++;
    5933             : 
    5934          34 :         if (strlen(line) >= sizeof(buf) - 1)
    5935             :         {
    5936           0 :             libpq_append_error(errorMessage,
    5937             :                                "line %d too long in service file \"%s\"",
    5938             :                                linenr,
    5939             :                                serviceFile);
    5940           0 :             result = 2;
    5941           0 :             goto exit;
    5942             :         }
    5943             : 
    5944             :         /* ignore whitespace at end of line, especially the newline */
    5945          34 :         len = strlen(line);
    5946          68 :         while (len > 0 && isspace((unsigned char) line[len - 1]))
    5947          34 :             line[--len] = '\0';
    5948             : 
    5949             :         /* ignore leading whitespace too */
    5950          34 :         while (*line && isspace((unsigned char) line[0]))
    5951           0 :             line++;
    5952             : 
    5953             :         /* ignore comments and empty lines */
    5954          34 :         if (line[0] == '\0' || line[0] == '#')
    5955          10 :             continue;
    5956             : 
    5957             :         /* Check for right groupname */
    5958          24 :         if (line[0] == '[')
    5959             :         {
    5960          22 :             if (*group_found)
    5961             :             {
    5962             :                 /* end of desired group reached; return success */
    5963           0 :                 goto exit;
    5964             :             }
    5965             : 
    5966          22 :             if (strncmp(line + 1, service, strlen(service)) == 0 &&
    5967          14 :                 line[strlen(service) + 1] == ']')
    5968          14 :                 *group_found = true;
    5969             :             else
    5970           8 :                 *group_found = false;
    5971             :         }
    5972             :         else
    5973             :         {
    5974           2 :             if (*group_found)
    5975             :             {
    5976             :                 /*
    5977             :                  * Finally, we are in the right group and can parse the line
    5978             :                  */
    5979             :                 char       *key,
    5980             :                            *val;
    5981             :                 bool        found_keyword;
    5982             : 
    5983             : #ifdef USE_LDAP
    5984           2 :                 if (strncmp(line, "ldap", 4) == 0)
    5985             :                 {
    5986           2 :                     int         rc = ldapServiceLookup(line, options, errorMessage);
    5987             : 
    5988             :                     /* if rc = 2, go on reading for fallback */
    5989           2 :                     switch (rc)
    5990             :                     {
    5991           0 :                         case 0:
    5992           0 :                             goto exit;
    5993           0 :                         case 1:
    5994             :                         case 3:
    5995           0 :                             result = 3;
    5996           0 :                             goto exit;
    5997           2 :                         case 2:
    5998           2 :                             continue;
    5999             :                     }
    6000             :                 }
    6001             : #endif
    6002             : 
    6003           0 :                 key = line;
    6004           0 :                 val = strchr(line, '=');
    6005           0 :                 if (val == NULL)
    6006             :                 {
    6007           0 :                     libpq_append_error(errorMessage,
    6008             :                                        "syntax error in service file \"%s\", line %d",
    6009             :                                        serviceFile,
    6010             :                                        linenr);
    6011           0 :                     result = 3;
    6012           0 :                     goto exit;
    6013             :                 }
    6014           0 :                 *val++ = '\0';
    6015             : 
    6016           0 :                 if (strcmp(key, "service") == 0)
    6017             :                 {
    6018           0 :                     libpq_append_error(errorMessage,
    6019             :                                        "nested service specifications not supported in service file \"%s\", line %d",
    6020             :                                        serviceFile,
    6021             :                                        linenr);
    6022           0 :                     result = 3;
    6023           0 :                     goto exit;
    6024             :                 }
    6025             : 
    6026             :                 /*
    6027             :                  * Set the parameter --- but don't override any previous
    6028             :                  * explicit setting.
    6029             :                  */
    6030           0 :                 found_keyword = false;
    6031           0 :                 for (i = 0; options[i].keyword; i++)
    6032             :                 {
    6033           0 :                     if (strcmp(options[i].keyword, key) == 0)
    6034             :                     {
    6035           0 :                         if (options[i].val == NULL)
    6036           0 :                             options[i].val = strdup(val);
    6037           0 :                         if (!options[i].val)
    6038             :                         {
    6039           0 :                             libpq_append_error(errorMessage, "out of memory");
    6040           0 :                             result = 3;
    6041           0 :                             goto exit;
    6042             :                         }
    6043           0 :                         found_keyword = true;
    6044           0 :                         break;
    6045             :                     }
    6046             :                 }
    6047             : 
    6048           0 :                 if (!found_keyword)
    6049             :                 {
    6050           0 :                     libpq_append_error(errorMessage,
    6051             :                                        "syntax error in service file \"%s\", line %d",
    6052             :                                        serviceFile,
    6053             :                                        linenr);
    6054           0 :                     result = 3;
    6055           0 :                     goto exit;
    6056             :                 }
    6057             :             }
    6058             :         }
    6059             :     }
    6060             : 
    6061          32 : exit:
    6062          32 :     fclose(f);
    6063             : 
    6064          32 :     return result;
    6065             : }
    6066             : 
    6067             : 
    6068             : /*
    6069             :  *      PQconninfoParse
    6070             :  *
    6071             :  * Parse a string like PQconnectdb() would do and return the
    6072             :  * resulting connection options array.  NULL is returned on failure.
    6073             :  * The result contains only options specified directly in the string,
    6074             :  * not any possible default values.
    6075             :  *
    6076             :  * If errmsg isn't NULL, *errmsg is set to NULL on success, or a malloc'd
    6077             :  * string on failure (use PQfreemem to free it).  In out-of-memory conditions
    6078             :  * both *errmsg and the result could be NULL.
    6079             :  *
    6080             :  * NOTE: the returned array is dynamically allocated and should
    6081             :  * be freed when no longer needed via PQconninfoFree().
    6082             :  */
    6083             : PQconninfoOption *
    6084        2382 : PQconninfoParse(const char *conninfo, char **errmsg)
    6085             : {
    6086             :     PQExpBufferData errorBuf;
    6087             :     PQconninfoOption *connOptions;
    6088             : 
    6089        2382 :     if (errmsg)
    6090        2356 :         *errmsg = NULL;         /* default */
    6091        2382 :     initPQExpBuffer(&errorBuf);
    6092        2382 :     if (PQExpBufferDataBroken(errorBuf))
    6093           0 :         return NULL;            /* out of memory already :-( */
    6094        2382 :     connOptions = parse_connection_string(conninfo, &errorBuf, false);
    6095        2382 :     if (connOptions == NULL && errmsg)
    6096          50 :         *errmsg = errorBuf.data;
    6097             :     else
    6098        2332 :         termPQExpBuffer(&errorBuf);
    6099        2382 :     return connOptions;
    6100             : }
    6101             : 
    6102             : /*
    6103             :  * Build a working copy of the constant PQconninfoOptions array.
    6104             :  */
    6105             : static PQconninfoOption *
    6106       51016 : conninfo_init(PQExpBuffer errorMessage)
    6107             : {
    6108             :     PQconninfoOption *options;
    6109             :     PQconninfoOption *opt_dest;
    6110             :     const internalPQconninfoOption *cur_opt;
    6111             : 
    6112             :     /*
    6113             :      * Get enough memory for all options in PQconninfoOptions, even if some
    6114             :      * end up being filtered out.
    6115             :      */
    6116       51016 :     options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
    6117       51016 :     if (options == NULL)
    6118             :     {
    6119           0 :         libpq_append_error(errorMessage, "out of memory");
    6120           0 :         return NULL;
    6121             :     }
    6122       51016 :     opt_dest = options;
    6123             : 
    6124     2448768 :     for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
    6125             :     {
    6126             :         /* Only copy the public part of the struct, not the full internal */
    6127     2397752 :         memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
    6128     2397752 :         opt_dest++;
    6129             :     }
    6130      408128 :     MemSet(opt_dest, 0, sizeof(PQconninfoOption));
    6131             : 
    6132       51016 :     return options;
    6133             : }
    6134             : 
    6135             : /*
    6136             :  * Connection string parser
    6137             :  *
    6138             :  * Returns a malloc'd PQconninfoOption array, if parsing is successful.
    6139             :  * Otherwise, NULL is returned and an error message is added to errorMessage.
    6140             :  *
    6141             :  * If use_defaults is true, default values are filled in (from a service file,
    6142             :  * environment variables, etc).
    6143             :  */
    6144             : static PQconninfoOption *
    6145       23872 : parse_connection_string(const char *connstr, PQExpBuffer errorMessage,
    6146             :                         bool use_defaults)
    6147             : {
    6148             :     /* Parse as URI if connection string matches URI prefix */
    6149       23872 :     if (uri_prefix_length(connstr) != 0)
    6150         128 :         return conninfo_uri_parse(connstr, errorMessage, use_defaults);
    6151             : 
    6152             :     /* Parse as default otherwise */
    6153       23744 :     return conninfo_parse(connstr, errorMessage, use_defaults);
    6154             : }
    6155             : 
    6156             : /*
    6157             :  * Checks if connection string starts with either of the valid URI prefix
    6158             :  * designators.
    6159             :  *
    6160             :  * Returns the URI prefix length, 0 if the string doesn't contain a URI prefix.
    6161             :  *
    6162             :  * XXX this is duplicated in psql/common.c.
    6163             :  */
    6164             : static int
    6165       49230 : uri_prefix_length(const char *connstr)
    6166             : {
    6167       49230 :     if (strncmp(connstr, uri_designator,
    6168             :                 sizeof(uri_designator) - 1) == 0)
    6169         172 :         return sizeof(uri_designator) - 1;
    6170             : 
    6171       49058 :     if (strncmp(connstr, short_uri_designator,
    6172             :                 sizeof(short_uri_designator) - 1) == 0)
    6173          88 :         return sizeof(short_uri_designator) - 1;
    6174             : 
    6175       48970 :     return 0;
    6176             : }
    6177             : 
    6178             : /*
    6179             :  * Recognized connection string either starts with a valid URI prefix or
    6180             :  * contains a "=" in it.
    6181             :  *
    6182             :  * Must be consistent with parse_connection_string: anything for which this
    6183             :  * returns true should at least look like it's parseable by that routine.
    6184             :  *
    6185             :  * XXX this is duplicated in psql/common.c
    6186             :  */
    6187             : static bool
    6188       25230 : recognized_connection_string(const char *connstr)
    6189             : {
    6190       25230 :     return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
    6191             : }
    6192             : 
    6193             : /*
    6194             :  * Subroutine for parse_connection_string
    6195             :  *
    6196             :  * Deal with a string containing key=value pairs.
    6197             :  */
    6198             : static PQconninfoOption *
    6199       23744 : conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
    6200             :                bool use_defaults)
    6201             : {
    6202             :     char       *pname;
    6203             :     char       *pval;
    6204             :     char       *buf;
    6205             :     char       *cp;
    6206             :     char       *cp2;
    6207             :     PQconninfoOption *options;
    6208             : 
    6209             :     /* Make a working copy of PQconninfoOptions */
    6210       23744 :     options = conninfo_init(errorMessage);
    6211       23744 :     if (options == NULL)
    6212           0 :         return NULL;
    6213             : 
    6214             :     /* Need a modifiable copy of the input string */
    6215       23744 :     if ((buf = strdup(conninfo)) == NULL)
    6216             :     {
    6217           0 :         libpq_append_error(errorMessage, "out of memory");
    6218           0 :         PQconninfoFree(options);
    6219           0 :         return NULL;
    6220             :     }
    6221       23744 :     cp = buf;
    6222             : 
    6223       96278 :     while (*cp)
    6224             :     {
    6225             :         /* Skip blanks before the parameter name */
    6226       72558 :         if (isspace((unsigned char) *cp))
    6227             :         {
    6228         702 :             cp++;
    6229         702 :             continue;
    6230             :         }
    6231             : 
    6232             :         /* Get the parameter name */
    6233       71856 :         pname = cp;
    6234      429266 :         while (*cp)
    6235             :         {
    6236      429248 :             if (*cp == '=')
    6237       71838 :                 break;
    6238      357410 :             if (isspace((unsigned char) *cp))
    6239             :             {
    6240           0 :                 *cp++ = '\0';
    6241           0 :                 while (*cp)
    6242             :                 {
    6243           0 :                     if (!isspace((unsigned char) *cp))
    6244           0 :                         break;
    6245           0 :                     cp++;
    6246             :                 }
    6247           0 :                 break;
    6248             :             }
    6249      357410 :             cp++;
    6250             :         }
    6251             : 
    6252             :         /* Check that there is a following '=' */
    6253       71856 :         if (*cp != '=')
    6254             :         {
    6255          18 :             libpq_append_error(errorMessage,
    6256             :                                "missing \"=\" after \"%s\" in connection info string",
    6257             :                                pname);
    6258          18 :             PQconninfoFree(options);
    6259          18 :             free(buf);
    6260          18 :             return NULL;
    6261             :         }
    6262       71838 :         *cp++ = '\0';
    6263             : 
    6264             :         /* Skip blanks after the '=' */
    6265       71838 :         while (*cp)
    6266             :         {
    6267       71834 :             if (!isspace((unsigned char) *cp))
    6268       71834 :                 break;
    6269           0 :             cp++;
    6270             :         }
    6271             : 
    6272             :         /* Get the parameter value */
    6273       71838 :         pval = cp;
    6274             : 
    6275       71838 :         if (*cp != '\'')
    6276             :         {
    6277       53426 :             cp2 = pval;
    6278      596018 :             while (*cp)
    6279             :             {
    6280      590192 :                 if (isspace((unsigned char) *cp))
    6281             :                 {
    6282       47600 :                     *cp++ = '\0';
    6283       47600 :                     break;
    6284             :                 }
    6285      542592 :                 if (*cp == '\\')
    6286             :                 {
    6287           2 :                     cp++;
    6288           2 :                     if (*cp != '\0')
    6289           2 :                         *cp2++ = *cp++;
    6290             :                 }
    6291             :                 else
    6292      542590 :                     *cp2++ = *cp++;
    6293             :             }
    6294       53426 :             *cp2 = '\0';
    6295             :         }
    6296             :         else
    6297             :         {
    6298       18412 :             cp2 = pval;
    6299       18412 :             cp++;
    6300             :             for (;;)
    6301             :             {
    6302      190870 :                 if (*cp == '\0')
    6303             :                 {
    6304           0 :                     libpq_append_error(errorMessage, "unterminated quoted string in connection info string");
    6305           0 :                     PQconninfoFree(options);
    6306           0 :                     free(buf);
    6307           0 :                     return NULL;
    6308             :                 }
    6309      190870 :                 if (*cp == '\\')
    6310             :                 {
    6311        1346 :                     cp++;
    6312        1346 :                     if (*cp != '\0')
    6313        1346 :                         *cp2++ = *cp++;
    6314        1346 :                     continue;
    6315             :                 }
    6316      189524 :                 if (*cp == '\'')
    6317             :                 {
    6318       18412 :                     *cp2 = '\0';
    6319       18412 :                     cp++;
    6320       18412 :                     break;
    6321             :                 }
    6322      171112 :                 *cp2++ = *cp++;
    6323             :             }
    6324             :         }
    6325             : 
    6326             :         /*
    6327             :          * Now that we have the name and the value, store the record.
    6328             :          */
    6329       71838 :         if (!conninfo_storeval(options, pname, pval, errorMessage, false, false))
    6330             :         {
    6331           6 :             PQconninfoFree(options);
    6332           6 :             free(buf);
    6333           6 :             return NULL;
    6334             :         }
    6335             :     }
    6336             : 
    6337             :     /* Done with the modifiable input string */
    6338       23720 :     free(buf);
    6339             : 
    6340             :     /*
    6341             :      * Add in defaults if the caller wants that.
    6342             :      */
    6343       23720 :     if (use_defaults)
    6344             :     {
    6345        2182 :         if (!conninfo_add_defaults(options, errorMessage))
    6346             :         {
    6347           0 :             PQconninfoFree(options);
    6348           0 :             return NULL;
    6349             :         }
    6350             :     }
    6351             : 
    6352       23720 :     return options;
    6353             : }
    6354             : 
    6355             : /*
    6356             :  * Conninfo array parser routine
    6357             :  *
    6358             :  * If successful, a malloc'd PQconninfoOption array is returned.
    6359             :  * If not successful, NULL is returned and an error message is
    6360             :  * appended to errorMessage.
    6361             :  * Defaults are supplied (from a service file, environment variables, etc)
    6362             :  * for unspecified options, but only if use_defaults is true.
    6363             :  *
    6364             :  * If expand_dbname is non-zero, and the value passed for the first occurrence
    6365             :  * of "dbname" keyword is a connection string (as indicated by
    6366             :  * recognized_connection_string) then parse and process it, overriding any
    6367             :  * previously processed conflicting keywords. Subsequent keywords will take
    6368             :  * precedence, however. In-tree programs generally specify expand_dbname=true,
    6369             :  * so command-line arguments naming a database can use a connection string.
    6370             :  * Some code acquires arbitrary database names from known-literal sources like
    6371             :  * PQdb(), PQconninfoParse() and pg_database.datname.  When connecting to such
    6372             :  * a database, in-tree code first wraps the name in a connection string.
    6373             :  */
    6374             : static PQconninfoOption *
    6375       26304 : conninfo_array_parse(const char *const *keywords, const char *const *values,
    6376             :                      PQExpBuffer errorMessage, bool use_defaults,
    6377             :                      int expand_dbname)
    6378             : {
    6379             :     PQconninfoOption *options;
    6380       26304 :     PQconninfoOption *dbname_options = NULL;
    6381             :     PQconninfoOption *option;
    6382       26304 :     int         i = 0;
    6383             : 
    6384             :     /*
    6385             :      * If expand_dbname is non-zero, check keyword "dbname" to see if val is
    6386             :      * actually a recognized connection string.
    6387             :      */
    6388      112958 :     while (expand_dbname && keywords[i])
    6389             :     {
    6390      111884 :         const char *pname = keywords[i];
    6391      111884 :         const char *pvalue = values[i];
    6392             : 
    6393             :         /* first find "dbname" if any */
    6394      111884 :         if (strcmp(pname, "dbname") == 0 && pvalue)
    6395             :         {
    6396             :             /*
    6397             :              * If value is a connection string, parse it, but do not use
    6398             :              * defaults here -- those get picked up later. We only want to
    6399             :              * override for those parameters actually passed.
    6400             :              */
    6401       25230 :             if (recognized_connection_string(pvalue))
    6402             :             {
    6403       19304 :                 dbname_options = parse_connection_string(pvalue, errorMessage, false);
    6404       19304 :                 if (dbname_options == NULL)
    6405           0 :                     return NULL;
    6406             :             }
    6407       25230 :             break;
    6408             :         }
    6409       86654 :         ++i;
    6410             :     }
    6411             : 
    6412             :     /* Make a working copy of PQconninfoOptions */
    6413       26304 :     options = conninfo_init(errorMessage);
    6414       26304 :     if (options == NULL)
    6415             :     {
    6416           0 :         PQconninfoFree(dbname_options);
    6417           0 :         return NULL;
    6418             :     }
    6419             : 
    6420             :     /* Parse the keywords/values arrays */
    6421       26304 :     i = 0;
    6422      198902 :     while (keywords[i])
    6423             :     {
    6424      172598 :         const char *pname = keywords[i];
    6425      172598 :         const char *pvalue = values[i];
    6426             : 
    6427      172598 :         if (pvalue != NULL && pvalue[0] != '\0')
    6428             :         {
    6429             :             /* Search for the param record */
    6430      850882 :             for (option = options; option->keyword != NULL; option++)
    6431             :             {
    6432      850882 :                 if (strcmp(option->keyword, pname) == 0)
    6433       67762 :                     break;
    6434             :             }
    6435             : 
    6436             :             /* Check for invalid connection option */
    6437       67762 :             if (option->keyword == NULL)
    6438             :             {
    6439           0 :                 libpq_append_error(errorMessage, "invalid connection option \"%s\"", pname);
    6440           0 :                 PQconninfoFree(options);
    6441           0 :                 PQconninfoFree(dbname_options);
    6442           0 :                 return NULL;
    6443             :             }
    6444             : 
    6445             :             /*
    6446             :              * If we are on the first dbname parameter, and we have a parsed
    6447             :              * connection string, copy those parameters across, overriding any
    6448             :              * existing previous settings.
    6449             :              */
    6450       67762 :             if (strcmp(pname, "dbname") == 0 && dbname_options)
    6451       19304 :             {
    6452             :                 PQconninfoOption *str_option;
    6453             : 
    6454      926592 :                 for (str_option = dbname_options; str_option->keyword != NULL; str_option++)
    6455             :                 {
    6456      907288 :                     if (str_option->val != NULL)
    6457             :                     {
    6458             :                         int         k;
    6459             : 
    6460      530480 :                         for (k = 0; options[k].keyword; k++)
    6461             :                         {
    6462      530480 :                             if (strcmp(options[k].keyword, str_option->keyword) == 0)
    6463             :                             {
    6464       59308 :                                 free(options[k].val);
    6465       59308 :                                 options[k].val = strdup(str_option->val);
    6466       59308 :                                 if (!options[k].val)
    6467             :                                 {
    6468           0 :                                     libpq_append_error(errorMessage, "out of memory");
    6469           0 :                                     PQconninfoFree(options);
    6470           0 :                                     PQconninfoFree(dbname_options);
    6471           0 :                                     return NULL;
    6472             :                                 }
    6473       59308 :                                 break;
    6474             :                             }
    6475             :                         }
    6476             :                     }
    6477             :                 }
    6478             : 
    6479             :                 /*
    6480             :                  * Forget the parsed connection string, so that any subsequent
    6481             :                  * dbname parameters will not be expanded.
    6482             :                  */
    6483       19304 :                 PQconninfoFree(dbname_options);
    6484       19304 :                 dbname_options = NULL;
    6485             :             }
    6486             :             else
    6487             :             {
    6488             :                 /*
    6489             :                  * Store the value, overriding previous settings
    6490             :                  */
    6491       48458 :                 free(option->val);
    6492       48458 :                 option->val = strdup(pvalue);
    6493       48458 :                 if (!option->val)
    6494             :                 {
    6495           0 :                     libpq_append_error(errorMessage, "out of memory");
    6496           0 :                     PQconninfoFree(options);
    6497           0 :                     PQconninfoFree(dbname_options);
    6498           0 :                     return NULL;
    6499             :                 }
    6500             :             }
    6501             :         }
    6502      172598 :         ++i;
    6503             :     }
    6504       26304 :     PQconninfoFree(dbname_options);
    6505             : 
    6506             :     /*
    6507             :      * Add in defaults if the caller wants that.
    6508             :      */
    6509       26304 :     if (use_defaults)
    6510             :     {
    6511       26304 :         if (!conninfo_add_defaults(options, errorMessage))
    6512             :         {
    6513          10 :             PQconninfoFree(options);
    6514          10 :             return NULL;
    6515             :         }
    6516             :     }
    6517             : 
    6518       26294 :     return options;
    6519             : }
    6520             : 
    6521             : /*
    6522             :  * Add the default values for any unspecified options to the connection
    6523             :  * options array.
    6524             :  *
    6525             :  * Defaults are obtained from a service file, environment variables, etc.
    6526             :  *
    6527             :  * Returns true if successful, otherwise false; errorMessage, if supplied,
    6528             :  * is filled in upon failure.  Note that failure to locate a default value
    6529             :  * is not an error condition here --- we just leave the option's value as
    6530             :  * NULL.
    6531             :  */
    6532             : static bool
    6533       28694 : conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
    6534             : {
    6535             :     PQconninfoOption *option;
    6536       28694 :     PQconninfoOption *sslmode_default = NULL,
    6537       28694 :                *sslrootcert = NULL;
    6538             :     char       *tmp;
    6539             : 
    6540             :     /*
    6541             :      * If there's a service spec, use it to obtain any not-explicitly-given
    6542             :      * parameters.  Ignore error if no error message buffer is passed because
    6543             :      * there is no way to pass back the failure message.
    6544             :      */
    6545       28694 :     if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
    6546          10 :         return false;
    6547             : 
    6548             :     /*
    6549             :      * Get the fallback resources for parameters not specified in the conninfo
    6550             :      * string nor the service.
    6551             :      */
    6552     1376832 :     for (option = options; option->keyword != NULL; option++)
    6553             :     {
    6554     1348148 :         if (strcmp(option->keyword, "sslrootcert") == 0)
    6555       28684 :             sslrootcert = option;   /* save for later */
    6556             : 
    6557     1348148 :         if (option->val != NULL)
    6558      113004 :             continue;           /* Value was in conninfo or service */
    6559             : 
    6560             :         /*
    6561             :          * Try to get the environment variable fallback
    6562             :          */
    6563     1235144 :         if (option->envvar != NULL)
    6564             :         {
    6565      861736 :             if ((tmp = getenv(option->envvar)) != NULL)
    6566             :             {
    6567       47250 :                 option->val = strdup(tmp);
    6568       47250 :                 if (!option->val)
    6569             :                 {
    6570           0 :                     if (errorMessage)
    6571           0 :                         libpq_append_error(errorMessage, "out of memory");
    6572           0 :                     return false;
    6573             :                 }
    6574       47250 :                 continue;
    6575             :             }
    6576             :         }
    6577             : 
    6578             :         /*
    6579             :          * Interpret the deprecated PGREQUIRESSL environment variable.  Per
    6580             :          * tradition, translate values starting with "1" to sslmode=require,
    6581             :          * and ignore other values.  Given both PGREQUIRESSL=1 and PGSSLMODE,
    6582             :          * PGSSLMODE takes precedence; the opposite was true before v9.3.
    6583             :          */
    6584     1187894 :         if (strcmp(option->keyword, "sslmode") == 0)
    6585             :         {
    6586       27992 :             const char *requiresslenv = getenv("PGREQUIRESSL");
    6587             : 
    6588       27992 :             if (requiresslenv != NULL && requiresslenv[0] == '1')
    6589             :             {
    6590           0 :                 option->val = strdup("require");
    6591           0 :                 if (!option->val)
    6592             :                 {
    6593           0 :                     if (errorMessage)
    6594           0 :                         libpq_append_error(errorMessage, "out of memory");
    6595           0 :                     return false;
    6596             :                 }
    6597           0 :                 continue;
    6598             :             }
    6599             : 
    6600             :             /*
    6601             :              * sslmode is not specified. Let it be filled in with the compiled
    6602             :              * default for now, but if sslrootcert=system, we'll override the
    6603             :              * default later before returning.
    6604             :              */
    6605       27992 :             sslmode_default = option;
    6606             :         }
    6607             : 
    6608             :         /*
    6609             :          * No environment variable specified or the variable isn't set - try
    6610             :          * compiled-in default
    6611             :          */
    6612     1187894 :         if (option->compiled != NULL)
    6613             :         {
    6614      332256 :             option->val = strdup(option->compiled);
    6615      332256 :             if (!option->val)
    6616             :             {
    6617           0 :                 if (errorMessage)
    6618           0 :                     libpq_append_error(errorMessage, "out of memory");
    6619           0 :                 return false;
    6620             :             }
    6621      332256 :             continue;
    6622             :         }
    6623             : 
    6624             :         /*
    6625             :          * Special handling for "user" option.  Note that if pg_fe_getauthname
    6626             :          * fails, we just leave the value as NULL; there's no need for this to
    6627             :          * be an error condition if the caller provides a user name.  The only
    6628             :          * reason we do this now at all is so that callers of PQconndefaults
    6629             :          * will see a correct default (barring error, of course).
    6630             :          */
    6631      855638 :         if (strcmp(option->keyword, "user") == 0)
    6632             :         {
    6633       26064 :             option->val = pg_fe_getauthname(NULL);
    6634       26064 :             continue;
    6635             :         }
    6636             :     }
    6637             : 
    6638             :     /*
    6639             :      * Special handling for sslrootcert=system with no sslmode explicitly
    6640             :      * defined. In this case we want to strengthen the default sslmode to
    6641             :      * verify-full.
    6642             :      */
    6643       28684 :     if (sslmode_default && sslrootcert)
    6644             :     {
    6645       27992 :         if (sslrootcert->val && strcmp(sslrootcert->val, "system") == 0)
    6646             :         {
    6647           8 :             free(sslmode_default->val);
    6648             : 
    6649           8 :             sslmode_default->val = strdup("verify-full");
    6650           8 :             if (!sslmode_default->val)
    6651             :             {
    6652           0 :                 if (errorMessage)
    6653           0 :                     libpq_append_error(errorMessage, "out of memory");
    6654           0 :                 return false;
    6655             :             }
    6656             :         }
    6657             :     }
    6658             : 
    6659       28684 :     return true;
    6660             : }
    6661             : 
    6662             : /*
    6663             :  * Subroutine for parse_connection_string
    6664             :  *
    6665             :  * Deal with a URI connection string.
    6666             :  */
    6667             : static PQconninfoOption *
    6668         128 : conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage,
    6669             :                    bool use_defaults)
    6670             : {
    6671             :     PQconninfoOption *options;
    6672             : 
    6673             :     /* Make a working copy of PQconninfoOptions */
    6674         128 :     options = conninfo_init(errorMessage);
    6675         128 :     if (options == NULL)
    6676           0 :         return NULL;
    6677             : 
    6678         128 :     if (!conninfo_uri_parse_options(options, uri, errorMessage))
    6679             :     {
    6680          30 :         PQconninfoFree(options);
    6681          30 :         return NULL;
    6682             :     }
    6683             : 
    6684             :     /*
    6685             :      * Add in defaults if the caller wants that.
    6686             :      */
    6687          98 :     if (use_defaults)
    6688             :     {
    6689           0 :         if (!conninfo_add_defaults(options, errorMessage))
    6690             :         {
    6691           0 :             PQconninfoFree(options);
    6692           0 :             return NULL;
    6693             :         }
    6694             :     }
    6695             : 
    6696          98 :     return options;
    6697             : }
    6698             : 
    6699             : /*
    6700             :  * conninfo_uri_parse_options
    6701             :  *      Actual URI parser.
    6702             :  *
    6703             :  * If successful, returns true while the options array is filled with parsed
    6704             :  * options from the URI.
    6705             :  * If not successful, returns false and fills errorMessage accordingly.
    6706             :  *
    6707             :  * Parses the connection URI string in 'uri' according to the URI syntax (RFC
    6708             :  * 3986):
    6709             :  *
    6710             :  * postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
    6711             :  *
    6712             :  * where "netloc" is a hostname, an IPv4 address, or an IPv6 address surrounded
    6713             :  * by literal square brackets.  As an extension, we also allow multiple
    6714             :  * netloc[:port] specifications, separated by commas:
    6715             :  *
    6716             :  * postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...]
    6717             :  *
    6718             :  * Any of the URI parts might use percent-encoding (%xy).
    6719             :  */
    6720             : static bool
    6721         128 : conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
    6722             :                            PQExpBuffer errorMessage)
    6723             : {
    6724             :     int         prefix_len;
    6725             :     char       *p;
    6726         128 :     char       *buf = NULL;
    6727             :     char       *start;
    6728         128 :     char        prevchar = '\0';
    6729         128 :     char       *user = NULL;
    6730         128 :     char       *host = NULL;
    6731         128 :     bool        retval = false;
    6732             :     PQExpBufferData hostbuf;
    6733             :     PQExpBufferData portbuf;
    6734             : 
    6735         128 :     initPQExpBuffer(&hostbuf);
    6736         128 :     initPQExpBuffer(&portbuf);
    6737         128 :     if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
    6738             :     {
    6739           0 :         libpq_append_error(errorMessage, "out of memory");
    6740           0 :         goto cleanup;
    6741             :     }
    6742             : 
    6743             :     /* need a modifiable copy of the input URI */
    6744         128 :     buf = strdup(uri);
    6745         128 :     if (buf == NULL)
    6746             :     {
    6747           0 :         libpq_append_error(errorMessage, "out of memory");
    6748           0 :         goto cleanup;
    6749             :     }
    6750         128 :     start = buf;
    6751             : 
    6752             :     /* Skip the URI prefix */
    6753         128 :     prefix_len = uri_prefix_length(uri);
    6754         128 :     if (prefix_len == 0)
    6755             :     {
    6756             :         /* Should never happen */
    6757           0 :         libpq_append_error(errorMessage,
    6758             :                            "invalid URI propagated to internal parser routine: \"%s\"",
    6759             :                            uri);
    6760           0 :         goto cleanup;
    6761             :     }
    6762         128 :     start += prefix_len;
    6763         128 :     p = start;
    6764             : 
    6765             :     /* Look ahead for possible user credentials designator */
    6766        1508 :     while (*p && *p != '@' && *p != '/')
    6767        1380 :         ++p;
    6768         128 :     if (*p == '@')
    6769             :     {
    6770             :         /*
    6771             :          * Found username/password designator, so URI should be of the form
    6772             :          * "scheme://user[:password]@[netloc]".
    6773             :          */
    6774          24 :         user = start;
    6775             : 
    6776          24 :         p = user;
    6777         208 :         while (*p != ':' && *p != '@')
    6778         184 :             ++p;
    6779             : 
    6780             :         /* Save last char and cut off at end of user name */
    6781          24 :         prevchar = *p;
    6782          24 :         *p = '\0';
    6783             : 
    6784          46 :         if (*user &&
    6785          22 :             !conninfo_storeval(options, "user", user,
    6786             :                                errorMessage, false, true))
    6787           0 :             goto cleanup;
    6788             : 
    6789          24 :         if (prevchar == ':')
    6790             :         {
    6791           2 :             const char *password = p + 1;
    6792             : 
    6793          16 :             while (*p != '@')
    6794          14 :                 ++p;
    6795           2 :             *p = '\0';
    6796             : 
    6797           4 :             if (*password &&
    6798           2 :                 !conninfo_storeval(options, "password", password,
    6799             :                                    errorMessage, false, true))
    6800           0 :                 goto cleanup;
    6801             :         }
    6802             : 
    6803             :         /* Advance past end of parsed user name or password token */
    6804          24 :         ++p;
    6805             :     }
    6806             :     else
    6807             :     {
    6808             :         /*
    6809             :          * No username/password designator found.  Reset to start of URI.
    6810             :          */
    6811         104 :         p = start;
    6812             :     }
    6813             : 
    6814             :     /*
    6815             :      * There may be multiple netloc[:port] pairs, each separated from the next
    6816             :      * by a comma.  When we initially enter this loop, "p" has been
    6817             :      * incremented past optional URI credential information at this point and
    6818             :      * now points at the "netloc" part of the URI.  On subsequent loop
    6819             :      * iterations, "p" has been incremented past the comma separator and now
    6820             :      * points at the start of the next "netloc".
    6821             :      */
    6822             :     for (;;)
    6823             :     {
    6824             :         /*
    6825             :          * Look for IPv6 address.
    6826             :          */
    6827         128 :         if (*p == '[')
    6828             :         {
    6829          16 :             host = ++p;
    6830         102 :             while (*p && *p != ']')
    6831          86 :                 ++p;
    6832          16 :             if (!*p)
    6833             :             {
    6834           2 :                 libpq_append_error(errorMessage,
    6835             :                                    "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"",
    6836             :                                    uri);
    6837           2 :                 goto cleanup;
    6838             :             }
    6839          14 :             if (p == host)
    6840             :             {
    6841           2 :                 libpq_append_error(errorMessage,
    6842             :                                    "IPv6 host address may not be empty in URI: \"%s\"",
    6843             :                                    uri);
    6844           2 :                 goto cleanup;
    6845             :             }
    6846             : 
    6847             :             /* Cut off the bracket and advance */
    6848          12 :             *(p++) = '\0';
    6849             : 
    6850             :             /*
    6851             :              * The address may be followed by a port specifier or a slash or a
    6852             :              * query or a separator comma.
    6853             :              */
    6854          12 :             if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
    6855             :             {
    6856           2 :                 libpq_append_error(errorMessage,
    6857             :                                    "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"",
    6858           2 :                                    *p, (int) (p - buf + 1), uri);
    6859           2 :                 goto cleanup;
    6860             :             }
    6861             :         }
    6862             :         else
    6863             :         {
    6864             :             /* not an IPv6 address: DNS-named or IPv4 netloc */
    6865         112 :             host = p;
    6866             : 
    6867             :             /*
    6868             :              * Look for port specifier (colon) or end of host specifier
    6869             :              * (slash) or query (question mark) or host separator (comma).
    6870             :              */
    6871         474 :             while (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
    6872         362 :                 ++p;
    6873             :         }
    6874             : 
    6875             :         /* Save the hostname terminator before we null it */
    6876         122 :         prevchar = *p;
    6877         122 :         *p = '\0';
    6878             : 
    6879         122 :         appendPQExpBufferStr(&hostbuf, host);
    6880             : 
    6881         122 :         if (prevchar == ':')
    6882             :         {
    6883          28 :             const char *port = ++p; /* advance past host terminator */
    6884             : 
    6885         158 :             while (*p && *p != '/' && *p != '?' && *p != ',')
    6886         130 :                 ++p;
    6887             : 
    6888          28 :             prevchar = *p;
    6889          28 :             *p = '\0';
    6890             : 
    6891          28 :             appendPQExpBufferStr(&portbuf, port);
    6892             :         }
    6893             : 
    6894         122 :         if (prevchar != ',')
    6895         122 :             break;
    6896           0 :         ++p;                    /* advance past comma separator */
    6897           0 :         appendPQExpBufferChar(&hostbuf, ',');
    6898           0 :         appendPQExpBufferChar(&portbuf, ',');
    6899             :     }
    6900             : 
    6901             :     /* Save final values for host and port. */
    6902         122 :     if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
    6903           0 :         goto cleanup;
    6904         210 :     if (hostbuf.data[0] &&
    6905          88 :         !conninfo_storeval(options, "host", hostbuf.data,
    6906             :                            errorMessage, false, true))
    6907           8 :         goto cleanup;
    6908         140 :     if (portbuf.data[0] &&
    6909          26 :         !conninfo_storeval(options, "port", portbuf.data,
    6910             :                            errorMessage, false, true))
    6911           0 :         goto cleanup;
    6912             : 
    6913         114 :     if (prevchar && prevchar != '?')
    6914             :     {
    6915          56 :         const char *dbname = ++p;   /* advance past host terminator */
    6916             : 
    6917             :         /* Look for query parameters */
    6918         132 :         while (*p && *p != '?')
    6919          76 :             ++p;
    6920             : 
    6921          56 :         prevchar = *p;
    6922          56 :         *p = '\0';
    6923             : 
    6924             :         /*
    6925             :          * Avoid setting dbname to an empty string, as it forces the default
    6926             :          * value (username) and ignores $PGDATABASE, as opposed to not setting
    6927             :          * it at all.
    6928             :          */
    6929          90 :         if (*dbname &&
    6930          34 :             !conninfo_storeval(options, "dbname", dbname,
    6931             :                                errorMessage, false, true))
    6932           0 :             goto cleanup;
    6933             :     }
    6934             : 
    6935         114 :     if (prevchar)
    6936             :     {
    6937          58 :         ++p;                    /* advance past terminator */
    6938             : 
    6939          58 :         if (!conninfo_uri_parse_params(p, options, errorMessage))
    6940          16 :             goto cleanup;
    6941             :     }
    6942             : 
    6943             :     /* everything parsed okay */
    6944          98 :     retval = true;
    6945             : 
    6946         128 : cleanup:
    6947         128 :     termPQExpBuffer(&hostbuf);
    6948         128 :     termPQExpBuffer(&portbuf);
    6949         128 :     free(buf);
    6950         128 :     return retval;
    6951             : }
    6952             : 
    6953             : /*
    6954             :  * Connection URI parameters parser routine
    6955             :  *
    6956             :  * If successful, returns true while connOptions is filled with parsed
    6957             :  * parameters.  Otherwise, returns false and fills errorMessage appropriately.
    6958             :  *
    6959             :  * Destructively modifies 'params' buffer.
    6960             :  */
    6961             : static bool
    6962          58 : conninfo_uri_parse_params(char *params,
    6963             :                           PQconninfoOption *connOptions,
    6964             :                           PQExpBuffer errorMessage)
    6965             : {
    6966         106 :     while (*params)
    6967             :     {
    6968          64 :         char       *keyword = params;
    6969          64 :         char       *value = NULL;
    6970          64 :         char       *p = params;
    6971          64 :         bool        malloced = false;
    6972             :         int         oldmsglen;
    6973             : 
    6974             :         /*
    6975             :          * Scan the params string for '=' and '&', marking the end of keyword
    6976             :          * and value respectively.
    6977             :          */
    6978             :         for (;;)
    6979             :         {
    6980        1072 :             if (*p == '=')
    6981             :             {
    6982             :                 /* Was there '=' already? */
    6983          62 :                 if (value != NULL)
    6984             :                 {
    6985           2 :                     libpq_append_error(errorMessage,
    6986             :                                        "extra key/value separator \"=\" in URI query parameter: \"%s\"",
    6987             :                                        keyword);
    6988           2 :                     return false;
    6989             :                 }
    6990             :                 /* Cut off keyword, advance to value */
    6991          60 :                 *p++ = '\0';
    6992          60 :                 value = p;
    6993             :             }
    6994        1010 :             else if (*p == '&' || *p == '\0')
    6995             :             {
    6996             :                 /*
    6997             :                  * If not at the end, cut off value and advance; leave p
    6998             :                  * pointing to start of the next parameter, if any.
    6999             :                  */
    7000          62 :                 if (*p != '\0')
    7001          14 :                     *p++ = '\0';
    7002             :                 /* Was there '=' at all? */
    7003          62 :                 if (value == NULL)
    7004             :                 {
    7005           4 :                     libpq_append_error(errorMessage,
    7006             :                                        "missing key/value separator \"=\" in URI query parameter: \"%s\"",
    7007             :                                        keyword);
    7008           4 :                     return false;
    7009             :                 }
    7010             :                 /* Got keyword and value, go process them. */
    7011          58 :                 break;
    7012             :             }
    7013             :             else
    7014         948 :                 ++p;            /* Advance over all other bytes. */
    7015             :         }
    7016             : 
    7017          58 :         keyword = conninfo_uri_decode(keyword, errorMessage);
    7018          58 :         if (keyword == NULL)
    7019             :         {
    7020             :             /* conninfo_uri_decode already set an error message */
    7021           2 :             return false;
    7022             :         }
    7023          56 :         value = conninfo_uri_decode(value, errorMessage);
    7024          56 :         if (value == NULL)
    7025             :         {
    7026             :             /* conninfo_uri_decode already set an error message */
    7027           4 :             free(keyword);
    7028           4 :             return false;
    7029             :         }
    7030          52 :         malloced = true;
    7031             : 
    7032             :         /*
    7033             :          * Special keyword handling for improved JDBC compatibility.
    7034             :          */
    7035          52 :         if (strcmp(keyword, "ssl") == 0 &&
    7036           0 :             strcmp(value, "true") == 0)
    7037             :         {
    7038           0 :             free(keyword);
    7039           0 :             free(value);
    7040           0 :             malloced = false;
    7041             : 
    7042           0 :             keyword = "sslmode";
    7043           0 :             value = "require";
    7044             :         }
    7045             : 
    7046             :         /*
    7047             :          * Store the value if the corresponding option exists; ignore
    7048             :          * otherwise.  At this point both keyword and value are not
    7049             :          * URI-encoded.
    7050             :          */
    7051          52 :         oldmsglen = errorMessage->len;
    7052          52 :         if (!conninfo_storeval(connOptions, keyword, value,
    7053             :                                errorMessage, true, false))
    7054             :         {
    7055             :             /* Insert generic message if conninfo_storeval didn't give one. */
    7056           4 :             if (errorMessage->len == oldmsglen)
    7057           4 :                 libpq_append_error(errorMessage,
    7058             :                                    "invalid URI query parameter: \"%s\"",
    7059             :                                    keyword);
    7060             :             /* And fail. */
    7061           4 :             if (malloced)
    7062             :             {
    7063           4 :                 free(keyword);
    7064           4 :                 free(value);
    7065             :             }
    7066           4 :             return false;
    7067             :         }
    7068             : 
    7069          48 :         if (malloced)
    7070             :         {
    7071          48 :             free(keyword);
    7072          48 :             free(value);
    7073             :         }
    7074             : 
    7075             :         /* Proceed to next key=value pair, if any */
    7076          48 :         params = p;
    7077             :     }
    7078             : 
    7079          42 :     return true;
    7080             : }
    7081             : 
    7082             : /*
    7083             :  * Connection URI decoder routine
    7084             :  *
    7085             :  * If successful, returns the malloc'd decoded string.
    7086             :  * If not successful, returns NULL and fills errorMessage accordingly.
    7087             :  *
    7088             :  * The string is decoded by replacing any percent-encoded tokens with
    7089             :  * corresponding characters, while preserving any non-encoded characters.  A
    7090             :  * percent-encoded token is a character triplet: a percent sign, followed by a
    7091             :  * pair of hexadecimal digits (0-9A-F), where lower- and upper-case letters are
    7092             :  * treated identically.
    7093             :  */
    7094             : static char *
    7095         286 : conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
    7096             : {
    7097             :     char       *buf;            /* result */
    7098             :     char       *p;              /* output location */
    7099         286 :     const char *q = str;        /* input location */
    7100             : 
    7101         286 :     buf = malloc(strlen(str) + 1);
    7102         286 :     if (buf == NULL)
    7103             :     {
    7104           0 :         libpq_append_error(errorMessage, "out of memory");
    7105           0 :         return NULL;
    7106             :     }
    7107         286 :     p = buf;
    7108             : 
    7109             :     /* skip leading whitespaces */
    7110         312 :     for (const char *s = q; *s == ' '; s++)
    7111             :     {
    7112          26 :         q++;
    7113          26 :         continue;
    7114             :     }
    7115             : 
    7116             :     for (;;)
    7117             :     {
    7118        1904 :         if (*q != '%')
    7119             :         {
    7120             :             /* if found a whitespace or NUL, the string ends */
    7121        1882 :             if (*q == ' ' || *q == '\0')
    7122         276 :                 goto end;
    7123             : 
    7124             :             /* copy character */
    7125        1606 :             *(p++) = *(q++);
    7126             :         }
    7127             :         else
    7128             :         {
    7129             :             int         hi;
    7130             :             int         lo;
    7131             :             int         c;
    7132             : 
    7133          22 :             ++q;                /* skip the percent sign itself */
    7134             : 
    7135             :             /*
    7136             :              * Possible EOL will be caught by the first call to
    7137             :              * get_hexdigit(), so we never dereference an invalid q pointer.
    7138             :              */
    7139          22 :             if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
    7140             :             {
    7141           8 :                 libpq_append_error(errorMessage,
    7142             :                                    "invalid percent-encoded token: \"%s\"",
    7143             :                                    str);
    7144           8 :                 free(buf);
    7145          10 :                 return NULL;
    7146             :             }
    7147             : 
    7148          14 :             c = (hi << 4) | lo;
    7149          14 :             if (c == 0)
    7150             :             {
    7151           2 :                 libpq_append_error(errorMessage,
    7152             :                                    "forbidden value %%00 in percent-encoded value: \"%s\"",
    7153             :                                    str);
    7154           2 :                 free(buf);
    7155           2 :                 return NULL;
    7156             :             }
    7157          12 :             *(p++) = c;
    7158             :         }
    7159             :     }
    7160             : 
    7161         276 : end:
    7162             : 
    7163             :     /* skip trailing whitespaces */
    7164         300 :     for (const char *s = q; *s == ' '; s++)
    7165             :     {
    7166          24 :         q++;
    7167          24 :         continue;
    7168             :     }
    7169             : 
    7170             :     /* Not at the end of the string yet?  Fail. */
    7171         276 :     if (*q != '\0')
    7172             :     {
    7173           4 :         libpq_append_error(errorMessage,
    7174             :                            "unexpected spaces found in \"%s\", use percent-encoded spaces (%%20) instead",
    7175             :                            str);
    7176           4 :         free(buf);
    7177           4 :         return NULL;
    7178             :     }
    7179             : 
    7180             :     /* Copy NUL terminator */
    7181         272 :     *p = '\0';
    7182             : 
    7183         272 :     return buf;
    7184             : }
    7185             : 
    7186             : /*
    7187             :  * Convert hexadecimal digit character to its integer value.
    7188             :  *
    7189             :  * If successful, returns true and value is filled with digit's base 16 value.
    7190             :  * If not successful, returns false.
    7191             :  *
    7192             :  * Lower- and upper-case letters in the range A-F are treated identically.
    7193             :  */
    7194             : static bool
    7195          38 : get_hexdigit(char digit, int *value)
    7196             : {
    7197          38 :     if ('0' <= digit && digit <= '9')
    7198          22 :         *value = digit - '0';
    7199          16 :     else if ('A' <= digit && digit <= 'F')
    7200           6 :         *value = digit - 'A' + 10;
    7201          10 :     else if ('a' <= digit && digit <= 'f')
    7202           2 :         *value = digit - 'a' + 10;
    7203             :     else
    7204           8 :         return false;
    7205             : 
    7206          30 :     return true;
    7207             : }
    7208             : 
    7209             : /*
    7210             :  * Find an option value corresponding to the keyword in the connOptions array.
    7211             :  *
    7212             :  * If successful, returns a pointer to the corresponding option's value.
    7213             :  * If not successful, returns NULL.
    7214             :  */
    7215             : static const char *
    7216     1367066 : conninfo_getval(PQconninfoOption *connOptions,
    7217             :                 const char *keyword)
    7218             : {
    7219             :     PQconninfoOption *option;
    7220             : 
    7221     1367066 :     option = conninfo_find(connOptions, keyword);
    7222             : 
    7223     1367066 :     return option ? option->val : NULL;
    7224             : }
    7225             : 
    7226             : /*
    7227             :  * Store a (new) value for an option corresponding to the keyword in
    7228             :  * connOptions array.
    7229             :  *
    7230             :  * If uri_decode is true, the value is URI-decoded.  The keyword is always
    7231             :  * assumed to be non URI-encoded.
    7232             :  *
    7233             :  * If successful, returns a pointer to the corresponding PQconninfoOption,
    7234             :  * which value is replaced with a strdup'd copy of the passed value string.
    7235             :  * The existing value for the option is free'd before replacing, if any.
    7236             :  *
    7237             :  * If not successful, returns NULL and fills errorMessage accordingly.
    7238             :  * However, if the reason of failure is an invalid keyword being passed and
    7239             :  * ignoreMissing is true, errorMessage will be left untouched.
    7240             :  */
    7241             : static PQconninfoOption *
    7242       84738 : conninfo_storeval(PQconninfoOption *connOptions,
    7243             :                   const char *keyword, const char *value,
    7244             :                   PQExpBuffer errorMessage, bool ignoreMissing,
    7245             :                   bool uri_decode)
    7246             : {
    7247             :     PQconninfoOption *option;
    7248             :     char       *value_copy;
    7249             : 
    7250             :     /*
    7251             :      * For backwards compatibility, requiressl=1 gets translated to
    7252             :      * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
    7253             :      * (which is the default for sslmode).
    7254             :      */
    7255       84738 :     if (strcmp(keyword, "requiressl") == 0)
    7256             :     {
    7257           0 :         keyword = "sslmode";
    7258           0 :         if (value[0] == '1')
    7259           0 :             value = "require";
    7260             :         else
    7261           0 :             value = "prefer";
    7262             :     }
    7263             : 
    7264       84738 :     option = conninfo_find(connOptions, keyword);
    7265       84738 :     if (option == NULL)
    7266             :     {
    7267          10 :         if (!ignoreMissing)
    7268           6 :             libpq_append_error(errorMessage,
    7269             :                                "invalid connection option \"%s\"",
    7270             :                                keyword);
    7271          10 :         return NULL;
    7272             :     }
    7273             : 
    7274       84728 :     if (uri_decode)
    7275             :     {
    7276         172 :         value_copy = conninfo_uri_decode(value, errorMessage);
    7277         172 :         if (value_copy == NULL)
    7278             :             /* conninfo_uri_decode already set an error message */
    7279           8 :             return NULL;
    7280             :     }
    7281             :     else
    7282             :     {
    7283       84556 :         value_copy = strdup(value);
    7284       84556 :         if (value_copy == NULL)
    7285             :         {
    7286           0 :             libpq_append_error(errorMessage, "out of memory");
    7287           0 :             return NULL;
    7288             :         }
    7289             :     }
    7290             : 
    7291       84720 :     free(option->val);
    7292       84720 :     option->val = value_copy;
    7293             : 
    7294       84720 :     return option;
    7295             : }
    7296             : 
    7297             : /*
    7298             :  * Find a PQconninfoOption option corresponding to the keyword in the
    7299             :  * connOptions array.
    7300             :  *
    7301             :  * If successful, returns a pointer to the corresponding PQconninfoOption
    7302             :  * structure.
    7303             :  * If not successful, returns NULL.
    7304             :  */
    7305             : static PQconninfoOption *
    7306     1451804 : conninfo_find(PQconninfoOption *connOptions, const char *keyword)
    7307             : {
    7308             :     PQconninfoOption *option;
    7309             : 
    7310    33062158 :     for (option = connOptions; option->keyword != NULL; option++)
    7311             :     {
    7312    33062148 :         if (strcmp(option->keyword, keyword) == 0)
    7313     1451794 :             return option;
    7314             :     }
    7315             : 
    7316          10 :     return NULL;
    7317             : }
    7318             : 
    7319             : 
    7320             : /*
    7321             :  * Return the connection options used for the connection
    7322             :  */
    7323             : PQconninfoOption *
    7324         632 : PQconninfo(PGconn *conn)
    7325             : {
    7326             :     PQExpBufferData errorBuf;
    7327             :     PQconninfoOption *connOptions;
    7328             : 
    7329         632 :     if (conn == NULL)
    7330           0 :         return NULL;
    7331             : 
    7332             :     /*
    7333             :      * We don't actually report any errors here, but callees want a buffer,
    7334             :      * and we prefer not to trash the conn's errorMessage.
    7335             :      */
    7336         632 :     initPQExpBuffer(&errorBuf);
    7337         632 :     if (PQExpBufferDataBroken(errorBuf))
    7338           0 :         return NULL;            /* out of memory already :-( */
    7339             : 
    7340         632 :     connOptions = conninfo_init(&errorBuf);
    7341             : 
    7342         632 :     if (connOptions != NULL)
    7343             :     {
    7344             :         const internalPQconninfoOption *option;
    7345             : 
    7346       30336 :         for (option = PQconninfoOptions; option->keyword; option++)
    7347             :         {
    7348             :             char      **connmember;
    7349             : 
    7350       29704 :             if (option->connofs < 0)
    7351           0 :                 continue;
    7352             : 
    7353       29704 :             connmember = (char **) ((char *) conn + option->connofs);
    7354             : 
    7355       29704 :             if (*connmember)
    7356       12676 :                 conninfo_storeval(connOptions, option->keyword, *connmember,
    7357             :                                   &errorBuf, true, false);
    7358             :         }
    7359             :     }
    7360             : 
    7361         632 :     termPQExpBuffer(&errorBuf);
    7362             : 
    7363         632 :     return connOptions;
    7364             : }
    7365             : 
    7366             : 
    7367             : void
    7368       78378 : PQconninfoFree(PQconninfoOption *connOptions)
    7369             : {
    7370       78378 :     if (connOptions == NULL)
    7371       27624 :         return;
    7372             : 
    7373     2436192 :     for (PQconninfoOption *option = connOptions; option->keyword != NULL; option++)
    7374     2385438 :         free(option->val);
    7375       50754 :     free(connOptions);
    7376             : }
    7377             : 
    7378             : 
    7379             : /* =========== accessor functions for PGconn ========= */
    7380             : char *
    7381       37068 : PQdb(const PGconn *conn)
    7382             : {
    7383       37068 :     if (!conn)
    7384           2 :         return NULL;
    7385       37066 :     return conn->dbName;
    7386             : }
    7387             : 
    7388             : char *
    7389       19520 : PQservice(const PGconn *conn)
    7390             : {
    7391       19520 :     if (!conn)
    7392           0 :         return NULL;
    7393       19520 :     return conn->pgservice;
    7394             : }
    7395             : 
    7396             : char *
    7397       19544 : PQuser(const PGconn *conn)
    7398             : {
    7399       19544 :     if (!conn)
    7400           0 :         return NULL;
    7401       19544 :     return conn->pguser;
    7402             : }
    7403             : 
    7404             : char *
    7405         362 : PQpass(const PGconn *conn)
    7406             : {
    7407         362 :     char       *password = NULL;
    7408             : 
    7409         362 :     if (!conn)
    7410           0 :         return NULL;
    7411         362 :     if (conn->connhost != NULL)
    7412         352 :         password = conn->connhost[conn->whichhost].password;
    7413         362 :     if (password == NULL)
    7414         358 :         password = conn->pgpass;
    7415             :     /* Historically we've returned "" not NULL for no password specified */
    7416         362 :     if (password == NULL)
    7417         230 :         password = "";
    7418         362 :     return password;
    7419             : }
    7420             : 
    7421             : char *
    7422       19842 : PQhost(const PGconn *conn)
    7423             : {
    7424       19842 :     if (!conn)
    7425           0 :         return NULL;
    7426             : 
    7427       19842 :     if (conn->connhost != NULL)
    7428             :     {
    7429             :         /*
    7430             :          * Return the verbatim host value provided by user, or hostaddr in its
    7431             :          * lack.
    7432             :          */
    7433       19842 :         if (conn->connhost[conn->whichhost].host != NULL &&
    7434       19842 :             conn->connhost[conn->whichhost].host[0] != '\0')
    7435       19842 :             return conn->connhost[conn->whichhost].host;
    7436           0 :         else if (conn->connhost[conn->whichhost].hostaddr != NULL &&
    7437           0 :                  conn->connhost[conn->whichhost].hostaddr[0] != '\0')
    7438           0 :             return conn->connhost[conn->whichhost].hostaddr;
    7439             :     }
    7440             : 
    7441           0 :     return "";
    7442             : }
    7443             : 
    7444             : char *
    7445           0 : PQhostaddr(const PGconn *conn)
    7446             : {
    7447           0 :     if (!conn)
    7448           0 :         return NULL;
    7449             : 
    7450             :     /* Return the parsed IP address */
    7451           0 :     if (conn->connhost != NULL && conn->connip != NULL)
    7452           0 :         return conn->connip;
    7453             : 
    7454           0 :     return "";
    7455             : }
    7456             : 
    7457             : char *
    7458       19842 : PQport(const PGconn *conn)
    7459             : {
    7460       19842 :     if (!conn)
    7461           0 :         return NULL;
    7462             : 
    7463       19842 :     if (conn->connhost != NULL)
    7464       19842 :         return conn->connhost[conn->whichhost].port;
    7465             : 
    7466           0 :     return "";
    7467             : }
    7468             : 
    7469             : /*
    7470             :  * No longer does anything, but the function remains for API backwards
    7471             :  * compatibility.
    7472             :  */
    7473             : char *
    7474           0 : PQtty(const PGconn *conn)
    7475             : {
    7476           0 :     if (!conn)
    7477           0 :         return NULL;
    7478           0 :     return "";
    7479             : }
    7480             : 
    7481             : char *
    7482           0 : PQoptions(const PGconn *conn)
    7483             : {
    7484           0 :     if (!conn)
    7485           0 :         return NULL;
    7486           0 :     return conn->pgoptions;
    7487             : }
    7488             : 
    7489             : ConnStatusType
    7490      458388 : PQstatus(const PGconn *conn)
    7491             : {
    7492      458388 :     if (!conn)
    7493           0 :         return CONNECTION_BAD;
    7494      458388 :     return conn->status;
    7495             : }
    7496             : 
    7497             : PGTransactionStatusType
    7498      371618 : PQtransactionStatus(const PGconn *conn)
    7499             : {
    7500      371618 :     if (!conn || conn->status != CONNECTION_OK)
    7501           0 :         return PQTRANS_UNKNOWN;
    7502      371618 :     if (conn->asyncStatus != PGASYNC_IDLE)
    7503        1174 :         return PQTRANS_ACTIVE;
    7504      370444 :     return conn->xactStatus;
    7505             : }
    7506             : 
    7507             : const char *
    7508      683016 : PQparameterStatus(const PGconn *conn, const char *paramName)
    7509             : {
    7510             :     const pgParameterStatus *pstatus;
    7511             : 
    7512      683016 :     if (!conn || !paramName)
    7513           0 :         return NULL;
    7514     3565586 :     for (pstatus = conn->pstatus; pstatus != NULL; pstatus = pstatus->next)
    7515             :     {
    7516     3565586 :         if (strcmp(pstatus->name, paramName) == 0)
    7517      683016 :             return pstatus->value;
    7518             :     }
    7519           0 :     return NULL;
    7520             : }
    7521             : 
    7522             : int
    7523           0 : PQprotocolVersion(const PGconn *conn)
    7524             : {
    7525           0 :     if (!conn)
    7526           0 :         return 0;
    7527           0 :     if (conn->status == CONNECTION_BAD)
    7528           0 :         return 0;
    7529           0 :     return PG_PROTOCOL_MAJOR(conn->pversion);
    7530             : }
    7531             : 
    7532             : int
    7533           0 : PQfullProtocolVersion(const PGconn *conn)
    7534             : {
    7535           0 :     if (!conn)
    7536           0 :         return 0;
    7537           0 :     if (conn->status == CONNECTION_BAD)
    7538           0 :         return 0;
    7539           0 :     return PG_PROTOCOL_FULL(conn->pversion);
    7540             : }
    7541             : 
    7542             : int
    7543       50364 : PQserverVersion(const PGconn *conn)
    7544             : {
    7545       50364 :     if (!conn)
    7546           0 :         return 0;
    7547       50364 :     if (conn->status == CONNECTION_BAD)
    7548           0 :         return 0;
    7549       50364 :     return conn->sversion;
    7550             : }
    7551             : 
    7552             : char *
    7553        1504 : PQerrorMessage(const PGconn *conn)
    7554             : {
    7555        1504 :     if (!conn)
    7556           0 :         return libpq_gettext("connection pointer is NULL\n");
    7557             : 
    7558             :     /*
    7559             :      * The errorMessage buffer might be marked "broken" due to having
    7560             :      * previously failed to allocate enough memory for the message.  In that
    7561             :      * case, tell the application we ran out of memory.
    7562             :      */
    7563        1504 :     if (PQExpBufferBroken(&conn->errorMessage))
    7564           0 :         return libpq_gettext("out of memory\n");
    7565             : 
    7566        1504 :     return conn->errorMessage.data;
    7567             : }
    7568             : 
    7569             : /*
    7570             :  * In Windows, socket values are unsigned, and an invalid socket value
    7571             :  * (INVALID_SOCKET) is ~0, which equals -1 in comparisons (with no compiler
    7572             :  * warning). Ideally we would return an unsigned value for PQsocket() on
    7573             :  * Windows, but that would cause the function's return value to differ from
    7574             :  * Unix, so we just return -1 for invalid sockets.
    7575             :  * http://msdn.microsoft.com/en-us/library/windows/desktop/cc507522%28v=vs.85%29.aspx
    7576             :  * http://stackoverflow.com/questions/10817252/why-is-invalid-socket-defined-as-0-in-winsock2-h-c
    7577             :  */
    7578             : int
    7579      449326 : PQsocket(const PGconn *conn)
    7580             : {
    7581      449326 :     if (!conn)
    7582           0 :         return -1;
    7583      449326 :     if (conn->altsock != PGINVALID_SOCKET)
    7584           0 :         return conn->altsock;
    7585      449326 :     return (conn->sock != PGINVALID_SOCKET) ? conn->sock : -1;
    7586             : }
    7587             : 
    7588             : int
    7589        1524 : PQbackendPID(const PGconn *conn)
    7590             : {
    7591        1524 :     if (!conn || conn->status != CONNECTION_OK)
    7592           0 :         return 0;
    7593        1524 :     return conn->be_pid;
    7594             : }
    7595             : 
    7596             : PGpipelineStatus
    7597     1363354 : PQpipelineStatus(const PGconn *conn)
    7598             : {
    7599     1363354 :     if (!conn)
    7600           0 :         return PQ_PIPELINE_OFF;
    7601             : 
    7602     1363354 :     return conn->pipelineStatus;
    7603             : }
    7604             : 
    7605             : int
    7606         362 : PQconnectionNeedsPassword(const PGconn *conn)
    7607             : {
    7608             :     char       *password;
    7609             : 
    7610         362 :     if (!conn)
    7611           0 :         return false;
    7612         362 :     password = PQpass(conn);
    7613         362 :     if (conn->password_needed &&
    7614          52 :         (password == NULL || password[0] == '\0'))
    7615           2 :         return true;
    7616             :     else
    7617         360 :         return false;
    7618             : }
    7619             : 
    7620             : int
    7621         676 : PQconnectionUsedPassword(const PGconn *conn)
    7622             : {
    7623         676 :     if (!conn)
    7624           0 :         return false;
    7625         676 :     if (conn->password_needed)
    7626          14 :         return true;
    7627             :     else
    7628         662 :         return false;
    7629             : }
    7630             : 
    7631             : int
    7632           0 : PQconnectionUsedGSSAPI(const PGconn *conn)
    7633             : {
    7634           0 :     if (!conn)
    7635           0 :         return false;
    7636           0 :     if (conn->gssapi_used)
    7637           0 :         return true;
    7638             :     else
    7639           0 :         return false;
    7640             : }
    7641             : 
    7642             : int
    7643      382268 : PQclientEncoding(const PGconn *conn)
    7644             : {
    7645      382268 :     if (!conn || conn->status != CONNECTION_OK)
    7646           0 :         return -1;
    7647      382268 :     return conn->client_encoding;
    7648             : }
    7649             : 
    7650             : int
    7651         170 : PQsetClientEncoding(PGconn *conn, const char *encoding)
    7652             : {
    7653             :     char        qbuf[128];
    7654             :     static const char query[] = "set client_encoding to '%s'";
    7655             :     PGresult   *res;
    7656             :     int         status;
    7657             : 
    7658         170 :     if (!conn || conn->status != CONNECTION_OK)
    7659           0 :         return -1;
    7660             : 
    7661         170 :     if (!encoding)
    7662           0 :         return -1;
    7663             : 
    7664             :     /* Resolve special "auto" value from the locale */
    7665         170 :     if (strcmp(encoding, "auto") == 0)
    7666           0 :         encoding = pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true));
    7667             : 
    7668             :     /* check query buffer overflow */
    7669         170 :     if (sizeof(qbuf) < (sizeof(query) + strlen(encoding)))
    7670           0 :         return -1;
    7671             : 
    7672             :     /* ok, now send a query */
    7673         170 :     sprintf(qbuf, query, encoding);
    7674         170 :     res = PQexec(conn, qbuf);
    7675             : 
    7676         170 :     if (res == NULL)
    7677           0 :         return -1;
    7678         170 :     if (res->resultStatus != PGRES_COMMAND_OK)
    7679           0 :         status = -1;
    7680             :     else
    7681             :     {
    7682             :         /*
    7683             :          * We rely on the backend to report the parameter value, and we'll
    7684             :          * change state at that time.
    7685             :          */
    7686         170 :         status = 0;             /* everything is ok */
    7687             :     }
    7688         170 :     PQclear(res);
    7689         170 :     return status;
    7690             : }
    7691             : 
    7692             : PGVerbosity
    7693       19688 : PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
    7694             : {
    7695             :     PGVerbosity old;
    7696             : 
    7697       19688 :     if (!conn)
    7698           0 :         return PQERRORS_DEFAULT;
    7699       19688 :     old = conn->verbosity;
    7700       19688 :     conn->verbosity = verbosity;
    7701       19688 :     return old;
    7702             : }
    7703             : 
    7704             : PGContextVisibility
    7705       19574 : PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
    7706             : {
    7707             :     PGContextVisibility old;
    7708             : 
    7709       19574 :     if (!conn)
    7710           0 :         return PQSHOW_CONTEXT_ERRORS;
    7711       19574 :     old = conn->show_context;
    7712       19574 :     conn->show_context = show_context;
    7713       19574 :     return old;
    7714             : }
    7715             : 
    7716             : PQnoticeReceiver
    7717         522 : PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
    7718             : {
    7719             :     PQnoticeReceiver old;
    7720             : 
    7721         522 :     if (conn == NULL)
    7722           0 :         return NULL;
    7723             : 
    7724         522 :     old = conn->noticeHooks.noticeRec;
    7725         522 :     if (proc)
    7726             :     {
    7727         522 :         conn->noticeHooks.noticeRec = proc;
    7728         522 :         conn->noticeHooks.noticeRecArg = arg;
    7729             :     }
    7730         522 :     return old;
    7731             : }
    7732             : 
    7733             : PQnoticeProcessor
    7734       21142 : PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
    7735             : {
    7736             :     PQnoticeProcessor old;
    7737             : 
    7738       21142 :     if (conn == NULL)
    7739           0 :         return NULL;
    7740             : 
    7741       21142 :     old = conn->noticeHooks.noticeProc;
    7742       21142 :     if (proc)
    7743             :     {
    7744       21142 :         conn->noticeHooks.noticeProc = proc;
    7745       21142 :         conn->noticeHooks.noticeProcArg = arg;
    7746             :     }
    7747       21142 :     return old;
    7748             : }
    7749             : 
    7750             : /*
    7751             :  * The default notice message receiver just gets the standard notice text
    7752             :  * and sends it to the notice processor.  This two-level setup exists
    7753             :  * mostly for backwards compatibility; perhaps we should deprecate use of
    7754             :  * PQsetNoticeProcessor?
    7755             :  */
    7756             : static void
    7757      156184 : defaultNoticeReceiver(void *arg, const PGresult *res)
    7758             : {
    7759             :     (void) arg;                 /* not used */
    7760      156184 :     if (res->noticeHooks.noticeProc != NULL)
    7761      156184 :         res->noticeHooks.noticeProc(res->noticeHooks.noticeProcArg,
    7762      156184 :                                     PQresultErrorMessage(res));
    7763      156184 : }
    7764             : 
    7765             : /*
    7766             :  * The default notice message processor just prints the
    7767             :  * message on stderr.  Applications can override this if they
    7768             :  * want the messages to go elsewhere (a window, for example).
    7769             :  * Note that simply discarding notices is probably a bad idea.
    7770             :  */
    7771             : static void
    7772         146 : defaultNoticeProcessor(void *arg, const char *message)
    7773             : {
    7774             :     (void) arg;                 /* not used */
    7775             :     /* Note: we expect the supplied string to end with a newline already. */
    7776         146 :     fprintf(stderr, "%s", message);
    7777         146 : }
    7778             : 
    7779             : /*
    7780             :  * returns a pointer to the next token or NULL if the current
    7781             :  * token doesn't match
    7782             :  */
    7783             : static char *
    7784          92 : pwdfMatchesString(char *buf, const char *token)
    7785             : {
    7786             :     char       *tbuf;
    7787             :     const char *ttok;
    7788          92 :     bool        bslash = false;
    7789             : 
    7790          92 :     if (buf == NULL || token == NULL)
    7791           0 :         return NULL;
    7792          92 :     tbuf = buf;
    7793          92 :     ttok = token;
    7794          92 :     if (tbuf[0] == '*' && tbuf[1] == ':')
    7795          56 :         return tbuf + 2;
    7796         292 :     while (*tbuf != 0)
    7797             :     {
    7798         292 :         if (*tbuf == '\\' && !bslash)
    7799             :         {
    7800           0 :             tbuf++;
    7801           0 :             bslash = true;
    7802             :         }
    7803         292 :         if (*tbuf == ':' && *ttok == 0 && !bslash)
    7804          26 :             return tbuf + 1;
    7805         266 :         bslash = false;
    7806         266 :         if (*ttok == 0)
    7807           0 :             return NULL;
    7808         266 :         if (*tbuf == *ttok)
    7809             :         {
    7810         256 :             tbuf++;
    7811         256 :             ttok++;
    7812             :         }
    7813             :         else
    7814          10 :             return NULL;
    7815             :     }
    7816           0 :     return NULL;
    7817             : }
    7818             : 
    7819             : /* Get a password from the password file. Return value is malloc'd. */
    7820             : static char *
    7821       28292 : passwordFromFile(const char *hostname, const char *port, const char *dbname,
    7822             :                  const char *username, const char *pgpassfile)
    7823             : {
    7824             :     FILE       *fp;
    7825             : #ifndef WIN32
    7826             :     struct stat stat_buf;
    7827             : #endif
    7828             :     PQExpBufferData buf;
    7829             : 
    7830       28292 :     if (dbname == NULL || dbname[0] == '\0')
    7831           0 :         return NULL;
    7832             : 
    7833       28292 :     if (username == NULL || username[0] == '\0')
    7834           0 :         return NULL;
    7835             : 
    7836             :     /* 'localhost' matches pghost of '' or the default socket directory */
    7837       28292 :     if (hostname == NULL || hostname[0] == '\0')
    7838           0 :         hostname = DefaultHost;
    7839       28292 :     else if (is_unixsock_path(hostname))
    7840             : 
    7841             :         /*
    7842             :          * We should probably use canonicalize_path(), but then we have to
    7843             :          * bring path.c into libpq, and it doesn't seem worth it.
    7844             :          */
    7845       27700 :         if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
    7846           0 :             hostname = DefaultHost;
    7847             : 
    7848       28292 :     if (port == NULL || port[0] == '\0')
    7849           0 :         port = DEF_PGPORT_STR;
    7850             : 
    7851             :     /* If password file cannot be opened, ignore it. */
    7852       28292 :     fp = fopen(pgpassfile, "r");
    7853       28292 :     if (fp == NULL)
    7854       28276 :         return NULL;
    7855             : 
    7856             : #ifndef WIN32
    7857          16 :     if (fstat(fileno(fp), &stat_buf) != 0)
    7858             :     {
    7859           0 :         fclose(fp);
    7860           0 :         return NULL;
    7861             :     }
    7862             : 
    7863          16 :     if (!S_ISREG(stat_buf.st_mode))
    7864             :     {
    7865           0 :         fprintf(stderr,
    7866           0 :                 libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
    7867             :                 pgpassfile);
    7868           0 :         fclose(fp);
    7869           0 :         return NULL;
    7870             :     }
    7871             : 
    7872             :     /* If password file is insecure, alert the user and ignore it. */
    7873          16 :     if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
    7874             :     {
    7875           0 :         fprintf(stderr,
    7876           0 :                 libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
    7877             :                 pgpassfile);
    7878           0 :         fclose(fp);
    7879           0 :         return NULL;
    7880             :     }
    7881             : #else
    7882             : 
    7883             :     /*
    7884             :      * On Win32, the directory is protected, so we don't have to check the
    7885             :      * file.
    7886             :      */
    7887             : #endif
    7888             : 
    7889             :     /* Use an expansible buffer to accommodate any reasonable line length */
    7890          16 :     initPQExpBuffer(&buf);
    7891             : 
    7892          80 :     while (!feof(fp) && !ferror(fp))
    7893             :     {
    7894             :         /* Make sure there's a reasonable amount of room in the buffer */
    7895          80 :         if (!enlargePQExpBuffer(&buf, 128))
    7896           0 :             break;
    7897             : 
    7898             :         /* Read some data, appending it to what we already have */
    7899          80 :         if (fgets(buf.data + buf.len, buf.maxlen - buf.len, fp) == NULL)
    7900           2 :             break;
    7901          78 :         buf.len += strlen(buf.data + buf.len);
    7902             : 
    7903             :         /* If we don't yet have a whole line, loop around to read more */
    7904          78 :         if (!(buf.len > 0 && buf.data[buf.len - 1] == '\n') && !feof(fp))
    7905          16 :             continue;
    7906             : 
    7907             :         /* ignore comments */
    7908          62 :         if (buf.data[0] != '#')
    7909             :         {
    7910          46 :             char       *t = buf.data;
    7911             :             int         len;
    7912             : 
    7913             :             /* strip trailing newline and carriage return */
    7914          46 :             len = pg_strip_crlf(t);
    7915             : 
    7916          70 :             if (len > 0 &&
    7917          48 :                 (t = pwdfMatchesString(t, hostname)) != NULL &&
    7918          48 :                 (t = pwdfMatchesString(t, port)) != NULL &&
    7919          44 :                 (t = pwdfMatchesString(t, dbname)) != NULL &&
    7920          20 :                 (t = pwdfMatchesString(t, username)) != NULL)
    7921             :             {
    7922             :                 /* Found a match. */
    7923             :                 char       *ret,
    7924             :                            *p1,
    7925             :                            *p2;
    7926             : 
    7927          14 :                 ret = strdup(t);
    7928             : 
    7929          14 :                 fclose(fp);
    7930          14 :                 explicit_bzero(buf.data, buf.maxlen);
    7931          14 :                 termPQExpBuffer(&buf);
    7932             : 
    7933          14 :                 if (!ret)
    7934             :                 {
    7935             :                     /* Out of memory. XXX: an error message would be nice. */
    7936           0 :                     return NULL;
    7937             :                 }
    7938             : 
    7939             :                 /* De-escape password. */
    7940          70 :                 for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
    7941             :                 {
    7942          56 :                     if (*p1 == '\\' && p1[1] != '\0')
    7943           6 :                         ++p1;
    7944          56 :                     *p2 = *p1;
    7945             :                 }
    7946          14 :                 *p2 = '\0';
    7947             : 
    7948          14 :                 return ret;
    7949             :             }
    7950             :         }
    7951             : 
    7952             :         /* No match, reset buffer to prepare for next line. */
    7953          48 :         buf.len = 0;
    7954             :     }
    7955             : 
    7956           2 :     fclose(fp);
    7957           2 :     explicit_bzero(buf.data, buf.maxlen);
    7958           2 :     termPQExpBuffer(&buf);
    7959           2 :     return NULL;
    7960             : }
    7961             : 
    7962             : 
    7963             : /*
    7964             :  *  If the connection failed due to bad password, we should mention
    7965             :  *  if we got the password from the pgpassfile.
    7966             :  */
    7967             : static void
    7968          96 : pgpassfileWarning(PGconn *conn)
    7969             : {
    7970             :     /* If it was 'invalid authorization', add pgpassfile mention */
    7971             :     /* only works with >= 9.0 servers */
    7972          96 :     if (conn->password_needed &&
    7973          42 :         conn->connhost[conn->whichhost].password != NULL &&
    7974           0 :         conn->result)
    7975             :     {
    7976           0 :         const char *sqlstate = PQresultErrorField(conn->result,
    7977             :                                                   PG_DIAG_SQLSTATE);
    7978             : 
    7979           0 :         if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
    7980           0 :             libpq_append_conn_error(conn, "password retrieved from file \"%s\"",
    7981             :                                     conn->pgpassfile);
    7982             :     }
    7983          96 : }
    7984             : 
    7985             : /*
    7986             :  * Check if the SSL protocol value given in input is valid or not.
    7987             :  * This is used as a sanity check routine for the connection parameters
    7988             :  * ssl_min_protocol_version and ssl_max_protocol_version.
    7989             :  */
    7990             : static bool
    7991       56854 : sslVerifyProtocolVersion(const char *version)
    7992             : {
    7993             :     /*
    7994             :      * An empty string and a NULL value are considered valid as it is
    7995             :      * equivalent to ignoring the parameter.
    7996             :      */
    7997       56854 :     if (!version || strlen(version) == 0)
    7998       28418 :         return true;
    7999             : 
    8000       56872 :     if (pg_strcasecmp(version, "TLSv1") == 0 ||
    8001       56870 :         pg_strcasecmp(version, "TLSv1.1") == 0 ||
    8002       28438 :         pg_strcasecmp(version, "TLSv1.2") == 0 ||
    8003           4 :         pg_strcasecmp(version, "TLSv1.3") == 0)
    8004       28432 :         return true;
    8005             : 
    8006             :     /* anything else is wrong */
    8007           4 :     return false;
    8008             : }
    8009             : 
    8010             : 
    8011             : /*
    8012             :  * Ensure that the SSL protocol range given in input is correct.  The check
    8013             :  * is performed on the input string to keep it TLS backend agnostic.  Input
    8014             :  * to this function is expected verified with sslVerifyProtocolVersion().
    8015             :  */
    8016             : static bool
    8017       28424 : sslVerifyProtocolRange(const char *min, const char *max)
    8018             : {
    8019             :     Assert(sslVerifyProtocolVersion(min) &&
    8020             :            sslVerifyProtocolVersion(max));
    8021             : 
    8022             :     /* If at least one of the bounds is not set, the range is valid */
    8023       28424 :     if (min == NULL || max == NULL || strlen(min) == 0 || strlen(max) == 0)
    8024       28418 :         return true;
    8025             : 
    8026             :     /*
    8027             :      * If the minimum version is the lowest one we accept, then all options
    8028             :      * for the maximum are valid.
    8029             :      */
    8030           6 :     if (pg_strcasecmp(min, "TLSv1") == 0)
    8031           0 :         return true;
    8032             : 
    8033             :     /*
    8034             :      * The minimum bound is valid, and cannot be TLSv1, so using TLSv1 for the
    8035             :      * maximum is incorrect.
    8036             :      */
    8037           6 :     if (pg_strcasecmp(max, "TLSv1") == 0)
    8038           0 :         return false;
    8039             : 
    8040             :     /*
    8041             :      * At this point we know that we have a mix of TLSv1.1 through 1.3
    8042             :      * versions.
    8043             :      */
    8044           6 :     if (pg_strcasecmp(min, max) > 0)
    8045           2 :         return false;
    8046             : 
    8047           4 :     return true;
    8048             : }
    8049             : 
    8050             : 
    8051             : /*
    8052             :  * Obtain user's home directory, return in given buffer
    8053             :  *
    8054             :  * On Unix, this actually returns the user's home directory.  On Windows
    8055             :  * it returns the PostgreSQL-specific application data folder.
    8056             :  *
    8057             :  * This is essentially the same as get_home_path(), but we don't use that
    8058             :  * because we don't want to pull path.c into libpq (it pollutes application
    8059             :  * namespace).
    8060             :  *
    8061             :  * Returns true on success, false on failure to obtain the directory name.
    8062             :  *
    8063             :  * CAUTION: although in most situations failure is unexpected, there are users
    8064             :  * who like to run applications in a home-directory-less environment.  On
    8065             :  * failure, you almost certainly DO NOT want to report an error.  Just act as
    8066             :  * though whatever file you were hoping to find in the home directory isn't
    8067             :  * there (which it isn't).
    8068             :  */
    8069             : bool
    8070       27710 : pqGetHomeDirectory(char *buf, int bufsize)
    8071             : {
    8072             : #ifndef WIN32
    8073             :     const char *home;
    8074             : 
    8075       27710 :     home = getenv("HOME");
    8076       27710 :     if (home && home[0])
    8077             :     {
    8078       27710 :         strlcpy(buf, home, bufsize);
    8079       27710 :         return true;
    8080             :     }
    8081             :     else
    8082             :     {
    8083             :         struct passwd pwbuf;
    8084             :         struct passwd *pw;
    8085             :         char        tmpbuf[1024];
    8086             :         int         rc;
    8087             : 
    8088           0 :         rc = getpwuid_r(geteuid(), &pwbuf, tmpbuf, sizeof tmpbuf, &pw);
    8089           0 :         if (rc != 0 || !pw)
    8090           0 :             return false;
    8091           0 :         strlcpy(buf, pw->pw_dir, bufsize);
    8092           0 :         return true;
    8093             :     }
    8094             : #else
    8095             :     char        tmppath[MAX_PATH];
    8096             : 
    8097             :     ZeroMemory(tmppath, sizeof(tmppath));
    8098             :     if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
    8099             :         return false;
    8100             :     snprintf(buf, bufsize, "%s/postgresql", tmppath);
    8101             :     return true;
    8102             : #endif
    8103             : }
    8104             : 
    8105             : /*
    8106             :  * Parse and try to interpret "value" as an integer value, and if successful,
    8107             :  * store it in *result, complaining if there is any trailing garbage or an
    8108             :  * overflow.  This allows any number of leading and trailing whitespaces.
    8109             :  */
    8110             : bool
    8111       28448 : pqParseIntParam(const char *value, int *result, PGconn *conn,
    8112             :                 const char *context)
    8113             : {
    8114             :     char       *end;
    8115             :     long        numval;
    8116             : 
    8117             :     Assert(value != NULL);
    8118             : 
    8119       28448 :     *result = 0;
    8120             : 
    8121             :     /* strtol(3) skips leading whitespaces */
    8122       28448 :     errno = 0;
    8123       28448 :     numval = strtol(value, &end, 10);
    8124             : 
    8125             :     /*
    8126             :      * If no progress was done during the parsing or an error happened, fail.
    8127             :      * This tests properly for overflows of the result.
    8128             :      */
    8129       28448 :     if (value == end || errno != 0 || numval != (int) numval)
    8130           0 :         goto error;
    8131             : 
    8132             :     /*
    8133             :      * Skip any trailing whitespace; if anything but whitespace remains before
    8134             :      * the terminating character, fail
    8135             :      */
    8136       28448 :     while (*end != '\0' && isspace((unsigned char) *end))
    8137           0 :         end++;
    8138             : 
    8139       28448 :     if (*end != '\0')
    8140           0 :         goto error;
    8141             : 
    8142       28448 :     *result = numval;
    8143       28448 :     return true;
    8144             : 
    8145           0 : error:
    8146           0 :     libpq_append_conn_error(conn, "invalid integer value \"%s\" for connection option \"%s\"",
    8147             :                             value, context);
    8148           0 :     return false;
    8149             : }
    8150             : 
    8151             : /*
    8152             :  * To keep the API consistent, the locking stubs are always provided, even
    8153             :  * if they are not required.
    8154             :  *
    8155             :  * Since we neglected to provide any error-return convention in the
    8156             :  * pgthreadlock_t API, we can't do much except Assert upon failure of any
    8157             :  * mutex primitive.  Fortunately, such failures appear to be nonexistent in
    8158             :  * the field.
    8159             :  */
    8160             : 
    8161             : static void
    8162           0 : default_threadlock(int acquire)
    8163             : {
    8164             :     static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
    8165             : 
    8166           0 :     if (acquire)
    8167             :     {
    8168           0 :         if (pthread_mutex_lock(&singlethread_lock))
    8169             :             Assert(false);
    8170             :     }
    8171             :     else
    8172             :     {
    8173           0 :         if (pthread_mutex_unlock(&singlethread_lock))
    8174             :             Assert(false);
    8175             :     }
    8176           0 : }
    8177             : 
    8178             : pgthreadlock_t
    8179           0 : PQregisterThreadLock(pgthreadlock_t newhandler)
    8180             : {
    8181           0 :     pgthreadlock_t prev = pg_g_threadlock;
    8182             : 
    8183           0 :     if (newhandler)
    8184           0 :         pg_g_threadlock = newhandler;
    8185             :     else
    8186           0 :         pg_g_threadlock = default_threadlock;
    8187             : 
    8188           0 :     return prev;
    8189             : }

Generated by: LCOV version 1.14