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