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