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