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