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