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