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