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