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